From e564e5c1aced8463442163abc77851d73e31117c Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 12 Sep 2022 20:54:07 +0300 Subject: [PATCH 01/36] sspi: init pku2u module; implement Negotiate state for Pku2u --- Cargo.toml | 9 +- src/sspi.rs | 5 + src/sspi/kerberos.rs | 7 +- src/sspi/kerberos/client/generators.rs | 4 +- src/sspi/kerberos/utils.rs | 11 -- src/sspi/pku2u.rs | 252 +++++++++++++++++++++++++ src/sspi/pku2u/generators.rs | 78 ++++++++ src/utils.rs | 10 + 8 files changed, 355 insertions(+), 21 deletions(-) create mode 100644 src/sspi/pku2u.rs create mode 100644 src/sspi/pku2u/generators.rs diff --git a/Cargo.toml b/Cargo.toml index 91587bdb..22623674 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,11 +37,12 @@ serde_derive = "1.0" winapi = { version = "0.3", features = ["sspi", "rpcdce", "impl-default", "timezoneapi", "wincrypt"] } url = "2.2.2" reqwest = { version = "0.11", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], optional = true, default-features = false } -picky-krb = "0.4.0" -picky-asn1 = { version = "0.5.0", features = ["chrono_conversion"] } -picky-asn1-der = "0.3.1" -picky-asn1-x509 = "0.7.0" +picky-krb = { path = "../picky-rs/picky-krb" } +picky-asn1 = { path = "../picky-rs/picky-asn1", features = ["chrono_conversion"] } +picky-asn1-der = { path = "../picky-rs/picky-asn1-der" } +picky-asn1-x509 = { path = "../picky-rs/picky-asn1-x509" } oid = "0.2.1" +uuid = "1.1" whoami = "0.5" trust-dns-resolver = { version = "0.21.2", optional = true } portpicker = { version = "0.1.1", optional = true } diff --git a/src/sspi.rs b/src/sspi.rs index f54434ce..0acdb7db 100644 --- a/src/sspi.rs +++ b/src/sspi.rs @@ -4,6 +4,7 @@ pub mod channel_bindings; pub mod internal; pub mod kerberos; pub mod negotiate; +pub mod pku2u; #[cfg(windows)] pub mod winapi; @@ -60,6 +61,7 @@ pub fn query_security_package_info(package_type: SecurityPackageType) -> Result< SecurityPackageType::Ntlm => Ok(ntlm::PACKAGE_INFO.clone()), SecurityPackageType::Kerberos => Ok(kerberos::PACKAGE_INFO.clone()), SecurityPackageType::Negotiate => Ok(negotiate::PACKAGE_INFO.clone()), + SecurityPackageType::Pku2u => Ok(pku2u::PACKAGE_INFO.clone()), SecurityPackageType::Other(s) => Err(Error::new( ErrorKind::Unknown, format!("Queried info about unknown package: {:?}", s), @@ -1071,6 +1073,7 @@ pub enum SecurityPackageType { Ntlm, Kerberos, Negotiate, + Pku2u, Other(String), } @@ -1080,6 +1083,7 @@ impl AsRef for SecurityPackageType { SecurityPackageType::Ntlm => ntlm::PKG_NAME, SecurityPackageType::Kerberos => kerberos::PKG_NAME, SecurityPackageType::Negotiate => negotiate::PKG_NAME, + SecurityPackageType::Pku2u => pku2u::PKG_NAME, SecurityPackageType::Other(name) => name.as_str(), } } @@ -1091,6 +1095,7 @@ impl string::ToString for SecurityPackageType { SecurityPackageType::Ntlm => ntlm::PKG_NAME.into(), SecurityPackageType::Kerberos => kerberos::PKG_NAME.into(), SecurityPackageType::Negotiate => negotiate::PKG_NAME.into(), + SecurityPackageType::Pku2u => pku2u::PKG_NAME.into(), SecurityPackageType::Other(name) => name.clone(), } } diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 6115a8f2..ef662290 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -30,7 +30,7 @@ use self::client::generators::{ }; use self::config::{KdcType, KerberosConfig}; use self::server::extractors::extract_tgt_ticket; -use self::utils::{serialize_message, utf16_bytes_to_utf8_string}; +use self::utils::serialize_message; use super::channel_bindings::ChannelBindings; use crate::builders::ChangePassword; use crate::kerberos::client::extractors::extract_status_code_from_krb_priv_response; @@ -42,6 +42,7 @@ use crate::sspi::kerberos::server::extractors::{ use crate::sspi::kerberos::utils::{generate_initiator_raw, validate_mic_token}; use crate::sspi::ntlm::AuthIdentityBuffers; use crate::sspi::{self, Error, ErrorKind, Result, Sspi, SspiEx, SspiImpl, PACKAGE_ID_NONE}; +use crate::utils::utf16_bytes_to_utf8_string; use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, InitializeSecurityContextResult, PackageCapabilities, PackageInfo, @@ -63,9 +64,9 @@ const DEFAULT_ENCRYPTION_TYPE: CipherSuite = CipherSuite::Aes256CtsHmacSha196; /// The RRC field is 12 if no encryption is requested or 28 if encryption is requested const RRC: u16 = 28; // wrap token header len -const MAX_SIGNATURE: usize = 16; +pub const MAX_SIGNATURE: usize = 16; // minimal len to fit encrypted public key in wrap token -const SECURITY_TRAILER: usize = 60; +pub const SECURITY_TRAILER: usize = 60; /// [Kerberos Change Password and Set Password Protocols](https://datatracker.ietf.org/doc/html/rfc3244#section-2) /// "The service accepts requests on UDP port 464 and TCP port 464 as well." const KPASSWD_PORT: u16 = 464; diff --git a/src/sspi/kerberos/client/generators.rs b/src/sspi/kerberos/client/generators.rs index 68a65a62..f8512dba 100644 --- a/src/sspi/kerberos/client/generators.rs +++ b/src/sspi/kerberos/client/generators.rs @@ -521,9 +521,7 @@ pub fn generate_krb_priv_request( )))), s_address: ExplicitContextTag4::from(HostAddress { addr_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![NET_BIOS_ADDR_TYPE])), - address: ExplicitContextTag1::from(OctetStringAsn1::from( - whoami::hostname().as_bytes().to_vec(), - )), + address: ExplicitContextTag1::from(OctetStringAsn1::from(whoami::hostname().as_bytes().to_vec())), }), r_address: Optional::from(None), }); diff --git a/src/sspi/kerberos/utils.rs b/src/sspi/kerberos/utils.rs index 1351dffa..539be35b 100644 --- a/src/sspi/kerberos/utils.rs +++ b/src/sspi/kerberos/utils.rs @@ -1,4 +1,3 @@ -use std::convert::TryInto; use std::io::Write; use picky_krb::constants::key_usages::INITIATOR_SIGN; @@ -23,16 +22,6 @@ pub fn serialize_message(v: &T) -> Result> { Ok(data) } -pub fn utf16_bytes_to_utf8_string(data: &[u8]) -> String { - debug_assert_eq!(data.len() % 2, 0); - String::from_utf16_lossy( - &data - .chunks(2) - .map(|c| u16::from_le_bytes(c.try_into().unwrap())) - .collect::>(), - ) -} - pub fn validate_mic_token(raw_token: &[u8], key_usage: i32, params: &EncryptionParams) -> Result<()> { let token = MicToken::decode(raw_token)?; diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs new file mode 100644 index 00000000..35ec25c4 --- /dev/null +++ b/src/sspi/pku2u.rs @@ -0,0 +1,252 @@ +mod generators; + +use std::io::Write; +use std::str::FromStr; + +use lazy_static::lazy_static; +use picky_asn1_x509::Certificate; +use picky_krb::negoex::data_types::MessageType; +use picky_krb::negoex::messages::{Exchange, Nego}; +use picky_krb::negoex::{NegoexMessage, RANDOM_ARRAY_SIZE}; +use rand::rngs::OsRng; +use rand::Rng; +use uuid::Uuid; + +use self::generators::{generate_neg_token_init, generate_pku2u_nego_req}; +use crate::builders::ChangePassword; +use crate::internal::SspiImpl; +use crate::kerberos::{EncryptionParams, MAX_SIGNATURE, SECURITY_TRAILER}; +use crate::sspi::{self, PACKAGE_ID_NONE}; +use crate::utils::utf16_bytes_to_utf8_string; +use crate::{ + AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, AuthIdentityBuffers, CertTrustStatus, + ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, EncryptionFlags, Error, ErrorKind, + InitializeSecurityContextResult, PackageCapabilities, PackageInfo, Result, SecurityBuffer, SecurityBufferType, + SecurityPackageType, SecurityStatus, Sspi, +}; + +pub const PKG_NAME: &str = "Pku2u"; + +/// Default NEGOEX authentication scheme +pub const AUTH_SCHEME: &str = "0d53335c-f9ea-4d0d-b2ec-4ae3786ec308"; + +lazy_static! { + pub static ref PACKAGE_INFO: PackageInfo = PackageInfo { + capabilities: PackageCapabilities::empty(), + rpc_id: PACKAGE_ID_NONE, + max_token_len: 0xbb80, // 48 000 bytes: default maximum token len in Windows + name: SecurityPackageType::Pku2u, + comment: String::from("Pku2u"), + }; +} + +#[derive(Debug, Clone)] +pub enum Pku2uState { + Negotiate, + Preauthentication, + ApExchange, + PubKeyAuth, + Credentials, + Final, +} + +#[derive(Debug, Clone)] +pub struct Pku2uConfig { + p2p_certificate: Certificate, + p2p_ca_certificate: Certificate, +} + +#[derive(Debug, Clone)] +pub struct Pku2u { + config: Pku2uConfig, + state: Pku2uState, + encryption_params: EncryptionParams, + auth_identity: Option, + conversation_id: Uuid, + seq_number: u32, + realm: Option, +} + +impl Pku2u { + pub fn new_client_from_config(config: Pku2uConfig) -> Result { + Ok(Self { + config, + state: Pku2uState::Negotiate, + encryption_params: EncryptionParams::default_for_client(), + auth_identity: None, + conversation_id: Uuid::new_v4(), + seq_number: 0, + realm: None, + }) + } + + pub fn next_seq_number(&mut self) -> u32 { + let seq_num = self.seq_number; + self.seq_number += 1; + + seq_num + } +} + +impl Sspi for Pku2u { + fn complete_auth_token(&mut self, _token: &mut [SecurityBuffer]) -> Result { + Ok(SecurityStatus::Ok) + } + + fn encrypt_message( + &mut self, + flags: EncryptionFlags, + message: &mut [SecurityBuffer], + sequence_number: u32, + ) -> Result { + todo!() + } + + fn decrypt_message(&mut self, message: &mut [SecurityBuffer], sequence_number: u32) -> Result { + todo!() + } + + fn query_context_sizes(&mut self) -> Result { + Ok(ContextSizes { + max_token: PACKAGE_INFO.max_token_len, + max_signature: MAX_SIGNATURE as u32, + block: 0, + security_trailer: SECURITY_TRAILER as u32, + }) + } + + fn query_context_names(&mut self) -> Result { + if let Some(ref identity_buffers) = self.auth_identity { + let identity: AuthIdentity = identity_buffers.clone().into(); + Ok(ContextNames { + username: identity.username, + domain: identity.domain, + }) + } else { + Err(sspi::Error::new( + sspi::ErrorKind::NoCredentials, + String::from("Requested Names, but no credentials were provided"), + )) + } + } + + fn query_context_package_info(&mut self) -> Result { + sspi::query_security_package_info(SecurityPackageType::Pku2u) + } + + fn query_context_cert_trust_status(&mut self) -> Result { + Err(Error::new( + ErrorKind::UnsupportedFunction, + "Certificate trust status is not supported".to_owned(), + )) + } + + fn change_password(&mut self, _change_password: ChangePassword) -> Result<()> { + Err(Error::new( + ErrorKind::UnsupportedFunction, + "change_password is not supported in PKU2U".into(), + )) + } +} + +impl SspiImpl for Pku2u { + type CredentialsHandle = Option; + + type AuthenticationData = AuthIdentity; + + fn acquire_credentials_handle_impl<'a>( + &'a mut self, + builder: crate::builders::FilledAcquireCredentialsHandle<'a, Self::CredentialsHandle, Self::AuthenticationData>, + ) -> super::Result> { + if builder.credential_use == CredentialUse::Outbound && builder.auth_data.is_none() { + return Err(Error::new( + ErrorKind::NoCredentials, + String::from("The client must specify the auth data"), + )); + } + + self.auth_identity = builder.auth_data.cloned().map(AuthIdentityBuffers::from); + + Ok(AcquireCredentialsHandleResult { + credentials_handle: self.auth_identity.clone(), + expiry: None, + }) + } + + fn initialize_security_context_impl<'a>( + &mut self, + builder: &mut crate::builders::FilledInitializeSecurityContext<'a, Self::CredentialsHandle>, + ) -> super::Result { + let status = match self.state { + Pku2uState::Negotiate => { + let credentials = builder + .credentials_handle + .as_ref() + .unwrap() + .as_ref() + .ok_or_else(|| Error { + error_type: ErrorKind::NoCredentials, + description: "No credentials provided".to_owned(), + })?; + + let username = utf16_bytes_to_utf8_string(&credentials.user); + + let mut mech_token = Vec::new(); + + let auth_scheme = Uuid::from_str(AUTH_SCHEME).unwrap(); + + let nego = Nego::new( + MessageType::InitiatorNego, + self.conversation_id, + self.next_seq_number(), + OsRng::new()?.gen::<[u8; RANDOM_ARRAY_SIZE]>(), + vec![auth_scheme], + vec![], + ); + nego.encode(&mut mech_token)?; + + let exchange = Exchange::new( + MessageType::InitiatorMetaData, + self.conversation_id, + self.next_seq_number(), + auth_scheme, + picky_asn1_der::to_vec(&generate_pku2u_nego_req(&username)?)?, + ); + exchange.encode(&mut mech_token)?; + + let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; + output_token + .buffer + .write_all(&picky_asn1_der::to_vec(&generate_neg_token_init(mech_token)?)?)?; + + self.state = Pku2uState::Preauthentication; + + SecurityStatus::ContinueNeeded + } + Pku2uState::Preauthentication => todo!(), + Pku2uState::ApExchange => todo!(), + _ => { + return Err(Error::new( + ErrorKind::OutOfSequence, + format!("Got wrong PKU2U state: {:?}", self.state), + )) + } + }; + + Ok(InitializeSecurityContextResult { + status, + flags: ClientResponseFlags::empty(), + expiry: None, + }) + } + + fn accept_security_context_impl<'a>( + &'a mut self, + _builder: crate::builders::FilledAcceptSecurityContext<'a, Self::AuthenticationData, Self::CredentialsHandle>, + ) -> super::Result { + Err(Error::new( + ErrorKind::UnsupportedFunction, + "accept_security_context is not implemented in PKU2U".into(), + )) + } +} diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs new file mode 100644 index 00000000..c9ad4dba --- /dev/null +++ b/src/sspi/pku2u/generators.rs @@ -0,0 +1,78 @@ +use std::convert::TryFrom; +use std::str::FromStr; + +use oid::ObjectIdentifier; +use picky_asn1::restricted_string::{BMPString, IA5String}; +use picky_asn1::wrapper::{ + Asn1SequenceOf, Asn1SetOf, BMPStringAsn1, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2, + ImplicitContextTag0, IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, Optional, +}; +use picky_asn1_x509::oids::{AT_COMMON_NAME, NEGOEX, SPNEGO}; +use picky_krb::constants::types::NT_SRV_INST; +use picky_krb::data_types::{KerberosStringAsn1, PrincipalName, Realm}; +use picky_krb::gss_api::{ApplicationTag0, GssApiNegInit, MechType, MechTypeList, NegTokenInit}; +use picky_krb::pkinit::{Pku2uNegoBody, Pku2uNegoReq, Pku2uNegoReqMetadata, Pku2uValue, Pku2uValueInner}; + +use crate::kerberos::SERVICE_NAME; +use crate::Result; + +/// [The PKU2U Realm Name](https://datatracker.ietf.org/doc/html/draft-zhu-pku2u-09#section-3) +/// The PKU2U realm name is defined as a reserved Kerberos realm name, and it has the value of "WELLKNOWN:PKU2U". +pub const WELLKNOWN_REALM: &str = "WELLKNOWN:PKU2U"; + +/// "MS-Organization-P2P-Access [2021]" in UTF-16 +pub const MS_ORGANIZATION_P2P_ACCESS: &str = + "\0M\0S\0-\0O\0r\0g\0a\0n\0i\0z\0a\0t\0i\0o\0n\0-\0P\02\0P\0-\0A\0c\0c\0e\0s\0s\0 \0[\02\00\02\01\0]"; + +// returns supported authentication types +pub fn get_mech_list() -> MechTypeList { + MechTypeList::from(vec![ + MechType::from(ObjectIdentifier::try_from(NEGOEX).unwrap()), + // MechType::from(ObjectIdentifier::try_from(NTLM_SSP).unwrap()), + ]) +} + +pub fn generate_pku2u_nego_req(username: &str) -> Result { + let inner = Pku2uValue { + inner: Asn1SetOf::from(vec![Pku2uValueInner { + identifier: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(AT_COMMON_NAME).unwrap()), + value: BMPStringAsn1::from(BMPString::from_str(MS_ORGANIZATION_P2P_ACCESS).unwrap()), + }]), + }; + + Ok(Pku2uNegoReq { + metadata: ExplicitContextTag0::from(Asn1SequenceOf::from(vec![Pku2uNegoReqMetadata { + inner: ImplicitContextTag0::from(OctetStringAsn1::from(picky_asn1_der::to_vec(&inner)?)), + }])), + body: ExplicitContextTag1::from(Pku2uNegoBody { + realm: ExplicitContextTag0::from(Realm::from(IA5String::from_str(WELLKNOWN_REALM).unwrap())), + sname: ExplicitContextTag1::from(PrincipalName { + name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![NT_SRV_INST])), + name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![ + KerberosStringAsn1::from(IA5String::from_str(SERVICE_NAME).unwrap()), + KerberosStringAsn1::from(IA5String::from_str(username).unwrap()), + ])), + }), + }), + }) +} + +pub fn generate_neg_token_init(mech_token: Vec) -> Result> { + Ok(ApplicationTag0(GssApiNegInit { + oid: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(SPNEGO).unwrap()), + neg_token_init: ExplicitContextTag0::from(NegTokenInit { + mech_types: Optional::from(Some(ExplicitContextTag0::from(get_mech_list()))), + req_flags: Optional::from(None), + mech_token: Optional::from(Some(ExplicitContextTag2::from(OctetStringAsn1::from(mech_token)))), + mech_list_mic: Optional::from(None), + }), + })) +} + +#[cfg(test)] +mod tests { + #[test] + fn neg_token_init_generation() { + // + } +} diff --git a/src/utils.rs b/src/utils.rs index 0456d3a8..8e652d66 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -23,6 +23,16 @@ pub fn get_domain_from_fqdn(fqdm: &[u8]) -> Option { fqdm.find('@').map(|index| fqdm.split_off(index + 1)) } +pub fn utf16_bytes_to_utf8_string(data: &[u8]) -> String { + debug_assert_eq!(data.len() % 2, 0); + String::from_utf16_lossy( + &data + .chunks(2) + .map(|c| u16::from_le_bytes(c.try_into().unwrap())) + .collect::>(), + ) +} + #[cfg(feature = "network_client")] pub fn resolve_kdc_host(domain: &str) -> Option { use trust_dns_resolver::system_conf::read_system_conf; From 715b19d5a1b29ddcba5c247a5e0f602ea1184e5e Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Wed, 14 Sep 2022 17:37:17 +0300 Subject: [PATCH 02/36] sspi: pku2u: implement Preauthentication state for Pku2u --- Cargo.toml | 3 +- src/sspi/kerberos.rs | 77 ++++++++----- src/sspi/kerberos/client/generators.rs | 110 +++++++++++-------- src/sspi/pku2u.rs | 67 +++++++++++- src/sspi/pku2u/generators.rs | 146 ++++++++++++++++++++++++- 5 files changed, 313 insertions(+), 90 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 22623674..9bbd3636 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ chrono = "0.4" md-5 = "0.9" md4 = "0.9" sha2 = "0.9" +sha1 = "0.10" hmac = "0.11" crypto-mac = "0.11" num-derive = "0.2" @@ -40,7 +41,7 @@ reqwest = { version = "0.11", features = ["blocking", "rustls-tls", "rustls-tls- picky-krb = { path = "../picky-rs/picky-krb" } picky-asn1 = { path = "../picky-rs/picky-asn1", features = ["chrono_conversion"] } picky-asn1-der = { path = "../picky-rs/picky-asn1-der" } -picky-asn1-x509 = { path = "../picky-rs/picky-asn1-x509" } +picky-asn1-x509 = { path = "../picky-rs/picky-asn1-x509", features = ["pkcs7"] } oid = "0.2.1" uuid = "1.1" whoami = "0.5" diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index ef662290..6d4b81a0 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -23,10 +23,10 @@ use self::client::extractors::{ extract_encryption_params_from_as_rep, extract_session_key_from_as_rep, extract_session_key_from_tgs_rep, }; use self::client::generators::{ - generate_ap_req, generate_as_req, generate_authenticator, generate_krb_priv_request, generate_neg_ap_req, - generate_neg_token_init, generate_tgs_req, get_client_principal_name_type, get_client_principal_realm, - ChecksumOptions, GenerateAsReqOptions, GenerateAuthenticatorOptions, AUTHENTICATOR_DEFAULT_CHECKSUM, - DEFAULT_AP_REQ_OPTIONS, + generate_ap_req, generate_as_req, generate_as_req_kdc_body, generate_authenticator, generate_krb_priv_request, + generate_neg_ap_req, generate_neg_token_init, generate_pa_datas_for_as_req, generate_tgs_req, + get_client_principal_name_type, get_client_principal_realm, ChecksumOptions, GenerateAsPaDataOptions, + GenerateAsReqOptions, GenerateAuthenticatorOptions, AUTHENTICATOR_DEFAULT_CHECKSUM, DEFAULT_AP_REQ_OPTIONS, }; use self::config::{KdcType, KerberosConfig}; use self::server::extractors::extract_tgt_ticket; @@ -142,9 +142,15 @@ impl Kerberos { } } - pub fn as_exchange(&mut self, mut options: GenerateAsReqOptions) -> Result { - options.with_pre_auth = false; - let as_req = generate_as_req(&options)?; + pub fn as_exchange( + &mut self, + options: GenerateAsReqOptions, + mut pa_data_options: GenerateAsPaDataOptions, + ) -> Result { + pa_data_options.with_pre_auth = false; + let pa_datas = generate_pa_datas_for_as_req(&pa_data_options)?; + let kdc_req_body = generate_as_req_kdc_body(&options)?; + let as_req = generate_as_req(&pa_datas, kdc_req_body); let response = self.send(&serialize_message(&as_req)?)?; @@ -160,11 +166,14 @@ impl Kerberos { } if let Some(correct_salt) = extract_salt_from_krb_error(&as_rep.unwrap_err())? { - options.salt = correct_salt.as_bytes().to_vec() + pa_data_options.salt = correct_salt.as_bytes().to_vec() } - options.with_pre_auth = true; - let as_req = generate_as_req(&options)?; + pa_data_options.with_pre_auth = false; + let pa_datas = generate_pa_datas_for_as_req(&pa_data_options)?; + + let kdc_req_body = generate_as_req_kdc_body(&options)?; + let as_req = generate_as_req(&pa_datas, kdc_req_body); let response = self.send(&serialize_message(&as_req)?)?; @@ -348,16 +357,20 @@ impl Sspi for Kerberos { let cname_type = get_client_principal_name_type(username, domain); let realm = &get_client_principal_realm(username, domain); - let as_rep = self.as_exchange(GenerateAsReqOptions { - realm, - username, - password, - salt: salt.as_bytes().to_vec(), - enc_params: self.encryption_params.clone(), - cname_type, - snames: &[KADMIN, CHANGE_PASSWORD_SERVICE_NAME], - with_pre_auth: false, - })?; + let as_rep = self.as_exchange( + GenerateAsReqOptions { + realm, + username, + cname_type, + snames: &[KADMIN, CHANGE_PASSWORD_SERVICE_NAME], + }, + GenerateAsPaDataOptions { + password, + salt: salt.as_bytes().to_vec(), + enc_params: self.encryption_params.clone(), + with_pre_auth: false, + }, + )?; self.realm = Some(as_rep.0.crealm.0.to_string()); @@ -505,16 +518,20 @@ impl SspiImpl for Kerberos { let cname_type = get_client_principal_name_type(&username, &domain); let realm = &get_client_principal_realm(&username, &domain); - let as_rep = self.as_exchange(GenerateAsReqOptions { - realm, - username: &username, - password: &password, - salt: salt.as_bytes().to_vec(), - enc_params: self.encryption_params.clone(), - cname_type, - snames: &[TGT_SERVICE_NAME, realm], - with_pre_auth: false, - })?; + let as_rep = self.as_exchange( + GenerateAsReqOptions { + realm, + username: &&username, + cname_type, + snames: &[TGT_SERVICE_NAME, realm], + }, + GenerateAsPaDataOptions { + password: &password, + salt: salt.as_bytes().to_vec(), + enc_params: self.encryption_params.clone(), + with_pre_auth: false, + }, + )?; self.realm = Some(as_rep.0.crealm.0.to_string()); diff --git a/src/sspi/kerberos/client/generators.rs b/src/sspi/kerberos/client/generators.rs index f8512dba..ff0ff54f 100644 --- a/src/sspi/kerberos/client/generators.rs +++ b/src/sspi/kerberos/client/generators.rs @@ -50,7 +50,7 @@ use crate::{Error, ErrorKind}; const TGT_TICKET_LIFETIME_DAYS: i64 = 3; const NONCE_LEN: usize = 4; -const MAX_MICROSECONDS_IN_SECOND: u32 = 999_999; +pub const MAX_MICROSECONDS_IN_SECOND: u32 = 999_999; const MD5_CHECKSUM_TYPE: [u8; 1] = [0x07]; pub const DEFAULT_AS_REQ_OPTIONS: [u8; 4] = [0x40, 0x81, 0x00, 0x10]; @@ -89,33 +89,21 @@ pub fn get_client_principal_realm(username: &str, domain: &str) -> String { domain.to_string() } -pub struct GenerateAsReqOptions<'a> { - pub realm: &'a str, - pub username: &'a str, +pub struct GenerateAsPaDataOptions<'a> { pub password: &'a str, pub salt: Vec, pub enc_params: EncryptionParams, - pub cname_type: u8, - pub snames: &'a [&'a str], pub with_pre_auth: bool, } -pub fn generate_as_req(options: &GenerateAsReqOptions) -> Result { - let GenerateAsReqOptions { - realm, - username, +pub fn generate_pa_datas_for_as_req(options: &GenerateAsPaDataOptions) -> Result> { + let GenerateAsPaDataOptions { password, salt, enc_params, - cname_type, - snames, with_pre_auth, } = options; - let expiration_date = Utc::now() - .checked_add_signed(Duration::days(TGT_TICKET_LIFETIME_DAYS)) - .unwrap(); - let mut pa_datas = if *with_pre_auth { let current_date = Utc::now(); let mut microseconds = current_date.timestamp_subsec_micros(); @@ -155,6 +143,28 @@ pub fn generate_as_req(options: &GenerateAsReqOptions) -> Result { })?)), }); + Ok(pa_datas) +} + +pub struct GenerateAsReqOptions<'a> { + pub realm: &'a str, + pub username: &'a str, + pub cname_type: u8, + pub snames: &'a [&'a str], +} + +pub fn generate_as_req_kdc_body(options: &GenerateAsReqOptions) -> Result { + let GenerateAsReqOptions { + realm, + username, + cname_type, + snames, + } = options; + + let expiration_date = Utc::now() + .checked_add_signed(Duration::days(TGT_TICKET_LIFETIME_DAYS)) + .unwrap(); + let address = Some(ExplicitContextTag9::from(Asn1SequenceOf::from(vec![HostAddress { addr_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![NET_BIOS_ADDR_TYPE])), address: ExplicitContextTag1::from(OctetStringAsn1::from(whoami::hostname().as_bytes().to_vec())), @@ -165,40 +175,44 @@ pub fn generate_as_req(options: &GenerateAsReqOptions) -> Result { service_names.push(KerberosStringAsn1::from(IA5String::from_string((*sname).to_owned())?)); } - Ok(AsReq::from(KdcReq { + Ok(KdcReqBody { + kdc_options: ExplicitContextTag0::from(KerberosFlags::from(BitString::with_bytes( + DEFAULT_AS_REQ_OPTIONS.to_vec(), + ))), + cname: Optional::from(Some(ExplicitContextTag1::from(PrincipalName { + name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![*cname_type])), + name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![KerberosStringAsn1::from( + IA5String::from_string((*username).into())?, + )])), + }))), + realm: ExplicitContextTag2::from(Realm::from(IA5String::from_string((*realm).into())?)), + sname: Optional::from(Some(ExplicitContextTag3::from(PrincipalName { + name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![NT_SRV_INST])), + name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(service_names)), + }))), + from: Optional::from(None), + till: ExplicitContextTag5::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(expiration_date))), + rtime: Optional::from(Some(ExplicitContextTag6::from(GeneralizedTimeAsn1::from( + GeneralizedTime::from(expiration_date), + )))), + nonce: ExplicitContextTag7::from(IntegerAsn1::from(OsRng::new()?.gen::<[u8; NONCE_LEN]>().to_vec())), + etype: ExplicitContextTag8::from(Asn1SequenceOf::from(vec![ + IntegerAsn1::from(vec![CipherSuite::Aes256CtsHmacSha196.into()]), + IntegerAsn1::from(vec![CipherSuite::Aes128CtsHmacSha196.into()]), + ])), + addresses: Optional::from(address), + enc_authorization_data: Optional::from(None), + additional_tickets: Optional::from(None), + }) +} + +pub fn generate_as_req(pa_datas: &Vec, kdc_req_body: KdcReqBody) -> AsReq { + AsReq::from(KdcReq { pvno: ExplicitContextTag1::from(IntegerAsn1::from(vec![KERBEROS_VERSION])), msg_type: ExplicitContextTag2::from(IntegerAsn1::from(vec![AS_REQ_MSG_TYPE])), - padata: Optional::from(Some(ExplicitContextTag3::from(Asn1SequenceOf::from(pa_datas)))), - req_body: ExplicitContextTag4::from(KdcReqBody { - kdc_options: ExplicitContextTag0::from(KerberosFlags::from(BitString::with_bytes( - DEFAULT_AS_REQ_OPTIONS.to_vec(), - ))), - cname: Optional::from(Some(ExplicitContextTag1::from(PrincipalName { - name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![*cname_type])), - name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![KerberosStringAsn1::from( - IA5String::from_string((*username).into())?, - )])), - }))), - realm: ExplicitContextTag2::from(Realm::from(IA5String::from_string((*realm).into())?)), - sname: Optional::from(Some(ExplicitContextTag3::from(PrincipalName { - name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![NT_SRV_INST])), - name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(service_names)), - }))), - from: Optional::from(None), - till: ExplicitContextTag5::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(expiration_date))), - rtime: Optional::from(Some(ExplicitContextTag6::from(GeneralizedTimeAsn1::from( - GeneralizedTime::from(expiration_date), - )))), - nonce: ExplicitContextTag7::from(IntegerAsn1::from(OsRng::new()?.gen::<[u8; NONCE_LEN]>().to_vec())), - etype: ExplicitContextTag8::from(Asn1SequenceOf::from(vec![ - IntegerAsn1::from(vec![CipherSuite::Aes256CtsHmacSha196.into()]), - IntegerAsn1::from(vec![CipherSuite::Aes128CtsHmacSha196.into()]), - ])), - addresses: Optional::from(address), - enc_authorization_data: Optional::from(None), - additional_tickets: Optional::from(None), - }), - })) + padata: Optional::from(Some(ExplicitContextTag3::from(Asn1SequenceOf::from(pa_datas.clone())))), + req_body: ExplicitContextTag4::from(kdc_req_body), + }) } pub fn generate_tgs_req( diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 35ec25c4..32230de7 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -12,10 +12,14 @@ use rand::rngs::OsRng; use rand::Rng; use uuid::Uuid; -use self::generators::{generate_neg_token_init, generate_pku2u_nego_req}; +use self::generators::{ + generate_neg_as_req, generate_neg_token_init, generate_neg_token_targ, generate_pa_datas_for_as_req, + generate_pku2u_nego_req, DH_NONCE_LEN, WELLKNOWN_REALM, +}; use crate::builders::ChangePassword; use crate::internal::SspiImpl; -use crate::kerberos::{EncryptionParams, MAX_SIGNATURE, SECURITY_TRAILER}; +use crate::kerberos::client::generators::{generate_as_req, generate_as_req_kdc_body, GenerateAsReqOptions}; +use crate::kerberos::{EncryptionParams, MAX_SIGNATURE, SECURITY_TRAILER, SERVICE_NAME}; use crate::sspi::{self, PACKAGE_ID_NONE}; use crate::utils::utf16_bytes_to_utf8_string; use crate::{ @@ -65,6 +69,9 @@ pub struct Pku2u { conversation_id: Uuid, seq_number: u32, realm: Option, + auth_nonce: u32, + dh_nonce: [u8; DH_NONCE_LEN], + opposite_dh_nonce: Option<[u8; DH_NONCE_LEN]>, } impl Pku2u { @@ -77,6 +84,9 @@ impl Pku2u { conversation_id: Uuid::new_v4(), seq_number: 0, realm: None, + auth_nonce: OsRng::new()?.gen::(), + dh_nonce: OsRng::new()?.gen::<[u8; DH_NONCE_LEN]>(), + opposite_dh_nonce: None, }) } @@ -177,6 +187,8 @@ impl SspiImpl for Pku2u { &mut self, builder: &mut crate::builders::FilledInitializeSecurityContext<'a, Self::CredentialsHandle>, ) -> super::Result { + let auth_scheme = Uuid::from_str(AUTH_SCHEME).unwrap(); + let status = match self.state { Pku2uState::Negotiate => { let credentials = builder @@ -193,8 +205,6 @@ impl SspiImpl for Pku2u { let mut mech_token = Vec::new(); - let auth_scheme = Uuid::from_str(AUTH_SCHEME).unwrap(); - let nego = Nego::new( MessageType::InitiatorNego, self.conversation_id, @@ -223,7 +233,54 @@ impl SspiImpl for Pku2u { SecurityStatus::ContinueNeeded } - Pku2uState::Preauthentication => todo!(), + Pku2uState::Preauthentication => { + let credentials = builder + .credentials_handle + .as_ref() + .unwrap() + .as_ref() + .ok_or_else(|| Error { + error_type: ErrorKind::NoCredentials, + description: "No credentials provided".to_owned(), + })?; + + let username = utf16_bytes_to_utf8_string(&credentials.user); + // todo: parse response. do not extract any data. just parse and make sure it valid + + let mut mech_token = Vec::new(); + + let kdc_req_body = generate_as_req_kdc_body(&GenerateAsReqOptions { + realm: WELLKNOWN_REALM, + username: &username, + cname_type: 0x80, + snames: &[SERVICE_NAME, &username], + })?; + let pa_datas = generate_pa_datas_for_as_req( + &self.config.p2p_certificate, + &self.config.p2p_ca_certificate, + &kdc_req_body, + self.auth_nonce, + Some(&self.dh_nonce), + )?; + + let exchange = Exchange::new( + MessageType::InitiatorMetaData, + self.conversation_id, + self.next_seq_number(), + auth_scheme, + picky_asn1_der::to_vec(&generate_neg_as_req(generate_as_req(&pa_datas, kdc_req_body)))?, + ); + exchange.encode(&mut mech_token)?; + + let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; + output_token + .buffer + .write_all(&picky_asn1_der::to_vec(&generate_neg_token_targ(mech_token)?)?)?; + + self.state = Pku2uState::ApExchange; + + SecurityStatus::ContinueNeeded + } Pku2uState::ApExchange => todo!(), _ => { return Err(Error::new( diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index c9ad4dba..43a2c47c 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -1,18 +1,40 @@ use std::convert::TryFrom; use std::str::FromStr; +use chrono::Utc; use oid::ObjectIdentifier; +use picky_asn1::date::GeneralizedTime; use picky_asn1::restricted_string::{BMPString, IA5String}; use picky_asn1::wrapper::{ Asn1SequenceOf, Asn1SetOf, BMPStringAsn1, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2, - ImplicitContextTag0, IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, Optional, + ExplicitContextTag3, ImplicitContextTag0, IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, Optional, }; -use picky_asn1_x509::oids::{AT_COMMON_NAME, NEGOEX, SPNEGO}; -use picky_krb::constants::types::NT_SRV_INST; -use picky_krb::data_types::{KerberosStringAsn1, PrincipalName, Realm}; -use picky_krb::gss_api::{ApplicationTag0, GssApiNegInit, MechType, MechTypeList, NegTokenInit}; -use picky_krb::pkinit::{Pku2uNegoBody, Pku2uNegoReq, Pku2uNegoReqMetadata, Pku2uValue, Pku2uValueInner}; +use picky_asn1_der::Asn1RawDer; +use picky_asn1_x509::cmsversion::CmsVersion; +use picky_asn1_x509::content_info::EncapsulatedContentInfo; +use picky_asn1_x509::oids::{AT_COMMON_NAME, KERBEROS_V5_PKINIT, NEGOEX, SPNEGO}; +use picky_asn1_x509::signed_data::{ + CertificateChoices, CertificateSet, DigestAlgorithmIdentifiers, SignedData, SignersInfos, +}; +use picky_asn1_x509::signer_info::{ + Attributes, DigestAlgorithmIdentifier, SignatureAlgorithmIdentifier, SignatureValue, SignerIdentifier, SignerInfo, + UnsignedAttributes, +}; +use picky_asn1_x509::{AlgorithmIdentifier, Certificate, SubjectKeyIdentifier, Version}; +use picky_krb::constants::gss_api::{ACCEPT_INCOMPLETE, AS_REQ_TOKEN_ID}; +use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REQ}; +use picky_krb::data_types::{KerberosStringAsn1, KerberosTime, PaData, PrincipalName, Realm}; +use picky_krb::gss_api::{ + ApplicationTag0, GssApiNegInit, KrbMessage, MechType, MechTypeList, NegTokenInit, NegTokenTarg, +}; +use picky_krb::messages::{AsReq, KdcReqBody}; +use picky_krb::pkinit::{ + AuthPack, PaPkAsReq, PkAuthenticator, Pku2uNegoBody, Pku2uNegoReq, Pku2uNegoReqMetadata, Pku2uValue, + Pku2uValueInner, +}; +use sha1::{Digest, Sha1}; +use crate::kerberos::client::generators::MAX_MICROSECONDS_IN_SECOND; use crate::kerberos::SERVICE_NAME; use crate::Result; @@ -24,6 +46,11 @@ pub const WELLKNOWN_REALM: &str = "WELLKNOWN:PKU2U"; pub const MS_ORGANIZATION_P2P_ACCESS: &str = "\0M\0S\0-\0O\0r\0g\0a\0n\0i\0z\0a\0t\0i\0o\0n\0-\0P\02\0P\0-\0A\0c\0c\0e\0s\0s\0 \0[\02\00\02\01\0]"; +/// [Generation of Client Request](https://www.rfc-editor.org/rfc/rfc4556.html#section-3.2.1) +/// 9. This nonce string MUST be as long as the longest key length of the symmetric key types that the client supports. +/// Key length of Aes256 is equal to 32 +pub const DH_NONCE_LEN: usize = 32; + // returns supported authentication types pub fn get_mech_list() -> MechTypeList { MechTypeList::from(vec![ @@ -69,6 +96,113 @@ pub fn generate_neg_token_init(mech_token: Vec) -> Result) -> Result> { + Ok(ExplicitContextTag1::from(NegTokenTarg { + neg_result: Optional::from(Some(ExplicitContextTag0::from(Asn1RawDer(ACCEPT_INCOMPLETE.to_vec())))), + supported_mech: Optional::from(None), + response_token: Optional::from(Some(ExplicitContextTag2::from(OctetStringAsn1::from(token)))), + mech_list_mic: Optional::from(None), + })) +} + +pub fn version_to_cms_version(v: Version) -> CmsVersion { + match v { + Version::V1 => CmsVersion::V1, + Version::V2 => CmsVersion::V2, + Version::V3 => CmsVersion::V3, + } +} + +pub fn generate_signer_info(p2p_ca_cert: &Certificate) -> SignerInfo { + SignerInfo { + version: version_to_cms_version(p2p_ca_cert.tbs_certificate.version.0), + sid: SignerIdentifier::SubjectKeyIdentifier(ImplicitContextTag0::from(SubjectKeyIdentifier::from( + p2p_ca_cert.subject_key_identifier().unwrap().to_vec(), + ))), + digest_algorithm: DigestAlgorithmIdentifier( + p2p_ca_cert.tbs_certificate.subject_public_key_info.algorithm.clone(), + ), + signed_attrs: Optional::from(Attributes(Asn1SequenceOf::from(vec![]))), + signature_algorithm: SignatureAlgorithmIdentifier(p2p_ca_cert.signature_algorithm.clone()), + signature: SignatureValue(OctetStringAsn1::from(p2p_ca_cert.signature_value.0.inner())), + unsigned_attrs: Optional::from(UnsignedAttributes(vec![])), + } +} + +pub fn generate_pa_datas_for_as_req( + p2p_cert: &Certificate, + p2p_ca_cert: &Certificate, + kdc_req_body: &KdcReqBody, + auth_nonce: u32, + dh_nonce: Option<&[u8; DH_NONCE_LEN]>, +) -> Result> { + let current_date = Utc::now(); + let mut microseconds = current_date.timestamp_subsec_micros(); + if microseconds > MAX_MICROSECONDS_IN_SECOND { + microseconds = MAX_MICROSECONDS_IN_SECOND; + } + + // [Generation of Client Request](https://www.rfc-editor.org/rfc/rfc4556.html#section-3.2.1) + // paChecksum: Contains the SHA1 checksum, performed over KDC-REQ-BODY. + let encoded_kdc_req_body = picky_asn1_der::to_vec(&kdc_req_body)?; + + let mut sha1 = Sha1::new(); + sha1.update(&encoded_kdc_req_body); + + let sha1_hash = sha1.finalize().to_vec(); + + let auth_pack = AuthPack { + pk_authenticator: ExplicitContextTag0::from(PkAuthenticator { + cusec: ExplicitContextTag0::from(IntegerAsn1::from(microseconds.to_be_bytes().to_vec())), + ctime: ExplicitContextTag1::from(KerberosTime::from(GeneralizedTime::from(current_date))), + nonce: ExplicitContextTag2::from(IntegerAsn1::from(auth_nonce.to_be_bytes().to_vec())), + pa_checksum: Optional::from(Some(ExplicitContextTag3::from(OctetStringAsn1::from(sha1_hash)))), + }), + client_public_value: Optional::from(Some(ExplicitContextTag1::from( + p2p_cert.tbs_certificate.subject_public_key_info.clone(), + ))), + supported_cms_types: Optional::from(None), + client_dh_nonce: Optional::from( + dh_nonce.map(|nonce| ExplicitContextTag3::from(OctetStringAsn1::from(nonce.to_vec()))), + ), + }; + + let signed_data = SignedData { + version: CmsVersion::V3, + digest_algorithms: DigestAlgorithmIdentifiers(Asn1SetOf::from(vec![ + AlgorithmIdentifier::new_sha1_with_rsa_encryption(), + ])), + content_info: EncapsulatedContentInfo::new( + ObjectIdentifier::try_from(KERBEROS_V5_PKINIT).unwrap(), + Some(picky_asn1_der::to_vec(&auth_pack)?), + ), + certificates: Optional::from(CertificateSet(vec![CertificateChoices::Certificate(Asn1RawDer( + picky_asn1_der::to_vec(p2p_cert)?, + ))])), + crls: None, + signers_infos: SignersInfos(Asn1SetOf::from(vec![generate_signer_info(p2p_ca_cert)])), + }; + + let pa_pk_as_req = PaPkAsReq { + signed_auth_pack: ImplicitContextTag0::from(OctetStringAsn1::from(picky_asn1_der::to_vec(&signed_data)?)), + trusted_certifiers: Optional::from(None), + kdc_pk_id: Optional::from(None), + }; + + Ok(vec![PaData { + padata_type: ExplicitContextTag1::from(IntegerAsn1::from(PA_PK_AS_REQ.to_vec())), + padata_data: ExplicitContextTag2::from(OctetStringAsn1::from(picky_asn1_der::to_vec(&pa_pk_as_req)?)), + }]) +} + +pub fn generate_neg_as_req(as_req: AsReq) -> ApplicationTag0> { + ApplicationTag0(KrbMessage { + krb5_oid: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("GSS_PKU2U").unwrap()), + krb5_token_id: AS_REQ_TOKEN_ID, + krb_msg: as_req, + }) +} + #[cfg(test)] mod tests { #[test] From d5e9dd1a71974ff94795beb1415983620c805822 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Thu, 15 Sep 2022 17:06:59 +0300 Subject: [PATCH 03/36] sspi: pku2u: improve reply message validation --- src/sspi/pku2u.rs | 86 +++++++++++++++++++++++++++++++++++++--- src/sspi/pku2u/macros.rs | 32 +++++++++++++++ 2 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 src/sspi/pku2u/macros.rs diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 32230de7..499e9e32 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -1,6 +1,8 @@ mod generators; +#[macro_use] +mod macros; -use std::io::Write; +use std::io::{Read, Write}; use std::str::FromStr; use lazy_static::lazy_static; @@ -48,6 +50,7 @@ lazy_static! { pub enum Pku2uState { Negotiate, Preauthentication, + AsExchange, ApExchange, PubKeyAuth, Credentials, @@ -67,6 +70,7 @@ pub struct Pku2u { encryption_params: EncryptionParams, auth_identity: Option, conversation_id: Uuid, + auth_scheme: Option, seq_number: u32, realm: Option, auth_nonce: u32, @@ -82,6 +86,7 @@ impl Pku2u { encryption_params: EncryptionParams::default_for_client(), auth_identity: None, conversation_id: Uuid::new_v4(), + auth_scheme: None, seq_number: 0, realm: None, auth_nonce: OsRng::new()?.gen::(), @@ -187,10 +192,10 @@ impl SspiImpl for Pku2u { &mut self, builder: &mut crate::builders::FilledInitializeSecurityContext<'a, Self::CredentialsHandle>, ) -> super::Result { - let auth_scheme = Uuid::from_str(AUTH_SCHEME).unwrap(); - let status = match self.state { Pku2uState::Negotiate => { + let auth_scheme = Uuid::from_str(AUTH_SCHEME).unwrap(); + let credentials = builder .credentials_handle .as_ref() @@ -234,6 +239,46 @@ impl SspiImpl for Pku2u { SecurityStatus::ContinueNeeded } Pku2uState::Preauthentication => { + let input = builder + .input + .as_ref() + .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "Input buffers must be specified".into()))?; + let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; + + let mut reader: Box = Box::new(input_token.buffer.as_slice()); + + let acceptor_nego = Nego::decode(&mut reader, &input_token.buffer)?; + + check_conversation_id!(acceptor_nego.header.conversation_id.0, self.conversation_id); + + // We support only one auth scheme. So the server must choose it otherwise it's an invalid behaviour + if let Some(auth_scheme) = acceptor_nego.auth_schemes.get(0) { + if auth_scheme.0 == Uuid::from_str(AUTH_SCHEME).unwrap() { + self.auth_scheme = Some(auth_scheme.0); + } else { + return + Err(Error::new( + ErrorKind::InvalidToken, + format!( + "The server selected unsupported auth scheme {:?}. The only one supported auth scheme: {}", + auth_scheme.0, AUTH_SCHEME) + )); + } + } else { + return Err(Error::new( + ErrorKind::InvalidToken, + "Server didn't send any auth scheme".into(), + )); + } + + let acceptor_exchange = Exchange::decode( + &mut reader, + &input_token.buffer[(acceptor_nego.header.message_len as usize)..], + )?; + + check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); + check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); + let credentials = builder .credentials_handle .as_ref() @@ -246,6 +291,7 @@ impl SspiImpl for Pku2u { let username = utf16_bytes_to_utf8_string(&credentials.user); // todo: parse response. do not extract any data. just parse and make sure it valid + // todo: validate auth scheme, etc let mut mech_token = Vec::new(); @@ -267,7 +313,7 @@ impl SspiImpl for Pku2u { MessageType::InitiatorMetaData, self.conversation_id, self.next_seq_number(), - auth_scheme, + self.auth_scheme.unwrap(), picky_asn1_der::to_vec(&generate_neg_as_req(generate_as_req(&pa_datas, kdc_req_body)))?, ); exchange.encode(&mut mech_token)?; @@ -277,11 +323,41 @@ impl SspiImpl for Pku2u { .buffer .write_all(&picky_asn1_der::to_vec(&generate_neg_token_targ(mech_token)?)?)?; + self.state = Pku2uState::AsExchange; + + SecurityStatus::ContinueNeeded + } + Pku2uState::AsExchange => { + let input = builder + .input + .as_ref() + .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "Input buffers must be specified".into()))?; + let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; + + let acceptor_exchange = Exchange::decode(input_token.buffer.as_slice(), &input_token.buffer)?; + + check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); + check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); + + // parse as_rep + + // extract key parameters, and other info. validate them + + // generate key (how? idk) + + // generate ap_req + self.state = Pku2uState::ApExchange; SecurityStatus::ContinueNeeded } - Pku2uState::ApExchange => todo!(), + Pku2uState::ApExchange => { + // todo!(); + + self.state = Pku2uState::PubKeyAuth; + + SecurityStatus::ContinueNeeded + } _ => { return Err(Error::new( ErrorKind::OutOfSequence, diff --git a/src/sspi/pku2u/macros.rs b/src/sspi/pku2u/macros.rs new file mode 100644 index 00000000..3cbad5f5 --- /dev/null +++ b/src/sspi/pku2u/macros.rs @@ -0,0 +1,32 @@ +macro_rules! check_conversation_id { + ($actual:expr, $expected:expr) => { + if $actual != $expected { + return Err(Error::new( + ErrorKind::InvalidToken, + format!( + "Server sent invalid conversation id. Got {:?} but expected {:?}.", + $actual, $expected + ), + )); + } + }; +} + +macro_rules! check_auth_scheme { + ($actual:expr, $expected:expr) => { + if $expected.is_none() { + return Err(Error::new(ErrorKind::InternalError, "auth scheme id is not set".into())); + } + + if $actual != $expected.unwrap() { + return Err(Error::new( + ErrorKind::InvalidToken, + format!( + "Server sent invalid conversation id. Got {:?} but expected {:?}.", + $actual, + $expected.unwrap() + ), + )); + } + }; +} From 96cda992a8ea7413e2f705076ece5e099d05534b Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 19 Sep 2022 13:26:27 +0300 Subject: [PATCH 04/36] sspi: pku2u: implement AsExchange state; improve errors handling and data extraction --- src/lib.rs | 1 + src/sspi.rs | 8 + src/sspi/kerberos.rs | 4 +- src/sspi/pku2u.rs | 285 ++++++++++++++++++++++++++++++++--- src/sspi/pku2u/extractors.rs | 254 +++++++++++++++++++++++++++++++ src/sspi/pku2u/generators.rs | 87 +++++++++-- 6 files changed, 597 insertions(+), 42 deletions(-) create mode 100644 src/sspi/pku2u/extractors.rs diff --git a/src/lib.rs b/src/lib.rs index b19b8a4a..a5aa1179 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,6 +88,7 @@ pub use utils::resolve_kdc_host; pub use crate::sspi::kerberos::config::KerberosConfig; pub use crate::sspi::kerberos::{Kerberos, KERBEROS_VERSION, PACKAGE_INFO as KERBEROS_PACKAGE_INFO}; pub use crate::sspi::negotiate::{Negotiate, NegotiateConfig}; +pub use crate::sspi::pku2u::{Pku2u, PACKAGE_INFO as PKU2U_PACKAGE_INFO}; #[cfg(windows)] pub use crate::sspi::winapi; pub use crate::sspi::{ diff --git a/src/sspi.rs b/src/sspi.rs index 0acdb7db..6a28e5ec 100644 --- a/src/sspi.rs +++ b/src/sspi.rs @@ -1518,6 +1518,14 @@ impl From for Error { error_type: ErrorKind::InvalidParameter, description: description.to_string(), }, + KerberosCryptoError::SeedBitLen(description) => Self { + error_type: ErrorKind::InvalidParameter, + description, + }, + KerberosCryptoError::AlgorithmIdentifierData(identifier) => Self { + error_type: ErrorKind::InvalidParameter, + description: format!("unknown algorithm identifier: {:?}", identifier), + }, } } } diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 6d4b81a0..5018bcf4 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -58,11 +58,11 @@ pub const CHANGE_PASSWORD_SERVICE_NAME: &str = "changepw"; pub const SSPI_KDC_URL_ENV: &str = "SSPI_KDC_URL"; -const DEFAULT_ENCRYPTION_TYPE: CipherSuite = CipherSuite::Aes256CtsHmacSha196; +pub const DEFAULT_ENCRYPTION_TYPE: CipherSuite = CipherSuite::Aes256CtsHmacSha196; /// [MS-KILE](https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-KILE/%5bMS-KILE%5d.pdf) /// The RRC field is 12 if no encryption is requested or 28 if encryption is requested -const RRC: u16 = 28; +pub const RRC: u16 = 28; // wrap token header len pub const MAX_SIGNATURE: usize = 16; // minimal len to fit encrypted public key in wrap token diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 499e9e32..1cc0554d 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -1,3 +1,4 @@ +mod extractors; mod generators; #[macro_use] mod macros; @@ -6,22 +7,35 @@ use std::io::{Read, Write}; use std::str::FromStr; use lazy_static::lazy_static; +use picky_asn1_x509::signed_data::SignedData; use picky_asn1_x509::Certificate; +use picky_krb::constants::gss_api::{AS_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE, AP_REQ_TOKEN_ID}; +use picky_krb::constants::key_usages::ACCEPTOR_SIGN; +use picky_krb::crypto::{CipherSuite, ChecksumSuite, Checksum}; +use picky_krb::diffie_hellman::{generate_key, DhNonce}; +use picky_krb::gss_api::WrapToken; use picky_krb::negoex::data_types::MessageType; -use picky_krb::negoex::messages::{Exchange, Nego}; +use picky_krb::negoex::messages::{Exchange, Nego, Verify}; use picky_krb::negoex::{NegoexMessage, RANDOM_ARRAY_SIZE}; +use picky_krb::pkinit::PaPkAsRep; use rand::rngs::OsRng; use rand::Rng; use uuid::Uuid; use self::generators::{ - generate_neg_as_req, generate_neg_token_init, generate_neg_token_targ, generate_pa_datas_for_as_req, - generate_pku2u_nego_req, DH_NONCE_LEN, WELLKNOWN_REALM, + generate_client_dh_parameters, generate_neg, generate_neg_token_init, generate_neg_token_targ, + generate_pa_datas_for_as_req, generate_pku2u_nego_req, DH_NONCE_LEN, WELLKNOWN_REALM, }; use crate::builders::ChangePassword; use crate::internal::SspiImpl; -use crate::kerberos::client::generators::{generate_as_req, generate_as_req_kdc_body, GenerateAsReqOptions}; -use crate::kerberos::{EncryptionParams, MAX_SIGNATURE, SECURITY_TRAILER, SERVICE_NAME}; +use crate::kerberos::client::generators::{ + generate_ap_req, generate_as_req, generate_as_req_kdc_body, generate_authenticator, ChecksumOptions, + GenerateAsReqOptions, GenerateAuthenticatorOptions, AUTHENTICATOR_DEFAULT_CHECKSUM, +}; +use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE, MAX_SIGNATURE, RRC, SECURITY_TRAILER, SERVICE_NAME}; +use crate::sspi::pku2u::extractors::{ + extract_as_rep, extract_pa_pk_as_rep, extract_server_dh_public_key, extract_server_nonce, +}; use crate::sspi::{self, PACKAGE_ID_NONE}; use crate::utils::utf16_bytes_to_utf8_string; use crate::{ @@ -63,6 +77,22 @@ pub struct Pku2uConfig { p2p_ca_certificate: Certificate, } +#[derive(Debug, Clone)] +pub struct DhParameters { + // g + base: usize, + // p + modulus: Vec, + // + q: Vec, + // generated private key + private_key: Vec, + // received public key + other_public_key: Option>, + client_nonce: Option<[u8; DH_NONCE_LEN]>, + server_nonce: Option<[u8; DH_NONCE_LEN]>, +} + #[derive(Debug, Clone)] pub struct Pku2u { config: Pku2uConfig, @@ -74,8 +104,12 @@ pub struct Pku2u { seq_number: u32, realm: Option, auth_nonce: u32, - dh_nonce: [u8; DH_NONCE_LEN], - opposite_dh_nonce: Option<[u8; DH_NONCE_LEN]>, + dh_parameters: DhParameters, + // all sent and received NEGOEX messages in one vector + // we need it for the further checksum calculation + // https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-NEGOEX/%5bMS-NEGOEX%5d.pdf + // The checksum is performed on all previous NEGOEX messages in the context negotiation. + negoex_messages: Vec, } impl Pku2u { @@ -89,9 +123,13 @@ impl Pku2u { auth_scheme: None, seq_number: 0, realm: None, - auth_nonce: OsRng::new()?.gen::(), - dh_nonce: OsRng::new()?.gen::<[u8; DH_NONCE_LEN]>(), - opposite_dh_nonce: None, + // https://www.rfc-editor.org/rfc/rfc4556.html#section-3.2.3 + // Contains the nonce in the pkAuthenticator field in the request if the DH keys are NOT reused, + // 0 otherwise. + auth_nonce: 0, + // generate dh parameters at the start in order to not waste time during authorization + dh_parameters: generate_client_dh_parameters(), + negoex_messages: Vec::new(), }) } @@ -110,15 +148,120 @@ impl Sspi for Pku2u { fn encrypt_message( &mut self, - flags: EncryptionFlags, + _flags: EncryptionFlags, message: &mut [SecurityBuffer], - sequence_number: u32, + _sequence_number: u32, ) -> Result { - todo!() + SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Token)?; + let data = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Data)?; + + let cipher = self + .encryption_params + .encryption_type + .as_ref() + .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) + .cipher(); + + let seq_number = self.next_seq_number(); + + // the sub-session key is always preferred over the session key + let key = if let Some(key) = self.encryption_params.sub_session_key.as_ref() { + key + } else if let Some(key) = self.encryption_params.session_key.as_ref() { + key + } else { + return Err(Error::new( + ErrorKind::EncryptFailure, + "No encryption key provided".into(), + )); + }; + let key_usage = self.encryption_params.sspi_encrypt_key_usage; + + let mut wrap_token = WrapToken::with_seq_number(seq_number as u64); + + let mut payload = data.buffer.to_vec(); + payload.extend_from_slice(&wrap_token.header()); + + let mut checksum = cipher.encrypt(key, key_usage, &payload)?; + checksum.rotate_right(RRC.into()); + + wrap_token.set_rrc(RRC); + wrap_token.set_checksum(checksum); + + let mut raw_wrap_token = Vec::with_capacity(92); + wrap_token.encode(&mut raw_wrap_token)?; + + match self.state { + Pku2uState::PubKeyAuth | Pku2uState::Credentials => { + *data.buffer.as_mut() = raw_wrap_token[SECURITY_TRAILER..].to_vec(); + let header = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Token)?; + *header.buffer.as_mut() = raw_wrap_token[0..SECURITY_TRAILER].to_vec(); + } + _ => { + return Err(Error { + error_type: ErrorKind::OutOfSequence, + description: "Kerberos context is not established or finished".to_owned(), + }) + } + }; + + Ok(SecurityStatus::Ok) } - fn decrypt_message(&mut self, message: &mut [SecurityBuffer], sequence_number: u32) -> Result { - todo!() + fn decrypt_message(&mut self, message: &mut [SecurityBuffer], _sequence_number: u32) -> Result { + let mut encrypted = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Token)? + .buffer + .clone(); + let data = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Data)?; + + encrypted.extend_from_slice(&data.buffer); + + let cipher = self + .encryption_params + .encryption_type + .as_ref() + .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) + .cipher(); + + // the sub-session key is always preferred over the session key + let key = if let Some(key) = self.encryption_params.sub_session_key.as_ref() { + key + } else if let Some(key) = self.encryption_params.session_key.as_ref() { + key + } else { + return Err(Error::new( + ErrorKind::DecryptFailure, + "No encryption key provided".into(), + )); + }; + let key_usage = self.encryption_params.sspi_decrypt_key_usage; + + let mut wrap_token = WrapToken::decode(encrypted.as_slice())?; + + wrap_token.checksum.rotate_left(RRC.into()); + + let mut decrypted = cipher.decrypt(key, key_usage, &wrap_token.checksum)?; + // remove wrap token header + decrypted.truncate(decrypted.len() - WrapToken::header_len()); + + match self.state { + Pku2uState::PubKeyAuth => { + self.state = Pku2uState::Credentials; + + *data.buffer.as_mut() = decrypted; + Ok(DecryptionFlags::empty()) + } + Pku2uState::Credentials => { + self.state = Pku2uState::Final; + + *data.buffer.as_mut() = decrypted; + Ok(DecryptionFlags::empty()) + } + _ => { + *data.buffer.as_mut() = decrypted; + Ok(DecryptionFlags::empty()) + } + } } fn query_context_sizes(&mut self) -> Result { @@ -229,6 +372,8 @@ impl SspiImpl for Pku2u { ); exchange.encode(&mut mech_token)?; + self.negoex_messages.extend_from_slice(&mech_token); + let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; output_token .buffer @@ -245,7 +390,11 @@ impl SspiImpl for Pku2u { .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "Input buffers must be specified".into()))?; let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; - let mut reader: Box = Box::new(input_token.buffer.as_slice()); + let buffer = input_token.buffer.as_slice(); + + self.negoex_messages.extend_from_slice(buffer); + + let mut reader: Box = Box::new(buffer); let acceptor_nego = Nego::decode(&mut reader, &input_token.buffer)?; @@ -291,7 +440,6 @@ impl SspiImpl for Pku2u { let username = utf16_bytes_to_utf8_string(&credentials.user); // todo: parse response. do not extract any data. just parse and make sure it valid - // todo: validate auth scheme, etc let mut mech_token = Vec::new(); @@ -306,7 +454,7 @@ impl SspiImpl for Pku2u { &self.config.p2p_ca_certificate, &kdc_req_body, self.auth_nonce, - Some(&self.dh_nonce), + &self.dh_parameters, )?; let exchange = Exchange::new( @@ -314,10 +462,12 @@ impl SspiImpl for Pku2u { self.conversation_id, self.next_seq_number(), self.auth_scheme.unwrap(), - picky_asn1_der::to_vec(&generate_neg_as_req(generate_as_req(&pa_datas, kdc_req_body)))?, + picky_asn1_der::to_vec(&generate_neg(generate_as_req(&pa_datas, kdc_req_body), AS_REQ_TOKEN_ID))?, ); exchange.encode(&mut mech_token)?; + self.negoex_messages.extend_from_slice(&mech_token); + let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; output_token .buffer @@ -334,18 +484,105 @@ impl SspiImpl for Pku2u { .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "Input buffers must be specified".into()))?; let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; - let acceptor_exchange = Exchange::decode(input_token.buffer.as_slice(), &input_token.buffer)?; + let buffer = input_token.buffer.as_slice(); + + self.negoex_messages.extend_from_slice(buffer); + + let acceptor_exchange = Exchange::decode(buffer, &input_token.buffer)?; check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); - // parse as_rep + let as_rep = extract_as_rep(&acceptor_exchange.exchange)?; + + // todo: validate server's certificate + + let dh_rep_info = match extract_pa_pk_as_rep(&as_rep)? { + PaPkAsRep::DhInfo(dh) => dh.0, + PaPkAsRep::EncKeyPack(_) => { + return Err(Error::new( + ErrorKind::OperationNotSupported, + "encKeyPack is not supported for the PA-PK-AS-REP".into(), + )) + } + }; + + self.dh_parameters.server_nonce = Some(extract_server_nonce(&dh_rep_info)?); + + let signed_data: SignedData = picky_asn1_der::from_bytes(&dh_rep_info.dh_signed_data.0)?; + + self.dh_parameters.other_public_key = Some(extract_server_dh_public_key(&signed_data)?); + + self.encryption_params.encryption_type = + Some(CipherSuite::try_from(as_rep.0.enc_part.0.etype.0 .0.as_slice())?); + self.encryption_params.session_key = Some(generate_key( + self.dh_parameters.other_public_key.as_ref().unwrap(), + &self.dh_parameters.private_key, + &self.dh_parameters.modulus, + Some(DhNonce { + client_nonce: self.dh_parameters.client_nonce.as_ref().unwrap(), + server_nonce: self.dh_parameters.server_nonce.as_ref().unwrap(), + }), + self.encryption_params + .encryption_type + .as_ref() + .unwrap() + .cipher() + .as_ref(), + )?); + + let authenticator = generate_authenticator(GenerateAuthenticatorOptions { + kdc_rep: &as_rep.0, + seq_num: Some(self.next_seq_number()), + sub_key: Some(OsRng::new()?.gen::<[u8; 32]>().to_vec()), + checksum: Some(ChecksumOptions { + checksum_type: AUTHENTICATOR_CHECKSUM_TYPE.to_vec(), + checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), + }), + channel_bindings: None, + })?; + let ap_req = generate_ap_req( + as_rep.0.ticket.0, + self.encryption_params.session_key.as_ref().unwrap(), + &authenticator, + &self.encryption_params, + &[2, 0, 0, 0], + )?; + + let mut mech_token = Vec::new(); + + let exchange = Exchange::new( + MessageType::InitiatorMetaData, + self.conversation_id, + self.next_seq_number(), + self.auth_scheme.unwrap(), + picky_asn1_der::to_vec(&generate_neg(ap_req, AP_REQ_TOKEN_ID))?, + ); + exchange.encode(&mut mech_token)?; - // extract key parameters, and other info. validate them + let verify = Verify::new( + MessageType::Verify, + self.conversation_id, + self.next_seq_number(), + self.auth_scheme.unwrap(), + self.encryption_params.encryption_type + .as_ref() + .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) + .into(), + ChecksumSuite::HmacSha196Aes256.hasher().checksum( + self.encryption_params.session_key.as_ref().unwrap(), + ACCEPTOR_SIGN, + &self.negoex_messages, + )?, + ); + verify.encode(&mut mech_token)?; - // generate key (how? idk) + self.negoex_messages.extend_from_slice(&mech_token); - // generate ap_req + let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; + output_token + .buffer + .write_all(&picky_asn1_der::to_vec(&generate_neg_token_targ(mech_token)?)?)?; self.state = Pku2uState::ApExchange; diff --git a/src/sspi/pku2u/extractors.rs b/src/sspi/pku2u/extractors.rs new file mode 100644 index 00000000..38fdb029 --- /dev/null +++ b/src/sspi/pku2u/extractors.rs @@ -0,0 +1,254 @@ +use std::convert::{TryFrom, TryInto}; + +use oid::ObjectIdentifier; +use picky_asn1::wrapper::IntegerAsn1; +use picky_asn1_der::application_tag::ApplicationTag; +use picky_asn1_der::Asn1RawDer; +use picky_asn1_x509::content_info::ContentValue; +use picky_asn1_x509::oids::PKINIT_DH_KEY_DATA; +use picky_asn1_x509::signed_data::SignedData; +use picky_krb::constants::types::PA_PK_AS_REP; +use picky_krb::messages::AsRep; +use picky_krb::pkinit::{DhRepInfo, KdcDhKeyInfo, PaPkAsRep}; + +use super::generators::DH_NONCE_LEN; +use crate::{Error, ErrorKind, Result}; + +pub fn extract_as_rep(mut data: &[u8]) -> Result { + let _oid: ApplicationTag = + picky_asn1_der::from_reader(&mut data).map_err(|e| Error::new(ErrorKind::InvalidToken, format!("{:?}", e)))?; + + // let oid: ObjectIdentifierAsn1 = picky_asn1_der::from_bytes(&oid.0.0)?; + + // let mut token_id = [0, 0]; + // data.read_exact(&mut token_id)?; + + // if token_id != AS_REP_TOKEN_ID { + // return Err(Error::new( + // ErrorKind::InvalidToken, + // format!("Invalid token id: {:?}. Expected: {:?}", token_id, AS_REP_TOKEN_ID), + // )); + // } + + Ok(picky_asn1_der::from_reader(&mut data)?) +} + +pub fn extract_pa_pk_as_rep(as_rep: &AsRep) -> Result { + Ok(picky_asn1_der::from_bytes( + &as_rep + .0 + .padata + .0 + .as_ref() + .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "pa-datas is not present in as rep".into()))? + .iter() + .find(|pa_data| &pa_data.padata_type.0 .0 == &PA_PK_AS_REP) + .ok_or_else(|| { + Error::new( + ErrorKind::InvalidToken, + "PA_PK_AS_REP is not present in pa-datas of the as rep".into(), + ) + })? + .padata_data + .0 + .0, + )?) +} + +pub fn extract_server_nonce(dh_rep_info: &DhRepInfo) -> Result<[u8; DH_NONCE_LEN]> { + let nonce = dh_rep_info + .server_dh_nonce + .0 + .as_ref() + .map(|nonce| nonce.0 .0.clone()) + .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "DH server nonce is not present".into()))?; + + if nonce.len() != DH_NONCE_LEN { + return Err(Error::new( + ErrorKind::InvalidToken, + format!( + "invalid server dh nonce length: {}. Expected: {}", + nonce.len(), + DH_NONCE_LEN + ), + )); + } + + Ok(nonce.try_into().unwrap()) +} + +pub fn extract_server_dh_public_key(signed_data: &SignedData) -> Result> { + let pkinit_dh_key_data = ObjectIdentifier::try_from(PKINIT_DH_KEY_DATA).unwrap(); + if signed_data.content_info.content_type.0 != pkinit_dh_key_data { + return Err(Error::new( + ErrorKind::InvalidToken, + format!( + "Invalid content info identifier: {:?}. Expected: {:?}", + signed_data.content_info.content_type.0, pkinit_dh_key_data + ), + )); + } + + let dh_key_info_data = match &signed_data + .content_info + .content + .as_ref() + .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "content info is not present".into()))? + .0 + { + ContentValue::OctetString(data) => &data.0, + _ => return Err(Error::new(ErrorKind::InvalidToken, "unexpected content info".into())), + }; + + let dh_key_info: KdcDhKeyInfo = picky_asn1_der::from_bytes(dh_key_info_data)?; + + if dh_key_info.nonce.0 != vec![0] { + return Err(Error::new( + ErrorKind::InvalidToken, + format!("DH key nonce must be 0. Got: {:?}", dh_key_info.nonce.0), + )); + } + + let key: IntegerAsn1 = picky_asn1_der::from_bytes(dh_key_info.subject_public_key.0.payload_view())?; + + Ok(key.as_unsigned_bytes_be().to_vec()) +} + +#[cfg(test)] +mod tests { + use super::extract_as_rep; + + #[test] + fn as_rep_extraction() { + let raw_message = [ + 96, 130, 11, 218, 6, 6, 43, 6, 1, 5, 2, 7, 6, 0, 107, 130, 11, 204, 48, 130, 11, 200, 160, 3, 2, 1, 5, 161, + 3, 2, 1, 11, 162, 130, 6, 128, 48, 130, 6, 124, 48, 130, 6, 120, 161, 3, 2, 1, 17, 162, 130, 6, 111, 4, + 130, 6, 107, 160, 130, 6, 103, 48, 130, 6, 99, 128, 130, 6, 59, 48, 130, 6, 55, 2, 1, 3, 49, 11, 48, 9, 6, + 5, 43, 14, 3, 2, 26, 5, 0, 48, 129, 162, 6, 7, 43, 6, 1, 5, 2, 3, 2, 160, 129, 150, 4, 129, 147, 48, 129, + 144, 160, 129, 136, 3, 129, 133, 0, 2, 129, 129, 0, 218, 76, 235, 63, 222, 122, 67, 6, 210, 4, 219, 144, + 10, 253, 105, 197, 87, 1, 68, 61, 12, 232, 203, 120, 225, 215, 208, 224, 194, 49, 162, 89, 251, 216, 82, + 14, 92, 119, 236, 147, 132, 225, 80, 117, 104, 218, 221, 117, 104, 149, 33, 9, 225, 159, 16, 243, 57, 44, + 147, 221, 164, 8, 131, 5, 43, 219, 70, 8, 7, 60, 118, 39, 124, 30, 48, 205, 41, 150, 112, 133, 151, 136, + 121, 91, 56, 12, 251, 210, 239, 155, 85, 63, 244, 177, 112, 133, 181, 245, 110, 164, 31, 197, 241, 14, 137, + 195, 223, 226, 23, 158, 68, 27, 66, 118, 200, 170, 122, 33, 156, 104, 103, 155, 136, 28, 247, 8, 54, 20, + 161, 3, 2, 1, 0, 160, 130, 3, 179, 48, 130, 3, 175, 48, 130, 2, 151, 160, 3, 2, 1, 2, 2, 16, 85, 47, 30, + 63, 139, 118, 224, 166, 140, 108, 227, 232, 117, 255, 59, 249, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, + 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, + 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, + 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 49, 0, 93, 48, 30, 23, 13, + 50, 50, 48, 53, 49, 55, 49, 57, 50, 52, 48, 54, 90, 23, 13, 50, 50, 48, 53, 49, 56, 49, 57, 50, 57, 48, 54, + 90, 48, 101, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 52, 99, 53, 97, 53, + 101, 99, 49, 45, 57, 97, 99, 53, 45, 52, 54, 49, 50, 45, 57, 98, 52, 99, 45, 54, 98, 101, 100, 49, 55, 56, + 98, 98, 54, 53, 97, 49, 45, 48, 43, 6, 3, 85, 4, 3, 12, 36, 99, 99, 51, 100, 57, 54, 98, 52, 45, 48, 97, + 48, 100, 45, 52, 97, 53, 100, 45, 56, 98, 102, 98, 45, 56, 100, 54, 101, 97, 56, 100, 57, 53, 53, 100, 50, + 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, + 2, 130, 1, 1, 0, 199, 77, 166, 39, 80, 222, 84, 115, 41, 66, 75, 180, 150, 219, 181, 13, 3, 102, 176, 46, + 8, 194, 243, 198, 233, 126, 112, 105, 214, 207, 85, 254, 186, 228, 217, 23, 28, 232, 31, 209, 227, 99, 220, + 60, 28, 78, 168, 51, 162, 48, 63, 120, 240, 186, 203, 224, 154, 164, 227, 78, 224, 4, 120, 160, 170, 134, + 185, 124, 156, 51, 235, 206, 20, 62, 191, 51, 182, 195, 7, 184, 139, 80, 198, 103, 40, 37, 155, 219, 95, + 56, 162, 242, 152, 249, 204, 236, 191, 67, 64, 180, 223, 13, 207, 32, 242, 203, 172, 126, 77, 90, 197, 6, + 32, 162, 179, 253, 86, 158, 233, 147, 176, 44, 132, 150, 128, 103, 128, 157, 185, 157, 131, 50, 142, 248, + 67, 68, 217, 122, 154, 103, 143, 101, 207, 136, 219, 79, 226, 0, 159, 117, 200, 43, 80, 95, 163, 247, 218, + 117, 69, 248, 88, 64, 5, 181, 63, 109, 247, 80, 141, 174, 38, 220, 64, 250, 3, 82, 187, 52, 243, 151, 141, + 237, 115, 115, 17, 199, 29, 213, 4, 197, 242, 40, 177, 141, 170, 241, 173, 179, 212, 100, 73, 102, 21, 255, + 74, 213, 158, 11, 241, 110, 82, 139, 142, 209, 118, 197, 15, 240, 243, 50, 39, 23, 243, 172, 152, 170, 75, + 97, 102, 169, 23, 245, 147, 180, 29, 22, 58, 3, 100, 35, 6, 98, 92, 164, 55, 39, 81, 87, 58, 25, 22, 31, + 234, 173, 200, 213, 2, 3, 1, 0, 1, 163, 115, 48, 113, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, + 160, 48, 45, 6, 3, 85, 29, 17, 4, 38, 48, 36, 130, 11, 65, 90, 82, 68, 79, 87, 78, 45, 87, 49, 48, 130, 11, + 65, 90, 82, 68, 79, 87, 78, 45, 87, 49, 48, 130, 8, 49, 48, 46, 49, 46, 48, 46, 52, 48, 19, 6, 3, 85, 29, + 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, + 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, + 1, 1, 0, 124, 211, 121, 241, 39, 108, 96, 140, 158, 149, 109, 212, 59, 78, 203, 168, 204, 137, 19, 171, 77, + 67, 61, 166, 94, 122, 197, 145, 118, 157, 192, 156, 113, 249, 60, 110, 33, 188, 169, 75, 137, 57, 64, 130, + 5, 128, 58, 248, 87, 211, 139, 50, 157, 138, 176, 226, 159, 239, 15, 103, 84, 126, 26, 147, 246, 82, 12, + 80, 56, 61, 192, 231, 75, 104, 125, 95, 59, 52, 28, 236, 7, 195, 239, 242, 49, 105, 113, 168, 210, 102, + 192, 207, 212, 185, 185, 100, 137, 250, 219, 180, 75, 84, 139, 15, 115, 187, 165, 170, 227, 48, 245, 58, + 91, 137, 220, 197, 161, 180, 99, 195, 82, 92, 119, 170, 199, 3, 161, 221, 211, 177, 124, 92, 195, 92, 210, + 165, 117, 41, 98, 234, 175, 123, 44, 252, 230, 121, 151, 208, 210, 165, 67, 150, 152, 200, 243, 21, 85, + 209, 223, 217, 73, 243, 38, 166, 60, 3, 6, 140, 26, 170, 243, 114, 205, 210, 117, 111, 235, 38, 42, 43, + 217, 170, 118, 150, 180, 38, 218, 39, 198, 156, 157, 182, 223, 198, 200, 13, 255, 101, 56, 124, 126, 126, + 10, 255, 166, 203, 26, 251, 140, 248, 229, 41, 19, 94, 135, 210, 18, 185, 30, 55, 23, 195, 54, 88, 140, + 174, 87, 65, 250, 143, 243, 163, 172, 142, 207, 190, 111, 113, 157, 204, 246, 0, 119, 11, 253, 208, 155, + 101, 40, 217, 188, 10, 14, 89, 120, 146, 49, 130, 1, 199, 48, 130, 1, 195, 2, 1, 1, 48, 97, 48, 77, 49, 75, + 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, + 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, + 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 49, 0, 93, 2, 16, 85, 47, 30, 63, 139, 118, 224, 166, + 140, 108, 227, 232, 117, 255, 59, 249, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 160, 61, 48, 22, 6, 9, 42, 134, + 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 2, 48, 35, 6, 9, 42, 134, 72, 134, 247, 13, 1, + 9, 4, 49, 22, 4, 20, 207, 84, 215, 76, 61, 237, 27, 245, 186, 203, 116, 211, 41, 149, 95, 129, 147, 149, + 136, 166, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 1, 0, 111, 17, 1, 8, 116, 231, + 197, 34, 227, 186, 92, 57, 120, 101, 232, 20, 207, 52, 39, 202, 112, 40, 194, 203, 86, 55, 75, 186, 92, 52, + 55, 244, 26, 119, 58, 46, 200, 251, 185, 76, 244, 242, 18, 149, 207, 17, 126, 4, 41, 216, 89, 14, 137, 100, + 190, 70, 0, 183, 138, 152, 26, 56, 162, 219, 146, 159, 128, 68, 195, 190, 195, 32, 2, 64, 118, 220, 182, + 183, 218, 219, 145, 62, 246, 216, 214, 182, 244, 251, 97, 78, 232, 123, 167, 187, 154, 212, 10, 222, 244, + 232, 249, 194, 202, 26, 149, 174, 109, 15, 218, 247, 45, 209, 232, 92, 5, 87, 249, 192, 249, 91, 240, 160, + 7, 202, 196, 8, 161, 2, 41, 10, 242, 107, 43, 100, 45, 5, 75, 49, 222, 172, 249, 252, 196, 68, 71, 250, + 195, 11, 185, 161, 184, 39, 65, 22, 44, 78, 245, 132, 193, 63, 231, 94, 113, 116, 125, 210, 243, 106, 48, + 201, 50, 14, 177, 43, 168, 94, 39, 44, 221, 97, 60, 94, 230, 117, 248, 57, 143, 88, 117, 139, 75, 113, 97, + 48, 39, 13, 168, 2, 247, 89, 110, 216, 96, 161, 47, 183, 168, 204, 145, 221, 28, 174, 247, 196, 69, 212, + 187, 37, 162, 198, 33, 238, 127, 68, 191, 239, 233, 46, 240, 67, 151, 40, 76, 232, 41, 137, 233, 117, 199, + 11, 95, 201, 123, 246, 188, 44, 122, 105, 175, 179, 204, 127, 221, 57, 190, 66, 161, 34, 4, 32, 160, 135, + 139, 83, 106, 40, 32, 75, 125, 12, 23, 191, 191, 163, 215, 162, 217, 132, 196, 80, 212, 102, 88, 251, 252, + 135, 151, 137, 121, 58, 199, 71, 163, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, + 85, 164, 45, 48, 43, 160, 3, 2, 1, 128, 161, 36, 48, 34, 27, 32, 65, 122, 117, 114, 101, 65, 68, 92, 109, + 97, 109, 111, 114, 101, 97, 117, 64, 100, 111, 119, 110, 104, 105, 108, 108, 112, 114, 111, 46, 120, 121, + 122, 165, 130, 3, 227, 97, 130, 3, 223, 48, 130, 3, 219, 160, 3, 2, 1, 5, 161, 17, 27, 15, 87, 69, 76, 76, + 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 162, 33, 48, 31, 160, 3, 2, 1, 2, 161, 24, 48, 22, 27, 7, 84, + 69, 82, 77, 83, 82, 86, 27, 11, 65, 90, 82, 68, 79, 87, 78, 45, 87, 49, 48, 163, 130, 3, 156, 48, 130, 3, + 152, 160, 3, 2, 1, 18, 162, 130, 3, 143, 4, 130, 3, 139, 1, 206, 220, 195, 79, 122, 192, 180, 36, 196, 136, + 196, 220, 73, 91, 167, 233, 45, 204, 201, 148, 192, 68, 0, 158, 26, 246, 183, 80, 77, 153, 236, 156, 126, + 210, 232, 48, 59, 26, 118, 6, 208, 56, 26, 19, 197, 158, 79, 33, 215, 127, 55, 149, 23, 63, 180, 58, 196, + 63, 108, 78, 65, 240, 36, 188, 65, 121, 222, 12, 131, 194, 73, 28, 16, 4, 115, 76, 185, 80, 244, 103, 75, + 230, 191, 180, 210, 101, 133, 243, 33, 19, 30, 164, 27, 201, 91, 124, 212, 223, 174, 207, 49, 102, 46, 5, + 167, 14, 17, 239, 249, 1, 152, 83, 9, 15, 249, 52, 54, 49, 168, 215, 221, 197, 127, 66, 68, 126, 207, 82, + 33, 111, 74, 177, 66, 11, 39, 232, 23, 171, 34, 222, 28, 5, 192, 21, 181, 248, 7, 156, 232, 23, 226, 28, + 131, 247, 28, 247, 233, 191, 193, 15, 8, 36, 103, 57, 30, 126, 241, 186, 182, 154, 144, 167, 47, 148, 40, + 216, 51, 92, 85, 74, 35, 242, 108, 37, 41, 254, 16, 213, 10, 97, 73, 217, 95, 67, 118, 96, 160, 231, 185, + 127, 86, 130, 62, 129, 86, 225, 98, 36, 109, 190, 150, 34, 203, 57, 8, 134, 122, 113, 131, 25, 57, 6, 121, + 114, 58, 132, 130, 212, 218, 214, 106, 150, 67, 131, 157, 85, 100, 120, 163, 203, 16, 120, 184, 11, 6, 20, + 74, 223, 54, 118, 38, 122, 161, 255, 128, 112, 242, 161, 73, 73, 159, 83, 200, 90, 171, 216, 124, 125, 156, + 40, 56, 174, 192, 89, 243, 43, 29, 232, 77, 10, 28, 250, 8, 63, 151, 152, 104, 123, 123, 8, 207, 246, 58, + 85, 107, 160, 82, 157, 237, 236, 52, 67, 231, 169, 176, 155, 96, 64, 217, 222, 141, 122, 70, 26, 222, 134, + 181, 175, 234, 24, 98, 149, 212, 60, 35, 102, 40, 213, 148, 199, 127, 13, 213, 197, 69, 169, 62, 186, 132, + 195, 110, 141, 53, 102, 66, 202, 123, 209, 232, 133, 183, 7, 223, 22, 27, 124, 4, 13, 234, 16, 204, 214, 9, + 53, 227, 236, 127, 12, 64, 90, 162, 24, 36, 51, 209, 203, 45, 175, 107, 12, 49, 7, 213, 247, 49, 204, 37, + 235, 71, 157, 113, 10, 42, 122, 159, 170, 147, 186, 222, 183, 248, 108, 83, 54, 175, 113, 189, 148, 152, + 121, 133, 168, 26, 98, 225, 211, 34, 217, 69, 214, 208, 143, 31, 153, 255, 152, 101, 226, 144, 203, 168, + 203, 72, 182, 35, 183, 15, 172, 54, 127, 120, 56, 38, 199, 135, 192, 204, 30, 17, 68, 186, 77, 41, 138, + 126, 247, 231, 168, 133, 219, 205, 163, 132, 66, 215, 190, 6, 171, 149, 79, 114, 66, 236, 245, 248, 66, + 197, 29, 204, 222, 1, 208, 38, 214, 112, 61, 25, 238, 246, 201, 87, 10, 241, 229, 39, 228, 235, 132, 15, + 215, 19, 172, 88, 239, 186, 141, 165, 141, 114, 29, 135, 23, 139, 72, 206, 83, 52, 80, 71, 71, 96, 109, 73, + 119, 236, 50, 100, 156, 0, 231, 218, 225, 37, 227, 244, 49, 121, 115, 6, 149, 43, 199, 84, 51, 105, 137, + 49, 209, 91, 187, 160, 165, 17, 141, 65, 91, 117, 174, 29, 187, 42, 8, 198, 188, 145, 43, 252, 86, 154, 57, + 42, 180, 153, 158, 240, 237, 189, 157, 244, 74, 181, 142, 129, 106, 137, 146, 46, 75, 23, 52, 18, 113, 187, + 111, 80, 113, 169, 214, 75, 103, 225, 196, 42, 88, 102, 80, 55, 87, 228, 252, 126, 74, 13, 28, 43, 217, + 209, 221, 231, 77, 36, 179, 70, 252, 120, 119, 247, 92, 20, 138, 238, 234, 75, 186, 86, 235, 32, 72, 53, + 40, 157, 42, 242, 123, 147, 189, 197, 206, 117, 121, 45, 17, 165, 152, 153, 42, 208, 28, 236, 236, 185, + 216, 213, 147, 234, 66, 158, 41, 105, 166, 60, 37, 34, 115, 185, 3, 62, 77, 75, 169, 77, 226, 91, 140, 58, + 132, 214, 182, 254, 101, 233, 60, 84, 150, 166, 105, 205, 190, 48, 151, 86, 41, 130, 129, 217, 39, 111, + 228, 12, 221, 142, 43, 224, 18, 225, 85, 27, 104, 81, 196, 125, 248, 18, 134, 94, 38, 225, 173, 210, 198, + 138, 249, 204, 123, 69, 248, 206, 206, 75, 119, 17, 96, 118, 8, 119, 184, 142, 108, 4, 38, 147, 176, 25, + 138, 213, 90, 83, 73, 219, 227, 198, 165, 72, 206, 105, 228, 140, 64, 43, 134, 234, 239, 54, 236, 117, 129, + 97, 179, 56, 56, 135, 249, 41, 63, 29, 114, 204, 103, 252, 138, 186, 144, 1, 38, 61, 243, 33, 239, 119, + 235, 67, 199, 73, 92, 124, 64, 76, 0, 245, 37, 113, 103, 97, 180, 244, 208, 194, 41, 152, 252, 231, 13, + 251, 13, 240, 166, 19, 66, 78, 183, 47, 64, 204, 133, 29, 200, 189, 20, 134, 179, 203, 197, 160, 49, 157, + 152, 228, 33, 209, 114, 248, 35, 46, 163, 17, 239, 65, 15, 188, 234, 161, 167, 39, 222, 100, 139, 80, 0, 4, + 201, 204, 30, 7, 187, 233, 25, 208, 84, 107, 238, 60, 120, 147, 192, 151, 35, 134, 245, 89, 12, 113, 235, + 87, 114, 11, 112, 230, 220, 36, 94, 9, 105, 29, 183, 50, 159, 166, 130, 1, 13, 48, 130, 1, 9, 160, 3, 2, 1, + 18, 162, 130, 1, 0, 4, 129, 253, 62, 242, 7, 228, 43, 94, 177, 66, 185, 89, 38, 84, 238, 3, 18, 84, 199, + 99, 235, 203, 159, 159, 208, 53, 56, 51, 109, 123, 123, 122, 95, 9, 93, 11, 217, 142, 76, 36, 26, 139, 102, + 253, 138, 130, 44, 44, 84, 239, 73, 108, 79, 194, 61, 63, 16, 84, 185, 127, 228, 25, 136, 185, 192, 36, + 227, 219, 18, 111, 51, 254, 227, 176, 247, 0, 77, 30, 160, 12, 53, 184, 74, 139, 147, 124, 145, 200, 139, + 123, 146, 54, 72, 71, 154, 17, 113, 26, 221, 205, 46, 50, 234, 181, 210, 133, 209, 48, 168, 209, 180, 8, 3, + 201, 198, 172, 85, 169, 196, 142, 105, 180, 35, 110, 160, 103, 151, 102, 227, 172, 217, 82, 142, 230, 223, + 92, 92, 228, 36, 46, 94, 151, 255, 148, 76, 100, 55, 152, 228, 206, 185, 202, 128, 35, 25, 7, 233, 135, + 114, 98, 166, 29, 103, 179, 166, 189, 122, 200, 177, 14, 156, 222, 120, 104, 179, 117, 47, 209, 139, 196, + 95, 193, 121, 163, 38, 4, 12, 178, 117, 14, 85, 17, 4, 39, 242, 7, 166, 154, 178, 98, 51, 125, 205, 40, + 177, 225, 47, 227, 212, 186, 33, 0, 255, 113, 231, 112, 119, 145, 37, 26, 198, 9, 35, 108, 143, 47, 147, + 91, 163, 80, 142, 155, 208, 102, 97, 235, 50, 189, 90, 114, 94, 27, 237, 206, 97, 10, 121, 166, 24, 3, 248, + 187, 142, 204, 99, + ]; + + println!("{:?}", extract_as_rep(&raw_message).unwrap()); + } +} diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index 43a2c47c..14117dcf 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -3,16 +3,18 @@ use std::str::FromStr; use chrono::Utc; use oid::ObjectIdentifier; +use picky_asn1::bit_string::BitString; use picky_asn1::date::GeneralizedTime; use picky_asn1::restricted_string::{BMPString, IA5String}; use picky_asn1::wrapper::{ - Asn1SequenceOf, Asn1SetOf, BMPStringAsn1, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2, - ExplicitContextTag3, ImplicitContextTag0, IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, Optional, + Asn1SequenceOf, Asn1SetOf, BMPStringAsn1, BitStringAsn1, ExplicitContextTag0, ExplicitContextTag1, + ExplicitContextTag2, ExplicitContextTag3, ImplicitContextTag0, IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, + Optional, }; use picky_asn1_der::Asn1RawDer; use picky_asn1_x509::cmsversion::CmsVersion; use picky_asn1_x509::content_info::EncapsulatedContentInfo; -use picky_asn1_x509::oids::{AT_COMMON_NAME, KERBEROS_V5_PKINIT, NEGOEX, SPNEGO}; +use picky_asn1_x509::oids::{AT_COMMON_NAME, DIFFIE_HELLMAN, GSS_PKU2U, NEGOEX, PKINIT_AUTH_DATA, SPNEGO}; use picky_asn1_x509::signed_data::{ CertificateChoices, CertificateSet, DigestAlgorithmIdentifiers, SignedData, SignersInfos, }; @@ -21,7 +23,7 @@ use picky_asn1_x509::signer_info::{ UnsignedAttributes, }; use picky_asn1_x509::{AlgorithmIdentifier, Certificate, SubjectKeyIdentifier, Version}; -use picky_krb::constants::gss_api::{ACCEPT_INCOMPLETE, AS_REQ_TOKEN_ID}; +use picky_krb::constants::gss_api::ACCEPT_INCOMPLETE; use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REQ}; use picky_krb::data_types::{KerberosStringAsn1, KerberosTime, PaData, PrincipalName, Realm}; use picky_krb::gss_api::{ @@ -29,11 +31,12 @@ use picky_krb::gss_api::{ }; use picky_krb::messages::{AsReq, KdcReqBody}; use picky_krb::pkinit::{ - AuthPack, PaPkAsReq, PkAuthenticator, Pku2uNegoBody, Pku2uNegoReq, Pku2uNegoReqMetadata, Pku2uValue, - Pku2uValueInner, + AuthPack, DhDomainParameters, DhReqInfo, DhReqKeyInfo, PaPkAsReq, PkAuthenticator, Pku2uNegoBody, Pku2uNegoReq, + Pku2uNegoReqMetadata, Pku2uValue, Pku2uValueInner, }; use sha1::{Digest, Sha1}; +use super::DhParameters; use crate::kerberos::client::generators::MAX_MICROSECONDS_IN_SECOND; use crate::kerberos::SERVICE_NAME; use crate::Result; @@ -129,12 +132,44 @@ pub fn generate_signer_info(p2p_ca_cert: &Certificate) -> SignerInfo { } } +pub fn generate_client_dh_parameters() -> DhParameters { + let modulus = vec![ + 0, 255, 255, 255, 255, 255, 255, 255, 255, 201, 15, 218, 162, 33, 104, 194, 52, 196, 198, 98, 139, 128, 220, + 28, 209, 41, 2, 78, 8, 138, 103, 204, 116, 2, 11, 190, 166, 59, 19, 155, 34, 81, 74, 8, 121, 142, 52, 4, 221, + 239, 149, 25, 179, 205, 58, 67, 27, 48, 43, 10, 109, 242, 95, 20, 55, 79, 225, 53, 109, 109, 81, 194, 69, 228, + 133, 181, 118, 98, 94, 126, 198, 244, 76, 66, 233, 166, 55, 237, 107, 11, 255, 92, 182, 244, 6, 183, 237, 238, + 56, 107, 251, 90, 137, 159, 165, 174, 159, 36, 17, 124, 75, 31, 230, 73, 40, 102, 81, 236, 230, 83, 129, 255, + 255, 255, 255, 255, 255, 255, 255, + ]; + let q = vec![ + 127, 255, 255, 255, 255, 255, 255, 255, 228, 135, 237, 81, 16, 180, 97, 26, 98, 99, 49, 69, 192, 110, 14, 104, + 148, 129, 39, 4, 69, 51, 230, 58, 1, 5, 223, 83, 29, 137, 205, 145, 40, 165, 4, 60, 199, 26, 2, 110, 247, 202, + 140, 217, 230, 157, 33, 141, 152, 21, 133, 54, 249, 47, 138, 27, 167, 240, 154, 182, 182, 168, 225, 34, 242, + 66, 218, 187, 49, 47, 63, 99, 122, 38, 33, 116, 211, 27, 246, 181, 133, 255, 174, 91, 122, 3, 91, 246, 247, 28, + 53, 253, 173, 68, 207, 210, 215, 79, 146, 8, 190, 37, 143, 243, 36, 148, 51, 40, 246, 115, 41, 192, 255, 255, + 255, 255, 255, 255, 255, 255, + ]; + + DhParameters { + base: 2, + modulus, + q, + private_key: todo!(), + other_public_key: None, + client_nonce: Some([ + 72, 91, 60, 222, 24, 28, 4, 155, 141, 138, 44, 10, 136, 54, 202, 60, 146, 234, 183, 130, 109, 34, 94, 10, + 87, 237, 162, 55, 173, 100, 115, 43, + ]), + server_nonce: None, + } +} + pub fn generate_pa_datas_for_as_req( p2p_cert: &Certificate, p2p_ca_cert: &Certificate, kdc_req_body: &KdcReqBody, auth_nonce: u32, - dh_nonce: Option<&[u8; DH_NONCE_LEN]>, + dh_parameters: &DhParameters, ) -> Result> { let current_date = Utc::now(); let mut microseconds = current_date.timestamp_subsec_micros(); @@ -158,12 +193,32 @@ pub fn generate_pa_datas_for_as_req( nonce: ExplicitContextTag2::from(IntegerAsn1::from(auth_nonce.to_be_bytes().to_vec())), pa_checksum: Optional::from(Some(ExplicitContextTag3::from(OctetStringAsn1::from(sha1_hash)))), }), - client_public_value: Optional::from(Some(ExplicitContextTag1::from( - p2p_cert.tbs_certificate.subject_public_key_info.clone(), - ))), + client_public_value: Optional::from(Some(ExplicitContextTag1::from(DhReqInfo { + key_info: DhReqKeyInfo { + identifier: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(DIFFIE_HELLMAN).unwrap()), + key_info: DhDomainParameters { + p: IntegerAsn1::from(dh_parameters.modulus.clone()), + g: IntegerAsn1::from(dh_parameters.base.to_be_bytes().to_vec()), + q: IntegerAsn1::from(dh_parameters.q.clone()), + j: Optional::from(None), + validation_params: Optional::from(None), + }, + }, + key_value: BitStringAsn1::from(BitString::with_bytes(vec![ + 2, 129, 129, 0, 219, 78, 185, 183, 129, 7, 4, 73, 79, 203, 237, 216, 60, 162, 113, 232, 36, 233, 162, + 75, 8, 200, 168, 109, 49, 32, 207, 86, 26, 198, 121, 143, 205, 90, 248, 169, 6, 178, 153, 1, 237, 156, + 2, 145, 162, 150, 218, 232, 144, 183, 193, 58, 7, 27, 217, 215, 160, 30, 69, 15, 211, 28, 18, 216, 145, + 196, 14, 47, 119, 76, 163, 178, 243, 136, 213, 190, 122, 108, 59, 140, 94, 32, 75, 114, 17, 239, 99, + 81, 208, 221, 232, 214, 193, 129, 129, 135, 191, 117, 72, 254, 44, 211, 92, 124, 203, 235, 196, 113, 1, + 123, 74, 139, 101, 121, 212, 210, 119, 162, 26, 230, 153, 254, 123, 68, 151, 135, 52, 29, + ])), + }))), supported_cms_types: Optional::from(None), client_dh_nonce: Optional::from( - dh_nonce.map(|nonce| ExplicitContextTag3::from(OctetStringAsn1::from(nonce.to_vec()))), + dh_parameters + .client_nonce + .as_ref() + .map(|nonce| ExplicitContextTag3::from(OctetStringAsn1::from(nonce.to_vec()))), ), }; @@ -173,7 +228,7 @@ pub fn generate_pa_datas_for_as_req( AlgorithmIdentifier::new_sha1_with_rsa_encryption(), ])), content_info: EncapsulatedContentInfo::new( - ObjectIdentifier::try_from(KERBEROS_V5_PKINIT).unwrap(), + ObjectIdentifier::try_from(PKINIT_AUTH_DATA).unwrap(), Some(picky_asn1_der::to_vec(&auth_pack)?), ), certificates: Optional::from(CertificateSet(vec![CertificateChoices::Certificate(Asn1RawDer( @@ -195,11 +250,11 @@ pub fn generate_pa_datas_for_as_req( }]) } -pub fn generate_neg_as_req(as_req: AsReq) -> ApplicationTag0> { +pub fn generate_neg(krb_msg: T, krb5_token_id: [u8; 2]) -> ApplicationTag0> { ApplicationTag0(KrbMessage { - krb5_oid: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("GSS_PKU2U").unwrap()), - krb5_token_id: AS_REQ_TOKEN_ID, - krb_msg: as_req, + krb5_oid: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(GSS_PKU2U).unwrap()), + krb5_token_id, + krb_msg, }) } From cef6548cb8c1736ca897486631f1a6f366f18dec Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 19 Sep 2022 14:30:13 +0300 Subject: [PATCH 05/36] sspi: pku2u: implement ApExchange state --- src/sspi/kerberos.rs | 2 +- src/sspi/pku2u.rs | 64 ++++++++++++++++++++++++++++++------ src/sspi/pku2u/extractors.rs | 12 ++++--- src/sspi/pku2u/generators.rs | 2 +- 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 5018bcf4..5252665c 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -2,7 +2,7 @@ pub mod client; pub mod config; mod encryption_params; pub mod network_client; -mod server; +pub mod server; mod utils; use std::fmt::Debug; diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 1cc0554d..33709a63 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -9,11 +9,12 @@ use std::str::FromStr; use lazy_static::lazy_static; use picky_asn1_x509::signed_data::SignedData; use picky_asn1_x509::Certificate; -use picky_krb::constants::gss_api::{AS_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE, AP_REQ_TOKEN_ID}; -use picky_krb::constants::key_usages::ACCEPTOR_SIGN; -use picky_krb::crypto::{CipherSuite, ChecksumSuite, Checksum}; +use picky_krb::constants::gss_api::{AP_REQ_TOKEN_ID, AS_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE}; +use picky_krb::constants::key_usages::{ACCEPTOR_SIGN, INITIATOR_SIGN}; +use picky_krb::crypto::{ChecksumSuite, CipherSuite}; use picky_krb::diffie_hellman::{generate_key, DhNonce}; use picky_krb::gss_api::WrapToken; +use picky_krb::messages::{ApRep, AsRep}; use picky_krb::negoex::data_types::MessageType; use picky_krb::negoex::messages::{Exchange, Nego, Verify}; use picky_krb::negoex::{NegoexMessage, RANDOM_ARRAY_SIZE}; @@ -32,9 +33,10 @@ use crate::kerberos::client::generators::{ generate_ap_req, generate_as_req, generate_as_req_kdc_body, generate_authenticator, ChecksumOptions, GenerateAsReqOptions, GenerateAuthenticatorOptions, AUTHENTICATOR_DEFAULT_CHECKSUM, }; +use crate::kerberos::server::extractors::extract_sub_session_key_from_ap_rep; use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE, MAX_SIGNATURE, RRC, SECURITY_TRAILER, SERVICE_NAME}; use crate::sspi::pku2u::extractors::{ - extract_as_rep, extract_pa_pk_as_rep, extract_server_dh_public_key, extract_server_nonce, + extract_krb_rep, extract_pa_pk_as_rep, extract_server_dh_public_key, extract_server_nonce, }; use crate::sspi::{self, PACKAGE_ID_NONE}; use crate::utils::utf16_bytes_to_utf8_string; @@ -102,7 +104,7 @@ pub struct Pku2u { conversation_id: Uuid, auth_scheme: Option, seq_number: u32, - realm: Option, + // realm: Option, auth_nonce: u32, dh_parameters: DhParameters, // all sent and received NEGOEX messages in one vector @@ -122,7 +124,7 @@ impl Pku2u { conversation_id: Uuid::new_v4(), auth_scheme: None, seq_number: 0, - realm: None, + // realm: None, // https://www.rfc-editor.org/rfc/rfc4556.html#section-3.2.3 // Contains the nonce in the pkAuthenticator field in the request if the DH keys are NOT reused, // 0 otherwise. @@ -391,7 +393,6 @@ impl SspiImpl for Pku2u { let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; let buffer = input_token.buffer.as_slice(); - self.negoex_messages.extend_from_slice(buffer); let mut reader: Box = Box::new(buffer); @@ -493,7 +494,7 @@ impl SspiImpl for Pku2u { check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); - let as_rep = extract_as_rep(&acceptor_exchange.exchange)?; + let (as_rep, _): (AsRep, _) = extract_krb_rep(&acceptor_exchange.exchange)?; // todo: validate server's certificate @@ -565,7 +566,8 @@ impl SspiImpl for Pku2u { self.conversation_id, self.next_seq_number(), self.auth_scheme.unwrap(), - self.encryption_params.encryption_type + self.encryption_params + .encryption_type .as_ref() .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) .into(), @@ -589,7 +591,49 @@ impl SspiImpl for Pku2u { SecurityStatus::ContinueNeeded } Pku2uState::ApExchange => { - // todo!(); + let input = builder + .input + .as_ref() + .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "Input buffers must be specified".into()))?; + let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; + + let buffer = input_token.buffer.as_slice(); + self.negoex_messages.extend_from_slice(buffer); + + let mut reader: Box = Box::new(buffer); + + let acceptor_exchange = Exchange::decode(&mut reader, &buffer)?; + + check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); + check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); + + let acceptor_verify = + Verify::decode(&mut reader, &buffer[(acceptor_exchange.header.message_len as usize)..])?; + + check_conversation_id!(acceptor_verify.header.conversation_id.0, self.conversation_id); + check_auth_scheme!(acceptor_verify.auth_scheme.0, self.auth_scheme); + + let (ap_rep, _): (ApRep, _) = extract_krb_rep(&acceptor_exchange.exchange)?; + + self.encryption_params.sub_session_key = Some(extract_sub_session_key_from_ap_rep( + &ap_rep, + self.encryption_params.session_key.as_ref().unwrap(), + &self.encryption_params, + )?); + + let checksum = ChecksumSuite::try_from(acceptor_verify.checksum.checksum_type as usize)? + .hasher() + .checksum( + self.encryption_params.session_key.as_ref().unwrap(), + INITIATOR_SIGN, + &self.negoex_messages, + )?; + if acceptor_verify.checksum.checksum_value != checksum { + return Err(Error::new( + ErrorKind::MessageAltered, + "bad Verify message signature".into(), + )); + } self.state = Pku2uState::PubKeyAuth; diff --git a/src/sspi/pku2u/extractors.rs b/src/sspi/pku2u/extractors.rs index 38fdb029..3758e999 100644 --- a/src/sspi/pku2u/extractors.rs +++ b/src/sspi/pku2u/extractors.rs @@ -10,11 +10,12 @@ use picky_asn1_x509::signed_data::SignedData; use picky_krb::constants::types::PA_PK_AS_REP; use picky_krb::messages::AsRep; use picky_krb::pkinit::{DhRepInfo, KdcDhKeyInfo, PaPkAsRep}; +use serde::Deserialize; use super::generators::DH_NONCE_LEN; use crate::{Error, ErrorKind, Result}; -pub fn extract_as_rep(mut data: &[u8]) -> Result { +pub fn extract_krb_rep<'a, T: Deserialize<'a>>(mut data: &'a [u8]) -> Result<(T, &'a [u8])> { let _oid: ApplicationTag = picky_asn1_der::from_reader(&mut data).map_err(|e| Error::new(ErrorKind::InvalidToken, format!("{:?}", e)))?; @@ -30,7 +31,7 @@ pub fn extract_as_rep(mut data: &[u8]) -> Result { // )); // } - Ok(picky_asn1_der::from_reader(&mut data)?) + Ok((picky_asn1_der::from_bytes(data)?, data)) } pub fn extract_pa_pk_as_rep(as_rep: &AsRep) -> Result { @@ -116,7 +117,9 @@ pub fn extract_server_dh_public_key(signed_data: &SignedData) -> Result> #[cfg(test)] mod tests { - use super::extract_as_rep; + use picky_krb::messages::AsRep; + + use super::extract_krb_rep; #[test] fn as_rep_extraction() { @@ -249,6 +252,7 @@ mod tests { 187, 142, 204, 99, ]; - println!("{:?}", extract_as_rep(&raw_message).unwrap()); + let (as_rep, _): (AsRep, _) = extract_krb_rep(&raw_message).unwrap(); + println!("{:?}", as_rep) } } diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index 14117dcf..c428e09b 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -29,7 +29,7 @@ use picky_krb::data_types::{KerberosStringAsn1, KerberosTime, PaData, PrincipalN use picky_krb::gss_api::{ ApplicationTag0, GssApiNegInit, KrbMessage, MechType, MechTypeList, NegTokenInit, NegTokenTarg, }; -use picky_krb::messages::{AsReq, KdcReqBody}; +use picky_krb::messages::KdcReqBody; use picky_krb::pkinit::{ AuthPack, DhDomainParameters, DhReqInfo, DhReqKeyInfo, PaPkAsReq, PkAuthenticator, Pku2uNegoBody, Pku2uNegoReq, Pku2uNegoReqMetadata, Pku2uValue, Pku2uValueInner, From ebe50c47ff0d492aec869a96eb89e71bab026b43 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 19 Sep 2022 21:27:47 +0300 Subject: [PATCH 06/36] sspi: negotiate: add Pku2u protocol support; sspi: pku2u: move config in separate file (module); --- Cargo.toml | 1 + src/sspi/negotiate.rs | 47 ++++++++++++++++++++++++++++++++++------ src/sspi/pku2u.rs | 20 ++++++++++------- src/sspi/pku2u/config.rs | 28 ++++++++++++++++++++++++ src/utils.rs | 8 +++++++ 5 files changed, 89 insertions(+), 15 deletions(-) create mode 100644 src/sspi/pku2u/config.rs diff --git a/Cargo.toml b/Cargo.toml index 9bbd3636..5b8d1ef8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ num-traits = "0.2" lazy_static = "1.2" serde = "1.0" serde_derive = "1.0" +schannel = "0.1.20" winapi = { version = "0.3", features = ["sspi", "rpcdce", "impl-default", "timezoneapi", "wincrypt"] } url = "2.2.2" reqwest = { version = "0.11", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], optional = true, default-features = false } diff --git a/src/sspi/negotiate.rs b/src/sspi/negotiate.rs index 7c284af8..f4abd4ea 100644 --- a/src/sspi/negotiate.rs +++ b/src/sspi/negotiate.rs @@ -7,6 +7,7 @@ use lazy_static::lazy_static; #[cfg(feature = "network_client")] use url::Url; +use super::pku2u::Pku2uConfig; use crate::internal::SspiImpl; #[cfg(feature = "network_client")] use crate::kerberos::config::KdcType; @@ -17,13 +18,14 @@ use crate::kerberos::SSPI_KDC_URL_ENV; use crate::sspi::{Result, PACKAGE_ID_NONE}; #[cfg(feature = "network_client")] use crate::utils::get_domain_from_fqdn; +use crate::utils::is_azure_ad_username; #[cfg(feature = "network_client")] use crate::utils::resolve_kdc_host; use crate::{ builders, AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, AuthIdentityBuffers, CertTrustStatus, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, Error, ErrorKind, - InitializeSecurityContextResult, Kerberos, KerberosConfig, Ntlm, PackageCapabilities, PackageInfo, SecurityBuffer, - SecurityPackageType, SecurityStatus, Sspi, SspiEx, + InitializeSecurityContextResult, Kerberos, KerberosConfig, Ntlm, PackageCapabilities, PackageInfo, Pku2u, + SecurityBuffer, SecurityPackageType, SecurityStatus, Sspi, SspiEx, }; pub const PKG_NAME: &str = "Negotiate"; @@ -41,16 +43,28 @@ lazy_static! { #[derive(Debug, Clone)] pub struct NegotiateConfig { pub krb_config: Option, + pub pku2u_config: Option, } impl NegotiateConfig { pub fn new() -> Self { - Self { krb_config: None } + Self { + krb_config: None, + pku2u_config: None, + } } pub fn new_with_kerberos(krb_config: KerberosConfig) -> Self { Self { krb_config: Some(krb_config), + pku2u_config: None, + } + } + + pub fn new_with_pku2u(pku2u_config: Pku2uConfig) -> Self { + Self { + krb_config: None, + pku2u_config: Some(pku2u_config), } } } @@ -64,6 +78,7 @@ impl Default for NegotiateConfig { #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone)] pub enum NegotiatedProtocol { + Pku2u(Pku2u), Kerberos(Kerberos), Ntlm(Ntlm), } @@ -80,6 +95,10 @@ impl Negotiate { Kerberos::new_client_from_config(krb_config) .map(NegotiatedProtocol::Kerberos) .unwrap_or_else(|_| NegotiatedProtocol::Ntlm(Ntlm::new())) + } else if let Some(pku2u_config) = config.pku2u_config { + Pku2u::new_client_from_config(pku2u_config) + .map(NegotiatedProtocol::Pku2u) + .unwrap_or_else(|_| NegotiatedProtocol::Ntlm(Ntlm::new())) } else { #[cfg(feature = "network_client")] if env::var(SSPI_KDC_URL_ENV).is_ok() { @@ -99,9 +118,14 @@ impl Negotiate { }) } - #[cfg(feature = "network_client")] fn negotiate_protocol(&mut self, username: &[u8]) -> Result<()> { if let NegotiatedProtocol::Ntlm(_) = &self.protocol { + if is_azure_ad_username(username) { + self.protocol = NegotiatedProtocol::Pku2u(Pku2u::new_client_from_config(Pku2uConfig::default())?); + return Ok(()); + } + + #[cfg(feature = "network_client")] if let Some(domain) = get_domain_from_fqdn(username) { if let Some(host) = resolve_kdc_host(&domain) { self.protocol = NegotiatedProtocol::Kerberos(Kerberos::new_client_from_config(KerberosConfig { @@ -122,6 +146,7 @@ impl SspiEx for Negotiate { self.auth_identity = Some(identity.clone().into()); match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.custom_set_auth_identity(identity), NegotiatedProtocol::Kerberos(kerberos) => kerberos.custom_set_auth_identity(identity), NegotiatedProtocol::Ntlm(ntlm) => ntlm.custom_set_auth_identity(identity), } @@ -131,6 +156,7 @@ impl SspiEx for Negotiate { impl Sspi for Negotiate { fn complete_auth_token(&mut self, token: &mut [SecurityBuffer]) -> Result { match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.complete_auth_token(token), NegotiatedProtocol::Kerberos(kerberos) => kerberos.complete_auth_token(token), NegotiatedProtocol::Ntlm(ntlm) => ntlm.complete_auth_token(token), } @@ -143,6 +169,7 @@ impl Sspi for Negotiate { sequence_number: u32, ) -> Result { match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.encrypt_message(flags, message, sequence_number), NegotiatedProtocol::Kerberos(kerberos) => kerberos.encrypt_message(flags, message, sequence_number), NegotiatedProtocol::Ntlm(ntlm) => ntlm.encrypt_message(flags, message, sequence_number), } @@ -150,6 +177,7 @@ impl Sspi for Negotiate { fn decrypt_message(&mut self, message: &mut [SecurityBuffer], sequence_number: u32) -> Result { match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.decrypt_message(message, sequence_number), NegotiatedProtocol::Kerberos(kerberos) => kerberos.decrypt_message(message, sequence_number), NegotiatedProtocol::Ntlm(ntlm) => ntlm.decrypt_message(message, sequence_number), } @@ -157,6 +185,7 @@ impl Sspi for Negotiate { fn query_context_sizes(&mut self) -> Result { match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.query_context_sizes(), NegotiatedProtocol::Kerberos(kerberos) => kerberos.query_context_sizes(), NegotiatedProtocol::Ntlm(ntlm) => ntlm.query_context_sizes(), } @@ -164,6 +193,7 @@ impl Sspi for Negotiate { fn query_context_names(&mut self) -> Result { match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.query_context_names(), NegotiatedProtocol::Kerberos(kerberos) => kerberos.query_context_names(), NegotiatedProtocol::Ntlm(ntlm) => ntlm.query_context_names(), } @@ -171,6 +201,7 @@ impl Sspi for Negotiate { fn query_context_package_info(&mut self) -> Result { match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.query_context_package_info(), NegotiatedProtocol::Kerberos(kerberos) => kerberos.query_context_package_info(), NegotiatedProtocol::Ntlm(ntlm) => ntlm.query_context_package_info(), } @@ -178,16 +209,17 @@ impl Sspi for Negotiate { fn query_context_cert_trust_status(&mut self) -> Result { match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.query_context_cert_trust_status(), NegotiatedProtocol::Kerberos(kerberos) => kerberos.query_context_cert_trust_status(), NegotiatedProtocol::Ntlm(ntlm) => ntlm.query_context_cert_trust_status(), } } fn change_password(&mut self, change_password: builders::ChangePassword) -> Result<()> { - #[cfg(feature = "network_client")] self.negotiate_protocol(change_password.account_name.as_bytes())?; match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.change_password(change_password), NegotiatedProtocol::Kerberos(kerberos) => kerberos.change_password(change_password), NegotiatedProtocol::Ntlm(ntlm) => ntlm.change_password(change_password), } @@ -209,7 +241,6 @@ impl SspiImpl for Negotiate { )); } - #[cfg(feature = "network_client")] if let Some(identity) = builder.auth_data { self.negotiate_protocol(identity.username.as_bytes())?; } @@ -217,6 +248,7 @@ impl SspiImpl for Negotiate { self.auth_identity = builder.auth_data.cloned().map(AuthIdentityBuffers::from); match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.acquire_credentials_handle_impl(builder)?, NegotiatedProtocol::Kerberos(kerberos) => kerberos.acquire_credentials_handle_impl(builder)?, NegotiatedProtocol::Ntlm(ntlm) => ntlm.acquire_credentials_handle_impl(builder)?, }; @@ -231,7 +263,6 @@ impl SspiImpl for Negotiate { &mut self, builder: &mut builders::FilledInitializeSecurityContext<'a, Self::CredentialsHandle>, ) -> Result { - #[cfg(feature = "network_client")] if let Some(Some(identity)) = builder.credentials_handle { self.negotiate_protocol(&identity.user)?; } @@ -249,6 +280,7 @@ impl SspiImpl for Negotiate { } match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.initialize_security_context_impl(builder), NegotiatedProtocol::Kerberos(kerberos) => kerberos.initialize_security_context_impl(builder), NegotiatedProtocol::Ntlm(ntlm) => ntlm.initialize_security_context_impl(builder), } @@ -259,6 +291,7 @@ impl SspiImpl for Negotiate { builder: builders::FilledAcceptSecurityContext<'a, Self::AuthenticationData, Self::CredentialsHandle>, ) -> Result { match &mut self.protocol { + NegotiatedProtocol::Pku2u(pku2u) => pku2u.accept_security_context_impl(builder), NegotiatedProtocol::Kerberos(kerberos) => kerberos.accept_security_context_impl(builder), NegotiatedProtocol::Ntlm(ntlm) => ntlm.accept_security_context_impl(builder), } diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 33709a63..30abd2d3 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -1,14 +1,16 @@ mod extractors; +mod config; mod generators; #[macro_use] mod macros; +pub use config::Pku2uConfig; + use std::io::{Read, Write}; use std::str::FromStr; use lazy_static::lazy_static; use picky_asn1_x509::signed_data::SignedData; -use picky_asn1_x509::Certificate; use picky_krb::constants::gss_api::{AP_REQ_TOKEN_ID, AS_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE}; use picky_krb::constants::key_usages::{ACCEPTOR_SIGN, INITIATOR_SIGN}; use picky_krb::crypto::{ChecksumSuite, CipherSuite}; @@ -44,11 +46,13 @@ use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, AuthIdentityBuffers, CertTrustStatus, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, EncryptionFlags, Error, ErrorKind, InitializeSecurityContextResult, PackageCapabilities, PackageInfo, Result, SecurityBuffer, SecurityBufferType, - SecurityPackageType, SecurityStatus, Sspi, + SecurityPackageType, SecurityStatus, Sspi, SspiEx, }; pub const PKG_NAME: &str = "Pku2u"; +pub const AZURE_AD_PREFIX: &str = "AzureAD\\"; + /// Default NEGOEX authentication scheme pub const AUTH_SCHEME: &str = "0d53335c-f9ea-4d0d-b2ec-4ae3786ec308"; @@ -73,12 +77,6 @@ pub enum Pku2uState { Final, } -#[derive(Debug, Clone)] -pub struct Pku2uConfig { - p2p_certificate: Certificate, - p2p_ca_certificate: Certificate, -} - #[derive(Debug, Clone)] pub struct DhParameters { // g @@ -664,3 +662,9 @@ impl SspiImpl for Pku2u { )) } } + +impl SspiEx for Pku2u { + fn custom_set_auth_identity(&mut self, identity: Self::AuthenticationData) { + self.auth_identity = Some(identity.into()); + } +} diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs new file mode 100644 index 00000000..cec903da --- /dev/null +++ b/src/sspi/pku2u/config.rs @@ -0,0 +1,28 @@ +use picky_asn1_x509::Certificate; + +#[derive(Debug, Clone)] +pub struct Pku2uConfig { + pub p2p_certificate: Certificate, + pub p2p_ca_certificate: Certificate, +} + +#[cfg(windows)] +impl Default for Pku2uConfig { + fn default() -> Self { + // Self { + // p2p_certificate: todo!(), + // p2p_ca_certificate: todo!(), + // } + todo!() + } +} + +#[cfg(not(windows))] +impl Default for Pku2uConfig { + fn default() -> Self { + Self { + p2p_certificate: todo!(), + p2p_ca_certificate: todo!(), + } + } +} diff --git a/src/utils.rs b/src/utils.rs index 8e652d66..53a2757b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,5 +1,7 @@ use byteorder::{LittleEndian, ReadBytesExt}; +use crate::sspi::pku2u::AZURE_AD_PREFIX; + pub fn string_to_utf16(value: &str) -> Vec { value .encode_utf16() @@ -23,6 +25,12 @@ pub fn get_domain_from_fqdn(fqdm: &[u8]) -> Option { fqdm.find('@').map(|index| fqdm.split_off(index + 1)) } +pub fn is_azure_ad_username(username: &[u8]) -> bool { + let username = bytes_to_utf16_string(username); + + username.starts_with(AZURE_AD_PREFIX) && username.contains('@') +} + pub fn utf16_bytes_to_utf8_string(data: &[u8]) -> String { debug_assert_eq!(data.len() % 2, 0); String::from_utf16_lossy( From 2c18fb30efd4e1dadf7aeca6033707ee0e1c1595 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Sun, 25 Sep 2022 12:24:54 +0300 Subject: [PATCH 07/36] sspi: Pku2uState::Negotiate works --- Cargo.toml | 2 +- src/sspi/internal/credssp.rs | 4 +- src/sspi/kerberos.rs | 10 +- src/sspi/kerberos/client/generators.rs | 4 +- src/sspi/ntlm/messages/client/authenticate.rs | 2 +- src/sspi/ntlm/messages/computations.rs | 2 +- src/sspi/pku2u.rs | 29 ++- src/sspi/pku2u/config.rs | 186 +++++++++++++++++- src/sspi/pku2u/generators.rs | 77 +++----- 9 files changed, 244 insertions(+), 72 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5b8d1ef8..3f681f42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ network_client = ["reqwest", "trust-dns-resolver", "portpicker"] [dependencies] byteorder = "1.2.7" bitflags = "1.0" -rand = "0.6" +rand = "0.8.5" cfg-if = "0.1" chrono = "0.4" md-5 = "0.9" diff --git a/src/sspi/internal/credssp.rs b/src/sspi/internal/credssp.rs index 25362137..17fa81c6 100644 --- a/src/sspi/internal/credssp.rs +++ b/src/sspi/internal/credssp.rs @@ -193,7 +193,7 @@ impl CredSspClient { credentials, public_key, cred_ssp_mode, - client_nonce: OsRng::new()?.gen::<[u8; NONCE_SIZE]>(), + client_nonce: OsRng::default().gen::<[u8; NONCE_SIZE]>(), credentials_handle: None, ts_request_version: TS_REQUEST_VERSION, client_mode, @@ -215,7 +215,7 @@ impl CredSspClient { credentials, public_key, cred_ssp_mode, - client_nonce: OsRng::new()?.gen::<[u8; NONCE_SIZE]>(), + client_nonce: OsRng::default().gen::<[u8; NONCE_SIZE]>(), credentials_handle: None, ts_request_version, client_mode, diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 5252665c..853c6eda 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -109,7 +109,7 @@ impl Kerberos { config, auth_identity: None, encryption_params: EncryptionParams::default_for_client(), - seq_number: OsRng::new()?.gen::(), + seq_number: OsRng::default().gen::(), realm: None, channel_bindings: None, }) @@ -121,7 +121,7 @@ impl Kerberos { config, auth_identity: None, encryption_params: EncryptionParams::default_for_server(), - seq_number: OsRng::new()?.gen::(), + seq_number: OsRng::default().gen::(), realm: None, channel_bindings: None, }) @@ -384,7 +384,7 @@ impl Sspi for Kerberos { let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, seq_num: Some(seq_num), - sub_key: Some(OsRng::new()?.gen::<[u8; 32]>().to_vec()), + sub_key: Some(OsRng::default().gen::<[u8; 32]>().to_vec()), checksum: None, channel_bindings: self.channel_bindings.as_ref(), })?; @@ -540,7 +540,7 @@ impl SspiImpl for Kerberos { let mut authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, - seq_num: Some(OsRng::new()?.gen::()), + seq_num: Some(OsRng::default().gen::()), sub_key: None, checksum: None, channel_bindings: self.channel_bindings.as_ref(), @@ -580,7 +580,7 @@ impl SspiImpl for Kerberos { let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &tgs_rep.0, seq_num: Some(self.next_seq_number()), - sub_key: Some(OsRng::new()?.gen::<[u8; 32]>().to_vec()), + sub_key: Some(OsRng::default().gen::<[u8; 32]>().to_vec()), checksum: Some(ChecksumOptions { checksum_type: AUTHENTICATOR_CHECKSUM_TYPE.to_vec(), checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), diff --git a/src/sspi/kerberos/client/generators.rs b/src/sspi/kerberos/client/generators.rs index ff0ff54f..eaa4b55a 100644 --- a/src/sspi/kerberos/client/generators.rs +++ b/src/sspi/kerberos/client/generators.rs @@ -195,7 +195,7 @@ pub fn generate_as_req_kdc_body(options: &GenerateAsReqOptions) -> Result().to_vec())), + nonce: ExplicitContextTag7::from(IntegerAsn1::from(OsRng::default().gen::<[u8; NONCE_LEN]>().to_vec())), etype: ExplicitContextTag8::from(Asn1SequenceOf::from(vec![ IntegerAsn1::from(vec![CipherSuite::Aes256CtsHmacSha196.into()]), IntegerAsn1::from(vec![CipherSuite::Aes128CtsHmacSha196.into()]), @@ -260,7 +260,7 @@ pub fn generate_tgs_req( from: Optional::from(None), till: ExplicitContextTag5::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(expiration_date))), rtime: Optional::from(None), - nonce: ExplicitContextTag7::from(IntegerAsn1::from(OsRng::new()?.gen::<[u8; NONCE_LEN]>().to_vec())), + nonce: ExplicitContextTag7::from(IntegerAsn1::from(OsRng::default().gen::<[u8; NONCE_LEN]>().to_vec())), etype: ExplicitContextTag8::from(Asn1SequenceOf::from(vec![ IntegerAsn1::from(vec![CipherSuite::Aes256CtsHmacSha196.into()]), IntegerAsn1::from(vec![CipherSuite::Aes128CtsHmacSha196.into()]), diff --git a/src/sspi/ntlm/messages/client/authenticate.rs b/src/sspi/ntlm/messages/client/authenticate.rs index 979cc17f..1fa6ab97 100644 --- a/src/sspi/ntlm/messages/client/authenticate.rs +++ b/src/sspi/ntlm/messages/client/authenticate.rs @@ -118,7 +118,7 @@ pub fn write_authenticate( ntlm_v2_hash.as_ref(), challenge_message.timestamp, )?; - let session_key = OsRng::new()?.gen::<[u8; SESSION_KEY_SIZE]>(); + let session_key = OsRng::default().gen::<[u8; SESSION_KEY_SIZE]>(); let encrypted_session_key_vec = Rc4::new(&key_exchange_key).process(session_key.as_ref()); let mut encrypted_session_key = [0x00; ENCRYPTED_RANDOM_SESSION_KEY_SIZE]; encrypted_session_key.clone_from_slice(encrypted_session_key_vec.as_ref()); diff --git a/src/sspi/ntlm/messages/computations.rs b/src/sspi/ntlm/messages/computations.rs index f39674a3..f9acd428 100644 --- a/src/sspi/ntlm/messages/computations.rs +++ b/src/sspi/ntlm/messages/computations.rs @@ -116,7 +116,7 @@ pub fn get_authenticate_target_info( } pub fn generate_challenge() -> Result<[u8; CHALLENGE_SIZE], rand::Error> { - Ok(OsRng::new()?.gen::<[u8; CHALLENGE_SIZE]>()) + Ok(OsRng::default().gen::<[u8; CHALLENGE_SIZE]>()) } pub fn generate_timestamp() -> sspi::Result { diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 30abd2d3..ea497350 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -1,20 +1,19 @@ -mod extractors; mod config; +mod extractors; mod generators; #[macro_use] mod macros; -pub use config::Pku2uConfig; - use std::io::{Read, Write}; use std::str::FromStr; +pub use config::Pku2uConfig; use lazy_static::lazy_static; use picky_asn1_x509::signed_data::SignedData; use picky_krb::constants::gss_api::{AP_REQ_TOKEN_ID, AS_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE}; use picky_krb::constants::key_usages::{ACCEPTOR_SIGN, INITIATOR_SIGN}; +use picky_krb::crypto::diffie_hellman::{generate_key, DhNonce}; use picky_krb::crypto::{ChecksumSuite, CipherSuite}; -use picky_krb::diffie_hellman::{generate_key, DhNonce}; use picky_krb::gss_api::WrapToken; use picky_krb::messages::{ApRep, AsRep}; use picky_krb::negoex::data_types::MessageType; @@ -80,7 +79,7 @@ pub enum Pku2uState { #[derive(Debug, Clone)] pub struct DhParameters { // g - base: usize, + base: Vec, // p modulus: Vec, // @@ -110,6 +109,7 @@ pub struct Pku2u { // https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-NEGOEX/%5bMS-NEGOEX%5d.pdf // The checksum is performed on all previous NEGOEX messages in the context negotiation. negoex_messages: Vec, + negoex_random: [u8; RANDOM_ARRAY_SIZE], } impl Pku2u { @@ -119,7 +119,9 @@ impl Pku2u { state: Pku2uState::Negotiate, encryption_params: EncryptionParams::default_for_client(), auth_identity: None, - conversation_id: Uuid::new_v4(), + // conversation_id: Uuid::new_v4(), + // for the debugging + conversation_id: Uuid::from_str("883f9d5e-1555-2de8-cc32-506de34031ae").unwrap(), auth_scheme: None, seq_number: 0, // realm: None, @@ -128,8 +130,14 @@ impl Pku2u { // 0 otherwise. auth_nonce: 0, // generate dh parameters at the start in order to not waste time during authorization - dh_parameters: generate_client_dh_parameters(), + dh_parameters: generate_client_dh_parameters()?, negoex_messages: Vec::new(), + // negoex_random: OsRng::default().gen::<[u8; RANDOM_ARRAY_SIZE]>(), + // for the debugging + negoex_random: [ + 10, 209, 111, 101, 206, 151, 53, 222, 225, 32, 241, 24, 15, 201, 210, 38, 133, 175, 97, 251, 27, 195, + 152, 39, 9, 97, 115, 227, 194, 196, 54, 245, + ], }) } @@ -357,7 +365,7 @@ impl SspiImpl for Pku2u { MessageType::InitiatorNego, self.conversation_id, self.next_seq_number(), - OsRng::new()?.gen::<[u8; RANDOM_ARRAY_SIZE]>(), + self.negoex_random.clone(), vec![auth_scheme], vec![], ); @@ -368,7 +376,7 @@ impl SspiImpl for Pku2u { self.conversation_id, self.next_seq_number(), auth_scheme, - picky_asn1_der::to_vec(&generate_pku2u_nego_req(&username)?)?, + picky_asn1_der::to_vec(&generate_pku2u_nego_req(&username, &self.config)?)?, ); exchange.encode(&mut mech_token)?; @@ -391,6 +399,7 @@ impl SspiImpl for Pku2u { let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; let buffer = input_token.buffer.as_slice(); + println!("buffer: {:?}", buffer); self.negoex_messages.extend_from_slice(buffer); let mut reader: Box = Box::new(buffer); @@ -533,7 +542,7 @@ impl SspiImpl for Pku2u { let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, seq_num: Some(self.next_seq_number()), - sub_key: Some(OsRng::new()?.gen::<[u8; 32]>().to_vec()), + sub_key: Some(OsRng::default().gen::<[u8; 32]>().to_vec()), checksum: Some(ChecksumOptions { checksum_type: AUTHENTICATOR_CHECKSUM_TYPE.to_vec(), checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index cec903da..9134faf4 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -2,6 +2,7 @@ use picky_asn1_x509::Certificate; #[derive(Debug, Clone)] pub struct Pku2uConfig { + pub device_certificate: Certificate, pub p2p_certificate: Certificate, pub p2p_ca_certificate: Certificate, } @@ -9,11 +10,134 @@ pub struct Pku2uConfig { #[cfg(windows)] impl Default for Pku2uConfig { fn default() -> Self { - // Self { - // p2p_certificate: todo!(), - // p2p_ca_certificate: todo!(), - // } - todo!() + Self { + device_certificate: picky_asn1_der::from_bytes(&[ + 48, 130, 3, 242, 48, 130, 2, 218, 160, 3, 2, 1, 2, 2, 16, 151, 57, 89, 108, 207, 42, 14, 171, 65, 62, + 108, 81, 115, 209, 185, 213, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 120, 49, 118, + 48, 17, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 3, 110, 101, 116, 48, 21, 6, 10, 9, 146, + 38, 137, 147, 242, 44, 100, 1, 25, 22, 7, 119, 105, 110, 100, 111, 119, 115, 48, 29, 6, 3, 85, 4, 3, + 19, 22, 77, 83, 45, 79, 114, 103, 97, 110, 105, 122, 97, 116, 105, 111, 110, 45, 65, 99, 99, 101, 115, + 115, 48, 43, 6, 3, 85, 4, 11, 19, 36, 56, 50, 100, 98, 97, 99, 97, 52, 45, 51, 101, 56, 49, 45, 52, 54, + 99, 97, 45, 57, 99, 55, 51, 45, 48, 57, 53, 48, 99, 49, 101, 97, 99, 97, 57, 55, 48, 30, 23, 13, 50, + 50, 48, 57, 50, 52, 49, 57, 53, 54, 49, 56, 90, 23, 13, 51, 50, 48, 57, 50, 52, 50, 48, 50, 54, 49, 56, + 90, 48, 47, 49, 45, 48, 43, 6, 3, 85, 4, 3, 19, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, + 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, + 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, + 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, + 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, + 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, + 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, + 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, + 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, + 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, + 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, + 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, + 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, + 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, + 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 129, 192, 48, 129, 189, + 48, 12, 6, 3, 85, 29, 19, 1, 1, 255, 4, 2, 48, 0, 48, 22, 6, 3, 85, 29, 37, 1, 1, 255, 4, 12, 48, 10, + 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 34, 6, 11, 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 2, 4, 19, 4, + 129, 16, 221, 203, 182, 201, 240, 211, 195, 74, 152, 121, 224, 174, 59, 97, 189, 148, 48, 34, 6, 11, + 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 3, 4, 19, 4, 129, 16, 69, 148, 59, 128, 155, 126, 130, 76, + 147, 242, 220, 233, 157, 233, 149, 191, 48, 34, 6, 11, 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 5, 4, + 19, 4, 129, 16, 72, 36, 37, 169, 183, 154, 176, 73, 187, 92, 242, 249, 35, 200, 70, 114, 48, 20, 6, 11, + 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 8, 4, 5, 4, 129, 2, 69, 85, 48, 19, 6, 11, 42, 134, 72, 134, + 247, 20, 1, 5, 130, 28, 7, 4, 4, 4, 129, 1, 49, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, + 0, 3, 130, 1, 1, 0, 67, 13, 108, 42, 1, 160, 165, 193, 26, 122, 235, 13, 116, 210, 230, 62, 133, 236, + 164, 204, 73, 214, 202, 141, 168, 17, 115, 121, 37, 179, 151, 87, 25, 75, 141, 49, 31, 202, 184, 84, + 89, 106, 122, 240, 137, 27, 17, 166, 19, 244, 186, 168, 110, 139, 45, 63, 131, 123, 248, 102, 32, 163, + 224, 224, 127, 189, 76, 54, 43, 0, 73, 79, 101, 144, 137, 155, 95, 33, 126, 119, 97, 164, 158, 3, 208, + 4, 241, 50, 251, 83, 10, 49, 42, 3, 95, 24, 35, 28, 251, 74, 244, 187, 247, 97, 188, 64, 82, 234, 157, + 207, 109, 184, 138, 218, 178, 86, 155, 223, 48, 6, 36, 71, 171, 113, 65, 64, 69, 54, 155, 146, 88, 2, + 54, 122, 213, 131, 176, 27, 195, 135, 143, 23, 170, 79, 226, 29, 87, 62, 72, 224, 53, 153, 83, 60, 159, + 56, 185, 255, 247, 69, 153, 177, 93, 233, 242, 168, 65, 191, 1, 204, 93, 72, 103, 91, 231, 38, 149, + 115, 221, 194, 167, 130, 134, 68, 82, 202, 255, 133, 220, 45, 19, 171, 103, 87, 127, 144, 94, 156, 71, + 246, 138, 18, 158, 238, 46, 191, 207, 212, 114, 117, 207, 170, 231, 110, 83, 146, 238, 199, 244, 226, + 209, 172, 245, 134, 211, 166, 151, 128, 64, 18, 2, 67, 104, 142, 206, 111, 151, 80, 100, 232, 49, 204, + 76, 204, 105, 136, 207, 36, 135, 236, 178, 239, 209, 196, 34, 246, + ]) + .unwrap(), + p2p_certificate: picky_asn1_der::from_bytes(&[ + 48, 130, 3, 128, 48, 130, 2, 104, 160, 3, 2, 1, 2, 2, 16, 116, 116, 177, 8, 107, 122, 107, 128, 130, + 210, 18, 39, 217, 141, 219, 189, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, + 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, + 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, + 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 48, + 57, 50, 52, 50, 48, 50, 49, 49, 57, 90, 23, 13, 50, 50, 48, 57, 50, 53, 50, 48, 50, 54, 49, 57, 90, 48, + 101, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, + 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, + 56, 52, 54, 55, 50, 49, 45, 48, 43, 6, 3, 85, 4, 3, 12, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, + 51, 102, 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, + 52, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, + 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, + 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, + 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, + 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, + 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, + 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, + 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, + 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, + 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, + 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, + 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, + 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 68, + 48, 66, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, + 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, + 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, + 1, 0, 2, 134, 185, 116, 6, 179, 66, 45, 132, 44, 219, 120, 122, 184, 124, 87, 219, 133, 97, 236, 71, + 221, 1, 224, 67, 10, 56, 17, 48, 48, 105, 39, 11, 252, 0, 166, 29, 141, 65, 45, 77, 244, 129, 209, 209, + 31, 63, 109, 55, 177, 252, 218, 204, 56, 85, 211, 18, 5, 54, 40, 143, 168, 187, 122, 234, 216, 118, + 232, 77, 59, 40, 224, 11, 235, 220, 97, 15, 137, 217, 114, 1, 5, 153, 167, 165, 206, 7, 163, 113, 4, + 230, 184, 221, 197, 255, 165, 53, 12, 227, 235, 177, 69, 98, 124, 55, 161, 253, 21, 6, 223, 3, 1, 72, + 206, 44, 52, 70, 174, 109, 239, 167, 71, 58, 214, 127, 181, 179, 37, 244, 15, 122, 181, 62, 49, 64, + 177, 83, 202, 89, 60, 211, 160, 223, 141, 16, 181, 88, 96, 224, 150, 176, 235, 203, 99, 81, 3, 137, 91, + 47, 125, 183, 224, 114, 254, 70, 10, 95, 110, 83, 234, 248, 251, 227, 193, 138, 4, 140, 171, 76, 113, + 43, 219, 78, 140, 66, 70, 154, 101, 16, 192, 207, 71, 135, 33, 199, 87, 66, 160, 239, 193, 105, 106, + 161, 21, 72, 202, 164, 120, 216, 13, 21, 89, 99, 186, 162, 88, 156, 42, 59, 4, 59, 81, 104, 85, 212, + 170, 167, 100, 197, 84, 19, 235, 40, 169, 17, 29, 180, 179, 107, 143, 116, 41, 43, 167, 77, 237, 202, + 214, 212, 5, 242, 107, 19, 104, 87, 199, + ]) + .unwrap(), + p2p_ca_certificate: picky_asn1_der::from_bytes(&[ + 48, 130, 3, 69, 48, 130, 2, 45, 160, 3, 2, 1, 2, 2, 16, 22, 50, 104, 218, 241, 214, 154, 131, 67, 50, + 108, 181, 181, 208, 215, 142, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, + 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, + 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, + 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 48, 56, + 48, 56, 48, 48, 48, 48, 48, 48, 90, 23, 13, 50, 51, 48, 56, 48, 56, 48, 48, 48, 48, 48, 48, 90, 48, 77, + 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, + 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, + 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 130, 1, 34, 48, 13, 6, + 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 203, + 229, 194, 53, 177, 190, 106, 224, 204, 234, 120, 252, 197, 60, 153, 3, 249, 198, 72, 46, 29, 126, 165, + 180, 235, 139, 6, 210, 99, 186, 112, 60, 215, 68, 17, 84, 58, 103, 86, 129, 113, 213, 113, 97, 65, 215, + 97, 126, 222, 16, 59, 165, 192, 127, 180, 9, 3, 75, 195, 228, 71, 182, 182, 163, 32, 17, 4, 127, 121, + 245, 14, 1, 207, 158, 142, 120, 172, 22, 130, 43, 168, 198, 120, 58, 60, 73, 211, 52, 220, 30, 135, + 204, 89, 199, 217, 159, 51, 13, 182, 40, 131, 141, 163, 180, 204, 139, 176, 104, 40, 233, 225, 169, 46, + 146, 246, 144, 113, 211, 192, 249, 228, 169, 197, 74, 79, 156, 195, 161, 218, 165, 30, 238, 130, 151, + 182, 82, 96, 153, 73, 49, 93, 39, 169, 139, 8, 18, 135, 4, 137, 220, 55, 64, 28, 15, 51, 113, 27, 217, + 149, 8, 83, 230, 139, 131, 174, 6, 26, 128, 159, 161, 113, 103, 161, 122, 140, 85, 28, 166, 100, 188, + 140, 93, 150, 131, 125, 62, 9, 222, 145, 80, 151, 199, 250, 202, 235, 106, 152, 27, 186, 143, 181, 195, + 196, 128, 4, 106, 105, 12, 196, 61, 69, 90, 39, 14, 87, 3, 153, 48, 175, 65, 97, 50, 224, 105, 117, + 198, 107, 9, 113, 240, 215, 255, 255, 116, 33, 9, 160, 131, 74, 88, 150, 15, 14, 206, 120, 227, 65, + 167, 80, 104, 117, 108, 166, 169, 169, 145, 2, 3, 1, 0, 1, 163, 33, 48, 31, 48, 29, 6, 3, 85, 29, 14, + 4, 22, 4, 20, 17, 90, 232, 137, 164, 206, 188, 19, 145, 103, 141, 13, 108, 109, 74, 100, 161, 175, 68, + 37, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 88, 161, 67, 230, 91, + 182, 227, 143, 148, 61, 244, 147, 62, 149, 14, 105, 227, 243, 179, 74, 31, 184, 56, 195, 133, 140, 235, + 199, 215, 77, 62, 35, 148, 213, 35, 138, 126, 108, 13, 95, 61, 170, 129, 230, 150, 106, 8, 28, 219, + 252, 196, 134, 152, 9, 229, 46, 249, 247, 113, 193, 28, 212, 252, 45, 178, 145, 155, 9, 83, 247, 238, + 42, 59, 191, 1, 220, 155, 13, 210, 18, 179, 168, 40, 87, 87, 202, 220, 205, 46, 43, 23, 41, 102, 161, + 66, 72, 165, 83, 107, 138, 159, 130, 28, 60, 143, 225, 85, 114, 158, 41, 101, 118, 229, 88, 17, 0, 237, + 229, 185, 36, 6, 139, 208, 142, 137, 229, 88, 250, 190, 156, 204, 89, 207, 235, 239, 151, 185, 134, 9, + 38, 30, 55, 97, 97, 194, 37, 22, 59, 128, 26, 14, 253, 13, 25, 40, 209, 221, 130, 117, 154, 151, 153, + 107, 219, 141, 195, 250, 114, 175, 152, 133, 214, 13, 1, 126, 57, 148, 32, 56, 2, 6, 154, 31, 221, 145, + 8, 196, 83, 36, 204, 56, 102, 177, 194, 14, 58, 212, 209, 40, 245, 124, 31, 99, 15, 247, 78, 219, 161, + 121, 245, 160, 215, 137, 133, 190, 214, 122, 129, 26, 91, 104, 176, 98, 191, 46, 17, 231, 252, 217, + 255, 13, 20, 171, 195, 33, 89, 235, 218, 120, 92, 124, 36, 168, 163, 254, 219, 23, 104, 111, 44, 69, + 240, 227, 125, 168, 185, + ]) + .unwrap(), + } } } @@ -21,8 +145,60 @@ impl Default for Pku2uConfig { impl Default for Pku2uConfig { fn default() -> Self { Self { + device_certificate: todo!(), p2p_certificate: todo!(), p2p_ca_certificate: todo!(), } } } + +#[cfg(test)] +mod tests { + use picky_asn1_x509::Certificate; + + #[test] + fn p2p_c() { + let cert: Certificate = picky_asn1_der::from_bytes(&[ + 48, 130, 3, 128, 48, 130, 2, 104, 160, 3, 2, 1, 2, 2, 16, 116, 116, 177, 8, 107, 122, 107, 128, 130, 210, + 18, 39, 217, 141, 219, 189, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, + 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, + 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, + 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 48, 57, 50, 52, 50, 48, + 50, 49, 49, 57, 90, 23, 13, 50, 50, 48, 57, 50, 53, 50, 48, 50, 54, 49, 57, 90, 48, 101, 49, 52, 48, 50, 6, + 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, + 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 45, 48, + 43, 6, 3, 85, 4, 3, 12, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, 48, 45, 52, 97, 99, 51, 45, + 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, 130, 1, 34, 48, 13, 6, 9, 42, + 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, + 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, + 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, + 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, + 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, + 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, + 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, + 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, + 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, + 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, + 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, + 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, + 1, 163, 68, 48, 66, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 19, 6, 3, 85, 29, 37, 4, + 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, + 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, + 1, 0, 2, 134, 185, 116, 6, 179, 66, 45, 132, 44, 219, 120, 122, 184, 124, 87, 219, 133, 97, 236, 71, 221, + 1, 224, 67, 10, 56, 17, 48, 48, 105, 39, 11, 252, 0, 166, 29, 141, 65, 45, 77, 244, 129, 209, 209, 31, 63, + 109, 55, 177, 252, 218, 204, 56, 85, 211, 18, 5, 54, 40, 143, 168, 187, 122, 234, 216, 118, 232, 77, 59, + 40, 224, 11, 235, 220, 97, 15, 137, 217, 114, 1, 5, 153, 167, 165, 206, 7, 163, 113, 4, 230, 184, 221, 197, + 255, 165, 53, 12, 227, 235, 177, 69, 98, 124, 55, 161, 253, 21, 6, 223, 3, 1, 72, 206, 44, 52, 70, 174, + 109, 239, 167, 71, 58, 214, 127, 181, 179, 37, 244, 15, 122, 181, 62, 49, 64, 177, 83, 202, 89, 60, 211, + 160, 223, 141, 16, 181, 88, 96, 224, 150, 176, 235, 203, 99, 81, 3, 137, 91, 47, 125, 183, 224, 114, 254, + 70, 10, 95, 110, 83, 234, 248, 251, 227, 193, 138, 4, 140, 171, 76, 113, 43, 219, 78, 140, 66, 70, 154, + 101, 16, 192, 207, 71, 135, 33, 199, 87, 66, 160, 239, 193, 105, 106, 161, 21, 72, 202, 164, 120, 216, 13, + 21, 89, 99, 186, 162, 88, 156, 42, 59, 4, 59, 81, 104, 85, 212, 170, 167, 100, 197, 84, 19, 235, 40, 169, + 17, 29, 180, 179, 107, 143, 116, 41, 43, 167, 77, 237, 202, 214, 212, 5, 242, 107, 19, 104, 87, 199, + ]) + .unwrap(); + + println!("{:?}", cert); + println!("{:?}", picky_asn1_der::to_vec(&cert.tbs_certificate.issuer).unwrap()); + } +} diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index c428e09b..90793c93 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -25,6 +25,7 @@ use picky_asn1_x509::signer_info::{ use picky_asn1_x509::{AlgorithmIdentifier, Certificate, SubjectKeyIdentifier, Version}; use picky_krb::constants::gss_api::ACCEPT_INCOMPLETE; use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REQ}; +use picky_krb::crypto::diffie_hellman::{generate_private_key, get_default_parameters}; use picky_krb::data_types::{KerberosStringAsn1, KerberosTime, PaData, PrincipalName, Realm}; use picky_krb::gss_api::{ ApplicationTag0, GssApiNegInit, KrbMessage, MechType, MechTypeList, NegTokenInit, NegTokenTarg, @@ -34,9 +35,11 @@ use picky_krb::pkinit::{ AuthPack, DhDomainParameters, DhReqInfo, DhReqKeyInfo, PaPkAsReq, PkAuthenticator, Pku2uNegoBody, Pku2uNegoReq, Pku2uNegoReqMetadata, Pku2uValue, Pku2uValueInner, }; +use rand::rngs::OsRng; +use rand::Rng; use sha1::{Digest, Sha1}; -use super::DhParameters; +use super::{DhParameters, Pku2uConfig}; use crate::kerberos::client::generators::MAX_MICROSECONDS_IN_SECOND; use crate::kerberos::SERVICE_NAME; use crate::Result; @@ -45,10 +48,6 @@ use crate::Result; /// The PKU2U realm name is defined as a reserved Kerberos realm name, and it has the value of "WELLKNOWN:PKU2U". pub const WELLKNOWN_REALM: &str = "WELLKNOWN:PKU2U"; -/// "MS-Organization-P2P-Access [2021]" in UTF-16 -pub const MS_ORGANIZATION_P2P_ACCESS: &str = - "\0M\0S\0-\0O\0r\0g\0a\0n\0i\0z\0a\0t\0i\0o\0n\0-\0P\02\0P\0-\0A\0c\0c\0e\0s\0s\0 \0[\02\00\02\01\0]"; - /// [Generation of Client Request](https://www.rfc-editor.org/rfc/rfc4556.html#section-3.2.1) /// 9. This nonce string MUST be as long as the longest key length of the symmetric key types that the client supports. /// Key length of Aes256 is equal to 32 @@ -62,25 +61,22 @@ pub fn get_mech_list() -> MechTypeList { ]) } -pub fn generate_pku2u_nego_req(username: &str) -> Result { - let inner = Pku2uValue { - inner: Asn1SetOf::from(vec![Pku2uValueInner { - identifier: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(AT_COMMON_NAME).unwrap()), - value: BMPStringAsn1::from(BMPString::from_str(MS_ORGANIZATION_P2P_ACCESS).unwrap()), - }]), - }; - +pub fn generate_pku2u_nego_req(_username: &str, config: &Pku2uConfig) -> Result { Ok(Pku2uNegoReq { metadata: ExplicitContextTag0::from(Asn1SequenceOf::from(vec![Pku2uNegoReqMetadata { - inner: ImplicitContextTag0::from(OctetStringAsn1::from(picky_asn1_der::to_vec(&inner)?)), + inner: ImplicitContextTag0::from(OctetStringAsn1::from(picky_asn1_der::to_vec( + &config.p2p_certificate.tbs_certificate.issuer, + )?)), }])), body: ExplicitContextTag1::from(Pku2uNegoBody { - realm: ExplicitContextTag0::from(Realm::from(IA5String::from_str(WELLKNOWN_REALM).unwrap())), + realm: ExplicitContextTag0::from(Realm::from(IA5String::from_str(WELLKNOWN_REALM)?)), sname: ExplicitContextTag1::from(PrincipalName { name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![NT_SRV_INST])), name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![ - KerberosStringAsn1::from(IA5String::from_str(SERVICE_NAME).unwrap()), - KerberosStringAsn1::from(IA5String::from_str(username).unwrap()), + KerberosStringAsn1::from(IA5String::from_str(SERVICE_NAME)?), + // KerberosStringAsn1::from(IA5String::from_str(username).unwrap()), + // for the debugging + KerberosStringAsn1::from(IA5String::from_str("192.168.0.105")?), ])), }), }), @@ -132,36 +128,22 @@ pub fn generate_signer_info(p2p_ca_cert: &Certificate) -> SignerInfo { } } -pub fn generate_client_dh_parameters() -> DhParameters { - let modulus = vec![ - 0, 255, 255, 255, 255, 255, 255, 255, 255, 201, 15, 218, 162, 33, 104, 194, 52, 196, 198, 98, 139, 128, 220, - 28, 209, 41, 2, 78, 8, 138, 103, 204, 116, 2, 11, 190, 166, 59, 19, 155, 34, 81, 74, 8, 121, 142, 52, 4, 221, - 239, 149, 25, 179, 205, 58, 67, 27, 48, 43, 10, 109, 242, 95, 20, 55, 79, 225, 53, 109, 109, 81, 194, 69, 228, - 133, 181, 118, 98, 94, 126, 198, 244, 76, 66, 233, 166, 55, 237, 107, 11, 255, 92, 182, 244, 6, 183, 237, 238, - 56, 107, 251, 90, 137, 159, 165, 174, 159, 36, 17, 124, 75, 31, 230, 73, 40, 102, 81, 236, 230, 83, 129, 255, - 255, 255, 255, 255, 255, 255, 255, - ]; - let q = vec![ - 127, 255, 255, 255, 255, 255, 255, 255, 228, 135, 237, 81, 16, 180, 97, 26, 98, 99, 49, 69, 192, 110, 14, 104, - 148, 129, 39, 4, 69, 51, 230, 58, 1, 5, 223, 83, 29, 137, 205, 145, 40, 165, 4, 60, 199, 26, 2, 110, 247, 202, - 140, 217, 230, 157, 33, 141, 152, 21, 133, 54, 249, 47, 138, 27, 167, 240, 154, 182, 182, 168, 225, 34, 242, - 66, 218, 187, 49, 47, 63, 99, 122, 38, 33, 116, 211, 27, 246, 181, 133, 255, 174, 91, 122, 3, 91, 246, 247, 28, - 53, 253, 173, 68, 207, 210, 215, 79, 146, 8, 190, 37, 143, 243, 36, 148, 51, 40, 246, 115, 41, 192, 255, 255, - 255, 255, 255, 255, 255, 255, - ]; +pub fn generate_client_dh_parameters() -> Result { + let (p, g, q) = get_default_parameters(); + + let mut rng = OsRng::default(); + + let private_key = generate_private_key(&q, &mut rng); - DhParameters { - base: 2, - modulus, + Ok(DhParameters { + base: g, + modulus: p, q, - private_key: todo!(), + private_key, other_public_key: None, - client_nonce: Some([ - 72, 91, 60, 222, 24, 28, 4, 155, 141, 138, 44, 10, 136, 54, 202, 60, 146, 234, 183, 130, 109, 34, 94, 10, - 87, 237, 162, 55, 173, 100, 115, 43, - ]), + client_nonce: Some(rng.gen()), server_nonce: None, - } + }) } pub fn generate_pa_datas_for_as_req( @@ -198,7 +180,7 @@ pub fn generate_pa_datas_for_as_req( identifier: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(DIFFIE_HELLMAN).unwrap()), key_info: DhDomainParameters { p: IntegerAsn1::from(dh_parameters.modulus.clone()), - g: IntegerAsn1::from(dh_parameters.base.to_be_bytes().to_vec()), + g: IntegerAsn1::from(dh_parameters.base.clone()), q: IntegerAsn1::from(dh_parameters.q.clone()), j: Optional::from(None), validation_params: Optional::from(None), @@ -260,8 +242,13 @@ pub fn generate_neg(krb_msg: T, krb5_token_id: [u8; 2]) -> Application #[cfg(test)] mod tests { + use super::generate_pku2u_nego_req; + use crate::sspi::pku2u::Pku2uConfig; + #[test] fn neg_token_init_generation() { - // + let token = generate_pku2u_nego_req("", &Pku2uConfig::default()).unwrap(); + + println!("{:?}", picky_asn1_der::to_vec(&token).unwrap()); } } From 912966d78228ba50df060f2bd44b0d416de96ded Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Sun, 2 Oct 2022 18:07:48 +0300 Subject: [PATCH 08/36] sspi: pku2u: improve errors handling; refactoring --- Cargo.toml | 1 + src/sspi/kerberos.rs | 1 + src/sspi/kerberos/client/generators.rs | 10 +- src/sspi/kerberos/server/extractors.rs | 9 +- src/sspi/pku2u.rs | 71 +++++-- src/sspi/pku2u/config.rs | 112 ++++------- src/sspi/pku2u/generators.rs | 245 ++++++++++++++++++++----- src/sspi/pku2u/macros.rs | 14 ++ 8 files changed, 311 insertions(+), 152 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3f681f42..460248ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,3 +48,4 @@ uuid = "1.1" whoami = "0.5" trust-dns-resolver = { version = "0.21.2", optional = true } portpicker = { version = "0.1.1", optional = true } +rsa = "0.6.1" \ No newline at end of file diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 853c6eda..76dcfeba 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -488,6 +488,7 @@ impl SspiImpl for Kerberos { let input = builder.input.as_ref().ok_or_else(|| { sspi::Error::new(ErrorKind::InvalidToken, "Input buffers must be specified".into()) })?; + if let Ok(sec_buffer) = SecurityBuffer::find_buffer(builder.input.as_ref().unwrap(), SecurityBufferType::ChannelBindings) { diff --git a/src/sspi/kerberos/client/generators.rs b/src/sspi/kerberos/client/generators.rs index eaa4b55a..10a1ce00 100644 --- a/src/sspi/kerberos/client/generators.rs +++ b/src/sspi/kerberos/client/generators.rs @@ -167,7 +167,8 @@ pub fn generate_as_req_kdc_body(options: &GenerateAsReqOptions) -> Result Result().to_vec())), + // nonce: ExplicitContextTag7::from(IntegerAsn1::from(OsRng::default().gen::<[u8; NONCE_LEN]>().to_vec())), + // we don't need a nonce in pku2u + nonce: ExplicitContextTag7::from(IntegerAsn1::from(vec![0])), etype: ExplicitContextTag8::from(Asn1SequenceOf::from(vec![ IntegerAsn1::from(vec![CipherSuite::Aes256CtsHmacSha196.into()]), IntegerAsn1::from(vec![CipherSuite::Aes128CtsHmacSha196.into()]), + IntegerAsn1::from(vec![0x17]), + IntegerAsn1::from(vec![0x18]), + IntegerAsn1::from(vec![0xff, 0x79]), ])), addresses: Optional::from(address), enc_authorization_data: Optional::from(None), diff --git a/src/sspi/kerberos/server/extractors.rs b/src/sspi/kerberos/server/extractors.rs index 18e87066..f7336b2d 100644 --- a/src/sspi/kerberos/server/extractors.rs +++ b/src/sspi/kerberos/server/extractors.rs @@ -67,21 +67,18 @@ pub fn extract_sub_session_key_from_ap_rep( } pub fn extract_tgt_ticket(data: &[u8]) -> Result> { - let neg_token_targ: NegTokenTarg1 = - picky_asn1_der::from_bytes(data).map_err(|e| Error::new(ErrorKind::InvalidToken, format!("{:?}", e)))?; + let neg_token_targ: NegTokenTarg1 = picky_asn1_der::from_bytes(data)?; if let Some(resp_token) = neg_token_targ.0.response_token.0.as_ref().map(|ticket| &ticket.0 .0) { let mut c = resp_token.as_slice(); - let _oid: ApplicationTag = - picky_asn1_der::from_reader(&mut c).map_err(|e| Error::new(ErrorKind::InvalidToken, format!("{:?}", e)))?; + let _oid: ApplicationTag = picky_asn1_der::from_reader(&mut c)?; let mut t = [0, 0]; c.read_exact(&mut t)?; - let tgt_rep: TgtRep = - picky_asn1_der::from_reader(&mut c).map_err(|e| Error::new(ErrorKind::InvalidToken, format!("{:?}", e)))?; + let tgt_rep: TgtRep = picky_asn1_der::from_reader(&mut c)?; Ok(Some(tgt_rep.ticket.0)) } else { diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index ea497350..0983ab60 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -14,7 +14,7 @@ use picky_krb::constants::gss_api::{AP_REQ_TOKEN_ID, AS_REQ_TOKEN_ID, AUTHENTICA use picky_krb::constants::key_usages::{ACCEPTOR_SIGN, INITIATOR_SIGN}; use picky_krb::crypto::diffie_hellman::{generate_key, DhNonce}; use picky_krb::crypto::{ChecksumSuite, CipherSuite}; -use picky_krb::gss_api::WrapToken; +use picky_krb::gss_api::{NegTokenTarg1, WrapToken}; use picky_krb::messages::{ApRep, AsRep}; use picky_krb::negoex::data_types::MessageType; use picky_krb::negoex::messages::{Exchange, Nego, Verify}; @@ -398,15 +398,29 @@ impl SspiImpl for Pku2u { .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "Input buffers must be specified".into()))?; let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; - let buffer = input_token.buffer.as_slice(); + let neg_token_targ: NegTokenTarg1 = picky_asn1_der::from_bytes(&input_token.buffer)?; + let buffer = neg_token_targ + .0 + .response_token + .0 + .ok_or_else(|| { + Error::new(ErrorKind::InvalidToken, "Missing response_token in NegTokenTarg".into()) + })? + .0 + .0; + println!("buffer: {:?}", buffer); - self.negoex_messages.extend_from_slice(buffer); - let mut reader: Box = Box::new(buffer); + self.negoex_messages.extend_from_slice(&buffer); + + let mut reader: Box = Box::new(buffer.as_slice()); - let acceptor_nego = Nego::decode(&mut reader, &input_token.buffer)?; + let acceptor_nego = Nego::decode(&mut reader, &buffer)?; + + println!("acceptor_nego: {:?}", acceptor_nego); check_conversation_id!(acceptor_nego.header.conversation_id.0, self.conversation_id); + check_sequence_number!(acceptor_nego.header.sequence_num, self.next_seq_number()); // We support only one auth scheme. So the server must choose it otherwise it's an invalid behaviour if let Some(auth_scheme) = acceptor_nego.auth_schemes.get(0) { @@ -428,14 +442,20 @@ impl SspiImpl for Pku2u { )); } - let acceptor_exchange = Exchange::decode( - &mut reader, - &input_token.buffer[(acceptor_nego.header.message_len as usize)..], - )?; + let acceptor_exchange_data = &buffer[(acceptor_nego.header.message_len as usize)..]; + println!("acceptor_exchage data: {:?}", acceptor_exchange_data); + let mut reader: Box = Box::new(acceptor_exchange_data); + + let acceptor_exchange = Exchange::decode(&mut reader, acceptor_exchange_data)?; + + println!("acceptor_exchange: {:?}", acceptor_exchange); check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); + check_sequence_number!(acceptor_exchange.header.sequence_num, self.next_seq_number()); check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); + println!("all parsed and verified"); + let credentials = builder .credentials_handle .as_ref() @@ -446,16 +466,19 @@ impl SspiImpl for Pku2u { description: "No credentials provided".to_owned(), })?; - let username = utf16_bytes_to_utf8_string(&credentials.user); - // todo: parse response. do not extract any data. just parse and make sure it valid + let _username = utf16_bytes_to_utf8_string(&credentials.user); let mut mech_token = Vec::new(); let kdc_req_body = generate_as_req_kdc_body(&GenerateAsReqOptions { realm: WELLKNOWN_REALM, - username: &username, + username: "AzureAD\\MS-Organization-P2P-Access [2022]\\S-1-12-1-3653211022-1339006422-2627573900-1560734919", cname_type: 0x80, - snames: &[SERVICE_NAME, &username], + snames: &[ + SERVICE_NAME, + // &username, + "192.168.0.117", + ], })?; let pa_datas = generate_pa_datas_for_as_req( &self.config.p2p_certificate, @@ -463,23 +486,29 @@ impl SspiImpl for Pku2u { &kdc_req_body, self.auth_nonce, &self.dh_parameters, + &self.config.device_private_key, )?; + let exchange_data = + picky_asn1_der::to_vec(&generate_neg(generate_as_req(&pa_datas, kdc_req_body), AS_REQ_TOKEN_ID))?; + println!("exchange_data: {:?}", exchange_data); + let exchange = Exchange::new( - MessageType::InitiatorMetaData, + MessageType::ApRequest, self.conversation_id, self.next_seq_number(), self.auth_scheme.unwrap(), - picky_asn1_der::to_vec(&generate_neg(generate_as_req(&pa_datas, kdc_req_body), AS_REQ_TOKEN_ID))?, + exchange_data, ); exchange.encode(&mut mech_token)?; self.negoex_messages.extend_from_slice(&mech_token); + let response_token = picky_asn1_der::to_vec(&generate_neg_token_targ(mech_token)?)?; + // println!("response_token: {:?}", response_token); + let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; - output_token - .buffer - .write_all(&picky_asn1_der::to_vec(&generate_neg_token_targ(mech_token)?)?)?; + output_token.buffer.write_all(&response_token)?; self.state = Pku2uState::AsExchange; @@ -494,11 +523,14 @@ impl SspiImpl for Pku2u { let buffer = input_token.buffer.as_slice(); + println!("AsExchange buffer: {:?}", buffer); + self.negoex_messages.extend_from_slice(buffer); let acceptor_exchange = Exchange::decode(buffer, &input_token.buffer)?; check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); + check_sequence_number!(acceptor_exchange.header.sequence_num, self.next_seq_number()); check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); let (as_rep, _): (AsRep, _) = extract_krb_rep(&acceptor_exchange.exchange)?; @@ -605,6 +637,7 @@ impl SspiImpl for Pku2u { let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; let buffer = input_token.buffer.as_slice(); + println!("ap_exchange buffer: {:?}", buffer); self.negoex_messages.extend_from_slice(buffer); let mut reader: Box = Box::new(buffer); @@ -612,12 +645,14 @@ impl SspiImpl for Pku2u { let acceptor_exchange = Exchange::decode(&mut reader, &buffer)?; check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); + check_sequence_number!(acceptor_exchange.header.sequence_num, self.next_seq_number()); check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); let acceptor_verify = Verify::decode(&mut reader, &buffer[(acceptor_exchange.header.message_len as usize)..])?; check_conversation_id!(acceptor_verify.header.conversation_id.0, self.conversation_id); + check_sequence_number!(acceptor_verify.header.sequence_num, self.next_seq_number()); check_auth_scheme!(acceptor_verify.auth_scheme.0, self.auth_scheme); let (ap_rep, _): (ApRep, _) = extract_krb_rep(&acceptor_exchange.exchange)?; diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index 9134faf4..4152a9c2 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -1,16 +1,22 @@ use picky_asn1_x509::Certificate; +use rsa::{RsaPrivateKey, pkcs8::DecodePrivateKey, pkcs1::DecodeRsaPrivateKey}; #[derive(Debug, Clone)] pub struct Pku2uConfig { pub device_certificate: Certificate, pub p2p_certificate: Certificate, pub p2p_ca_certificate: Certificate, + pub device_private_key: RsaPrivateKey, } #[cfg(windows)] impl Default for Pku2uConfig { fn default() -> Self { Self { + device_private_key: RsaPrivateKey::from_pkcs1_der(&[ + 48, 130, 4, 165, 2, 1, 0, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 2, 130, 1, 1, 0, 178, 100, 113, 112, 83, 117, 20, 63, 122, 193, 220, 139, 33, 125, 192, 43, 177, 21, 73, 211, 19, 185, 156, 118, 207, 73, 129, 192, 247, 51, 158, 195, 136, 5, 172, 74, 184, 177, 186, 122, 237, 139, 78, 252, 182, 87, 192, 192, 77, 118, 229, 137, 49, 38, 209, 247, 17, 157, 81, 12, 230, 106, 251, 51, 249, 143, 104, 96, 46, 172, 243, 245, 1, 50, 76, 45, 78, 7, 124, 39, 154, 210, 203, 152, 22, 233, 32, 40, 58, 181, 148, 56, 109, 47, 82, 91, 87, 29, 152, 222, 103, 131, 74, 240, 136, 153, 216, 37, 69, 139, 116, 176, 2, 68, 83, 195, 189, 56, 108, 213, 40, 14, 135, 90, 152, 90, 78, 38, 229, 107, 54, 252, 110, 117, 3, 112, 160, 108, 229, 3, 134, 204, 214, 191, 152, 126, 249, 36, 155, 78, 97, 103, 237, 230, 138, 248, 84, 3, 34, 49, 203, 13, 164, 86, 10, 202, 94, 130, 87, 200, 189, 49, 172, 188, 188, 47, 235, 200, 96, 125, 17, 109, 170, 32, 215, 71, 8, 96, 245, 83, 239, 39, 109, 70, 187, 58, 121, 243, 179, 33, 46, 74, 48, 152, 249, 31, 211, 187, 234, 68, 22, 229, 223, 192, 70, 160, 33, 51, 33, 141, 231, 191, 193, 245, 182, 154, 93, 29, 179, 172, 169, 96, 159, 37, 159, 38, 140, 138, 152, 58, 186, 185, 25, 167, 44, 165, 186, 154, 216, 239, 40, 255, 73, 166, 213, 161, 2, 129, 129, 0, 206, 19, 212, 71, 145, 69, 123, 105, 175, 72, 169, 243, 189, 229, 3, 31, 87, 12, 12, 36, 187, 203, 30, 253, 241, 36, 63, 106, 76, 219, 159, 75, 119, 134, 97, 40, 29, 131, 21, 132, 122, 5, 167, 85, 135, 221, 116, 118, 27, 210, 167, 98, 157, 232, 42, 248, 159, 82, 155, 166, 95, 216, 236, 85, 231, 201, 90, 175, 220, 38, 197, 150, 54, 139, 123, 200, 81, 29, 190, 118, 179, 194, 54, 100, 207, 117, 10, 10, 195, 68, 131, 61, 163, 27, 187, 12, 249, 219, 101, 130, 228, 95, 247, 106, 1, 175, 141, 203, 28, 139, 41, 166, 91, 128, 158, 134, 108, 11, 136, 45, 6, 171, 236, 237, 15, 150, 117, 95, 2, 129, 129, 0, 247, 129, 4, 52, 135, 135, 143, 100, 220, 70, 79, 249, 17, 41, 57, 48, 74, 214, 52, 154, 34, 108, 20, 220, 90, 193, 210, 111, 79, 27, 35, 148, 111, 200, 241, 155, 141, 14, 175, 35, 56, 216, 209, 3, 218, 231, 171, 210, 186, 196, 183, 67, 83, 186, 32, 149, 178, 235, 111, 76, 134, 61, 39, 80, 49, 105, 3, 109, 229, 69, 156, 191, 182, 230, 148, 62, 232, 99, 101, 95, 234, 211, 145, 211, 147, 234, 12, 242, 237, 87, 99, 85, 164, 109, 78, 31, 99, 144, 116, 97, 55, 103, 77, 29, 249, 69, 69, 134, 88, 189, 232, 240, 150, 61, 212, 193, 250, 40, 135, 9, 234, 22, 119, 138, 223, 174, 157, 203, 2, 129, 128, 124, 53, 109, 116, 121, 118, 4, 173, 173, 141, 193, 137, 253, 1, 228, 192, 230, 9, 135, 228, 56, 32, 116, 156, 160, 212, 181, 56, 79, 252, 235, 229, 99, 180, 102, 40, 244, 168, 198, 182, 99, 137, 182, 211, 17, 162, 4, 9, 16, 58, 6, 211, 164, 211, 131, 218, 248, 196, 164, 182, 65, 253, 16, 109, 178, 216, 37, 69, 236, 14, 158, 119, 44, 135, 35, 227, 152, 40, 178, 92, 255, 121, 230, 169, 26, 117, 179, 200, 202, 235, 39, 163, 102, 5, 87, 215, 185, 93, 104, 176, 221, 15, 142, 163, 161, 66, 123, 215, 89, 107, 243, 125, 166, 151, 62, 117, 76, 248, 34, 106, 233, 35, 133, 25, 89, 148, 217, 71, 2, 129, 129, 0, 136, 161, 197, 131, 134, 42, 20, 195, 246, 66, 46, 149, 237, 158, 87, 62, 204, 161, 113, 202, 129, 36, 47, 99, 242, 10, 59, 180, 76, 244, 75, 112, 255, 64, 235, 248, 22, 39, 188, 17, 114, 169, 102, 193, 125, 16, 21, 175, 176, 129, 54, 54, 73, 187, 95, 143, 164, 133, 10, 29, 49, 162, 2, 216, 231, 93, 244, 145, 175, 86, 253, 144, 108, 84, 224, 19, 214, 80, 64, 191, 113, 176, 56, 57, 151, 215, 70, 44, 185, 79, 91, 188, 4, 152, 126, 223, 31, 36, 184, 202, 142, 62, 77, 185, 53, 73, 195, 118, 197, 248, 152, 230, 111, 218, 84, 96, 125, 75, 240, 56, 77, 236, 247, 51, 72, 6, 106, 127, 2, 129, 129, 0, 149, 64, 160, 185, 80, 7, 183, 188, 145, 39, 11, 48, 140, 239, 229, 100, 176, 249, 209, 241, 141, 224, 143, 180, 104, 197, 208, 174, 104, 121, 96, 243, 82, 121, 68, 94, 71, 78, 232, 206, 19, 70, 69, 110, 43, 66, 13, 16, 132, 63, 6, 115, 26, 56, 165, 174, 101, 190, 241, 247, 21, 150, 21, 96, 129, 114, 137, 162, 153, 128, 80, 140, 190, 170, 49, 14, 215, 134, 38, 81, 184, 113, 249, 230, 67, 239, 18, 68, 120, 202, 123, 6, 105, 202, 250, 129, 65, 217, 155, 156, 82, 210, 157, 130, 233, 38, 238, 208, 32, 242, 29, 27, 254, 49, 143, 91, 50, 163, 81, 16, 2, 227, 182, 144, 234, 118, 212, 40 + ]) + .unwrap(), device_certificate: picky_asn1_der::from_bytes(&[ 48, 130, 3, 242, 48, 130, 2, 218, 160, 3, 2, 1, 2, 2, 16, 151, 57, 89, 108, 207, 42, 14, 171, 65, 62, 108, 81, 115, 209, 185, 213, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 120, 49, 118, @@ -58,44 +64,7 @@ impl Default for Pku2uConfig { ]) .unwrap(), p2p_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 128, 48, 130, 2, 104, 160, 3, 2, 1, 2, 2, 16, 116, 116, 177, 8, 107, 122, 107, 128, 130, - 210, 18, 39, 217, 141, 219, 189, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, - 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, - 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, - 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 48, - 57, 50, 52, 50, 48, 50, 49, 49, 57, 90, 23, 13, 50, 50, 48, 57, 50, 53, 50, 48, 50, 54, 49, 57, 90, 48, - 101, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, - 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, - 56, 52, 54, 55, 50, 49, 45, 48, 43, 6, 3, 85, 4, 3, 12, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, - 51, 102, 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, - 52, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, - 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, - 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, - 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, - 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, - 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, - 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, - 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, - 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, - 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, - 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, - 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, - 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 68, - 48, 66, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, - 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, - 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, - 1, 0, 2, 134, 185, 116, 6, 179, 66, 45, 132, 44, 219, 120, 122, 184, 124, 87, 219, 133, 97, 236, 71, - 221, 1, 224, 67, 10, 56, 17, 48, 48, 105, 39, 11, 252, 0, 166, 29, 141, 65, 45, 77, 244, 129, 209, 209, - 31, 63, 109, 55, 177, 252, 218, 204, 56, 85, 211, 18, 5, 54, 40, 143, 168, 187, 122, 234, 216, 118, - 232, 77, 59, 40, 224, 11, 235, 220, 97, 15, 137, 217, 114, 1, 5, 153, 167, 165, 206, 7, 163, 113, 4, - 230, 184, 221, 197, 255, 165, 53, 12, 227, 235, 177, 69, 98, 124, 55, 161, 253, 21, 6, 223, 3, 1, 72, - 206, 44, 52, 70, 174, 109, 239, 167, 71, 58, 214, 127, 181, 179, 37, 244, 15, 122, 181, 62, 49, 64, - 177, 83, 202, 89, 60, 211, 160, 223, 141, 16, 181, 88, 96, 224, 150, 176, 235, 203, 99, 81, 3, 137, 91, - 47, 125, 183, 224, 114, 254, 70, 10, 95, 110, 83, 234, 248, 251, 227, 193, 138, 4, 140, 171, 76, 113, - 43, 219, 78, 140, 66, 70, 154, 101, 16, 192, 207, 71, 135, 33, 199, 87, 66, 160, 239, 193, 105, 106, - 161, 21, 72, 202, 164, 120, 216, 13, 21, 89, 99, 186, 162, 88, 156, 42, 59, 4, 59, 81, 104, 85, 212, - 170, 167, 100, 197, 84, 19, 235, 40, 169, 17, 29, 180, 179, 107, 143, 116, 41, 43, 167, 77, 237, 202, - 214, 212, 5, 242, 107, 19, 104, 87, 199, + 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 41, 174, 13, 91, 182, 83, 154, 144, 159, 209, 107, 121, 229, 255, 133, 88, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 48, 50, 49, 50, 51, 53, 53, 56, 90, 23, 13, 50, 50, 49, 48, 48, 50, 49, 51, 52, 48, 53, 56, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 142, 165, 234, 4, 42, 30, 175, 127, 217, 93, 96, 27, 30, 8, 42, 85, 134, 117, 240, 214, 211, 39, 117, 8, 125, 60, 202, 146, 212, 156, 177, 221, 241, 36, 93, 134, 230, 19, 250, 92, 233, 135, 245, 57, 15, 179, 212, 44, 200, 217, 103, 99, 145, 232, 110, 52, 57, 145, 207, 191, 68, 142, 175, 189, 141, 93, 25, 153, 52, 3, 197, 144, 68, 237, 42, 26, 15, 4, 254, 130, 247, 193, 26, 100, 152, 4, 248, 155, 56, 207, 92, 50, 89, 222, 224, 170, 25, 45, 174, 106, 142, 238, 114, 219, 184, 172, 116, 221, 135, 71, 55, 76, 160, 102, 155, 197, 195, 185, 214, 177, 164, 238, 188, 13, 126, 84, 198, 50, 37, 164, 198, 158, 102, 100, 47, 227, 132, 192, 201, 148, 30, 174, 68, 13, 207, 59, 90, 27, 222, 108, 144, 125, 162, 121, 80, 100, 151, 220, 196, 45, 121, 153, 156, 180, 19, 43, 143, 213, 184, 48, 164, 69, 178, 195, 199, 126, 139, 22, 108, 0, 25, 104, 69, 190, 239, 12, 15, 252, 198, 98, 87, 0, 208, 249, 101, 48, 112, 192, 239, 101, 144, 45, 159, 43, 191, 63, 179, 32, 254, 184, 191, 119, 103, 19, 73, 221, 205, 102, 0, 230, 98, 205, 23, 40, 35, 208, 232, 198, 210, 231, 108, 103, 81, 27, 181, 90, 226, 47, 84, 157, 125, 103, 143, 11, 64, 165, 49, 29, 40, 52, 47, 168, 179, 53, 237, 215 ]) .unwrap(), p2p_ca_certificate: picky_asn1_der::from_bytes(&[ @@ -156,49 +125,32 @@ impl Default for Pku2uConfig { mod tests { use picky_asn1_x509::Certificate; + use super::Pku2uConfig; + + use rsa::{RsaPrivateKey, RsaPublicKey, PaddingScheme, PublicKey}; + #[test] - fn p2p_c() { - let cert: Certificate = picky_asn1_der::from_bytes(&[ - 48, 130, 3, 128, 48, 130, 2, 104, 160, 3, 2, 1, 2, 2, 16, 116, 116, 177, 8, 107, 122, 107, 128, 130, 210, - 18, 39, 217, 141, 219, 189, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, - 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, - 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, - 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 48, 57, 50, 52, 50, 48, - 50, 49, 49, 57, 90, 23, 13, 50, 50, 48, 57, 50, 53, 50, 48, 50, 54, 49, 57, 90, 48, 101, 49, 52, 48, 50, 6, - 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, - 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 45, 48, - 43, 6, 3, 85, 4, 3, 12, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, 48, 45, 52, 97, 99, 51, 45, - 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, 130, 1, 34, 48, 13, 6, 9, 42, - 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, - 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, - 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, - 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, - 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, - 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, - 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, - 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, - 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, - 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, - 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, - 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, - 1, 163, 68, 48, 66, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 19, 6, 3, 85, 29, 37, 4, - 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, - 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, - 1, 0, 2, 134, 185, 116, 6, 179, 66, 45, 132, 44, 219, 120, 122, 184, 124, 87, 219, 133, 97, 236, 71, 221, - 1, 224, 67, 10, 56, 17, 48, 48, 105, 39, 11, 252, 0, 166, 29, 141, 65, 45, 77, 244, 129, 209, 209, 31, 63, - 109, 55, 177, 252, 218, 204, 56, 85, 211, 18, 5, 54, 40, 143, 168, 187, 122, 234, 216, 118, 232, 77, 59, - 40, 224, 11, 235, 220, 97, 15, 137, 217, 114, 1, 5, 153, 167, 165, 206, 7, 163, 113, 4, 230, 184, 221, 197, - 255, 165, 53, 12, 227, 235, 177, 69, 98, 124, 55, 161, 253, 21, 6, 223, 3, 1, 72, 206, 44, 52, 70, 174, - 109, 239, 167, 71, 58, 214, 127, 181, 179, 37, 244, 15, 122, 181, 62, 49, 64, 177, 83, 202, 89, 60, 211, - 160, 223, 141, 16, 181, 88, 96, 224, 150, 176, 235, 203, 99, 81, 3, 137, 91, 47, 125, 183, 224, 114, 254, - 70, 10, 95, 110, 83, 234, 248, 251, 227, 193, 138, 4, 140, 171, 76, 113, 43, 219, 78, 140, 66, 70, 154, - 101, 16, 192, 207, 71, 135, 33, 199, 87, 66, 160, 239, 193, 105, 106, 161, 21, 72, 202, 164, 120, 216, 13, - 21, 89, 99, 186, 162, 88, 156, 42, 59, 4, 59, 81, 104, 85, 212, 170, 167, 100, 197, 84, 19, 235, 40, 169, - 17, 29, 180, 179, 107, 143, 116, 41, 43, 167, 77, 237, 202, 214, 212, 5, 242, 107, 19, 104, 87, 199, - ]) - .unwrap(); + fn p2p_i() { + let config = Pku2uConfig::default(); + println!("{:x?}", config.p2p_certificate.tbs_certificate.serial_number); + println!("{:?}", picky_asn1_der::to_vec(&config.p2p_certificate.tbs_certificate.serial_number).unwrap()); + } - println!("{:?}", cert); - println!("{:?}", picky_asn1_der::to_vec(&cert.tbs_certificate.issuer).unwrap()); + #[test] + fn p2p_c() { + let config = Pku2uConfig::default(); + let mut rng = rand::thread_rng(); + // let s = config.device_private_key.to_public_key().encrypt( + // &mut rng, + // PaddingScheme::new_pkcs1v15_encrypt(), + // &[206, 152, 81, 67, 179, 29, 86, 137, 195, 0, 176, 87, 13, 194, 202, 115, 155, 82, 108, 32] + // ).unwrap(); + let s = config.device_private_key.sign( + // &mut rng, + PaddingScheme::new_pkcs1v15_sign(None), + &[206, 152, 81, 67, 179, 29, 86, 137, 195, 0, 176, 87, 13, 194, 202, 115, 155, 82, 108, 32] + ).unwrap(); + println!("{:?}", s); + println!("{}", s.len()); } } diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index 90793c93..18a5d62c 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -1,4 +1,5 @@ use std::convert::TryFrom; +use std::fmt::Debug; use std::str::FromStr; use chrono::Utc; @@ -11,21 +12,26 @@ use picky_asn1::wrapper::{ ExplicitContextTag2, ExplicitContextTag3, ImplicitContextTag0, IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, Optional, }; +use picky_asn1_der::application_tag::ApplicationTag; use picky_asn1_der::Asn1RawDer; use picky_asn1_x509::cmsversion::CmsVersion; use picky_asn1_x509::content_info::EncapsulatedContentInfo; -use picky_asn1_x509::oids::{AT_COMMON_NAME, DIFFIE_HELLMAN, GSS_PKU2U, NEGOEX, PKINIT_AUTH_DATA, SPNEGO}; +use picky_asn1_x509::oids::{AT_COMMON_NAME, DIFFIE_HELLMAN, GSS_PKU2U, NEGOEX, NTLM_SSP, PKINIT_AUTH_DATA, SPNEGO}; use picky_asn1_x509::signed_data::{ CertificateChoices, CertificateSet, DigestAlgorithmIdentifiers, SignedData, SignersInfos, }; use picky_asn1_x509::signer_info::{ - Attributes, DigestAlgorithmIdentifier, SignatureAlgorithmIdentifier, SignatureValue, SignerIdentifier, SignerInfo, - UnsignedAttributes, + Attributes, CertificateSerialNumber, DigestAlgorithmIdentifier, IssuerAndSerialNumber, + SignatureAlgorithmIdentifier, SignatureValue, SignerIdentifier, SignerInfo, UnsignedAttributes, +}; +use picky_asn1_x509::{ + AlgorithmIdentifier, Attribute, AttributeTypeAndValue, AttributeTypeAndValueParameters, AttributeValues, + Certificate, DirectoryString, Name, RdnSequence, RelativeDistinguishedName, ShaVariant, SubjectKeyIdentifier, + Version, }; -use picky_asn1_x509::{AlgorithmIdentifier, Certificate, SubjectKeyIdentifier, Version}; use picky_krb::constants::gss_api::ACCEPT_INCOMPLETE; use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REQ}; -use picky_krb::crypto::diffie_hellman::{generate_private_key, get_default_parameters}; +use picky_krb::crypto::diffie_hellman::{compute_public_key, generate_private_key, get_default_parameters}; use picky_krb::data_types::{KerberosStringAsn1, KerberosTime, PaData, PrincipalName, Realm}; use picky_krb::gss_api::{ ApplicationTag0, GssApiNegInit, KrbMessage, MechType, MechTypeList, NegTokenInit, NegTokenTarg, @@ -36,7 +42,7 @@ use picky_krb::pkinit::{ Pku2uNegoReqMetadata, Pku2uValue, Pku2uValueInner, }; use rand::rngs::OsRng; -use rand::Rng; +use rsa::{RsaPrivateKey, PaddingScheme}; use sha1::{Digest, Sha1}; use super::{DhParameters, Pku2uConfig}; @@ -57,7 +63,7 @@ pub const DH_NONCE_LEN: usize = 32; pub fn get_mech_list() -> MechTypeList { MechTypeList::from(vec![ MechType::from(ObjectIdentifier::try_from(NEGOEX).unwrap()), - // MechType::from(ObjectIdentifier::try_from(NTLM_SSP).unwrap()), + MechType::from(ObjectIdentifier::try_from(NTLM_SSP).unwrap()), ]) } @@ -76,7 +82,7 @@ pub fn generate_pku2u_nego_req(_username: &str, config: &Pku2uConfig) -> Result< KerberosStringAsn1::from(IA5String::from_str(SERVICE_NAME)?), // KerberosStringAsn1::from(IA5String::from_str(username).unwrap()), // for the debugging - KerberosStringAsn1::from(IA5String::from_str("192.168.0.105")?), + KerberosStringAsn1::from(IA5String::from_str("192.168.0.117")?), ])), }), }), @@ -104,27 +110,64 @@ pub fn generate_neg_token_targ(token: Vec) -> Result CmsVersion { - match v { - Version::V1 => CmsVersion::V1, - Version::V2 => CmsVersion::V2, - Version::V3 => CmsVersion::V3, - } -} +// pub fn version_to_cms_version(v: Version) -> CmsVersion { +// match v { +// Version::V1 => CmsVersion::V1, +// Version::V2 => CmsVersion::V2, +// Version::V3 => CmsVersion::V3, +// } +// } -pub fn generate_signer_info(p2p_ca_cert: &Certificate) -> SignerInfo { +pub fn generate_signer_info(p2p_cert: &Certificate, digest: Vec, encrypted: Vec) -> SignerInfo { + // SignerInfo { + // version: version_to_cms_version(p2p_ca_cert.tbs_certificate.version.0), + // sid: SignerIdentifier::SubjectKeyIdentifier(ImplicitContextTag0::from(SubjectKeyIdentifier::from( + // p2p_ca_cert.subject_key_identifier().unwrap().to_vec(), + // ))), + // digest_algorithm: DigestAlgorithmIdentifier( + // p2p_ca_cert.tbs_certificate.subject_public_key_info.algorithm.clone(), + // ), + // signed_attrs: Optional::from(Attributes(Asn1SequenceOf::from(vec![]))), + // signature_algorithm: SignatureAlgorithmIdentifier(p2p_ca_cert.signature_algorithm.clone()), + // signature: SignatureValue(OctetStringAsn1::from(p2p_ca_cert.signature_value.0.inner())), + // unsigned_attrs: Optional::from(UnsignedAttributes(vec![])), + // } + println!("{:x?}", p2p_cert.tbs_certificate.serial_number); + println!("{:?}", picky_asn1_der::to_vec(&p2p_cert.tbs_certificate.serial_number).unwrap()); SignerInfo { - version: version_to_cms_version(p2p_ca_cert.tbs_certificate.version.0), - sid: SignerIdentifier::SubjectKeyIdentifier(ImplicitContextTag0::from(SubjectKeyIdentifier::from( - p2p_ca_cert.subject_key_identifier().unwrap().to_vec(), - ))), + version: CmsVersion::V1, + sid: SignerIdentifier::IssuerAndSerialNumber(IssuerAndSerialNumber { + // issuer: Name(RdnSequence::from(vec![ + // RelativeDistinguishedName::from(vec![ + // AttributeTypeAndValue { + // ty: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("2.5.4.3").unwrap()), + // value: AttributeTypeAndValueParameters::CommonName(DirectoryString::BmpString(BMPStringAsn1(BMPString::from_str("\0M\0S\0-\0O\0r\0g\0a\0n\0i\0z\0a\0t\0i\0o\0n\0-\0P\02\0P\0-\0A\0c\0c\0e\0s\0s\0 \0[\02\00\02\02\0]").unwrap()))), + // }, + // ]), + // ])), + issuer: p2p_cert.tbs_certificate.issuer.clone(), + serial_number: CertificateSerialNumber(p2p_cert.tbs_certificate.serial_number.clone()), + }), digest_algorithm: DigestAlgorithmIdentifier( - p2p_ca_cert.tbs_certificate.subject_public_key_info.algorithm.clone(), + AlgorithmIdentifier::new_sha(ShaVariant::SHA1) ), - signed_attrs: Optional::from(Attributes(Asn1SequenceOf::from(vec![]))), - signature_algorithm: SignatureAlgorithmIdentifier(p2p_ca_cert.signature_algorithm.clone()), - signature: SignatureValue(OctetStringAsn1::from(p2p_ca_cert.signature_value.0.inner())), - unsigned_attrs: Optional::from(UnsignedAttributes(vec![])), + signed_attrs: Optional::from(Attributes(Asn1SequenceOf::from(vec![ + Attribute { + ty: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("1.2.840.113549.1.9.3").unwrap()), + value: AttributeValues::ContentType(Asn1SetOf::from(vec![ + ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("1.3.6.1.5.2.3.1").unwrap()), + ])), + }, + Attribute { + ty: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("1.2.840.113549.1.9.4").unwrap()), + value: AttributeValues::MessageDigest(Asn1SetOf::from(vec![ + OctetStringAsn1::from(digest), + ])), + }, + ]))), + signature_algorithm: SignatureAlgorithmIdentifier(AlgorithmIdentifier::new_rsa_encryption()), + signature: SignatureValue(OctetStringAsn1::from(encrypted)), + unsigned_attrs: Optional::from(UnsignedAttributes(Vec::new())), } } @@ -141,7 +184,10 @@ pub fn generate_client_dh_parameters() -> Result { q, private_key, other_public_key: None, - client_nonce: Some(rng.gen()), + client_nonce: Some([ + 142, 91, 149, 4, 44, 55, 103, 6, 75, 168, 207, 165, 162, 197, 172, 27, 2, 108, 166, 10, 240, 52, 179, 24, + 56, 73, 137, 103, 160, 81, 236, 230, + ]), server_nonce: None, }) } @@ -152,6 +198,7 @@ pub fn generate_pa_datas_for_as_req( kdc_req_body: &KdcReqBody, auth_nonce: u32, dh_parameters: &DhParameters, + private_key: &RsaPrivateKey, ) -> Result> { let current_date = Utc::now(); let mut microseconds = current_date.timestamp_subsec_micros(); @@ -166,14 +213,30 @@ pub fn generate_pa_datas_for_as_req( let mut sha1 = Sha1::new(); sha1.update(&encoded_kdc_req_body); - let sha1_hash = sha1.finalize().to_vec(); + let kdc_req_body_sha1_hash = sha1.finalize().to_vec(); + + // let public_value = compute_public_key(&dh_parameters.private_key, &dh_parameters.modulus, &dh_parameters.base); + let public_value = vec![ + 2, 129, 129, 0, 249, 88, 64, 57, 194, 169, 38, 81, 23, 108, 110, 192, 241, 51, 44, 113, 50, 16, 179, 173, 72, + 57, 1, 65, 37, 199, 206, 229, 194, 186, 223, 122, 110, 117, 97, 237, 76, 86, 102, 153, 66, 47, 52, 176, 243, + 60, 14, 170, 4, 193, 138, 1, 193, 17, 154, 245, 113, 70, 182, 157, 112, 20, 178, 250, 176, 201, 248, 194, 226, + 23, 111, 177, 147, 141, 23, 77, 151, 226, 57, 213, 242, 172, 56, 40, 47, 191, 10, 135, 217, 26, 111, 24, 45, + 196, 40, 228, 106, 72, 173, 249, 255, 19, 254, 97, 184, 175, 205, 84, 209, 200, 11, 137, 117, 233, 218, 62, + 190, 76, 27, 110, 224, 185, 213, 207, 159, 52, 106, 94, + ]; + + println!("public key value len: {:?} bytes", public_value); let auth_pack = AuthPack { pk_authenticator: ExplicitContextTag0::from(PkAuthenticator { - cusec: ExplicitContextTag0::from(IntegerAsn1::from(microseconds.to_be_bytes().to_vec())), + // cusec: ExplicitContextTag0::from(IntegerAsn1::from(microseconds.to_be_bytes().to_vec())), + cusec: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x04, 0x4e, 0x14])), ctime: ExplicitContextTag1::from(KerberosTime::from(GeneralizedTime::from(current_date))), - nonce: ExplicitContextTag2::from(IntegerAsn1::from(auth_nonce.to_be_bytes().to_vec())), - pa_checksum: Optional::from(Some(ExplicitContextTag3::from(OctetStringAsn1::from(sha1_hash)))), + // nonce: ExplicitContextTag2::from(IntegerAsn1::from(auth_nonce.to_be_bytes().to_vec())), + nonce: ExplicitContextTag2::from(IntegerAsn1::from(vec![0])), + pa_checksum: Optional::from(Some(ExplicitContextTag3::from(OctetStringAsn1::from( + kdc_req_body_sha1_hash, + )))), }), client_public_value: Optional::from(Some(ExplicitContextTag1::from(DhReqInfo { key_info: DhReqKeyInfo { @@ -186,14 +249,20 @@ pub fn generate_pa_datas_for_as_req( validation_params: Optional::from(None), }, }, - key_value: BitStringAsn1::from(BitString::with_bytes(vec![ - 2, 129, 129, 0, 219, 78, 185, 183, 129, 7, 4, 73, 79, 203, 237, 216, 60, 162, 113, 232, 36, 233, 162, - 75, 8, 200, 168, 109, 49, 32, 207, 86, 26, 198, 121, 143, 205, 90, 248, 169, 6, 178, 153, 1, 237, 156, - 2, 145, 162, 150, 218, 232, 144, 183, 193, 58, 7, 27, 217, 215, 160, 30, 69, 15, 211, 28, 18, 216, 145, - 196, 14, 47, 119, 76, 163, 178, 243, 136, 213, 190, 122, 108, 59, 140, 94, 32, 75, 114, 17, 239, 99, - 81, 208, 221, 232, 214, 193, 129, 129, 135, 191, 117, 72, 254, 44, 211, 92, 124, 203, 235, 196, 113, 1, - 123, 74, 139, 101, 121, 212, 210, 119, 162, 26, 230, 153, 254, 123, 68, 151, 135, 52, 29, - ])), + key_value: BitStringAsn1::from(BitString::with_bytes( + // picky_asn1_der::to_vec(&IntegerAsn1::from( + // public_value, + // ))? + vec![ + 2, 129, 129, 0, 249, 88, 64, 57, 194, 169, 38, 81, 23, 108, 110, 192, 241, 51, 44, 113, 50, 16, + 179, 173, 72, 57, 1, 65, 37, 199, 206, 229, 194, 186, 223, 122, 110, 117, 97, 237, 76, 86, 102, + 153, 66, 47, 52, 176, 243, 60, 14, 170, 4, 193, 138, 1, 193, 17, 154, 245, 113, 70, 182, 157, 112, + 20, 178, 250, 176, 201, 248, 194, 226, 23, 111, 177, 147, 141, 23, 77, 151, 226, 57, 213, 242, 172, + 56, 40, 47, 191, 10, 135, 217, 26, 111, 24, 45, 196, 40, 228, 106, 72, 173, 249, 255, 19, 254, 97, + 184, 175, 205, 84, 209, 200, 11, 137, 117, 233, 218, 62, 190, 76, 27, 110, 224, 185, 213, 207, 159, + 52, 106, 94, + ], + )), }))), supported_cms_types: Optional::from(None), client_dh_nonce: Optional::from( @@ -204,20 +273,43 @@ pub fn generate_pa_datas_for_as_req( ), }; + let encoded_auth_pack = picky_asn1_der::to_vec(&auth_pack)?; + + let mut sha1 = Sha1::new(); + sha1.update(&encoded_auth_pack); + + let digest = sha1.finalize().to_vec(); + println!("digest: {:?}", digest); + + let mut new_digest = b"AzureAD\\MS-Organization-P2P-Access [2022]\\faadc5d3-fb45-4d03-902e-9965a96c463e".to_vec(); + new_digest.extend_from_slice(&[0x00]); + // new_digest.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); + new_digest.extend_from_slice(&digest); + + let mut sha1 = Sha1::new(); + sha1.update(&new_digest); + + let h = sha1.finalize().to_vec(); + + let rsa_signature = private_key.sign( + // PaddingScheme::new_pkcs1v15_sign(None), + PaddingScheme::new_pkcs1v15_sign(Some(rsa::Hash::SHA1)), + &h, + ).unwrap(); + println!("rsa_signature: {} {:?}", rsa_signature.len(), rsa_signature); + let signed_data = SignedData { version: CmsVersion::V3, - digest_algorithms: DigestAlgorithmIdentifiers(Asn1SetOf::from(vec![ - AlgorithmIdentifier::new_sha1_with_rsa_encryption(), - ])), + digest_algorithms: DigestAlgorithmIdentifiers(Asn1SetOf::from(vec![AlgorithmIdentifier::new_sha1()])), content_info: EncapsulatedContentInfo::new( ObjectIdentifier::try_from(PKINIT_AUTH_DATA).unwrap(), - Some(picky_asn1_der::to_vec(&auth_pack)?), + Some(encoded_auth_pack), ), certificates: Optional::from(CertificateSet(vec![CertificateChoices::Certificate(Asn1RawDer( picky_asn1_der::to_vec(p2p_cert)?, ))])), crls: None, - signers_infos: SignersInfos(Asn1SetOf::from(vec![generate_signer_info(p2p_ca_cert)])), + signers_infos: SignersInfos(Asn1SetOf::from(vec![generate_signer_info(p2p_cert, digest, rsa_signature)])), }; let pa_pk_as_req = PaPkAsReq { @@ -232,8 +324,11 @@ pub fn generate_pa_datas_for_as_req( }]) } -pub fn generate_neg(krb_msg: T, krb5_token_id: [u8; 2]) -> ApplicationTag0> { - ApplicationTag0(KrbMessage { +pub fn generate_neg( + krb_msg: T, + krb5_token_id: [u8; 2], +) -> ApplicationTag, 0> { + ApplicationTag::from(KrbMessage { krb5_oid: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(GSS_PKU2U).unwrap()), krb5_token_id, krb_msg, @@ -242,13 +337,71 @@ pub fn generate_neg(krb_msg: T, krb5_token_id: [u8; 2]) -> Application #[cfg(test)] mod tests { + use oid::ObjectIdentifier; + use picky_asn1::bit_string::BitString; + use picky_asn1::wrapper::{BitStringAsn1, ObjectIdentifierAsn1}; + use picky_asn1_x509::oids::NEGOEX; + use picky_krb::crypto::CipherSuite; + use sha1::{Digest, Sha1}; + use super::generate_pku2u_nego_req; + use crate::sspi::pku2u::generators::generate_neg; use crate::sspi::pku2u::Pku2uConfig; #[test] - fn neg_token_init_generation() { + fn _neg_token_init_generation() { let token = generate_pku2u_nego_req("", &Pku2uConfig::default()).unwrap(); println!("{:?}", picky_asn1_der::to_vec(&token).unwrap()); } + + #[test] + fn neg() { + let o = ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(NEGOEX).unwrap()); + + let token = generate_neg(o, [0x05, 0x00]); + + println!("{:?}", picky_asn1_der::to_vec(&token).unwrap()); + } + + #[test] + fn bit() { + let data = [ + 3, 129, 133, 0, 2, 129, 129, 0, 249, 88, 64, 57, 194, 169, 38, 81, 23, 108, 110, 192, 241, 51, 44, 113, 50, + 16, 179, 173, 72, 57, 1, 65, 37, 199, 206, 229, 194, 186, 223, 122, 110, 117, 97, 237, 76, 86, 102, 153, + 66, 47, 52, 176, 243, 60, 14, 170, 4, 193, 138, 1, 193, 17, 154, 245, 113, 70, 182, 157, 112, 20, 178, 250, + 176, 201, 248, 194, 226, 23, 111, 177, 147, 141, 23, 77, 151, 226, 57, 213, 242, 172, 56, 40, 47, 191, 10, + 135, 217, 26, 111, 24, 45, 196, 40, 228, 106, 72, 173, 249, 255, 19, 254, 97, 184, 175, 205, 84, 209, 200, + 11, 137, 117, 233, 218, 62, 190, 76, 27, 110, 224, 185, 213, 207, 159, 52, 106, 94, + ]; + + let b: BitStringAsn1 = picky_asn1_der::from_bytes(&data).unwrap(); + let c = BitStringAsn1::from(BitString::with_bytes(vec![ + 2, 129, 129, 0, 249, 88, 64, 57, 194, 169, 38, 81, 23, 108, 110, 192, 241, 51, 44, 113, 50, 16, 179, 173, + 72, 57, 1, 65, 37, 199, 206, 229, 194, 186, 223, 122, 110, 117, 97, 237, 76, 86, 102, 153, 66, 47, 52, 176, + 243, 60, 14, 170, 4, 193, 138, 1, 193, 17, 154, 245, 113, 70, 182, 157, 112, 20, 178, 250, 176, 201, 248, + 194, 226, 23, 111, 177, 147, 141, 23, 77, 151, 226, 57, 213, 242, 172, 56, 40, 47, 191, 10, 135, 217, 26, + 111, 24, 45, 196, 40, 228, 106, 72, 173, 249, 255, 19, 254, 97, 184, 175, 205, 84, 209, 200, 11, 137, 117, + 233, 218, 62, 190, 76, 27, 110, 224, 185, 213, 207, 159, 52, 106, 94, + ])); + println!("{:?}", b); + println!("{:?}", c); + assert_eq!(b, c); + } + + #[test] + fn s1() { + let data = [48, 130, 1, 12, 160, 7, 3, 5, 0, 64, 129, 0, 16, 161, 107, 48, 105, 160, 3, 2, 1, 128, 161, 98, 48, 96, 27, 94, 65, 122, 117, 114, 101, 65, 68, 92, 77, 83, 45, 79, 114, 103, 97, 110, 105, 122, 97, 116, 105, 111, 110, 45, 80, 50, 80, 45, 65, 99, 99, 101, 115, 115, 32, 91, 50, 48, 50, 50, 93, 92, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 162, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 163, 35, 48, 33, 160, 3, 2, 1, 2, 161, 26, 48, 24, 27, 7, 84, 69, 82, 77, 83, 82, 86, 27, 13, 49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 49, 55, 165, 17, 24, 15, 50, 48, 50, 50, 49, 48, 48, 53, 48, 56, 51, 54, 51, 50, 90, 166, 17, 24, 15, 50, 48, 50, 50, 49, 48, 48, 53, 48, 56, 51, 54, 51, 50, 90, 167, 3, 2, 1, 0, 168, 18, 48, 16, 2, 1, 18, 2, 1, 17, 2, 1, 23, 2, 1, 24, 2, 2, 255, 121, 169, 29, 48, 27, 48, 25, 160, 3, 2, 1, 20, 161, 18, 4, 16, 68, 69, 83, 75, 84, 79, 80, 45, 56, 70, 51, 51, 82, 70, 72, 32]; + + let mut sha1 = Sha1::new(); + + sha1.update(&data); + + let hash = sha1.finalize().to_vec(); + + assert_eq!( + &[249, 161, 134, 235, 134, 197, 25, 245, 122, 58, 180, 205, 8, 178, 158, 103, 207, 8, 208, 168], + hash.as_slice(), + ); + } } diff --git a/src/sspi/pku2u/macros.rs b/src/sspi/pku2u/macros.rs index 3cbad5f5..50da88bc 100644 --- a/src/sspi/pku2u/macros.rs +++ b/src/sspi/pku2u/macros.rs @@ -30,3 +30,17 @@ macro_rules! check_auth_scheme { } }; } + +macro_rules! check_sequence_number { + ($actual:expr, $expected:expr) => { + if $actual != $expected { + return Err(Error::new( + ErrorKind::InvalidToken, + format!( + "Server sent invalid sequence number. Got {:?} but expected {:?}.", + $actual, $expected + ), + )); + } + }; +} From 7608bf19b930e361e60ea766a4f06c2e62ff8067 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 3 Oct 2022 21:38:43 +0300 Subject: [PATCH 09/36] sspi: pku2u: improve as exchange --- src/sspi/kerberos/client/extractors.rs | 6 +- src/sspi/pku2u.rs | 41 +++++- src/sspi/pku2u/config.rs | 162 +++++++++++++++++++--- src/sspi/pku2u/extractors.rs | 181 +++++++------------------ src/sspi/pku2u/generators.rs | 164 +++++++++++----------- src/sspi/pku2u/macros.rs | 2 +- 6 files changed, 303 insertions(+), 253 deletions(-) diff --git a/src/sspi/kerberos/client/extractors.rs b/src/sspi/kerberos/client/extractors.rs index e2a70c5c..21e9ca2e 100644 --- a/src/sspi/kerberos/client/extractors.rs +++ b/src/sspi/kerberos/client/extractors.rs @@ -42,11 +42,7 @@ pub fn extract_session_key_from_as_rep( let key = cipher.generate_key_from_password(password.as_bytes(), salt.as_bytes())?; let enc_data = cipher - .decrypt(&key, AS_REP_ENC, &as_rep.0.enc_part.0.cipher.0 .0) - .map_err(|e| Error { - error_type: ErrorKind::DecryptFailure, - description: format!("Cannot decrypt as_rep.enc_part: {:?}", e), - })?; + .decrypt(&key, AS_REP_ENC, &as_rep.0.enc_part.0.cipher.0 .0)?; let enc_as_rep_part: EncAsRepPart = picky_asn1_der::from_bytes(&enc_data)?; diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 0983ab60..b1fee24a 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -38,6 +38,7 @@ use crate::kerberos::server::extractors::extract_sub_session_key_from_ap_rep; use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE, MAX_SIGNATURE, RRC, SECURITY_TRAILER, SERVICE_NAME}; use crate::sspi::pku2u::extractors::{ extract_krb_rep, extract_pa_pk_as_rep, extract_server_dh_public_key, extract_server_nonce, + extract_session_key_from_as_rep, }; use crate::sspi::{self, PACKAGE_ID_NONE}; use crate::utils::utf16_bytes_to_utf8_string; @@ -521,18 +522,29 @@ impl SspiImpl for Pku2u { .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "Input buffers must be specified".into()))?; let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; - let buffer = input_token.buffer.as_slice(); + let neg_token_targ: NegTokenTarg1 = picky_asn1_der::from_bytes(&input_token.buffer)?; + let buffer = neg_token_targ + .0 + .response_token + .0 + .ok_or_else(|| { + Error::new(ErrorKind::InvalidToken, "Missing response_token in NegTokenTarg".into()) + })? + .0 + .0; - println!("AsExchange buffer: {:?}", buffer); + // println!("AsExchange buffer: {:?}", buffer); - self.negoex_messages.extend_from_slice(buffer); + self.negoex_messages.extend_from_slice(&buffer); - let acceptor_exchange = Exchange::decode(buffer, &input_token.buffer)?; + let acceptor_exchange = Exchange::decode(buffer.as_slice(), &buffer)?; check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); check_sequence_number!(acceptor_exchange.header.sequence_num, self.next_seq_number()); check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); + println!("as. after checks. exchange: {:?}", acceptor_exchange.exchange); + let (as_rep, _): (AsRep, _) = extract_krb_rep(&acceptor_exchange.exchange)?; // todo: validate server's certificate @@ -547,11 +559,20 @@ impl SspiImpl for Pku2u { } }; - self.dh_parameters.server_nonce = Some(extract_server_nonce(&dh_rep_info)?); + println!("dh_rep_info: {:?}", dh_rep_info); + + let server_nonce = extract_server_nonce(&dh_rep_info)?; + println!("server_nonce: {:?}", server_nonce); + + self.dh_parameters.server_nonce = Some(server_nonce); let signed_data: SignedData = picky_asn1_der::from_bytes(&dh_rep_info.dh_signed_data.0)?; - self.dh_parameters.other_public_key = Some(extract_server_dh_public_key(&signed_data)?); + // validate server's signature + + let public_key = extract_server_dh_public_key(&signed_data)?; + println!("public key: {:?}", public_key); + self.dh_parameters.other_public_key = Some(public_key); self.encryption_params.encryption_type = Some(CipherSuite::try_from(as_rep.0.enc_part.0.etype.0 .0.as_slice())?); @@ -570,6 +591,14 @@ impl SspiImpl for Pku2u { .cipher() .as_ref(), )?); + println!("session key: {:?}", self.encryption_params.session_key); + + self.encryption_params.session_key = Some(extract_session_key_from_as_rep( + &as_rep, + self.encryption_params.session_key.as_ref().unwrap(), + &self.encryption_params, + )?); + println!("session key: {:?}", self.encryption_params.session_key); let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index 4152a9c2..1c6f5d9d 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -1,5 +1,7 @@ use picky_asn1_x509::Certificate; -use rsa::{RsaPrivateKey, pkcs8::DecodePrivateKey, pkcs1::DecodeRsaPrivateKey}; +use rsa::pkcs1::DecodeRsaPrivateKey; +use rsa::pkcs8::DecodePrivateKey; +use rsa::RsaPrivateKey; #[derive(Debug, Clone)] pub struct Pku2uConfig { @@ -14,7 +16,59 @@ impl Default for Pku2uConfig { fn default() -> Self { Self { device_private_key: RsaPrivateKey::from_pkcs1_der(&[ - 48, 130, 4, 165, 2, 1, 0, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 2, 130, 1, 1, 0, 178, 100, 113, 112, 83, 117, 20, 63, 122, 193, 220, 139, 33, 125, 192, 43, 177, 21, 73, 211, 19, 185, 156, 118, 207, 73, 129, 192, 247, 51, 158, 195, 136, 5, 172, 74, 184, 177, 186, 122, 237, 139, 78, 252, 182, 87, 192, 192, 77, 118, 229, 137, 49, 38, 209, 247, 17, 157, 81, 12, 230, 106, 251, 51, 249, 143, 104, 96, 46, 172, 243, 245, 1, 50, 76, 45, 78, 7, 124, 39, 154, 210, 203, 152, 22, 233, 32, 40, 58, 181, 148, 56, 109, 47, 82, 91, 87, 29, 152, 222, 103, 131, 74, 240, 136, 153, 216, 37, 69, 139, 116, 176, 2, 68, 83, 195, 189, 56, 108, 213, 40, 14, 135, 90, 152, 90, 78, 38, 229, 107, 54, 252, 110, 117, 3, 112, 160, 108, 229, 3, 134, 204, 214, 191, 152, 126, 249, 36, 155, 78, 97, 103, 237, 230, 138, 248, 84, 3, 34, 49, 203, 13, 164, 86, 10, 202, 94, 130, 87, 200, 189, 49, 172, 188, 188, 47, 235, 200, 96, 125, 17, 109, 170, 32, 215, 71, 8, 96, 245, 83, 239, 39, 109, 70, 187, 58, 121, 243, 179, 33, 46, 74, 48, 152, 249, 31, 211, 187, 234, 68, 22, 229, 223, 192, 70, 160, 33, 51, 33, 141, 231, 191, 193, 245, 182, 154, 93, 29, 179, 172, 169, 96, 159, 37, 159, 38, 140, 138, 152, 58, 186, 185, 25, 167, 44, 165, 186, 154, 216, 239, 40, 255, 73, 166, 213, 161, 2, 129, 129, 0, 206, 19, 212, 71, 145, 69, 123, 105, 175, 72, 169, 243, 189, 229, 3, 31, 87, 12, 12, 36, 187, 203, 30, 253, 241, 36, 63, 106, 76, 219, 159, 75, 119, 134, 97, 40, 29, 131, 21, 132, 122, 5, 167, 85, 135, 221, 116, 118, 27, 210, 167, 98, 157, 232, 42, 248, 159, 82, 155, 166, 95, 216, 236, 85, 231, 201, 90, 175, 220, 38, 197, 150, 54, 139, 123, 200, 81, 29, 190, 118, 179, 194, 54, 100, 207, 117, 10, 10, 195, 68, 131, 61, 163, 27, 187, 12, 249, 219, 101, 130, 228, 95, 247, 106, 1, 175, 141, 203, 28, 139, 41, 166, 91, 128, 158, 134, 108, 11, 136, 45, 6, 171, 236, 237, 15, 150, 117, 95, 2, 129, 129, 0, 247, 129, 4, 52, 135, 135, 143, 100, 220, 70, 79, 249, 17, 41, 57, 48, 74, 214, 52, 154, 34, 108, 20, 220, 90, 193, 210, 111, 79, 27, 35, 148, 111, 200, 241, 155, 141, 14, 175, 35, 56, 216, 209, 3, 218, 231, 171, 210, 186, 196, 183, 67, 83, 186, 32, 149, 178, 235, 111, 76, 134, 61, 39, 80, 49, 105, 3, 109, 229, 69, 156, 191, 182, 230, 148, 62, 232, 99, 101, 95, 234, 211, 145, 211, 147, 234, 12, 242, 237, 87, 99, 85, 164, 109, 78, 31, 99, 144, 116, 97, 55, 103, 77, 29, 249, 69, 69, 134, 88, 189, 232, 240, 150, 61, 212, 193, 250, 40, 135, 9, 234, 22, 119, 138, 223, 174, 157, 203, 2, 129, 128, 124, 53, 109, 116, 121, 118, 4, 173, 173, 141, 193, 137, 253, 1, 228, 192, 230, 9, 135, 228, 56, 32, 116, 156, 160, 212, 181, 56, 79, 252, 235, 229, 99, 180, 102, 40, 244, 168, 198, 182, 99, 137, 182, 211, 17, 162, 4, 9, 16, 58, 6, 211, 164, 211, 131, 218, 248, 196, 164, 182, 65, 253, 16, 109, 178, 216, 37, 69, 236, 14, 158, 119, 44, 135, 35, 227, 152, 40, 178, 92, 255, 121, 230, 169, 26, 117, 179, 200, 202, 235, 39, 163, 102, 5, 87, 215, 185, 93, 104, 176, 221, 15, 142, 163, 161, 66, 123, 215, 89, 107, 243, 125, 166, 151, 62, 117, 76, 248, 34, 106, 233, 35, 133, 25, 89, 148, 217, 71, 2, 129, 129, 0, 136, 161, 197, 131, 134, 42, 20, 195, 246, 66, 46, 149, 237, 158, 87, 62, 204, 161, 113, 202, 129, 36, 47, 99, 242, 10, 59, 180, 76, 244, 75, 112, 255, 64, 235, 248, 22, 39, 188, 17, 114, 169, 102, 193, 125, 16, 21, 175, 176, 129, 54, 54, 73, 187, 95, 143, 164, 133, 10, 29, 49, 162, 2, 216, 231, 93, 244, 145, 175, 86, 253, 144, 108, 84, 224, 19, 214, 80, 64, 191, 113, 176, 56, 57, 151, 215, 70, 44, 185, 79, 91, 188, 4, 152, 126, 223, 31, 36, 184, 202, 142, 62, 77, 185, 53, 73, 195, 118, 197, 248, 152, 230, 111, 218, 84, 96, 125, 75, 240, 56, 77, 236, 247, 51, 72, 6, 106, 127, 2, 129, 129, 0, 149, 64, 160, 185, 80, 7, 183, 188, 145, 39, 11, 48, 140, 239, 229, 100, 176, 249, 209, 241, 141, 224, 143, 180, 104, 197, 208, 174, 104, 121, 96, 243, 82, 121, 68, 94, 71, 78, 232, 206, 19, 70, 69, 110, 43, 66, 13, 16, 132, 63, 6, 115, 26, 56, 165, 174, 101, 190, 241, 247, 21, 150, 21, 96, 129, 114, 137, 162, 153, 128, 80, 140, 190, 170, 49, 14, 215, 134, 38, 81, 184, 113, 249, 230, 67, 239, 18, 68, 120, 202, 123, 6, 105, 202, 250, 129, 65, 217, 155, 156, 82, 210, 157, 130, 233, 38, 238, 208, 32, 242, 29, 27, 254, 49, 143, 91, 50, 163, 81, 16, 2, 227, 182, 144, 234, 118, 212, 40 + 48, 130, 4, 165, 2, 1, 0, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, + 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, + 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, + 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, + 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, + 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, + 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, + 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, + 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, + 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, + 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, + 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, + 1, 2, 130, 1, 1, 0, 178, 100, 113, 112, 83, 117, 20, 63, 122, 193, 220, 139, 33, 125, 192, 43, 177, 21, + 73, 211, 19, 185, 156, 118, 207, 73, 129, 192, 247, 51, 158, 195, 136, 5, 172, 74, 184, 177, 186, 122, + 237, 139, 78, 252, 182, 87, 192, 192, 77, 118, 229, 137, 49, 38, 209, 247, 17, 157, 81, 12, 230, 106, + 251, 51, 249, 143, 104, 96, 46, 172, 243, 245, 1, 50, 76, 45, 78, 7, 124, 39, 154, 210, 203, 152, 22, + 233, 32, 40, 58, 181, 148, 56, 109, 47, 82, 91, 87, 29, 152, 222, 103, 131, 74, 240, 136, 153, 216, 37, + 69, 139, 116, 176, 2, 68, 83, 195, 189, 56, 108, 213, 40, 14, 135, 90, 152, 90, 78, 38, 229, 107, 54, + 252, 110, 117, 3, 112, 160, 108, 229, 3, 134, 204, 214, 191, 152, 126, 249, 36, 155, 78, 97, 103, 237, + 230, 138, 248, 84, 3, 34, 49, 203, 13, 164, 86, 10, 202, 94, 130, 87, 200, 189, 49, 172, 188, 188, 47, + 235, 200, 96, 125, 17, 109, 170, 32, 215, 71, 8, 96, 245, 83, 239, 39, 109, 70, 187, 58, 121, 243, 179, + 33, 46, 74, 48, 152, 249, 31, 211, 187, 234, 68, 22, 229, 223, 192, 70, 160, 33, 51, 33, 141, 231, 191, + 193, 245, 182, 154, 93, 29, 179, 172, 169, 96, 159, 37, 159, 38, 140, 138, 152, 58, 186, 185, 25, 167, + 44, 165, 186, 154, 216, 239, 40, 255, 73, 166, 213, 161, 2, 129, 129, 0, 206, 19, 212, 71, 145, 69, + 123, 105, 175, 72, 169, 243, 189, 229, 3, 31, 87, 12, 12, 36, 187, 203, 30, 253, 241, 36, 63, 106, 76, + 219, 159, 75, 119, 134, 97, 40, 29, 131, 21, 132, 122, 5, 167, 85, 135, 221, 116, 118, 27, 210, 167, + 98, 157, 232, 42, 248, 159, 82, 155, 166, 95, 216, 236, 85, 231, 201, 90, 175, 220, 38, 197, 150, 54, + 139, 123, 200, 81, 29, 190, 118, 179, 194, 54, 100, 207, 117, 10, 10, 195, 68, 131, 61, 163, 27, 187, + 12, 249, 219, 101, 130, 228, 95, 247, 106, 1, 175, 141, 203, 28, 139, 41, 166, 91, 128, 158, 134, 108, + 11, 136, 45, 6, 171, 236, 237, 15, 150, 117, 95, 2, 129, 129, 0, 247, 129, 4, 52, 135, 135, 143, 100, + 220, 70, 79, 249, 17, 41, 57, 48, 74, 214, 52, 154, 34, 108, 20, 220, 90, 193, 210, 111, 79, 27, 35, + 148, 111, 200, 241, 155, 141, 14, 175, 35, 56, 216, 209, 3, 218, 231, 171, 210, 186, 196, 183, 67, 83, + 186, 32, 149, 178, 235, 111, 76, 134, 61, 39, 80, 49, 105, 3, 109, 229, 69, 156, 191, 182, 230, 148, + 62, 232, 99, 101, 95, 234, 211, 145, 211, 147, 234, 12, 242, 237, 87, 99, 85, 164, 109, 78, 31, 99, + 144, 116, 97, 55, 103, 77, 29, 249, 69, 69, 134, 88, 189, 232, 240, 150, 61, 212, 193, 250, 40, 135, 9, + 234, 22, 119, 138, 223, 174, 157, 203, 2, 129, 128, 124, 53, 109, 116, 121, 118, 4, 173, 173, 141, 193, + 137, 253, 1, 228, 192, 230, 9, 135, 228, 56, 32, 116, 156, 160, 212, 181, 56, 79, 252, 235, 229, 99, + 180, 102, 40, 244, 168, 198, 182, 99, 137, 182, 211, 17, 162, 4, 9, 16, 58, 6, 211, 164, 211, 131, 218, + 248, 196, 164, 182, 65, 253, 16, 109, 178, 216, 37, 69, 236, 14, 158, 119, 44, 135, 35, 227, 152, 40, + 178, 92, 255, 121, 230, 169, 26, 117, 179, 200, 202, 235, 39, 163, 102, 5, 87, 215, 185, 93, 104, 176, + 221, 15, 142, 163, 161, 66, 123, 215, 89, 107, 243, 125, 166, 151, 62, 117, 76, 248, 34, 106, 233, 35, + 133, 25, 89, 148, 217, 71, 2, 129, 129, 0, 136, 161, 197, 131, 134, 42, 20, 195, 246, 66, 46, 149, 237, + 158, 87, 62, 204, 161, 113, 202, 129, 36, 47, 99, 242, 10, 59, 180, 76, 244, 75, 112, 255, 64, 235, + 248, 22, 39, 188, 17, 114, 169, 102, 193, 125, 16, 21, 175, 176, 129, 54, 54, 73, 187, 95, 143, 164, + 133, 10, 29, 49, 162, 2, 216, 231, 93, 244, 145, 175, 86, 253, 144, 108, 84, 224, 19, 214, 80, 64, 191, + 113, 176, 56, 57, 151, 215, 70, 44, 185, 79, 91, 188, 4, 152, 126, 223, 31, 36, 184, 202, 142, 62, 77, + 185, 53, 73, 195, 118, 197, 248, 152, 230, 111, 218, 84, 96, 125, 75, 240, 56, 77, 236, 247, 51, 72, 6, + 106, 127, 2, 129, 129, 0, 149, 64, 160, 185, 80, 7, 183, 188, 145, 39, 11, 48, 140, 239, 229, 100, 176, + 249, 209, 241, 141, 224, 143, 180, 104, 197, 208, 174, 104, 121, 96, 243, 82, 121, 68, 94, 71, 78, 232, + 206, 19, 70, 69, 110, 43, 66, 13, 16, 132, 63, 6, 115, 26, 56, 165, 174, 101, 190, 241, 247, 21, 150, + 21, 96, 129, 114, 137, 162, 153, 128, 80, 140, 190, 170, 49, 14, 215, 134, 38, 81, 184, 113, 249, 230, + 67, 239, 18, 68, 120, 202, 123, 6, 105, 202, 250, 129, 65, 217, 155, 156, 82, 210, 157, 130, 233, 38, + 238, 208, 32, 242, 29, 27, 254, 49, 143, 91, 50, 163, 81, 16, 2, 227, 182, 144, 234, 118, 212, 40, ]) .unwrap(), device_certificate: picky_asn1_der::from_bytes(&[ @@ -64,7 +118,7 @@ impl Default for Pku2uConfig { ]) .unwrap(), p2p_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 41, 174, 13, 91, 182, 83, 154, 144, 159, 209, 107, 121, 229, 255, 133, 88, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 48, 50, 49, 50, 51, 53, 53, 56, 90, 23, 13, 50, 50, 49, 48, 48, 50, 49, 51, 52, 48, 53, 56, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 142, 165, 234, 4, 42, 30, 175, 127, 217, 93, 96, 27, 30, 8, 42, 85, 134, 117, 240, 214, 211, 39, 117, 8, 125, 60, 202, 146, 212, 156, 177, 221, 241, 36, 93, 134, 230, 19, 250, 92, 233, 135, 245, 57, 15, 179, 212, 44, 200, 217, 103, 99, 145, 232, 110, 52, 57, 145, 207, 191, 68, 142, 175, 189, 141, 93, 25, 153, 52, 3, 197, 144, 68, 237, 42, 26, 15, 4, 254, 130, 247, 193, 26, 100, 152, 4, 248, 155, 56, 207, 92, 50, 89, 222, 224, 170, 25, 45, 174, 106, 142, 238, 114, 219, 184, 172, 116, 221, 135, 71, 55, 76, 160, 102, 155, 197, 195, 185, 214, 177, 164, 238, 188, 13, 126, 84, 198, 50, 37, 164, 198, 158, 102, 100, 47, 227, 132, 192, 201, 148, 30, 174, 68, 13, 207, 59, 90, 27, 222, 108, 144, 125, 162, 121, 80, 100, 151, 220, 196, 45, 121, 153, 156, 180, 19, 43, 143, 213, 184, 48, 164, 69, 178, 195, 199, 126, 139, 22, 108, 0, 25, 104, 69, 190, 239, 12, 15, 252, 198, 98, 87, 0, 208, 249, 101, 48, 112, 192, 239, 101, 144, 45, 159, 43, 191, 63, 179, 32, 254, 184, 191, 119, 103, 19, 73, 221, 205, 102, 0, 230, 98, 205, 23, 40, 35, 208, 232, 198, 210, 231, 108, 103, 81, 27, 181, 90, 226, 47, 84, 157, 125, 103, 143, 11, 64, 165, 49, 29, 40, 52, 47, 168, 179, 53, 237, 215 + 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 113, 168, 131, 223, 47, 27, 109, 2, 232, 155, 24, 86, 159, 205, 201, 173, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 48, 51, 49, 53, 49, 52, 53, 49, 90, 23, 13, 50, 50, 49, 48, 48, 51, 49, 54, 49, 57, 53, 49, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 163, 20, 78, 245, 235, 195, 75, 236, 168, 191, 219, 20, 154, 22, 239, 226, 26, 249, 16, 221, 118, 28, 180, 76, 54, 217, 69, 164, 190, 120, 102, 233, 240, 94, 174, 87, 46, 7, 50, 152, 98, 125, 176, 250, 39, 49, 12, 18, 98, 239, 1, 168, 60, 129, 173, 204, 85, 251, 201, 115, 230, 195, 206, 161, 104, 127, 67, 108, 23, 26, 196, 168, 182, 248, 179, 84, 42, 239, 254, 186, 155, 90, 193, 118, 91, 81, 10, 199, 236, 226, 163, 199, 244, 120, 156, 58, 184, 219, 106, 179, 120, 197, 101, 190, 229, 211, 33, 54, 156, 75, 10, 177, 10, 5, 113, 87, 47, 138, 186, 83, 81, 80, 127, 79, 248, 78, 158, 27, 23, 60, 72, 52, 140, 87, 225, 246, 82, 142, 100, 15, 141, 9, 171, 203, 7, 108, 229, 231, 105, 5, 35, 98, 228, 236, 99, 54, 3, 114, 184, 119, 76, 118, 126, 36, 114, 198, 37, 60, 47, 178, 137, 114, 16, 250, 159, 166, 25, 213, 8, 12, 118, 63, 213, 83, 160, 224, 6, 166, 203, 5, 223, 176, 205, 85, 74, 205, 5, 112, 242, 65, 231, 196, 171, 86, 208, 229, 32, 31, 151, 90, 8, 199, 110, 162, 35, 177, 218, 77, 93, 179, 174, 43, 69, 137, 10, 144, 219, 214, 128, 83, 87, 137, 189, 55, 193, 73, 216, 64, 14, 47, 190, 138, 152, 129, 35, 13, 195, 221, 48, 126, 188, 249, 149, 236, 138, 126 ]) .unwrap(), p2p_ca_certificate: picky_asn1_der::from_bytes(&[ @@ -124,33 +178,103 @@ impl Default for Pku2uConfig { #[cfg(test)] mod tests { use picky_asn1_x509::Certificate; + use rsa::pkcs1::DecodeRsaPublicKey; + use rsa::{Hash, PaddingScheme, PublicKey, RsaPrivateKey, RsaPublicKey}; + use sha1::{Digest, Sha1}; use super::Pku2uConfig; - use rsa::{RsaPrivateKey, RsaPublicKey, PaddingScheme, PublicKey}; - #[test] fn p2p_i() { let config = Pku2uConfig::default(); println!("{:x?}", config.p2p_certificate.tbs_certificate.serial_number); - println!("{:?}", picky_asn1_der::to_vec(&config.p2p_certificate.tbs_certificate.serial_number).unwrap()); + println!( + "{:?}", + picky_asn1_der::to_vec(&config.p2p_certificate.tbs_certificate.serial_number).unwrap() + ); } #[test] fn p2p_c() { let config = Pku2uConfig::default(); - let mut rng = rand::thread_rng(); - // let s = config.device_private_key.to_public_key().encrypt( - // &mut rng, - // PaddingScheme::new_pkcs1v15_encrypt(), - // &[206, 152, 81, 67, 179, 29, 86, 137, 195, 0, 176, 87, 13, 194, 202, 115, 155, 82, 108, 32] - // ).unwrap(); - let s = config.device_private_key.sign( - // &mut rng, - PaddingScheme::new_pkcs1v15_sign(None), - &[206, 152, 81, 67, 179, 29, 86, 137, 195, 0, 176, 87, 13, 194, 202, 115, 155, 82, 108, 32] - ).unwrap(); - println!("{:?}", s); - println!("{}", s.len()); + + let signed_attributes = [ + 49, 61, 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, + 42, 134, 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 37, 144, 68, 78, 210, 60, 230, 236, 125, 249, 8, 246, + 201, 77, 20, 197, 108, 52, 75, 76, + ]; + let mut sha1 = Sha1::new(); + sha1.update(signed_attributes); + let res = sha1.finalize().to_vec(); + + let signature = config + .device_private_key + .sign(PaddingScheme::new_pkcs1v15_sign(Some(rsa::hash::Hash::SHA1)), &res) + .unwrap(); + println!("{:?}", signature); + println!("{}", signature.len()); + + println!( + "{:?}", + config.device_private_key.to_public_key().verify( + PaddingScheme::PKCS1v15Sign { hash: Some(Hash::SHA1) }, + &res, + &signature, + ) + ); + } + + #[test] + fn p2p_s() { + let public_key: RsaPublicKey = RsaPublicKey::from_pkcs1_pem( + "-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEApVx8YtLpzFFGmDmhI9f5JPUx1sEe6xJm39QwUuOZYKHbSSRLxVRh +Fy7uSnYS9gcn07b7kJoijCSYm+JJsUalGf32UlUoNppFxnhf3hVVj36eDijNQ/PT +qOQAYRJX/dsgIeXUW7rpCwJhSRSgHhEoxtfM7klZizNoZnSnJZUc7r8FK1R+6Mh7 +WWcOrkbv3PV7jD3ow8cjb82HqwWxSCpunh18yhPYituKGRfGoNnKxso4DuKhKH+r +RxGvd+moUmz2DWMqF5U6hdi3yBEGhkqFA1cpIGtdBewDWM2PYly3e4VH1BUeqgfq +xrG+r67m+4UEewwfRSQ0Wb6RmjlYtCy5nQIDAQAB +-----END RSA PUBLIC KEY-----", + ) + .unwrap(); + + let signed_attributes = [ + 49, 61, 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, + 42, 134, 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 37, 144, 68, 78, 210, 60, 230, 236, 125, 249, 8, 246, + 201, 77, 20, 197, 108, 52, 75, 76, + ]; + + let mut sha1 = Sha1::new(); + sha1.update(signed_attributes); + + let res = sha1.finalize().to_vec(); + + let signature = [ + 48, 127, 17, 243, 30, 27, 158, 81, 187, 246, 135, 199, 188, 180, 74, 19, 19, 201, 95, 142, 99, 234, 136, + 80, 71, 222, 71, 215, 251, 157, 78, 191, 97, 63, 240, 189, 68, 54, 186, 182, 87, 106, 249, 127, 176, 220, + 207, 191, 214, 158, 155, 182, 28, 230, 57, 172, 76, 203, 134, 248, 43, 70, 114, 183, 5, 111, 137, 6, 208, + 219, 139, 231, 164, 164, 206, 166, 69, 159, 70, 144, 168, 44, 139, 138, 8, 84, 2, 224, 192, 54, 238, 88, + 174, 197, 135, 69, 235, 159, 72, 206, 13, 214, 121, 180, 203, 152, 186, 70, 167, 45, 127, 37, 89, 238, 118, + 130, 56, 90, 54, 221, 72, 84, 48, 86, 58, 24, 242, 88, 78, 59, 8, 65, 27, 141, 157, 19, 59, 50, 155, 36, + 68, 48, 119, 77, 36, 137, 128, 47, 129, 216, 235, 94, 253, 236, 181, 249, 254, 116, 123, 84, 211, 146, 251, + 142, 134, 246, 128, 251, 173, 72, 204, 160, 42, 121, 78, 242, 27, 243, 168, 136, 42, 13, 162, 141, 139, 84, + 151, 156, 215, 141, 110, 39, 236, 155, 76, 115, 224, 254, 180, 69, 238, 134, 73, 101, 155, 194, 202, 63, + 22, 97, 6, 166, 14, 76, 191, 231, 247, 230, 12, 169, 228, 9, 88, 32, 251, 241, 138, 8, 146, 20, 252, 27, + 82, 204, 112, 98, 110, 168, 240, 76, 96, 38, 73, 88, 251, 202, 75, 147, 96, 223, 110, 226, 48, 136, 51, + 238, + ]; + + println!( + "{:?}", + public_key.verify( + PaddingScheme::PKCS1v15Sign { hash: Some(Hash::SHA1) }, + &signed_attributes, + &signature, + ) + ); + println!( + "{:?}", + public_key.verify(PaddingScheme::PKCS1v15Sign { hash: Some(Hash::SHA1) }, &res, &signature,) + ); } } diff --git a/src/sspi/pku2u/extractors.rs b/src/sspi/pku2u/extractors.rs index 3758e999..11a1832c 100644 --- a/src/sspi/pku2u/extractors.rs +++ b/src/sspi/pku2u/extractors.rs @@ -7,12 +7,14 @@ use picky_asn1_der::Asn1RawDer; use picky_asn1_x509::content_info::ContentValue; use picky_asn1_x509::oids::PKINIT_DH_KEY_DATA; use picky_asn1_x509::signed_data::SignedData; +use picky_krb::constants::key_usages::AS_REP_ENC; use picky_krb::constants::types::PA_PK_AS_REP; -use picky_krb::messages::AsRep; +use picky_krb::messages::{AsRep, EncAsRepPart}; use picky_krb::pkinit::{DhRepInfo, KdcDhKeyInfo, PaPkAsRep}; use serde::Deserialize; use super::generators::DH_NONCE_LEN; +use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE}; use crate::{Error, ErrorKind, Result}; pub fn extract_krb_rep<'a, T: Deserialize<'a>>(mut data: &'a [u8]) -> Result<(T, &'a [u8])> { @@ -115,144 +117,55 @@ pub fn extract_server_dh_public_key(signed_data: &SignedData) -> Result> Ok(key.as_unsigned_bytes_be().to_vec()) } +pub fn extract_session_key_from_as_rep(as_rep: &AsRep, key: &[u8], enc_params: &EncryptionParams) -> Result> { + let cipher = enc_params + .encryption_type + .as_ref() + .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) + .cipher(); + + let enc_data = cipher + .decrypt(&key, AS_REP_ENC, &as_rep.0.enc_part.0.cipher.0 .0)?; + println!("as rep decrypted!"); + + let enc_as_rep_part: EncAsRepPart = picky_asn1_der::from_bytes(&enc_data)?; + + Ok(enc_as_rep_part.0.key.0.key_value.0.to_vec()) +} + #[cfg(test)] mod tests { - use picky_krb::messages::AsRep; + use picky_krb::{messages::AsRep, crypto::{CipherSuite, diffie_hellman::{generate_key, DhNonce}}}; - use super::extract_krb_rep; + use crate::kerberos::EncryptionParams; + + use super::{extract_krb_rep, extract_session_key_from_as_rep}; #[test] fn as_rep_extraction() { - let raw_message = [ - 96, 130, 11, 218, 6, 6, 43, 6, 1, 5, 2, 7, 6, 0, 107, 130, 11, 204, 48, 130, 11, 200, 160, 3, 2, 1, 5, 161, - 3, 2, 1, 11, 162, 130, 6, 128, 48, 130, 6, 124, 48, 130, 6, 120, 161, 3, 2, 1, 17, 162, 130, 6, 111, 4, - 130, 6, 107, 160, 130, 6, 103, 48, 130, 6, 99, 128, 130, 6, 59, 48, 130, 6, 55, 2, 1, 3, 49, 11, 48, 9, 6, - 5, 43, 14, 3, 2, 26, 5, 0, 48, 129, 162, 6, 7, 43, 6, 1, 5, 2, 3, 2, 160, 129, 150, 4, 129, 147, 48, 129, - 144, 160, 129, 136, 3, 129, 133, 0, 2, 129, 129, 0, 218, 76, 235, 63, 222, 122, 67, 6, 210, 4, 219, 144, - 10, 253, 105, 197, 87, 1, 68, 61, 12, 232, 203, 120, 225, 215, 208, 224, 194, 49, 162, 89, 251, 216, 82, - 14, 92, 119, 236, 147, 132, 225, 80, 117, 104, 218, 221, 117, 104, 149, 33, 9, 225, 159, 16, 243, 57, 44, - 147, 221, 164, 8, 131, 5, 43, 219, 70, 8, 7, 60, 118, 39, 124, 30, 48, 205, 41, 150, 112, 133, 151, 136, - 121, 91, 56, 12, 251, 210, 239, 155, 85, 63, 244, 177, 112, 133, 181, 245, 110, 164, 31, 197, 241, 14, 137, - 195, 223, 226, 23, 158, 68, 27, 66, 118, 200, 170, 122, 33, 156, 104, 103, 155, 136, 28, 247, 8, 54, 20, - 161, 3, 2, 1, 0, 160, 130, 3, 179, 48, 130, 3, 175, 48, 130, 2, 151, 160, 3, 2, 1, 2, 2, 16, 85, 47, 30, - 63, 139, 118, 224, 166, 140, 108, 227, 232, 117, 255, 59, 249, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, - 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, - 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, - 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 49, 0, 93, 48, 30, 23, 13, - 50, 50, 48, 53, 49, 55, 49, 57, 50, 52, 48, 54, 90, 23, 13, 50, 50, 48, 53, 49, 56, 49, 57, 50, 57, 48, 54, - 90, 48, 101, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 52, 99, 53, 97, 53, - 101, 99, 49, 45, 57, 97, 99, 53, 45, 52, 54, 49, 50, 45, 57, 98, 52, 99, 45, 54, 98, 101, 100, 49, 55, 56, - 98, 98, 54, 53, 97, 49, 45, 48, 43, 6, 3, 85, 4, 3, 12, 36, 99, 99, 51, 100, 57, 54, 98, 52, 45, 48, 97, - 48, 100, 45, 52, 97, 53, 100, 45, 56, 98, 102, 98, 45, 56, 100, 54, 101, 97, 56, 100, 57, 53, 53, 100, 50, - 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, - 2, 130, 1, 1, 0, 199, 77, 166, 39, 80, 222, 84, 115, 41, 66, 75, 180, 150, 219, 181, 13, 3, 102, 176, 46, - 8, 194, 243, 198, 233, 126, 112, 105, 214, 207, 85, 254, 186, 228, 217, 23, 28, 232, 31, 209, 227, 99, 220, - 60, 28, 78, 168, 51, 162, 48, 63, 120, 240, 186, 203, 224, 154, 164, 227, 78, 224, 4, 120, 160, 170, 134, - 185, 124, 156, 51, 235, 206, 20, 62, 191, 51, 182, 195, 7, 184, 139, 80, 198, 103, 40, 37, 155, 219, 95, - 56, 162, 242, 152, 249, 204, 236, 191, 67, 64, 180, 223, 13, 207, 32, 242, 203, 172, 126, 77, 90, 197, 6, - 32, 162, 179, 253, 86, 158, 233, 147, 176, 44, 132, 150, 128, 103, 128, 157, 185, 157, 131, 50, 142, 248, - 67, 68, 217, 122, 154, 103, 143, 101, 207, 136, 219, 79, 226, 0, 159, 117, 200, 43, 80, 95, 163, 247, 218, - 117, 69, 248, 88, 64, 5, 181, 63, 109, 247, 80, 141, 174, 38, 220, 64, 250, 3, 82, 187, 52, 243, 151, 141, - 237, 115, 115, 17, 199, 29, 213, 4, 197, 242, 40, 177, 141, 170, 241, 173, 179, 212, 100, 73, 102, 21, 255, - 74, 213, 158, 11, 241, 110, 82, 139, 142, 209, 118, 197, 15, 240, 243, 50, 39, 23, 243, 172, 152, 170, 75, - 97, 102, 169, 23, 245, 147, 180, 29, 22, 58, 3, 100, 35, 6, 98, 92, 164, 55, 39, 81, 87, 58, 25, 22, 31, - 234, 173, 200, 213, 2, 3, 1, 0, 1, 163, 115, 48, 113, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, - 160, 48, 45, 6, 3, 85, 29, 17, 4, 38, 48, 36, 130, 11, 65, 90, 82, 68, 79, 87, 78, 45, 87, 49, 48, 130, 11, - 65, 90, 82, 68, 79, 87, 78, 45, 87, 49, 48, 130, 8, 49, 48, 46, 49, 46, 48, 46, 52, 48, 19, 6, 3, 85, 29, - 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, - 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, - 1, 1, 0, 124, 211, 121, 241, 39, 108, 96, 140, 158, 149, 109, 212, 59, 78, 203, 168, 204, 137, 19, 171, 77, - 67, 61, 166, 94, 122, 197, 145, 118, 157, 192, 156, 113, 249, 60, 110, 33, 188, 169, 75, 137, 57, 64, 130, - 5, 128, 58, 248, 87, 211, 139, 50, 157, 138, 176, 226, 159, 239, 15, 103, 84, 126, 26, 147, 246, 82, 12, - 80, 56, 61, 192, 231, 75, 104, 125, 95, 59, 52, 28, 236, 7, 195, 239, 242, 49, 105, 113, 168, 210, 102, - 192, 207, 212, 185, 185, 100, 137, 250, 219, 180, 75, 84, 139, 15, 115, 187, 165, 170, 227, 48, 245, 58, - 91, 137, 220, 197, 161, 180, 99, 195, 82, 92, 119, 170, 199, 3, 161, 221, 211, 177, 124, 92, 195, 92, 210, - 165, 117, 41, 98, 234, 175, 123, 44, 252, 230, 121, 151, 208, 210, 165, 67, 150, 152, 200, 243, 21, 85, - 209, 223, 217, 73, 243, 38, 166, 60, 3, 6, 140, 26, 170, 243, 114, 205, 210, 117, 111, 235, 38, 42, 43, - 217, 170, 118, 150, 180, 38, 218, 39, 198, 156, 157, 182, 223, 198, 200, 13, 255, 101, 56, 124, 126, 126, - 10, 255, 166, 203, 26, 251, 140, 248, 229, 41, 19, 94, 135, 210, 18, 185, 30, 55, 23, 195, 54, 88, 140, - 174, 87, 65, 250, 143, 243, 163, 172, 142, 207, 190, 111, 113, 157, 204, 246, 0, 119, 11, 253, 208, 155, - 101, 40, 217, 188, 10, 14, 89, 120, 146, 49, 130, 1, 199, 48, 130, 1, 195, 2, 1, 1, 48, 97, 48, 77, 49, 75, - 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, - 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, - 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 49, 0, 93, 2, 16, 85, 47, 30, 63, 139, 118, 224, 166, - 140, 108, 227, 232, 117, 255, 59, 249, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 160, 61, 48, 22, 6, 9, 42, 134, - 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 2, 48, 35, 6, 9, 42, 134, 72, 134, 247, 13, 1, - 9, 4, 49, 22, 4, 20, 207, 84, 215, 76, 61, 237, 27, 245, 186, 203, 116, 211, 41, 149, 95, 129, 147, 149, - 136, 166, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 1, 0, 111, 17, 1, 8, 116, 231, - 197, 34, 227, 186, 92, 57, 120, 101, 232, 20, 207, 52, 39, 202, 112, 40, 194, 203, 86, 55, 75, 186, 92, 52, - 55, 244, 26, 119, 58, 46, 200, 251, 185, 76, 244, 242, 18, 149, 207, 17, 126, 4, 41, 216, 89, 14, 137, 100, - 190, 70, 0, 183, 138, 152, 26, 56, 162, 219, 146, 159, 128, 68, 195, 190, 195, 32, 2, 64, 118, 220, 182, - 183, 218, 219, 145, 62, 246, 216, 214, 182, 244, 251, 97, 78, 232, 123, 167, 187, 154, 212, 10, 222, 244, - 232, 249, 194, 202, 26, 149, 174, 109, 15, 218, 247, 45, 209, 232, 92, 5, 87, 249, 192, 249, 91, 240, 160, - 7, 202, 196, 8, 161, 2, 41, 10, 242, 107, 43, 100, 45, 5, 75, 49, 222, 172, 249, 252, 196, 68, 71, 250, - 195, 11, 185, 161, 184, 39, 65, 22, 44, 78, 245, 132, 193, 63, 231, 94, 113, 116, 125, 210, 243, 106, 48, - 201, 50, 14, 177, 43, 168, 94, 39, 44, 221, 97, 60, 94, 230, 117, 248, 57, 143, 88, 117, 139, 75, 113, 97, - 48, 39, 13, 168, 2, 247, 89, 110, 216, 96, 161, 47, 183, 168, 204, 145, 221, 28, 174, 247, 196, 69, 212, - 187, 37, 162, 198, 33, 238, 127, 68, 191, 239, 233, 46, 240, 67, 151, 40, 76, 232, 41, 137, 233, 117, 199, - 11, 95, 201, 123, 246, 188, 44, 122, 105, 175, 179, 204, 127, 221, 57, 190, 66, 161, 34, 4, 32, 160, 135, - 139, 83, 106, 40, 32, 75, 125, 12, 23, 191, 191, 163, 215, 162, 217, 132, 196, 80, 212, 102, 88, 251, 252, - 135, 151, 137, 121, 58, 199, 71, 163, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, - 85, 164, 45, 48, 43, 160, 3, 2, 1, 128, 161, 36, 48, 34, 27, 32, 65, 122, 117, 114, 101, 65, 68, 92, 109, - 97, 109, 111, 114, 101, 97, 117, 64, 100, 111, 119, 110, 104, 105, 108, 108, 112, 114, 111, 46, 120, 121, - 122, 165, 130, 3, 227, 97, 130, 3, 223, 48, 130, 3, 219, 160, 3, 2, 1, 5, 161, 17, 27, 15, 87, 69, 76, 76, - 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 162, 33, 48, 31, 160, 3, 2, 1, 2, 161, 24, 48, 22, 27, 7, 84, - 69, 82, 77, 83, 82, 86, 27, 11, 65, 90, 82, 68, 79, 87, 78, 45, 87, 49, 48, 163, 130, 3, 156, 48, 130, 3, - 152, 160, 3, 2, 1, 18, 162, 130, 3, 143, 4, 130, 3, 139, 1, 206, 220, 195, 79, 122, 192, 180, 36, 196, 136, - 196, 220, 73, 91, 167, 233, 45, 204, 201, 148, 192, 68, 0, 158, 26, 246, 183, 80, 77, 153, 236, 156, 126, - 210, 232, 48, 59, 26, 118, 6, 208, 56, 26, 19, 197, 158, 79, 33, 215, 127, 55, 149, 23, 63, 180, 58, 196, - 63, 108, 78, 65, 240, 36, 188, 65, 121, 222, 12, 131, 194, 73, 28, 16, 4, 115, 76, 185, 80, 244, 103, 75, - 230, 191, 180, 210, 101, 133, 243, 33, 19, 30, 164, 27, 201, 91, 124, 212, 223, 174, 207, 49, 102, 46, 5, - 167, 14, 17, 239, 249, 1, 152, 83, 9, 15, 249, 52, 54, 49, 168, 215, 221, 197, 127, 66, 68, 126, 207, 82, - 33, 111, 74, 177, 66, 11, 39, 232, 23, 171, 34, 222, 28, 5, 192, 21, 181, 248, 7, 156, 232, 23, 226, 28, - 131, 247, 28, 247, 233, 191, 193, 15, 8, 36, 103, 57, 30, 126, 241, 186, 182, 154, 144, 167, 47, 148, 40, - 216, 51, 92, 85, 74, 35, 242, 108, 37, 41, 254, 16, 213, 10, 97, 73, 217, 95, 67, 118, 96, 160, 231, 185, - 127, 86, 130, 62, 129, 86, 225, 98, 36, 109, 190, 150, 34, 203, 57, 8, 134, 122, 113, 131, 25, 57, 6, 121, - 114, 58, 132, 130, 212, 218, 214, 106, 150, 67, 131, 157, 85, 100, 120, 163, 203, 16, 120, 184, 11, 6, 20, - 74, 223, 54, 118, 38, 122, 161, 255, 128, 112, 242, 161, 73, 73, 159, 83, 200, 90, 171, 216, 124, 125, 156, - 40, 56, 174, 192, 89, 243, 43, 29, 232, 77, 10, 28, 250, 8, 63, 151, 152, 104, 123, 123, 8, 207, 246, 58, - 85, 107, 160, 82, 157, 237, 236, 52, 67, 231, 169, 176, 155, 96, 64, 217, 222, 141, 122, 70, 26, 222, 134, - 181, 175, 234, 24, 98, 149, 212, 60, 35, 102, 40, 213, 148, 199, 127, 13, 213, 197, 69, 169, 62, 186, 132, - 195, 110, 141, 53, 102, 66, 202, 123, 209, 232, 133, 183, 7, 223, 22, 27, 124, 4, 13, 234, 16, 204, 214, 9, - 53, 227, 236, 127, 12, 64, 90, 162, 24, 36, 51, 209, 203, 45, 175, 107, 12, 49, 7, 213, 247, 49, 204, 37, - 235, 71, 157, 113, 10, 42, 122, 159, 170, 147, 186, 222, 183, 248, 108, 83, 54, 175, 113, 189, 148, 152, - 121, 133, 168, 26, 98, 225, 211, 34, 217, 69, 214, 208, 143, 31, 153, 255, 152, 101, 226, 144, 203, 168, - 203, 72, 182, 35, 183, 15, 172, 54, 127, 120, 56, 38, 199, 135, 192, 204, 30, 17, 68, 186, 77, 41, 138, - 126, 247, 231, 168, 133, 219, 205, 163, 132, 66, 215, 190, 6, 171, 149, 79, 114, 66, 236, 245, 248, 66, - 197, 29, 204, 222, 1, 208, 38, 214, 112, 61, 25, 238, 246, 201, 87, 10, 241, 229, 39, 228, 235, 132, 15, - 215, 19, 172, 88, 239, 186, 141, 165, 141, 114, 29, 135, 23, 139, 72, 206, 83, 52, 80, 71, 71, 96, 109, 73, - 119, 236, 50, 100, 156, 0, 231, 218, 225, 37, 227, 244, 49, 121, 115, 6, 149, 43, 199, 84, 51, 105, 137, - 49, 209, 91, 187, 160, 165, 17, 141, 65, 91, 117, 174, 29, 187, 42, 8, 198, 188, 145, 43, 252, 86, 154, 57, - 42, 180, 153, 158, 240, 237, 189, 157, 244, 74, 181, 142, 129, 106, 137, 146, 46, 75, 23, 52, 18, 113, 187, - 111, 80, 113, 169, 214, 75, 103, 225, 196, 42, 88, 102, 80, 55, 87, 228, 252, 126, 74, 13, 28, 43, 217, - 209, 221, 231, 77, 36, 179, 70, 252, 120, 119, 247, 92, 20, 138, 238, 234, 75, 186, 86, 235, 32, 72, 53, - 40, 157, 42, 242, 123, 147, 189, 197, 206, 117, 121, 45, 17, 165, 152, 153, 42, 208, 28, 236, 236, 185, - 216, 213, 147, 234, 66, 158, 41, 105, 166, 60, 37, 34, 115, 185, 3, 62, 77, 75, 169, 77, 226, 91, 140, 58, - 132, 214, 182, 254, 101, 233, 60, 84, 150, 166, 105, 205, 190, 48, 151, 86, 41, 130, 129, 217, 39, 111, - 228, 12, 221, 142, 43, 224, 18, 225, 85, 27, 104, 81, 196, 125, 248, 18, 134, 94, 38, 225, 173, 210, 198, - 138, 249, 204, 123, 69, 248, 206, 206, 75, 119, 17, 96, 118, 8, 119, 184, 142, 108, 4, 38, 147, 176, 25, - 138, 213, 90, 83, 73, 219, 227, 198, 165, 72, 206, 105, 228, 140, 64, 43, 134, 234, 239, 54, 236, 117, 129, - 97, 179, 56, 56, 135, 249, 41, 63, 29, 114, 204, 103, 252, 138, 186, 144, 1, 38, 61, 243, 33, 239, 119, - 235, 67, 199, 73, 92, 124, 64, 76, 0, 245, 37, 113, 103, 97, 180, 244, 208, 194, 41, 152, 252, 231, 13, - 251, 13, 240, 166, 19, 66, 78, 183, 47, 64, 204, 133, 29, 200, 189, 20, 134, 179, 203, 197, 160, 49, 157, - 152, 228, 33, 209, 114, 248, 35, 46, 163, 17, 239, 65, 15, 188, 234, 161, 167, 39, 222, 100, 139, 80, 0, 4, - 201, 204, 30, 7, 187, 233, 25, 208, 84, 107, 238, 60, 120, 147, 192, 151, 35, 134, 245, 89, 12, 113, 235, - 87, 114, 11, 112, 230, 220, 36, 94, 9, 105, 29, 183, 50, 159, 166, 130, 1, 13, 48, 130, 1, 9, 160, 3, 2, 1, - 18, 162, 130, 1, 0, 4, 129, 253, 62, 242, 7, 228, 43, 94, 177, 66, 185, 89, 38, 84, 238, 3, 18, 84, 199, - 99, 235, 203, 159, 159, 208, 53, 56, 51, 109, 123, 123, 122, 95, 9, 93, 11, 217, 142, 76, 36, 26, 139, 102, - 253, 138, 130, 44, 44, 84, 239, 73, 108, 79, 194, 61, 63, 16, 84, 185, 127, 228, 25, 136, 185, 192, 36, - 227, 219, 18, 111, 51, 254, 227, 176, 247, 0, 77, 30, 160, 12, 53, 184, 74, 139, 147, 124, 145, 200, 139, - 123, 146, 54, 72, 71, 154, 17, 113, 26, 221, 205, 46, 50, 234, 181, 210, 133, 209, 48, 168, 209, 180, 8, 3, - 201, 198, 172, 85, 169, 196, 142, 105, 180, 35, 110, 160, 103, 151, 102, 227, 172, 217, 82, 142, 230, 223, - 92, 92, 228, 36, 46, 94, 151, 255, 148, 76, 100, 55, 152, 228, 206, 185, 202, 128, 35, 25, 7, 233, 135, - 114, 98, 166, 29, 103, 179, 166, 189, 122, 200, 177, 14, 156, 222, 120, 104, 179, 117, 47, 209, 139, 196, - 95, 193, 121, 163, 38, 4, 12, 178, 117, 14, 85, 17, 4, 39, 242, 7, 166, 154, 178, 98, 51, 125, 205, 40, - 177, 225, 47, 227, 212, 186, 33, 0, 255, 113, 231, 112, 119, 145, 37, 26, 198, 9, 35, 108, 143, 47, 147, - 91, 163, 80, 142, 155, 208, 102, 97, 235, 50, 189, 90, 114, 94, 27, 237, 206, 97, 10, 121, 166, 24, 3, 248, - 187, 142, 204, 99, - ]; - - let (as_rep, _): (AsRep, _) = extract_krb_rep(&raw_message).unwrap(); - println!("{:?}", as_rep) + let enc_type = CipherSuite::Aes256CtsHmacSha196; + + let as_rep: AsRep = picky_asn1_der::from_bytes(&[]).unwrap(); + + let enc_params = EncryptionParams { + encryption_type: Some(enc_type.clone()), + session_key: None, + sub_session_key: None, + sspi_encrypt_key_usage: 0, + sspi_decrypt_key_usage: 0, + }; + + let key = generate_key( + &[], + &[], + &[], + Some(DhNonce { + client_nonce: &[142, 91, 149, 4, 44, 55, 103, 6, 75, 168, 207, 165, 162, 197, 172, 27, 2, 108, 166, 10, 240, 52, 179, 24, 56, 73, 137, 103, 160, 81, 236, 230], + server_nonce: &[], + }), + enc_type.cipher().as_ref(), + ).unwrap(); + + println!("{:?}", extract_session_key_from_as_rep(&as_rep, &key, &enc_params).unwrap()); } } diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index 18a5d62c..07c23d3a 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -42,7 +42,7 @@ use picky_krb::pkinit::{ Pku2uNegoReqMetadata, Pku2uValue, Pku2uValueInner, }; use rand::rngs::OsRng; -use rsa::{RsaPrivateKey, PaddingScheme}; +use rsa::{Hash, PaddingScheme, RsaPrivateKey}; use sha1::{Digest, Sha1}; use super::{DhParameters, Pku2uConfig}; @@ -118,57 +118,58 @@ pub fn generate_neg_token_targ(token: Vec) -> Result, encrypted: Vec) -> SignerInfo { - // SignerInfo { - // version: version_to_cms_version(p2p_ca_cert.tbs_certificate.version.0), - // sid: SignerIdentifier::SubjectKeyIdentifier(ImplicitContextTag0::from(SubjectKeyIdentifier::from( - // p2p_ca_cert.subject_key_identifier().unwrap().to_vec(), - // ))), - // digest_algorithm: DigestAlgorithmIdentifier( - // p2p_ca_cert.tbs_certificate.subject_public_key_info.algorithm.clone(), - // ), - // signed_attrs: Optional::from(Attributes(Asn1SequenceOf::from(vec![]))), - // signature_algorithm: SignatureAlgorithmIdentifier(p2p_ca_cert.signature_algorithm.clone()), - // signature: SignatureValue(OctetStringAsn1::from(p2p_ca_cert.signature_value.0.inner())), - // unsigned_attrs: Optional::from(UnsignedAttributes(vec![])), - // } +pub fn generate_signer_info( + p2p_cert: &Certificate, + digest: Vec, + private_key: &RsaPrivateKey, +) -> Result { println!("{:x?}", p2p_cert.tbs_certificate.serial_number); - println!("{:?}", picky_asn1_der::to_vec(&p2p_cert.tbs_certificate.serial_number).unwrap()); - SignerInfo { + println!( + "{:?}", + picky_asn1_der::to_vec(&p2p_cert.tbs_certificate.serial_number).unwrap() + ); + + let signed_attributes = Asn1SetOf::from(vec![ + Attribute { + ty: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("1.2.840.113549.1.9.3").unwrap()), + value: AttributeValues::ContentType(Asn1SetOf::from(vec![ObjectIdentifierAsn1::from( + ObjectIdentifier::try_from("1.3.6.1.5.2.3.1").unwrap(), + )])), + }, + Attribute { + ty: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("1.2.840.113549.1.9.4").unwrap()), + value: AttributeValues::MessageDigest(Asn1SetOf::from(vec![OctetStringAsn1::from(digest)])), + }, + ]); + + let encoded_signed_attributes = picky_asn1_der::to_vec(&signed_attributes)?; + + let mut sha1 = Sha1::new(); + sha1.update(&encoded_signed_attributes); + + let hashed_signed_attributes = sha1.finalize().to_vec(); + + let signature = private_key + .sign( + PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA1)), + &hashed_signed_attributes, + ) + .unwrap(); + + println!("signature: {} {:?}", signature.len(), signature); + + Ok(SignerInfo { version: CmsVersion::V1, sid: SignerIdentifier::IssuerAndSerialNumber(IssuerAndSerialNumber { - // issuer: Name(RdnSequence::from(vec![ - // RelativeDistinguishedName::from(vec![ - // AttributeTypeAndValue { - // ty: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("2.5.4.3").unwrap()), - // value: AttributeTypeAndValueParameters::CommonName(DirectoryString::BmpString(BMPStringAsn1(BMPString::from_str("\0M\0S\0-\0O\0r\0g\0a\0n\0i\0z\0a\0t\0i\0o\0n\0-\0P\02\0P\0-\0A\0c\0c\0e\0s\0s\0 \0[\02\00\02\02\0]").unwrap()))), - // }, - // ]), - // ])), issuer: p2p_cert.tbs_certificate.issuer.clone(), serial_number: CertificateSerialNumber(p2p_cert.tbs_certificate.serial_number.clone()), }), - digest_algorithm: DigestAlgorithmIdentifier( - AlgorithmIdentifier::new_sha(ShaVariant::SHA1) - ), - signed_attrs: Optional::from(Attributes(Asn1SequenceOf::from(vec![ - Attribute { - ty: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("1.2.840.113549.1.9.3").unwrap()), - value: AttributeValues::ContentType(Asn1SetOf::from(vec![ - ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("1.3.6.1.5.2.3.1").unwrap()), - ])), - }, - Attribute { - ty: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("1.2.840.113549.1.9.4").unwrap()), - value: AttributeValues::MessageDigest(Asn1SetOf::from(vec![ - OctetStringAsn1::from(digest), - ])), - }, - ]))), + digest_algorithm: DigestAlgorithmIdentifier(AlgorithmIdentifier::new_sha(ShaVariant::SHA1)), + signed_attrs: Optional::from(Attributes(Asn1SequenceOf::from(signed_attributes.0))), signature_algorithm: SignatureAlgorithmIdentifier(AlgorithmIdentifier::new_rsa_encryption()), - signature: SignatureValue(OctetStringAsn1::from(encrypted)), + signature: SignatureValue(OctetStringAsn1::from(signature)), unsigned_attrs: Optional::from(UnsignedAttributes(Vec::new())), - } + }) } pub fn generate_client_dh_parameters() -> Result { @@ -178,6 +179,8 @@ pub fn generate_client_dh_parameters() -> Result { let private_key = generate_private_key(&q, &mut rng); + println!("dh private_key: {:?}", private_key); + Ok(DhParameters { base: g, modulus: p, @@ -215,15 +218,7 @@ pub fn generate_pa_datas_for_as_req( let kdc_req_body_sha1_hash = sha1.finalize().to_vec(); - // let public_value = compute_public_key(&dh_parameters.private_key, &dh_parameters.modulus, &dh_parameters.base); - let public_value = vec![ - 2, 129, 129, 0, 249, 88, 64, 57, 194, 169, 38, 81, 23, 108, 110, 192, 241, 51, 44, 113, 50, 16, 179, 173, 72, - 57, 1, 65, 37, 199, 206, 229, 194, 186, 223, 122, 110, 117, 97, 237, 76, 86, 102, 153, 66, 47, 52, 176, 243, - 60, 14, 170, 4, 193, 138, 1, 193, 17, 154, 245, 113, 70, 182, 157, 112, 20, 178, 250, 176, 201, 248, 194, 226, - 23, 111, 177, 147, 141, 23, 77, 151, 226, 57, 213, 242, 172, 56, 40, 47, 191, 10, 135, 217, 26, 111, 24, 45, - 196, 40, 228, 106, 72, 173, 249, 255, 19, 254, 97, 184, 175, 205, 84, 209, 200, 11, 137, 117, 233, 218, 62, - 190, 76, 27, 110, 224, 185, 213, 207, 159, 52, 106, 94, - ]; + let public_value = compute_public_key(&dh_parameters.private_key, &dh_parameters.modulus, &dh_parameters.base); println!("public key value len: {:?} bytes", public_value); @@ -250,18 +245,18 @@ pub fn generate_pa_datas_for_as_req( }, }, key_value: BitStringAsn1::from(BitString::with_bytes( - // picky_asn1_der::to_vec(&IntegerAsn1::from( - // public_value, - // ))? - vec![ - 2, 129, 129, 0, 249, 88, 64, 57, 194, 169, 38, 81, 23, 108, 110, 192, 241, 51, 44, 113, 50, 16, - 179, 173, 72, 57, 1, 65, 37, 199, 206, 229, 194, 186, 223, 122, 110, 117, 97, 237, 76, 86, 102, - 153, 66, 47, 52, 176, 243, 60, 14, 170, 4, 193, 138, 1, 193, 17, 154, 245, 113, 70, 182, 157, 112, - 20, 178, 250, 176, 201, 248, 194, 226, 23, 111, 177, 147, 141, 23, 77, 151, 226, 57, 213, 242, 172, - 56, 40, 47, 191, 10, 135, 217, 26, 111, 24, 45, 196, 40, 228, 106, 72, 173, 249, 255, 19, 254, 97, - 184, 175, 205, 84, 209, 200, 11, 137, 117, 233, 218, 62, 190, 76, 27, 110, 224, 185, 213, 207, 159, - 52, 106, 94, - ], + picky_asn1_der::to_vec(&IntegerAsn1::from( + public_value, + ))? + // vec![ + // 2, 129, 129, 0, 249, 88, 64, 57, 194, 169, 38, 81, 23, 108, 110, 192, 241, 51, 44, 113, 50, 16, + // 179, 173, 72, 57, 1, 65, 37, 199, 206, 229, 194, 186, 223, 122, 110, 117, 97, 237, 76, 86, 102, + // 153, 66, 47, 52, 176, 243, 60, 14, 170, 4, 193, 138, 1, 193, 17, 154, 245, 113, 70, 182, 157, 112, + // 20, 178, 250, 176, 201, 248, 194, 226, 23, 111, 177, 147, 141, 23, 77, 151, 226, 57, 213, 242, 172, + // 56, 40, 47, 191, 10, 135, 217, 26, 111, 24, 45, 196, 40, 228, 106, 72, 173, 249, 255, 19, 254, 97, + // 184, 175, 205, 84, 209, 200, 11, 137, 117, 233, 218, 62, 190, 76, 27, 110, 224, 185, 213, 207, 159, + // 52, 106, 94, + // ], )), }))), supported_cms_types: Optional::from(None), @@ -281,23 +276,6 @@ pub fn generate_pa_datas_for_as_req( let digest = sha1.finalize().to_vec(); println!("digest: {:?}", digest); - let mut new_digest = b"AzureAD\\MS-Organization-P2P-Access [2022]\\faadc5d3-fb45-4d03-902e-9965a96c463e".to_vec(); - new_digest.extend_from_slice(&[0x00]); - // new_digest.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); - new_digest.extend_from_slice(&digest); - - let mut sha1 = Sha1::new(); - sha1.update(&new_digest); - - let h = sha1.finalize().to_vec(); - - let rsa_signature = private_key.sign( - // PaddingScheme::new_pkcs1v15_sign(None), - PaddingScheme::new_pkcs1v15_sign(Some(rsa::Hash::SHA1)), - &h, - ).unwrap(); - println!("rsa_signature: {} {:?}", rsa_signature.len(), rsa_signature); - let signed_data = SignedData { version: CmsVersion::V3, digest_algorithms: DigestAlgorithmIdentifiers(Asn1SetOf::from(vec![AlgorithmIdentifier::new_sha1()])), @@ -309,7 +287,11 @@ pub fn generate_pa_datas_for_as_req( picky_asn1_der::to_vec(p2p_cert)?, ))])), crls: None, - signers_infos: SignersInfos(Asn1SetOf::from(vec![generate_signer_info(p2p_cert, digest, rsa_signature)])), + signers_infos: SignersInfos(Asn1SetOf::from(vec![generate_signer_info( + p2p_cert, + digest, + private_key, + )?])), }; let pa_pk_as_req = PaPkAsReq { @@ -391,7 +373,11 @@ mod tests { #[test] fn s1() { - let data = [48, 130, 1, 12, 160, 7, 3, 5, 0, 64, 129, 0, 16, 161, 107, 48, 105, 160, 3, 2, 1, 128, 161, 98, 48, 96, 27, 94, 65, 122, 117, 114, 101, 65, 68, 92, 77, 83, 45, 79, 114, 103, 97, 110, 105, 122, 97, 116, 105, 111, 110, 45, 80, 50, 80, 45, 65, 99, 99, 101, 115, 115, 32, 91, 50, 48, 50, 50, 93, 92, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 162, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 163, 35, 48, 33, 160, 3, 2, 1, 2, 161, 26, 48, 24, 27, 7, 84, 69, 82, 77, 83, 82, 86, 27, 13, 49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 49, 55, 165, 17, 24, 15, 50, 48, 50, 50, 49, 48, 48, 53, 48, 56, 51, 54, 51, 50, 90, 166, 17, 24, 15, 50, 48, 50, 50, 49, 48, 48, 53, 48, 56, 51, 54, 51, 50, 90, 167, 3, 2, 1, 0, 168, 18, 48, 16, 2, 1, 18, 2, 1, 17, 2, 1, 23, 2, 1, 24, 2, 2, 255, 121, 169, 29, 48, 27, 48, 25, 160, 3, 2, 1, 20, 161, 18, 4, 16, 68, 69, 83, 75, 84, 79, 80, 45, 56, 70, 51, 51, 82, 70, 72, 32]; + let data = [ + 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, 42, 134, + 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 37, 144, 68, 78, 210, 60, 230, 236, 125, 249, 8, 246, 201, 77, + 20, 197, 108, 52, 75, 76, + ]; let mut sha1 = Sha1::new(); @@ -399,9 +385,11 @@ mod tests { let hash = sha1.finalize().to_vec(); - assert_eq!( - &[249, 161, 134, 235, 134, 197, 25, 245, 122, 58, 180, 205, 8, 178, 158, 103, 207, 8, 208, 168], - hash.as_slice(), - ); + println!("hash: {:?}", hash); + + // assert_eq!( + // &[214, 215, 210, 143, 189, 21, 220, 123, 16, 202, 62, 239, 143, 239, 72, 75, 129, 19, 192, 25], + // hash.as_slice(), + // ); } } diff --git a/src/sspi/pku2u/macros.rs b/src/sspi/pku2u/macros.rs index 50da88bc..09581fa4 100644 --- a/src/sspi/pku2u/macros.rs +++ b/src/sspi/pku2u/macros.rs @@ -35,7 +35,7 @@ macro_rules! check_sequence_number { ($actual:expr, $expected:expr) => { if $actual != $expected { return Err(Error::new( - ErrorKind::InvalidToken, + ErrorKind::OutOfSequence, format!( "Server sent invalid sequence number. Got {:?} but expected {:?}.", $actual, $expected From f54234f6505c26d8d0a85fab3a8d58dca708d378 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Wed, 5 Oct 2022 12:40:53 +0300 Subject: [PATCH 10/36] . --- src/sspi/kerberos/client/generators.rs | 6 +++++- src/sspi/pku2u.rs | 27 ++++++++++++++++---------- src/sspi/pku2u/config.rs | 16 ++++++++++++++- src/sspi/pku2u/generators.rs | 22 ++++++++++++++++----- 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/src/sspi/kerberos/client/generators.rs b/src/sspi/kerberos/client/generators.rs index 10a1ce00..a31c97cb 100644 --- a/src/sspi/kerberos/client/generators.rs +++ b/src/sspi/kerberos/client/generators.rs @@ -439,11 +439,15 @@ pub fn generate_ap_req( let encryption_type = enc_params.encryption_type.as_ref().unwrap_or(&DEFAULT_ENCRYPTION_TYPE); let cipher = encryption_type.cipher(); + let encoded_authenticator = picky_asn1_der::to_vec(&authenticator)?; + println!("encoded authenticator: {:?}", encoded_authenticator); + let encrypted_authenticator = cipher.encrypt( session_key, AP_REQ_AUTHENTICATOR, - &picky_asn1_der::to_vec(&authenticator)?, + &encoded_authenticator, )?; + // let encrypted_authenticator = vec![80, 58, 178, 30, 181, 48, 100, 50, 91, 8, 248, 83, 53, 188, 200, 102, 243, 158, 83, 177, 114, 25, 52, 239, 62, 75, 30, 27, 36, 28, 89, 25, 245, 73, 139, 74, 148, 218, 247, 99, 184, 143, 51, 70, 243, 20, 101, 219, 128, 55, 188, 223, 241, 26, 161, 134, 42, 224, 42, 71, 37, 6, 8, 126, 244, 71, 108, 57, 43, 198, 18, 79, 134, 236, 3, 44, 47, 126, 8, 31, 138, 167, 110, 190, 74, 2, 67, 240, 102, 227, 87, 148, 113, 230, 206, 156, 133, 116, 179, 151, 234, 27, 46, 3, 156, 89, 138, 49, 9, 191, 81, 78, 20, 229, 204, 148, 29, 246, 108, 161, 126, 173, 237, 116, 50, 189, 133, 89, 161, 156, 144, 228, 215, 254, 152, 133, 240, 154, 17, 242, 0, 5, 77, 249, 61, 171, 226, 114, 6, 220, 162, 247, 108, 14, 249, 30, 46, 81, 226, 239, 2, 131, 64, 220, 63, 44, 119, 17, 55, 197, 60, 83, 218, 165, 66, 185, 96, 154, 144, 37, 155, 243, 48, 104, 170, 28, 198, 61, 210, 91, 110, 19, 32, 7, 211, 1, 29, 40, 222, 231, 246, 102, 131, 90, 174, 60, 104, 87, 185, 216, 160, 250, 147, 206, 185, 140, 222, 162, 79, 249, 249, 206, 171, 15, 181, 200, 161, 10, 82, 52, 253, 242, 14, 85, 96, 198, 20, 105, 241, 1, 231, 132, 92, 240, 125, 25, 70, 159, 183, 181, 232, 135, 144, 112, 177, 168, 192, 205, 8, 123, 94, 139, 75, 12, 182, 20, 197, 235, 109, 41, 254, 14, 109, 118, 84, 178, 27, 134, 164, 121, 81, 126, 167, 5, 61, 223, 187, 149, 210, 146, 44, 96, 144, 224, 239, 55, 28, 247, 29, 159, 36, 235, 107, 213, 24, 79, 212, 193, 139, 187, 35, 157, 160, 135, 102, 181, 156, 123, 23, 203, 70, 184, 59, 20, 67, 253, 105, 147, 213, 54]; Ok(ApReq::from(ApReqInner { pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![KERBEROS_VERSION])), diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index b1fee24a..1c0050d3 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -600,9 +600,12 @@ impl SspiImpl for Pku2u { )?); println!("session key: {:?}", self.encryption_params.session_key); + let exchange_seq_number = self.next_seq_number(); + let verify_seq_number = self.next_seq_number(); + let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, - seq_num: Some(self.next_seq_number()), + seq_num: Some(exchange_seq_number), sub_key: Some(OsRng::default().gen::<[u8; 32]>().to_vec()), checksum: Some(ChecksumOptions { checksum_type: AUTHENTICATOR_CHECKSUM_TYPE.to_vec(), @@ -615,30 +618,33 @@ impl SspiImpl for Pku2u { self.encryption_params.session_key.as_ref().unwrap(), &authenticator, &self.encryption_params, - &[2, 0, 0, 0], + &[0x20, 0x00, 0x00, 0x00], )?; let mut mech_token = Vec::new(); let exchange = Exchange::new( - MessageType::InitiatorMetaData, + MessageType::ApRequest, self.conversation_id, - self.next_seq_number(), + exchange_seq_number, self.auth_scheme.unwrap(), picky_asn1_der::to_vec(&generate_neg(ap_req, AP_REQ_TOKEN_ID))?, ); exchange.encode(&mut mech_token)?; + // exchange.encode(&mut self.negoex_messages)?; + let verify = Verify::new( MessageType::Verify, self.conversation_id, - self.next_seq_number(), + verify_seq_number, self.auth_scheme.unwrap(), - self.encryption_params - .encryption_type - .as_ref() - .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) - .into(), + 16, + // self.encryption_params + // .encryption_type + // .as_ref() + // .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) + // .into(), ChecksumSuite::HmacSha196Aes256.hasher().checksum( self.encryption_params.session_key.as_ref().unwrap(), ACCEPTOR_SIGN, @@ -647,6 +653,7 @@ impl SspiImpl for Pku2u { ); verify.encode(&mut mech_token)?; + // verify.encode(&mut self.negoex_messages)?; self.negoex_messages.extend_from_slice(&mech_token); let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index 1c6f5d9d..4016a0cc 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -118,7 +118,7 @@ impl Default for Pku2uConfig { ]) .unwrap(), p2p_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 113, 168, 131, 223, 47, 27, 109, 2, 232, 155, 24, 86, 159, 205, 201, 173, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 48, 51, 49, 53, 49, 52, 53, 49, 90, 23, 13, 50, 50, 49, 48, 48, 51, 49, 54, 49, 57, 53, 49, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 163, 20, 78, 245, 235, 195, 75, 236, 168, 191, 219, 20, 154, 22, 239, 226, 26, 249, 16, 221, 118, 28, 180, 76, 54, 217, 69, 164, 190, 120, 102, 233, 240, 94, 174, 87, 46, 7, 50, 152, 98, 125, 176, 250, 39, 49, 12, 18, 98, 239, 1, 168, 60, 129, 173, 204, 85, 251, 201, 115, 230, 195, 206, 161, 104, 127, 67, 108, 23, 26, 196, 168, 182, 248, 179, 84, 42, 239, 254, 186, 155, 90, 193, 118, 91, 81, 10, 199, 236, 226, 163, 199, 244, 120, 156, 58, 184, 219, 106, 179, 120, 197, 101, 190, 229, 211, 33, 54, 156, 75, 10, 177, 10, 5, 113, 87, 47, 138, 186, 83, 81, 80, 127, 79, 248, 78, 158, 27, 23, 60, 72, 52, 140, 87, 225, 246, 82, 142, 100, 15, 141, 9, 171, 203, 7, 108, 229, 231, 105, 5, 35, 98, 228, 236, 99, 54, 3, 114, 184, 119, 76, 118, 126, 36, 114, 198, 37, 60, 47, 178, 137, 114, 16, 250, 159, 166, 25, 213, 8, 12, 118, 63, 213, 83, 160, 224, 6, 166, 203, 5, 223, 176, 205, 85, 74, 205, 5, 112, 242, 65, 231, 196, 171, 86, 208, 229, 32, 31, 151, 90, 8, 199, 110, 162, 35, 177, 218, 77, 93, 179, 174, 43, 69, 137, 10, 144, 219, 214, 128, 83, 87, 137, 189, 55, 193, 73, 216, 64, 14, 47, 190, 138, 152, 129, 35, 13, 195, 221, 48, 126, 188, 249, 149, 236, 138, 126 + 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 81, 76, 18, 240, 204, 162, 54, 186, 109, 8, 20, 195, 34, 154, 97, 251, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 48, 53, 48, 57, 50, 49, 52, 52, 90, 23, 13, 50, 50, 49, 48, 48, 53, 49, 48, 50, 54, 52, 52, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 61, 214, 255, 95, 227, 238, 112, 81, 189, 103, 123, 34, 104, 181, 4, 62, 65, 5, 49, 157, 227, 48, 164, 123, 86, 226, 13, 0, 189, 225, 185, 173, 212, 105, 81, 155, 16, 225, 160, 87, 242, 120, 130, 178, 19, 242, 28, 239, 204, 164, 222, 58, 222, 72, 145, 188, 17, 151, 159, 246, 128, 27, 11, 244, 119, 187, 129, 197, 242, 140, 39, 88, 27, 42, 21, 78, 93, 183, 99, 160, 128, 211, 116, 180, 93, 162, 135, 143, 182, 213, 211, 195, 141, 90, 78, 232, 55, 42, 47, 37, 197, 247, 42, 108, 240, 85, 37, 170, 72, 123, 185, 245, 173, 104, 219, 59, 11, 95, 135, 113, 188, 109, 19, 202, 163, 167, 77, 68, 211, 81, 232, 2, 220, 153, 113, 54, 220, 125, 27, 125, 0, 153, 19, 4, 68, 246, 123, 108, 139, 116, 33, 135, 245, 86, 34, 86, 54, 117, 225, 231, 93, 30, 127, 59, 7, 80, 25, 82, 180, 122, 48, 164, 32, 45, 70, 194, 89, 72, 203, 125, 27, 38, 254, 14, 150, 183, 149, 183, 85, 11, 164, 223, 212, 139, 131, 202, 5, 102, 82, 94, 73, 205, 75, 99, 20, 47, 219, 36, 168, 245, 172, 157, 24, 51, 1, 32, 15, 234, 159, 205, 240, 145, 117, 86, 74, 81, 214, 59, 71, 144, 0, 120, 171, 28, 120, 108, 136, 250, 113, 96, 46, 130, 141, 174, 226, 52, 113, 166, 51, 173, 86, 174, 50, 88, 212, 19 ]) .unwrap(), p2p_ca_certificate: picky_asn1_der::from_bytes(&[ @@ -178,6 +178,7 @@ impl Default for Pku2uConfig { #[cfg(test)] mod tests { use picky_asn1_x509::Certificate; + use picky_krb::crypto::CipherSuite; use rsa::pkcs1::DecodeRsaPublicKey; use rsa::{Hash, PaddingScheme, PublicKey, RsaPrivateKey, RsaPublicKey}; use sha1::{Digest, Sha1}; @@ -277,4 +278,17 @@ xrG+r67m+4UEewwfRSQ0Wb6RmjlYtCy5nQIDAQAB public_key.verify(PaddingScheme::PKCS1v15Sign { hash: Some(Hash::SHA1) }, &res, &signature,) ); } + + #[test] + fn hack() { + let data = [35, 111, 126, 23, 87, 190, 91, 115, 200, 160, 49, 19, 149, 223, 17, 183, 196, 209, 202, 166, 164, 175, 68, 100, 199, 205, 149, 86, 193, 231, 139, 142, 89, 21, 134, 214, 169, 241, 98, 172, 70, 134, 41, 83, 82, 214, 164, 12, 251, 197, 62, 76, 69, 22, 199, 80, 136, 206, 246, 164, 246, 215, 183, 122, 254, 21, 44, 251, 83, 58, 71, 59, 191, 89, 101, 186, 162, 78, 32, 54, 154, 137, 69, 23, 27, 114, 157, 125, 239, 158, 211, 89, 145, 211, 190, 134, 49, 235, 63, 88, 22, 222, 8, 167, 113, 117, 158, 163, 236, 93, 163, 125, 205, 68, 77, 229, 125, 250, 34, 125, 230, 199, 6, 49, 158, 5, 36, 246, 0, 175, 25, 130, 150, 116, 39, 101, 76, 177, 180, 48, 166, 23, 203, 187, 83, 254, 174, 247, 243, 136, 125, 128, 84, 184, 136, 180, 239, 3, 194, 87, 17, 214, 208, 9, 254, 108, 120, 87, 197, 74, 237, 155, 34, 190, 54, 132, 171, 249, 218, 79, 246, 254, 224, 158, 162, 230, 234, 71, 151, 95, 163, 208, 124, 42, 183, 2, 247, 116, 49, 40, 142, 122, 20, 202, 65, 19, 155, 215, 80, 101, 46, 87, 44, 57, 25, 15, 17, 123, 150, 106, 146, 34, 237, 141, 164, 104, 125, 154, 109, 132, 1, 45, 171, 247, 226, 40, 0, 168, 123, 250, 223, 165, 29, 244, 152, 216, 148, 176, 142, 255, 135, 59, 24, 125, 140, 210, 227, 165, 93, 98, 240, 108, 15, 153, 253, 172, 192, 132, 174, 156, 195, 226, 206, 103, 230, 203, 206, 209, 223, 152, 15, 212, 139, 19, 160, 28, 15, 119, 49, 159, 38, 148, 240, 186, 243, 30, 246, 118, 105, 135, 22, 108, 106, 189, 169, 105, 164, 21, 61, 174, 81, 113, 62, 174, 5, 173, 121, 51, 207, 181, 171, 171, 110]; + let password = "qweQWE123!@#"; + let salt = "QKATION.COMp3"; + + let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); + + let key = cipher.generate_key_from_password(password.as_bytes(), salt.as_bytes()).unwrap(); + + println!("{:?}", cipher.decrypt(&key, 2, &data)); + } } diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index 07c23d3a..d0dbfe2e 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -25,13 +25,12 @@ use picky_asn1_x509::signer_info::{ SignatureAlgorithmIdentifier, SignatureValue, SignerIdentifier, SignerInfo, UnsignedAttributes, }; use picky_asn1_x509::{ - AlgorithmIdentifier, Attribute, AttributeTypeAndValue, AttributeTypeAndValueParameters, AttributeValues, - Certificate, DirectoryString, Name, RdnSequence, RelativeDistinguishedName, ShaVariant, SubjectKeyIdentifier, - Version, + AlgorithmIdentifier, Attribute, AttributeValues, + Certificate, ShaVariant, }; use picky_krb::constants::gss_api::ACCEPT_INCOMPLETE; use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REQ}; -use picky_krb::crypto::diffie_hellman::{compute_public_key, generate_private_key, get_default_parameters}; +use picky_krb::crypto::diffie_hellman::{compute_public_key, generate_private_key}; use picky_krb::data_types::{KerberosStringAsn1, KerberosTime, PaData, PrincipalName, Realm}; use picky_krb::gss_api::{ ApplicationTag0, GssApiNegInit, KrbMessage, MechType, MechTypeList, NegTokenInit, NegTokenTarg, @@ -39,7 +38,7 @@ use picky_krb::gss_api::{ use picky_krb::messages::KdcReqBody; use picky_krb::pkinit::{ AuthPack, DhDomainParameters, DhReqInfo, DhReqKeyInfo, PaPkAsReq, PkAuthenticator, Pku2uNegoBody, Pku2uNegoReq, - Pku2uNegoReqMetadata, Pku2uValue, Pku2uValueInner, + Pku2uNegoReqMetadata, }; use rand::rngs::OsRng; use rsa::{Hash, PaddingScheme, RsaPrivateKey}; @@ -172,6 +171,19 @@ pub fn generate_signer_info( }) } +/// returns (p, g, q) +pub fn get_default_parameters() -> (Vec, Vec, Vec) { + ( + vec![ + 0, 255, 255, 255, 255, 255, 255, 255, 255, 201, 15, 218, 162, 33, 104, 194, 52, 196, 198, 98, 139, 128, 220, 28, 209, 41, 2, 78, 8, 138, 103, 204, 116, 2, 11, 190, 166, 59, 19, 155, 34, 81, 74, 8, 121, 142, 52, 4, 221, 239, 149, 25, 179, 205, 58, 67, 27, 48, 43, 10, 109, 242, 95, 20, 55, 79, 225, 53, 109, 109, 81, 194, 69, 228, 133, 181, 118, 98, 94, 126, 198, 244, 76, 66, 233, 166, 55, 237, 107, 11, 255, 92, 182, 244, 6, 183, 237, 238, 56, 107, 251, 90, 137, 159, 165, 174, 159, 36, 17, 124, 75, 31, 230, 73, 40, 102, 81, 236, 230, 83, 129, 255, 255, 255, 255, 255, 255, 255, 255 + ], + vec![2], + vec![ + 127, 255, 255, 255, 255, 255, 255, 255, 228, 135, 237, 81, 16, 180, 97, 26, 98, 99, 49, 69, 192, 110, 14, 104, 148, 129, 39, 4, 69, 51, 230, 58, 1, 5, 223, 83, 29, 137, 205, 145, 40, 165, 4, 60, 199, 26, 2, 110, 247, 202, 140, 217, 230, 157, 33, 141, 152, 21, 133, 54, 249, 47, 138, 27, 167, 240, 154, 182, 182, 168, 225, 34, 242, 66, 218, 187, 49, 47, 63, 99, 122, 38, 33, 116, 211, 27, 246, 181, 133, 255, 174, 91, 122, 3, 91, 246, 247, 28, 53, 253, 173, 68, 207, 210, 215, 79, 146, 8, 190, 37, 143, 243, 36, 148, 51, 40, 246, 115, 41, 192, 255, 255, 255, 255, 255, 255, 255, 255 + ], + ) +} + pub fn generate_client_dh_parameters() -> Result { let (p, g, q) = get_default_parameters(); From 4c028bb2730bdacfaca0b5c94dfbdd3deff70677 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 24 Oct 2022 01:19:29 +0300 Subject: [PATCH 11/36] sspi: pku2u: finally works. needs a refactoring --- Cargo.toml | 3 +- src/lib.rs | 2 +- src/sspi/internal/credssp.rs | 88 +++- src/sspi/internal/credssp/ts_request/test.rs | 76 ++++ src/sspi/kerberos.rs | 3 + src/sspi/kerberos/client/generators.rs | 4 +- src/sspi/kerberos/server/extractors.rs | 4 + src/sspi/ntlm.rs | 9 + src/sspi/pku2u.rs | 449 +++++++++++++++++-- src/sspi/pku2u/config.rs | 141 +++++- src/sspi/pku2u/extractors.rs | 274 ++++++++++- src/sspi/pku2u/generators.rs | 351 +++++++++++++-- 12 files changed, 1308 insertions(+), 96 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 460248ef..d76ee0b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,4 +48,5 @@ uuid = "1.1" whoami = "0.5" trust-dns-resolver = { version = "0.21.2", optional = true } portpicker = { version = "0.1.1", optional = true } -rsa = "0.6.1" \ No newline at end of file +rsa = "0.6.1" +kerberos_crypto = "0.3.6" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index a5aa1179..edb9ba86 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,7 +88,7 @@ pub use utils::resolve_kdc_host; pub use crate::sspi::kerberos::config::KerberosConfig; pub use crate::sspi::kerberos::{Kerberos, KERBEROS_VERSION, PACKAGE_INFO as KERBEROS_PACKAGE_INFO}; pub use crate::sspi::negotiate::{Negotiate, NegotiateConfig}; -pub use crate::sspi::pku2u::{Pku2u, PACKAGE_INFO as PKU2U_PACKAGE_INFO}; +pub use crate::sspi::pku2u::{Pku2u, PACKAGE_INFO as PKU2U_PACKAGE_INFO, Pku2uConfig}; #[cfg(windows)] pub use crate::sspi::winapi; pub use crate::sspi::{ diff --git a/src/sspi/internal/credssp.rs b/src/sspi/internal/credssp.rs index 17fa81c6..87b11814 100644 --- a/src/sspi/internal/credssp.rs +++ b/src/sspi/internal/credssp.rs @@ -22,6 +22,7 @@ use crate::sspi::internal::SspiImpl; use crate::sspi::kerberos::config::KerberosConfig; use crate::sspi::kerberos::Kerberos; use crate::sspi::ntlm::{AuthIdentity, AuthIdentityBuffers, Ntlm, SIGNATURE_SIZE}; +use crate::sspi::pku2u::Pku2uConfig; use crate::sspi::{ self, CertTrustStatus, ClientRequestFlags, ContextNames, ContextSizes, CredentialUse, DataRepresentation, DecryptionFlags, EncryptionFlags, FilledAcceptSecurityContext, FilledAcquireCredentialsHandle, @@ -30,14 +31,14 @@ use crate::sspi::{ }; use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, ErrorKind, InitializeSecurityContextResult, Negotiate, - NegotiateConfig, + NegotiateConfig, Pku2u, }; pub const EARLY_USER_AUTH_RESULT_PDU_SIZE: usize = 4; const HASH_MAGIC_LEN: usize = 38; -const SERVER_CLIENT_HASH_MAGIC: &[u8; HASH_MAGIC_LEN] = b"CredSSP Server-To-Client Binding Hash\0"; -const CLIENT_SERVER_HASH_MAGIC: &[u8; HASH_MAGIC_LEN] = b"CredSSP Client-To-Server Binding Hash\0"; +pub const SERVER_CLIENT_HASH_MAGIC: &[u8; HASH_MAGIC_LEN] = b"CredSSP Server-To-Client Binding Hash\0"; +pub const CLIENT_SERVER_HASH_MAGIC: &[u8; HASH_MAGIC_LEN] = b"CredSSP Client-To-Server Binding Hash\0"; /// Provides an interface for implementing proxy credentials structures. pub trait CredentialsProxy { @@ -156,6 +157,7 @@ enum EndpointType { pub enum ClientMode { Negotiate(NegotiateConfig), Kerberos(KerberosConfig), + Pku2u(Pku2uConfig), Ntlm, } @@ -191,6 +193,7 @@ impl CredSspClient { state: CredSspState::NegoToken, context: None, credentials, + // public_key: vec![48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1], public_key, cred_ssp_mode, client_nonce: OsRng::default().gen::<[u8; NONCE_SIZE]>(), @@ -213,6 +216,7 @@ impl CredSspClient { state: CredSspState::NegoToken, context: None, credentials, + // public_key: vec![48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1], public_key, cred_ssp_mode, client_nonce: OsRng::default().gen::<[u8; NONCE_SIZE]>(), @@ -235,6 +239,9 @@ impl CredSspClient { ClientMode::Kerberos(kerberos_config) => Some(CredSspContext::new(SspiContext::Kerberos( Kerberos::new_client_from_config(kerberos_config.clone())?, ))), + ClientMode::Pku2u(pku2u) => Some(CredSspContext::new(SspiContext::Pku2u( + Pku2u::new_client_from_config(pku2u.clone())?, + ))), ClientMode::Ntlm => Some(CredSspContext::new(SspiContext::Ntlm(Ntlm::new()))), }; let AcquireCredentialsHandleResult { credentials_handle, .. } = self @@ -275,6 +282,8 @@ impl CredSspClient { ts_request.nego_tokens = Some(output_token.remove(0).buffer); if result.status == SecurityStatus::Ok { + println!("start auth info"); + println!("public key: {:?}", self.public_key); let peer_version = self.context.as_ref().unwrap().peer_version.expect( "An encrypt public key client function cannot be fired without any incoming TSRequest", @@ -286,12 +295,14 @@ impl CredSspClient { peer_version, )?); ts_request.client_nonce = Some(self.client_nonce); + ts_request.nego_tokens = None; self.state = CredSspState::AuthInfo; } Ok(ClientState::ReplyNeeded(ts_request)) } CredSspState::AuthInfo => { + println!("got pub key auth reply. start credentials transferring"); ts_request.nego_tokens = None; let pub_key_auth = ts_request.pub_key_auth.take().ok_or_else(|| { @@ -314,6 +325,12 @@ impl CredSspClient { peer_version, )?; + self.credentials = AuthIdentity { + username: "s7@dataans.com".into(), + password: "wwwWWW222@@@".into(), + domain: Some("AzureAD".into()), + }; + ts_request.auth_info = Some( self.context .as_mut() @@ -351,11 +368,12 @@ pub struct CredSspServer> impl> CredSspServer { pub fn new(public_key: Vec, credentials: C, client_mode: ClientMode) -> sspi::Result { + println!("server's public key: {:?}", public_key); Ok(Self { state: CredSspState::NegoToken, context: None, credentials, - public_key, + public_key: vec![48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1], credentials_handle: None, ts_request_version: TS_REQUEST_VERSION, context_config: client_mode, @@ -395,6 +413,9 @@ impl> CredSspServer { try_cred_ssp_server!(Kerberos::new_server_from_config(kerberos_config.clone()), ts_request), ))), ClientMode::Ntlm => Some(CredSspContext::new(SspiContext::Ntlm(Ntlm::new()))), + ClientMode::Pku2u(pku2u) => Some(CredSspContext::new(SspiContext::Pku2u( + try_cred_ssp_server!(Pku2u::new_server_from_config(pku2u.clone()), ts_request) + ))), }; let AcquireCredentialsHandleResult { credentials_handle, .. } = try_cred_ssp_server!( self.context @@ -427,27 +448,37 @@ impl> CredSspServer { ts_request ); + println!("auth_info: {:?}", auth_info); + let read_credentials = try_cred_ssp_server!( self.context.as_mut().unwrap().decrypt_ts_credentials(&auth_info), ts_request ); + panic!("creds: {:?}", read_credentials); self.state = CredSspState::Final; Ok(ServerState::Finished(read_credentials.into())) } CredSspState::NegoToken => { - let input = try_cred_ssp_server!( - ts_request.nego_tokens.take().ok_or_else(|| { - sspi::Error::new( - sspi::ErrorKind::InvalidToken, - String::from("Got empty nego_tokens field"), - ) - }), - ts_request - ); + println!("public key: {:?}", self.public_key); + // let input = try_cred_ssp_server!( + // ts_request + // .nego_tokens + // .take() + // .ok_or_else(|| { + // sspi::Error::new( + // sspi::ErrorKind::InvalidToken, + // String::from("Got empty nego_tokens field"), + // ) + // }), + // ts_request + // ); + let input = ts_request.nego_tokens.take().unwrap_or(Vec::new()); let input_token = SecurityBuffer::new(input, SecurityBufferType::Token); let mut output_token = vec![SecurityBuffer::new(Vec::with_capacity(1024), SecurityBufferType::Token)]; + println!("ts_request: {:?}", ts_request); + let mut credentials_handle = self.credentials_handle.take(); match try_cred_ssp_server!( self.context @@ -467,10 +498,14 @@ impl> CredSspServer { ts_request.nego_tokens = Some(output_token.remove(0).buffer); } AcceptSecurityContextResult { status, .. } if status == SecurityStatus::CompleteNeeded => { + println!("I'M HERE: TS_REQUEST: {:?}", ts_request); + println!("--------------------------------"); + let ContextNames { username, domain } = try_cred_ssp_server!( self.context.as_mut().unwrap().sspi_context.query_context_names(), ts_request ); + println!("context names here"); let auth_data = try_cred_ssp_server!( self.credentials .auth_data_by_user(username, domain) @@ -482,6 +517,7 @@ impl> CredSspServer { .unwrap() .sspi_context .custom_set_auth_identity(auth_data); + println!("custom auth identity are set"); try_cred_ssp_server!( self.context.as_mut().unwrap().sspi_context.complete_auth_token(&mut []), @@ -524,7 +560,7 @@ impl> CredSspServer { self.state = CredSspState::AuthInfo; } - _ => unreachable!(), + q => unreachable!("AcceptSecurityContextResult: {:?}", q), }; self.credentials_handle = credentials_handle; @@ -543,6 +579,7 @@ pub enum SspiContext { Ntlm(Ntlm), Kerberos(Kerberos), Negotiate(Negotiate), + Pku2u(Pku2u), } impl SspiImpl for SspiContext { @@ -557,6 +594,7 @@ impl SspiImpl for SspiContext { SspiContext::Ntlm(ntlm) => builder.transform(ntlm).execute(), SspiContext::Kerberos(kerberos) => builder.transform(kerberos).execute(), SspiContext::Negotiate(negotiate) => builder.transform(negotiate).execute(), + SspiContext::Pku2u(pku2u) => builder.transform(pku2u).execute(), } } @@ -568,6 +606,7 @@ impl SspiImpl for SspiContext { SspiContext::Ntlm(ntlm) => ntlm.initialize_security_context_impl(builder), SspiContext::Kerberos(kerberos) => kerberos.initialize_security_context_impl(builder), SspiContext::Negotiate(negotiate) => negotiate.initialize_security_context_impl(builder), + SspiContext::Pku2u(pku2u) => pku2u.initialize_security_context_impl(builder), } } @@ -579,6 +618,7 @@ impl SspiImpl for SspiContext { SspiContext::Ntlm(ntlm) => builder.transform(ntlm).execute(), SspiContext::Kerberos(kerberos) => builder.transform(kerberos).execute(), SspiContext::Negotiate(negotiate) => builder.transform(negotiate).execute(), + SspiContext::Pku2u(pku2u) => builder.transform(pku2u).execute(), } } } @@ -589,6 +629,7 @@ impl Sspi for SspiContext { SspiContext::Ntlm(ntlm) => ntlm.complete_auth_token(token), SspiContext::Kerberos(kerberos) => kerberos.complete_auth_token(token), SspiContext::Negotiate(negotiate) => negotiate.complete_auth_token(token), + SspiContext::Pku2u(pku2u) => pku2u.complete_auth_token(token), } } @@ -602,6 +643,7 @@ impl Sspi for SspiContext { SspiContext::Ntlm(ntlm) => ntlm.encrypt_message(flags, message, sequence_number), SspiContext::Kerberos(kerberos) => kerberos.encrypt_message(flags, message, sequence_number), SspiContext::Negotiate(negotiate) => negotiate.encrypt_message(flags, message, sequence_number), + SspiContext::Pku2u(pku2u) => pku2u.encrypt_message(flags, message, sequence_number), } } @@ -614,6 +656,7 @@ impl Sspi for SspiContext { SspiContext::Ntlm(ntlm) => ntlm.decrypt_message(message, sequence_number), SspiContext::Kerberos(kerberos) => kerberos.decrypt_message(message, sequence_number), SspiContext::Negotiate(negotiate) => negotiate.decrypt_message(message, sequence_number), + SspiContext::Pku2u(pku2u) => pku2u.decrypt_message(message, sequence_number), } } @@ -622,6 +665,7 @@ impl Sspi for SspiContext { SspiContext::Ntlm(ntlm) => ntlm.query_context_sizes(), SspiContext::Kerberos(kerberos) => kerberos.query_context_sizes(), SspiContext::Negotiate(negotiate) => negotiate.query_context_sizes(), + SspiContext::Pku2u(pku2u) => pku2u.query_context_sizes(), } } fn query_context_names(&mut self) -> sspi::Result { @@ -629,6 +673,7 @@ impl Sspi for SspiContext { SspiContext::Ntlm(ntlm) => ntlm.query_context_names(), SspiContext::Kerberos(kerberos) => kerberos.query_context_names(), SspiContext::Negotiate(negotiate) => negotiate.query_context_names(), + SspiContext::Pku2u(pku2u) => pku2u.query_context_names(), } } fn query_context_package_info(&mut self) -> sspi::Result { @@ -636,6 +681,7 @@ impl Sspi for SspiContext { SspiContext::Ntlm(ntlm) => ntlm.query_context_package_info(), SspiContext::Kerberos(kerberos) => kerberos.query_context_package_info(), SspiContext::Negotiate(negotiate) => negotiate.query_context_package_info(), + SspiContext::Pku2u(pku2u) => pku2u.query_context_package_info(), } } fn query_context_cert_trust_status(&mut self) -> sspi::Result { @@ -643,6 +689,7 @@ impl Sspi for SspiContext { SspiContext::Ntlm(ntlm) => ntlm.query_context_cert_trust_status(), SspiContext::Kerberos(kerberos) => kerberos.query_context_cert_trust_status(), SspiContext::Negotiate(negotiate) => negotiate.query_context_cert_trust_status(), + SspiContext::Pku2u(pku2u) => pku2u.query_context_cert_trust_status(), } } @@ -651,6 +698,7 @@ impl Sspi for SspiContext { SspiContext::Ntlm(ntlm) => ntlm.change_password(change_password), SspiContext::Kerberos(kerberos) => kerberos.change_password(change_password), SspiContext::Negotiate(negotiate) => negotiate.change_password(change_password), + SspiContext::Pku2u(pku2u) => pku2u.change_password(change_password), } } } @@ -661,6 +709,7 @@ impl SspiEx for SspiContext { SspiContext::Ntlm(ntlm) => ntlm.custom_set_auth_identity(identity), SspiContext::Kerberos(kerberos) => kerberos.custom_set_auth_identity(identity), SspiContext::Negotiate(negotiate) => negotiate.custom_set_auth_identity(identity), + SspiContext::Pku2u(pku2u) => pku2u.custom_set_auth_identity(identity), } } } @@ -768,6 +817,7 @@ impl CredSspContext { } SspiContext::Kerberos(_) => {} SspiContext::Negotiate(_) => {} + SspiContext::Pku2u(_) => {} }; self.encrypt_message(&public_key) @@ -814,7 +864,9 @@ impl CredSspContext { hash_magic: &[u8], client_nonce: &[u8], ) -> sspi::Result<()> { + println!("start decrypt"); let decrypted_public_key = self.decrypt_message(encrypted_public_key)?; + println!("finish decrypt"); let mut data = hash_magic.to_vec(); data.extend(client_nonce); @@ -822,10 +874,13 @@ impl CredSspContext { let expected_public_key = compute_sha256(&data); if expected_public_key.as_ref() != decrypted_public_key.as_slice() { + println!("hashes are not the same"); return Err(sspi::Error::new( sspi::ErrorKind::MessageAltered, String::from("Could not verify a public key hash"), )); + } else { + println!("yes, they are the same"); } Ok(()) @@ -836,11 +891,14 @@ impl CredSspContext { credentials: &AuthIdentityBuffers, cred_ssp_mode: CredSspMode, ) -> sspi::Result> { - self.encrypt_message(&ts_request::write_ts_credentials(credentials, cred_ssp_mode)?) + let encoded_ts_creds = ts_request::write_ts_credentials(credentials, cred_ssp_mode)?; + println!("encoded_ts_creds: {:?}", encoded_ts_creds); + self.encrypt_message(&encoded_ts_creds) } fn decrypt_ts_credentials(&mut self, auth_info: &[u8]) -> sspi::Result { let ts_credentials_buffer = self.decrypt_message(auth_info)?; + println!("decrypted creds: {:?}", ts_credentials_buffer); Ok(ts_request::read_ts_credentials(ts_credentials_buffer.as_slice())?) } diff --git a/src/sspi/internal/credssp/ts_request/test.rs b/src/sspi/internal/credssp/ts_request/test.rs index 15f70323..7d3c7ca3 100644 --- a/src/sspi/internal/credssp/ts_request/test.rs +++ b/src/sspi/internal/credssp/ts_request/test.rs @@ -600,3 +600,79 @@ fn buffer_len_correct_returns_len_with_garbage() { assert_eq!((buffer.len() - garbage_len) as u16, ts_request.buffer_len()); } + +use crate::{internal::credssp::{CredSspClient, ClientMode, CredSspServer, ClientState, ServerState}, Pku2uConfig}; + +use super::TsRequest; + +fn send_to_server(client_state: ClientState, server: &mut CredSspServer) -> TsRequest { + match client_state { + ClientState::ReplyNeeded(ts_request) => { + match server.process(ts_request).unwrap() { + ServerState::ReplyNeeded(ts) => ts, + a => panic!("{:?}", a), + } + }, + ClientState::FinalMessage(ts_request) => { + match server.process(ts_request).unwrap() { + ServerState::ReplyNeeded(ts) => ts, + a => panic!("{:?}", a), + } + }, + } +} + +#[test] +pub fn auth() { + let mut client = CredSspClient::new( + Vec::new(), + AuthIdentity { + username: "AzureAD\\s7@dataans.com".into(), + password: "wwwWWW222@@@".into(), + domain: None, + }, + CredSspMode::WithCredentials, + ClientMode::Pku2u(Pku2uConfig::default()), + "TERMSRV/dest.dataans.com".into(), + ).unwrap(); + let mut server = CredSspServer::new( + Vec::new(), + AuthIdentity { + username: "AzureAD\\s7@dataans.com".into(), + password: "wwwWWW222@@@".into(), + domain: None, + }, + ClientMode::Pku2u(Pku2uConfig::default_server_config()), + ).unwrap(); + + // nego/preauth + let ts_request = TsRequest::default(); + let client_state = client.process(ts_request).unwrap(); + println!("=========> NEGO CLIENT PROCESSED"); + + let ts_request = send_to_server(client_state, &mut server); + println!("=========> NEGO SERVER PROCESSED"); + + // as exchange + let client_state = client.process(ts_request).unwrap(); + println!("=========> AS_REQ CLIENT PROCESSED"); + + let ts_request = send_to_server(client_state, &mut server); + println!("=========> AS_REP SERVER PROCESSED"); + + // ap exchange + let client_state = client.process(ts_request).unwrap(); + println!("=========> AP_REQ CLIENT PROCESSED"); + + let ts_request = send_to_server(client_state, &mut server); + println!("=========> AP_REP SERVER PROCESSED"); + + // pub key auth + let client_state = client.process(ts_request).unwrap(); + println!("=========> PUB KEY AUTH CLIENT PROCESSED"); + + let ts_request = send_to_server(client_state, &mut server); + println!("=========> PUB KEY AUTH SERVER PROCESSED"); + + println!("wow, we're here"); +} diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 76dcfeba..39aba90d 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -387,6 +387,7 @@ impl Sspi for Kerberos { sub_key: Some(OsRng::default().gen::<[u8; 32]>().to_vec()), checksum: None, channel_bindings: self.channel_bindings.as_ref(), + extension: vec![], })?; let krb_priv = generate_krb_priv_request( @@ -545,6 +546,7 @@ impl SspiImpl for Kerberos { sub_key: None, checksum: None, channel_bindings: self.channel_bindings.as_ref(), + extension: vec![], })?; let session_key_1 = @@ -587,6 +589,7 @@ impl SspiImpl for Kerberos { checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), }), channel_bindings: self.channel_bindings.as_ref(), + extension: vec![], })?; let ap_req = generate_ap_req( diff --git a/src/sspi/kerberos/client/generators.rs b/src/sspi/kerberos/client/generators.rs index a31c97cb..5647f8e6 100644 --- a/src/sspi/kerberos/client/generators.rs +++ b/src/sspi/kerberos/client/generators.rs @@ -326,6 +326,7 @@ pub struct GenerateAuthenticatorOptions<'a> { pub sub_key: Option>, pub checksum: Option, pub channel_bindings: Option<&'a ChannelBindings>, + pub extension: Vec, } pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result { @@ -335,6 +336,7 @@ pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result, } +impl CredentialsProxy for AuthIdentity { + type AuthenticationData = AuthIdentity; + + fn auth_data_by_user(&mut self, username: String, domain: Option) -> io::Result { + Ok(self.clone()) + } +} + #[derive(Debug, Clone, Eq, PartialEq, Default)] pub struct AuthIdentityBuffers { pub user: Vec, diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 1c0050d3..b00439ef 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -10,12 +10,12 @@ use std::str::FromStr; pub use config::Pku2uConfig; use lazy_static::lazy_static; use picky_asn1_x509::signed_data::SignedData; -use picky_krb::constants::gss_api::{AP_REQ_TOKEN_ID, AS_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE}; +use picky_krb::constants::gss_api::{AP_REQ_TOKEN_ID, AS_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE, AS_REP_TOKEN_ID, AP_REP_TOKEN_ID}; use picky_krb::constants::key_usages::{ACCEPTOR_SIGN, INITIATOR_SIGN}; use picky_krb::crypto::diffie_hellman::{generate_key, DhNonce}; use picky_krb::crypto::{ChecksumSuite, CipherSuite}; -use picky_krb::gss_api::{NegTokenTarg1, WrapToken}; -use picky_krb::messages::{ApRep, AsRep}; +use picky_krb::gss_api::{NegTokenTarg1, WrapToken, ApplicationTag0, GssApiNegInit, NegTokenInit}; +use picky_krb::messages::{ApRep, AsRep, AsReq, ApReq}; use picky_krb::negoex::data_types::MessageType; use picky_krb::negoex::messages::{Exchange, Nego, Verify}; use picky_krb::negoex::{NegoexMessage, RANDOM_ARRAY_SIZE}; @@ -26,27 +26,28 @@ use uuid::Uuid; use self::generators::{ generate_client_dh_parameters, generate_neg, generate_neg_token_init, generate_neg_token_targ, - generate_pa_datas_for_as_req, generate_pku2u_nego_req, DH_NONCE_LEN, WELLKNOWN_REALM, + generate_pa_datas_for_as_req, generate_pku2u_nego_req, DH_NONCE_LEN, WELLKNOWN_REALM, generate_server_dh_parameters, }; use crate::builders::ChangePassword; use crate::internal::SspiImpl; use crate::kerberos::client::generators::{ - generate_ap_req, generate_as_req, generate_as_req_kdc_body, generate_authenticator, ChecksumOptions, + generate_ap_req, generate_as_req, generate_as_req_kdc_body, ChecksumOptions, GenerateAsReqOptions, GenerateAuthenticatorOptions, AUTHENTICATOR_DEFAULT_CHECKSUM, }; use crate::kerberos::server::extractors::extract_sub_session_key_from_ap_rep; use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE, MAX_SIGNATURE, RRC, SECURITY_TRAILER, SERVICE_NAME}; use crate::sspi::pku2u::extractors::{ extract_krb_rep, extract_pa_pk_as_rep, extract_server_dh_public_key, extract_server_nonce, - extract_session_key_from_as_rep, + extract_session_key_from_as_rep, extract_pa_pk_as_req, compute_session_key_from_pa_pk_as_req, extract_sub_session_key_from_ap_req, }; +use crate::sspi::pku2u::generators::{generate_authenticator, generate_neg_token_init_s, generate_pa_datas_for_as_rep, generate_as_rep, generate_ap_rep, generate_neg_token_completed}; use crate::sspi::{self, PACKAGE_ID_NONE}; use crate::utils::utf16_bytes_to_utf8_string; use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, AuthIdentityBuffers, CertTrustStatus, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, EncryptionFlags, Error, ErrorKind, InitializeSecurityContextResult, PackageCapabilities, PackageInfo, Result, SecurityBuffer, SecurityBufferType, - SecurityPackageType, SecurityStatus, Sspi, SspiEx, + SecurityPackageType, SecurityStatus, Sspi, SspiEx, ServerResponseFlags, }; pub const PKG_NAME: &str = "Pku2u"; @@ -110,10 +111,42 @@ pub struct Pku2u { // https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-NEGOEX/%5bMS-NEGOEX%5d.pdf // The checksum is performed on all previous NEGOEX messages in the context negotiation. negoex_messages: Vec, + gss_api_messages: Vec, + exchange_data: Vec, negoex_random: [u8; RANDOM_ARRAY_SIZE], } impl Pku2u { + pub fn new_server_from_config(config: Pku2uConfig) -> Result { + Ok(Self { + config, + state: Pku2uState::Preauthentication, + encryption_params: EncryptionParams::default_for_client(), + auth_identity: None, + // conversation_id: Uuid::new_v4(), + // for the debugging + conversation_id: Uuid::from_str("e2506b43-4f8f-3534-f0e4-5ddf02b7f7c4").unwrap(), + auth_scheme: Some(Uuid::from_str("0d53335c-f9ea-4d0d-b2ec-4ae3786ec308").unwrap()), + seq_number: 2, + // realm: None, + // https://www.rfc-editor.org/rfc/rfc4556.html#section-3.2.3 + // Contains the nonce in the pkAuthenticator field in the request if the DH keys are NOT reused, + // 0 otherwise. + auth_nonce: 0, + // generate dh parameters at the start in order to not waste time during authorization + dh_parameters: generate_server_dh_parameters()?, + negoex_messages: Vec::new(), + gss_api_messages: Vec::new(), + exchange_data: Vec::new(), + // negoex_random: OsRng::default().gen::<[u8; RANDOM_ARRAY_SIZE]>(), + // for the debugging + negoex_random: [ + 10, 209, 111, 101, 206, 151, 53, 222, 225, 32, 241, 24, 15, 201, 210, 38, 133, 175, 97, 251, 27, 195, + 152, 39, 9, 97, 115, 227, 194, 196, 54, 245, + ], + }) + } + pub fn new_client_from_config(config: Pku2uConfig) -> Result { Ok(Self { config, @@ -122,7 +155,7 @@ impl Pku2u { auth_identity: None, // conversation_id: Uuid::new_v4(), // for the debugging - conversation_id: Uuid::from_str("883f9d5e-1555-2de8-cc32-506de34031ae").unwrap(), + conversation_id: Uuid::from_str("e2506b43-4f8f-3534-f0e4-5ddf02b7f7c4").unwrap(), auth_scheme: None, seq_number: 0, // realm: None, @@ -133,6 +166,8 @@ impl Pku2u { // generate dh parameters at the start in order to not waste time during authorization dh_parameters: generate_client_dh_parameters()?, negoex_messages: Vec::new(), + gss_api_messages: Vec::new(), + exchange_data: Vec::new(), // negoex_random: OsRng::default().gen::<[u8; RANDOM_ARRAY_SIZE]>(), // for the debugging negoex_random: [ @@ -159,7 +194,7 @@ impl Sspi for Pku2u { &mut self, _flags: EncryptionFlags, message: &mut [SecurityBuffer], - _sequence_number: u32, + sequence_number: u32, ) -> Result { SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Token)?; let data = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Data)?; @@ -171,8 +206,6 @@ impl Sspi for Pku2u { .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) .cipher(); - let seq_number = self.next_seq_number(); - // the sub-session key is always preferred over the session key let key = if let Some(key) = self.encryption_params.sub_session_key.as_ref() { key @@ -185,13 +218,20 @@ impl Sspi for Pku2u { )); }; let key_usage = self.encryption_params.sspi_encrypt_key_usage; + println!("encrypt key {:?} usage: {}", key, key_usage); - let mut wrap_token = WrapToken::with_seq_number(seq_number as u64); + // sequence number is always 0 in Pku2u + let mut wrap_token = WrapToken::with_seq_number(sequence_number as u64); + wrap_token.flags = 2; + // wrap_token.flags = 3; let mut payload = data.buffer.to_vec(); payload.extend_from_slice(&wrap_token.header()); + println!("data to encrypt: {:?} {}", payload, sequence_number); + let mut checksum = cipher.encrypt(key, key_usage, &payload)?; + // let mut checksum = cipher.encrypt(key, 22, &payload)?; checksum.rotate_right(RRC.into()); wrap_token.set_rrc(RRC); @@ -225,6 +265,9 @@ impl Sspi for Pku2u { encrypted.extend_from_slice(&data.buffer); + println!("message to decrypt: encrypted mic: {:?}", encrypted); + // panic!("{:?}", encrypted); + let cipher = self .encryption_params .encryption_type @@ -244,12 +287,15 @@ impl Sspi for Pku2u { )); }; let key_usage = self.encryption_params.sspi_decrypt_key_usage; + println!("decrypt key {:?} usage: {}", key, key_usage); let mut wrap_token = WrapToken::decode(encrypted.as_slice())?; wrap_token.checksum.rotate_left(RRC.into()); let mut decrypted = cipher.decrypt(key, key_usage, &wrap_token.checksum)?; + // let mut decrypted = cipher.decrypt(key, 24, &wrap_token.checksum)?; + println!("decrypted: {:?}", decrypted); // remove wrap token header decrypted.truncate(decrypted.len() - WrapToken::header_len()); @@ -290,10 +336,14 @@ impl Sspi for Pku2u { domain: identity.domain, }) } else { - Err(sspi::Error::new( - sspi::ErrorKind::NoCredentials, - String::from("Requested Names, but no credentials were provided"), - )) + Ok(ContextNames { + username: "s7@dataans.com".into(), + domain: Some("AzureAD".into()), + }) + // Err(sspi::Error::new( + // sspi::ErrorKind::NoCredentials, + // String::from("Requested Names, but no credentials were provided"), + // )) } } @@ -372,6 +422,8 @@ impl SspiImpl for Pku2u { ); nego.encode(&mut mech_token)?; + // nego.encode(&mut self.negoex_messages)?; + let exchange = Exchange::new( MessageType::InitiatorMetaData, self.conversation_id, @@ -382,6 +434,7 @@ impl SspiImpl for Pku2u { exchange.encode(&mut mech_token)?; self.negoex_messages.extend_from_slice(&mech_token); + // exchange.encode(&mut self.negoex_messages)?; let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; output_token @@ -478,12 +531,12 @@ impl SspiImpl for Pku2u { snames: &[ SERVICE_NAME, // &username, - "192.168.0.117", + // "192.168.0.117", + "dest.dataans.com", ], })?; let pa_datas = generate_pa_datas_for_as_req( &self.config.p2p_certificate, - &self.config.p2p_ca_certificate, &kdc_req_body, self.auth_nonce, &self.dh_parameters, @@ -493,6 +546,7 @@ impl SspiImpl for Pku2u { let exchange_data = picky_asn1_der::to_vec(&generate_neg(generate_as_req(&pa_datas, kdc_req_body), AS_REQ_TOKEN_ID))?; println!("exchange_data: {:?}", exchange_data); + self.gss_api_messages.extend_from_slice(&exchange_data); let exchange = Exchange::new( MessageType::ApRequest, @@ -544,6 +598,7 @@ impl SspiImpl for Pku2u { check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); println!("as. after checks. exchange: {:?}", acceptor_exchange.exchange); + self.gss_api_messages.extend_from_slice(&acceptor_exchange.exchange); let (as_rep, _): (AsRep, _) = extract_krb_rep(&acceptor_exchange.exchange)?; @@ -603,15 +658,19 @@ impl SspiImpl for Pku2u { let exchange_seq_number = self.next_seq_number(); let verify_seq_number = self.next_seq_number(); + let test_session_key = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; + let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, seq_num: Some(exchange_seq_number), - sub_key: Some(OsRng::default().gen::<[u8; 32]>().to_vec()), + // sub_key: Some(OsRng::default().gen::<[u8; 32]>().to_vec()), + sub_key: Some(test_session_key.to_vec()), checksum: Some(ChecksumOptions { checksum_type: AUTHENTICATOR_CHECKSUM_TYPE.to_vec(), checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), }), channel_bindings: None, + extension: ChecksumSuite::HmacSha196Aes256.hasher().checksum(&test_session_key, 41, &self.gss_api_messages).unwrap(), })?; let ap_req = generate_ap_req( as_rep.0.ticket.0, @@ -630,9 +689,19 @@ impl SspiImpl for Pku2u { self.auth_scheme.unwrap(), picky_asn1_der::to_vec(&generate_neg(ap_req, AP_REQ_TOKEN_ID))?, ); + println!("exchange: {:?}", exchange); exchange.encode(&mut mech_token)?; - // exchange.encode(&mut self.negoex_messages)?; + exchange.encode(&mut self.negoex_messages)?; + + // println!("negoex messages: {:?}", self.negoex_messages); + + let c2 = ChecksumSuite::HmacSha196Aes256.hasher().checksum( + &test_session_key, + // self.encryption_params.session_key.as_ref().unwrap(), + 25, + &self.negoex_messages, + )?; let verify = Verify::new( MessageType::Verify, @@ -645,16 +714,17 @@ impl SspiImpl for Pku2u { // .as_ref() // .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) // .into(), - ChecksumSuite::HmacSha196Aes256.hasher().checksum( - self.encryption_params.session_key.as_ref().unwrap(), - ACCEPTOR_SIGN, - &self.negoex_messages, - )?, + // ChecksumSuite::HmacSha196Aes256.hasher().checksum( + // self.encryption_params.session_key.as_ref().unwrap(), + // ACCEPTOR_SIGN, + // &self.negoex_messages, + // )?, + c2, ); verify.encode(&mut mech_token)?; - // verify.encode(&mut self.negoex_messages)?; - self.negoex_messages.extend_from_slice(&mech_token); + verify.encode(&mut self.negoex_messages)?; + // self.negoex_messages.extend_from_slice(&mech_token); let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; output_token @@ -672,41 +742,65 @@ impl SspiImpl for Pku2u { .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "Input buffers must be specified".into()))?; let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; - let buffer = input_token.buffer.as_slice(); + let neg_token_targ: NegTokenTarg1 = picky_asn1_der::from_bytes(&input_token.buffer)?; + + // todo: check negResult (should be accept completed: 0) + + let buffer = neg_token_targ + .0 + .response_token + .0 + .ok_or_else(|| { + Error::new(ErrorKind::InvalidToken, "Missing response_token in NegTokenTarg".into()) + })? + .0 + .0; + println!("ap_exchange buffer: {:?}", buffer); - self.negoex_messages.extend_from_slice(buffer); + // self.negoex_messages.extend_from_slice(&buffer); - let mut reader: Box = Box::new(buffer); + let mut reader: Box = Box::new(buffer.as_slice()); let acceptor_exchange = Exchange::decode(&mut reader, &buffer)?; + println!("acceptor exchange: {:?}", acceptor_exchange); check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); check_sequence_number!(acceptor_exchange.header.sequence_num, self.next_seq_number()); check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); + self.negoex_messages.extend_from_slice(&buffer[0..(acceptor_exchange.header.message_len as usize)]); + + let acceptor_verify_data = &buffer[(acceptor_exchange.header.message_len as usize)..]; + println!("buffer for verify: {:?}", acceptor_verify_data); + let acceptor_verify = - Verify::decode(&mut reader, &buffer[(acceptor_exchange.header.message_len as usize)..])?; + Verify::decode(acceptor_verify_data, acceptor_verify_data)?; + println!("acceptor verify: {:?}", acceptor_verify); check_conversation_id!(acceptor_verify.header.conversation_id.0, self.conversation_id); check_sequence_number!(acceptor_verify.header.sequence_num, self.next_seq_number()); check_auth_scheme!(acceptor_verify.auth_scheme.0, self.auth_scheme); + println!("all verified"); + let (ap_rep, _): (ApRep, _) = extract_krb_rep(&acceptor_exchange.exchange)?; + println!("ap_rep: {:?}", ap_rep); self.encryption_params.sub_session_key = Some(extract_sub_session_key_from_ap_rep( &ap_rep, self.encryption_params.session_key.as_ref().unwrap(), &self.encryption_params, )?); + println!("ap_rep sub session key: {:?}", self.encryption_params.sub_session_key); - let checksum = ChecksumSuite::try_from(acceptor_verify.checksum.checksum_type as usize)? + let acceptor_checksum = ChecksumSuite::try_from(acceptor_verify.checksum.checksum_type as usize)? .hasher() .checksum( - self.encryption_params.session_key.as_ref().unwrap(), - INITIATOR_SIGN, + self.encryption_params.sub_session_key.as_ref().unwrap(), + 23, &self.negoex_messages, )?; - if acceptor_verify.checksum.checksum_value != checksum { + if acceptor_verify.checksum.checksum_value != acceptor_checksum { return Err(Error::new( ErrorKind::MessageAltered, "bad Verify message signature".into(), @@ -715,7 +809,7 @@ impl SspiImpl for Pku2u { self.state = Pku2uState::PubKeyAuth; - SecurityStatus::ContinueNeeded + SecurityStatus::Ok } _ => { return Err(Error::new( @@ -734,12 +828,285 @@ impl SspiImpl for Pku2u { fn accept_security_context_impl<'a>( &'a mut self, - _builder: crate::builders::FilledAcceptSecurityContext<'a, Self::AuthenticationData, Self::CredentialsHandle>, + builder: crate::builders::FilledAcceptSecurityContext<'a, Self::AuthenticationData, Self::CredentialsHandle>, ) -> super::Result { - Err(Error::new( - ErrorKind::UnsupportedFunction, - "accept_security_context is not implemented in PKU2U".into(), - )) + println!("accept_security_context_impl"); + let input = builder + .input + .ok_or_else(|| sspi::Error::new(ErrorKind::InvalidToken, "Input buffers must be specified".into()))?; + + let status = match &self.state { + Pku2uState::Preauthentication => { + let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; + println!("server: nego buffer: {:?}", input_token); + + self.gss_api_messages.extend_from_slice(&input_token.buffer); + + println!("server: neg init token: {:?}", &input_token.buffer[16..]); + let neg_token_init: NegTokenInit = picky_asn1_der::from_bytes(&input_token.buffer[16..]).unwrap(); + + println!("server: neg init parsed: {:?}", neg_token_init); + + let data = neg_token_init.mech_token.0.unwrap().0.0; + + let mut reader: Box = Box::new(data.as_slice()); + + self.negoex_messages.extend_from_slice(&data); + + let initiator_nego = Nego::decode(&mut reader, &data)?; + + let initiator_exchange_data = &data[(initiator_nego.header.message_len as usize)..]; + println!("server: acceptor_exchage data: {:?}", initiator_exchange_data); + + let mut reader: Box = Box::new(initiator_exchange_data); + + let initiator_exchange = Exchange::decode(&mut reader, initiator_exchange_data)?; + + println!("server: acceptor_exchange: {:?}", initiator_exchange); + self.exchange_data.extend_from_slice(&initiator_exchange.exchange); + + self.conversation_id = initiator_nego.header.conversation_id.0; + + let mut mech_token = Vec::new(); + + let auth_scheme = Uuid::from_str(AUTH_SCHEME).unwrap(); + + let nego = Nego::new( + MessageType::AcceptorNego, + self.conversation_id, + self.next_seq_number(), + self.negoex_random.clone(), + vec![auth_scheme], + vec![], + ); + nego.encode(&mut mech_token)?; + + let exchange = Exchange::new( + MessageType::AcceptorMetaData, + self.conversation_id, + self.next_seq_number(), + auth_scheme, + vec![48, 87, 160, 85, 48, 83, 48, 81, 128, 79, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93], + ); + exchange.encode(&mut mech_token)?; + + self.negoex_messages.extend_from_slice(&mech_token); + self.exchange_data.extend_from_slice(&exchange.exchange); + + let result_token = picky_asn1_der::to_vec(&generate_neg_token_init_s(mech_token)?)?; + self.gss_api_messages.extend_from_slice(&result_token); + + let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; + output_token + .buffer + .write_all(&result_token)?; + + self.state = Pku2uState::AsExchange; + + SecurityStatus::ContinueNeeded + } + Pku2uState::AsExchange => { + let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; + println!("server: as exchange buffer:: {:?}", input_token); + + self.gss_api_messages.extend_from_slice(&input_token.buffer); + + let nego_token: NegTokenTarg1 = picky_asn1_der::from_bytes(&input_token.buffer)?; + + let buffer = nego_token.0.response_token.0.unwrap().0.0; + + self.negoex_messages.extend_from_slice(&buffer); + + let acceptor_exchange = Exchange::decode(buffer.as_slice(), &buffer)?; + self.exchange_data.extend_from_slice(&acceptor_exchange.exchange); + + self.next_seq_number(); + + let (as_req, _): (AsReq, _) = extract_krb_rep(&acceptor_exchange.exchange)?; + println!("server: as_req parsed"); + let pa_pk_as_req = extract_pa_pk_as_req(&as_req)?; + + let mut f = std::fs::File::create("as_req_cert").unwrap(); + f.write_all(&acceptor_exchange.exchange).unwrap(); + + let (session_key, dh_server_public) = compute_session_key_from_pa_pk_as_req( + &pa_pk_as_req, + self.dh_parameters.server_nonce.as_ref().unwrap(), + )?; + + println!("dh session key: {:?}", session_key); + + self.encryption_params.session_key = Some(session_key); + + let new_key = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; + println!("server's session key: {:?}", new_key); + + let pa_datas = generate_pa_datas_for_as_rep( + &self.config.p2p_certificate, + self.dh_parameters.server_nonce.as_ref().unwrap(), + &dh_server_public, &self.config.device_private_key, + )?; + let as_rep = generate_as_rep( + pa_datas, + self.encryption_params.session_key.as_ref().unwrap(), + new_key.clone() + )?; + + let exchange_data = + picky_asn1_der::to_vec(&generate_neg(as_rep, AS_REP_TOKEN_ID))?; + println!("exchange_data: {:?}", exchange_data); + + let mut mech_token = Vec::new(); + + let exchange = Exchange::new( + MessageType::Challenge, + self.conversation_id, + self.next_seq_number(), + self.auth_scheme.unwrap(), + exchange_data, + ); + exchange.encode(&mut mech_token)?; + + self.negoex_messages.extend_from_slice(&mech_token); + self.exchange_data.extend_from_slice(&exchange.exchange); + + let response_token = picky_asn1_der::to_vec(&generate_neg_token_targ(mech_token)?)?; + self.gss_api_messages.extend_from_slice(&response_token); + // println!("response_token: {:?}", response_token); + + self.encryption_params.session_key = Some(new_key); + + let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; + output_token.buffer.write_all(&response_token)?; + + self.state = Pku2uState::ApExchange; + + SecurityStatus::ContinueNeeded + } + Pku2uState::ApExchange => { + println!("server: ap exchange: {:?}", input); + // println!("negoexmessages: {:?}", self.negoex_messages); + let mut f = std::fs::File::create("negoex_messages.txt").unwrap(); + f.write_all(format!("{:?}", self.negoex_messages).as_bytes()).unwrap(); + + let mut f = std::fs::File::create("gss_api_messages.txt").unwrap(); + f.write_all(format!("{:?}", self.gss_api_messages).as_bytes()).unwrap(); + + let mut f = std::fs::File::create("exchange_data.txt").unwrap(); + f.write_all(format!("{:?}", self.exchange_data).as_bytes()).unwrap(); + + // let new_key = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; + // println!("checksum: {:?}", ChecksumSuite::HmacSha196Aes256.hasher().checksum(&new_key, 41, &self.gss_api_messages)); + + println!("ap_req: {:?}", input); + + let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; + println!("server: ap_req exchange buffer:: {:?}", input_token); + + // self.gss_api_messages.extend_from_slice(&input_token.buffer); + + let nego_token: NegTokenTarg1 = picky_asn1_der::from_bytes(&input_token.buffer)?; + + let buffer = nego_token.0.response_token.0.unwrap().0.0; + + + let initiator_exchange = Exchange::decode(buffer.as_slice(), &buffer)?; + self.exchange_data.extend_from_slice(&initiator_exchange.exchange); + + self.next_seq_number(); + + let initiator_verify_data = &buffer[(initiator_exchange.header.message_len as usize)..]; + println!("buffer for verify: {:?}", initiator_verify_data); + + let initiator_verify = + Verify::decode(initiator_verify_data, initiator_verify_data)?; + println!("initiator verify: {:?}", initiator_verify); + + self.negoex_messages.extend_from_slice(&buffer[0..(initiator_exchange.header.message_len as usize)]); + + let (ap_req, _): (ApReq, _) = extract_krb_rep(&initiator_exchange.exchange)?; + println!("ap_req: {:?}", ap_req); + let sub_session_key = extract_sub_session_key_from_ap_req(&ap_req, self.encryption_params.session_key.as_ref().unwrap())?; + println!("ap_req authenticator key: {:?}", sub_session_key); + if initiator_verify.checksum.checksum_value != ChecksumSuite::HmacSha196Aes256.hasher().checksum(&sub_session_key, 25, &self.negoex_messages)? { + println!("bad initiator checksum"); + } else { + println!("good initiator checksum"); + } + + self.negoex_messages.extend_from_slice(&buffer[(initiator_exchange.header.message_len as usize)..]); + + self.next_seq_number(); + + let test_sub_session_key = [2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + self.encryption_params.sub_session_key = Some(test_sub_session_key.to_vec()); + println!("ap_rep enc part key: {:?}", test_sub_session_key); + + let ap_rep = generate_ap_rep( + self.encryption_params.session_key.as_ref().unwrap(), + // &sub_session_key, + &test_sub_session_key, + ); + + let mut mech_token = Vec::new(); + + let exchange = Exchange::new( + MessageType::Challenge, + self.conversation_id, + self.next_seq_number(), + self.auth_scheme.unwrap(), + picky_asn1_der::to_vec(&generate_neg(ap_rep, AP_REP_TOKEN_ID))?, + ); + println!("exchange ap_rep: {:?}", exchange); + exchange.encode(&mut mech_token)?; + + exchange.encode(&mut self.negoex_messages)?; + + // println!("negoex messages: {:?}", self.negoex_messages); + + let c2 = ChecksumSuite::HmacSha196Aes256.hasher().checksum( + &test_sub_session_key, + // self.encryption_params.session_key.as_ref().unwrap(), + 23, + &self.negoex_messages, + )?; + + let verify = Verify::new( + MessageType::Verify, + self.conversation_id, + self.next_seq_number(), + self.auth_scheme.unwrap(), + 16, + c2, + ); + verify.encode(&mut mech_token)?; + + verify.encode(&mut self.negoex_messages)?; + + let resp_token = picky_asn1_der::to_vec(&generate_neg_token_completed(mech_token)?)?; + println!("resp_token: {:?}", resp_token); + + let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; + output_token + .buffer + .write_all(&resp_token)?; + + self.state = Pku2uState::PubKeyAuth; + + SecurityStatus::ContinueNeeded + } + state => { + println!("wow, I'm here: {:?}", state); + + SecurityStatus::CompleteNeeded + } + }; + + Ok(AcceptSecurityContextResult { + status, + flags: ServerResponseFlags::empty(), + expiry: None, + }) } } diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index 4016a0cc..fdb21232 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -11,6 +11,123 @@ pub struct Pku2uConfig { pub device_private_key: RsaPrivateKey, } +impl Pku2uConfig { + pub fn default_server_config() -> Self { + Self { + device_private_key: RsaPrivateKey::from_pkcs1_der(&[ + 48, 130, 4, 165, 2, 1, 0, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, + 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, + 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, + 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, + 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, + 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, + 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, + 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, + 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, + 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, + 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, + 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, + 1, 2, 130, 1, 1, 0, 178, 100, 113, 112, 83, 117, 20, 63, 122, 193, 220, 139, 33, 125, 192, 43, 177, 21, + 73, 211, 19, 185, 156, 118, 207, 73, 129, 192, 247, 51, 158, 195, 136, 5, 172, 74, 184, 177, 186, 122, + 237, 139, 78, 252, 182, 87, 192, 192, 77, 118, 229, 137, 49, 38, 209, 247, 17, 157, 81, 12, 230, 106, + 251, 51, 249, 143, 104, 96, 46, 172, 243, 245, 1, 50, 76, 45, 78, 7, 124, 39, 154, 210, 203, 152, 22, + 233, 32, 40, 58, 181, 148, 56, 109, 47, 82, 91, 87, 29, 152, 222, 103, 131, 74, 240, 136, 153, 216, 37, + 69, 139, 116, 176, 2, 68, 83, 195, 189, 56, 108, 213, 40, 14, 135, 90, 152, 90, 78, 38, 229, 107, 54, + 252, 110, 117, 3, 112, 160, 108, 229, 3, 134, 204, 214, 191, 152, 126, 249, 36, 155, 78, 97, 103, 237, + 230, 138, 248, 84, 3, 34, 49, 203, 13, 164, 86, 10, 202, 94, 130, 87, 200, 189, 49, 172, 188, 188, 47, + 235, 200, 96, 125, 17, 109, 170, 32, 215, 71, 8, 96, 245, 83, 239, 39, 109, 70, 187, 58, 121, 243, 179, + 33, 46, 74, 48, 152, 249, 31, 211, 187, 234, 68, 22, 229, 223, 192, 70, 160, 33, 51, 33, 141, 231, 191, + 193, 245, 182, 154, 93, 29, 179, 172, 169, 96, 159, 37, 159, 38, 140, 138, 152, 58, 186, 185, 25, 167, + 44, 165, 186, 154, 216, 239, 40, 255, 73, 166, 213, 161, 2, 129, 129, 0, 206, 19, 212, 71, 145, 69, + 123, 105, 175, 72, 169, 243, 189, 229, 3, 31, 87, 12, 12, 36, 187, 203, 30, 253, 241, 36, 63, 106, 76, + 219, 159, 75, 119, 134, 97, 40, 29, 131, 21, 132, 122, 5, 167, 85, 135, 221, 116, 118, 27, 210, 167, + 98, 157, 232, 42, 248, 159, 82, 155, 166, 95, 216, 236, 85, 231, 201, 90, 175, 220, 38, 197, 150, 54, + 139, 123, 200, 81, 29, 190, 118, 179, 194, 54, 100, 207, 117, 10, 10, 195, 68, 131, 61, 163, 27, 187, + 12, 249, 219, 101, 130, 228, 95, 247, 106, 1, 175, 141, 203, 28, 139, 41, 166, 91, 128, 158, 134, 108, + 11, 136, 45, 6, 171, 236, 237, 15, 150, 117, 95, 2, 129, 129, 0, 247, 129, 4, 52, 135, 135, 143, 100, + 220, 70, 79, 249, 17, 41, 57, 48, 74, 214, 52, 154, 34, 108, 20, 220, 90, 193, 210, 111, 79, 27, 35, + 148, 111, 200, 241, 155, 141, 14, 175, 35, 56, 216, 209, 3, 218, 231, 171, 210, 186, 196, 183, 67, 83, + 186, 32, 149, 178, 235, 111, 76, 134, 61, 39, 80, 49, 105, 3, 109, 229, 69, 156, 191, 182, 230, 148, + 62, 232, 99, 101, 95, 234, 211, 145, 211, 147, 234, 12, 242, 237, 87, 99, 85, 164, 109, 78, 31, 99, + 144, 116, 97, 55, 103, 77, 29, 249, 69, 69, 134, 88, 189, 232, 240, 150, 61, 212, 193, 250, 40, 135, 9, + 234, 22, 119, 138, 223, 174, 157, 203, 2, 129, 128, 124, 53, 109, 116, 121, 118, 4, 173, 173, 141, 193, + 137, 253, 1, 228, 192, 230, 9, 135, 228, 56, 32, 116, 156, 160, 212, 181, 56, 79, 252, 235, 229, 99, + 180, 102, 40, 244, 168, 198, 182, 99, 137, 182, 211, 17, 162, 4, 9, 16, 58, 6, 211, 164, 211, 131, 218, + 248, 196, 164, 182, 65, 253, 16, 109, 178, 216, 37, 69, 236, 14, 158, 119, 44, 135, 35, 227, 152, 40, + 178, 92, 255, 121, 230, 169, 26, 117, 179, 200, 202, 235, 39, 163, 102, 5, 87, 215, 185, 93, 104, 176, + 221, 15, 142, 163, 161, 66, 123, 215, 89, 107, 243, 125, 166, 151, 62, 117, 76, 248, 34, 106, 233, 35, + 133, 25, 89, 148, 217, 71, 2, 129, 129, 0, 136, 161, 197, 131, 134, 42, 20, 195, 246, 66, 46, 149, 237, + 158, 87, 62, 204, 161, 113, 202, 129, 36, 47, 99, 242, 10, 59, 180, 76, 244, 75, 112, 255, 64, 235, + 248, 22, 39, 188, 17, 114, 169, 102, 193, 125, 16, 21, 175, 176, 129, 54, 54, 73, 187, 95, 143, 164, + 133, 10, 29, 49, 162, 2, 216, 231, 93, 244, 145, 175, 86, 253, 144, 108, 84, 224, 19, 214, 80, 64, 191, + 113, 176, 56, 57, 151, 215, 70, 44, 185, 79, 91, 188, 4, 152, 126, 223, 31, 36, 184, 202, 142, 62, 77, + 185, 53, 73, 195, 118, 197, 248, 152, 230, 111, 218, 84, 96, 125, 75, 240, 56, 77, 236, 247, 51, 72, 6, + 106, 127, 2, 129, 129, 0, 149, 64, 160, 185, 80, 7, 183, 188, 145, 39, 11, 48, 140, 239, 229, 100, 176, + 249, 209, 241, 141, 224, 143, 180, 104, 197, 208, 174, 104, 121, 96, 243, 82, 121, 68, 94, 71, 78, 232, + 206, 19, 70, 69, 110, 43, 66, 13, 16, 132, 63, 6, 115, 26, 56, 165, 174, 101, 190, 241, 247, 21, 150, + 21, 96, 129, 114, 137, 162, 153, 128, 80, 140, 190, 170, 49, 14, 215, 134, 38, 81, 184, 113, 249, 230, + 67, 239, 18, 68, 120, 202, 123, 6, 105, 202, 250, 129, 65, 217, 155, 156, 82, 210, 157, 130, 233, 38, + 238, 208, 32, 242, 29, 27, 254, 49, 143, 91, 50, 163, 81, 16, 2, 227, 182, 144, 234, 118, 212, 40, + ]) + .unwrap(), + device_certificate: picky_asn1_der::from_bytes(&[ + 48, 130, 3, 242, 48, 130, 2, 218, 160, 3, 2, 1, 2, 2, 16, 151, 57, 89, 108, 207, 42, 14, 171, 65, 62, + 108, 81, 115, 209, 185, 213, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 120, 49, 118, + 48, 17, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 3, 110, 101, 116, 48, 21, 6, 10, 9, 146, + 38, 137, 147, 242, 44, 100, 1, 25, 22, 7, 119, 105, 110, 100, 111, 119, 115, 48, 29, 6, 3, 85, 4, 3, + 19, 22, 77, 83, 45, 79, 114, 103, 97, 110, 105, 122, 97, 116, 105, 111, 110, 45, 65, 99, 99, 101, 115, + 115, 48, 43, 6, 3, 85, 4, 11, 19, 36, 56, 50, 100, 98, 97, 99, 97, 52, 45, 51, 101, 56, 49, 45, 52, 54, + 99, 97, 45, 57, 99, 55, 51, 45, 48, 57, 53, 48, 99, 49, 101, 97, 99, 97, 57, 55, 48, 30, 23, 13, 50, + 50, 48, 57, 50, 52, 49, 57, 53, 54, 49, 56, 90, 23, 13, 51, 50, 48, 57, 50, 52, 50, 48, 50, 54, 49, 56, + 90, 48, 47, 49, 45, 48, 43, 6, 3, 85, 4, 3, 19, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, + 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, + 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, + 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, + 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, + 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, + 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, + 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, + 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, + 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, + 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, + 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, + 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, + 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, + 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 129, 192, 48, 129, 189, + 48, 12, 6, 3, 85, 29, 19, 1, 1, 255, 4, 2, 48, 0, 48, 22, 6, 3, 85, 29, 37, 1, 1, 255, 4, 12, 48, 10, + 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 34, 6, 11, 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 2, 4, 19, 4, + 129, 16, 221, 203, 182, 201, 240, 211, 195, 74, 152, 121, 224, 174, 59, 97, 189, 148, 48, 34, 6, 11, + 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 3, 4, 19, 4, 129, 16, 69, 148, 59, 128, 155, 126, 130, 76, + 147, 242, 220, 233, 157, 233, 149, 191, 48, 34, 6, 11, 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 5, 4, + 19, 4, 129, 16, 72, 36, 37, 169, 183, 154, 176, 73, 187, 92, 242, 249, 35, 200, 70, 114, 48, 20, 6, 11, + 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 8, 4, 5, 4, 129, 2, 69, 85, 48, 19, 6, 11, 42, 134, 72, 134, + 247, 20, 1, 5, 130, 28, 7, 4, 4, 4, 129, 1, 49, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, + 0, 3, 130, 1, 1, 0, 67, 13, 108, 42, 1, 160, 165, 193, 26, 122, 235, 13, 116, 210, 230, 62, 133, 236, + 164, 204, 73, 214, 202, 141, 168, 17, 115, 121, 37, 179, 151, 87, 25, 75, 141, 49, 31, 202, 184, 84, + 89, 106, 122, 240, 137, 27, 17, 166, 19, 244, 186, 168, 110, 139, 45, 63, 131, 123, 248, 102, 32, 163, + 224, 224, 127, 189, 76, 54, 43, 0, 73, 79, 101, 144, 137, 155, 95, 33, 126, 119, 97, 164, 158, 3, 208, + 4, 241, 50, 251, 83, 10, 49, 42, 3, 95, 24, 35, 28, 251, 74, 244, 187, 247, 97, 188, 64, 82, 234, 157, + 207, 109, 184, 138, 218, 178, 86, 155, 223, 48, 6, 36, 71, 171, 113, 65, 64, 69, 54, 155, 146, 88, 2, + 54, 122, 213, 131, 176, 27, 195, 135, 143, 23, 170, 79, 226, 29, 87, 62, 72, 224, 53, 153, 83, 60, 159, + 56, 185, 255, 247, 69, 153, 177, 93, 233, 242, 168, 65, 191, 1, 204, 93, 72, 103, 91, 231, 38, 149, + 115, 221, 194, 167, 130, 134, 68, 82, 202, 255, 133, 220, 45, 19, 171, 103, 87, 127, 144, 94, 156, 71, + 246, 138, 18, 158, 238, 46, 191, 207, 212, 114, 117, 207, 170, 231, 110, 83, 146, 238, 199, 244, 226, + 209, 172, 245, 134, 211, 166, 151, 128, 64, 18, 2, 67, 104, 142, 206, 111, 151, 80, 100, 232, 49, 204, + 76, 204, 105, 136, 207, 36, 135, 236, 178, 239, 209, 196, 34, 246, + ]) + .unwrap(), + p2p_certificate: picky_asn1_der::from_bytes(&[ + 48, 130, 3, 154, 48, 130, 2, 130, 160, 3, 2, 1, 2, 2, 16, 60, 109, 248, 96, 153, 84, 93, 167, 227, 157, 154, 24, 242, 1, 254, 35, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 51, 49, 53, 51, 52, 51, 55, 90, 23, 13, 50, 50, 49, 48, 50, 52, 49, 53, 51, 57, 51, 55, 90, 48, 101, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 45, 48, 43, 6, 3, 85, 4, 3, 12, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 94, 48, 92, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 24, 6, 3, 85, 29, 17, 4, 17, 48, 15, 130, 13, 49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 57, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 175, 83, 189, 222, 20, 148, 46, 36, 168, 75, 200, 211, 109, 120, 6, 149, 61, 74, 49, 198, 33, 86, 3, 11, 136, 226, 121, 180, 159, 141, 98, 194, 235, 199, 249, 60, 107, 8, 47, 104, 56, 133, 210, 193, 127, 70, 248, 207, 56, 63, 37, 12, 169, 64, 36, 7, 227, 231, 226, 70, 157, 70, 65, 171, 182, 109, 170, 128, 30, 212, 44, 177, 225, 37, 73, 152, 196, 105, 162, 8, 251, 77, 23, 244, 14, 202, 90, 248, 178, 144, 236, 4, 120, 181, 168, 105, 117, 229, 48, 245, 36, 17, 235, 172, 221, 140, 125, 39, 241, 97, 235, 195, 98, 109, 40, 12, 72, 113, 95, 40, 188, 98, 160, 57, 222, 79, 102, 168, 85, 98, 124, 73, 57, 98, 77, 241, 142, 11, 69, 230, 15, 122, 119, 140, 200, 183, 130, 42, 55, 231, 119, 199, 213, 235, 133, 107, 125, 28, 54, 102, 173, 132, 176, 218, 90, 174, 195, 255, 70, 179, 87, 119, 102, 233, 209, 27, 230, 182, 112, 70, 184, 243, 64, 186, 168, 246, 106, 95, 50, 193, 253, 55, 83, 241, 244, 157, 252, 224, 251, 253, 131, 17, 224, 200, 39, 174, 206, 231, 64, 144, 24, 198, 75, 192, 171, 128, 135, 100, 102, 253, 13, 56, 28, 197, 255, 13, 16, 233, 136, 40, 131, 53, 73, 211, 217, 48, 103, 242, 65, 20, 173, 214, 133, 233, 214, 194, 209, 44, 239, 231, 37, 245, 138, 44, 108, 83 + ]) + .unwrap(), + p2p_ca_certificate: picky_asn1_der::from_bytes(&[ + 48, 130, 3, 69, 48, 130, 2, 45, 160, 3, 2, 1, 2, 2, 16, 22, 50, 104, 218, 241, 214, 154, 131, 67, 50, 108, 181, 181, 208, 215, 142, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 48, 56, 48, 56, 48, 48, 48, 48, 48, 48, 90, 23, 13, 50, 51, 48, 56, 48, 56, 48, 48, 48, 48, 48, 48, 90, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 203, 229, 194, 53, 177, 190, 106, 224, 204, 234, 120, 252, 197, 60, 153, 3, 249, 198, 72, 46, 29, 126, 165, 180, 235, 139, 6, 210, 99, 186, 112, 60, 215, 68, 17, 84, 58, 103, 86, 129, 113, 213, 113, 97, 65, 215, 97, 126, 222, 16, 59, 165, 192, 127, 180, 9, 3, 75, 195, 228, 71, 182, 182, 163, 32, 17, 4, 127, 121, 245, 14, 1, 207, 158, 142, 120, 172, 22, 130, 43, 168, 198, 120, 58, 60, 73, 211, 52, 220, 30, 135, 204, 89, 199, 217, 159, 51, 13, 182, 40, 131, 141, 163, 180, 204, 139, 176, 104, 40, 233, 225, 169, 46, 146, 246, 144, 113, 211, 192, 249, 228, 169, 197, 74, 79, 156, 195, 161, 218, 165, 30, 238, 130, 151, 182, 82, 96, 153, 73, 49, 93, 39, 169, 139, 8, 18, 135, 4, 137, 220, 55, 64, 28, 15, 51, 113, 27, 217, 149, 8, 83, 230, 139, 131, 174, 6, 26, 128, 159, 161, 113, 103, 161, 122, 140, 85, 28, 166, 100, 188, 140, 93, 150, 131, 125, 62, 9, 222, 145, 80, 151, 199, 250, 202, 235, 106, 152, 27, 186, 143, 181, 195, 196, 128, 4, 106, 105, 12, 196, 61, 69, 90, 39, 14, 87, 3, 153, 48, 175, 65, 97, 50, 224, 105, 117, 198, 107, 9, 113, 240, 215, 255, 255, 116, 33, 9, 160, 131, 74, 88, 150, 15, 14, 206, 120, 227, 65, 167, 80, 104, 117, 108, 166, 169, 169, 145, 2, 3, 1, 0, 1, 163, 33, 48, 31, 48, 29, 6, 3, 85, 29, 14, 4, 22, 4, 20, 17, 90, 232, 137, 164, 206, 188, 19, 145, 103, 141, 13, 108, 109, 74, 100, 161, 175, 68, 37, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 88, 161, 67, 230, 91, 182, 227, 143, 148, 61, 244, 147, 62, 149, 14, 105, 227, 243, 179, 74, 31, 184, 56, 195, 133, 140, 235, 199, 215, 77, 62, 35, 148, 213, 35, 138, 126, 108, 13, 95, 61, 170, 129, 230, 150, 106, 8, 28, 219, 252, 196, 134, 152, 9, 229, 46, 249, 247, 113, 193, 28, 212, 252, 45, 178, 145, 155, 9, 83, 247, 238, 42, 59, 191, 1, 220, 155, 13, 210, 18, 179, 168, 40, 87, 87, 202, 220, 205, 46, 43, 23, 41, 102, 161, 66, 72, 165, 83, 107, 138, 159, 130, 28, 60, 143, 225, 85, 114, 158, 41, 101, 118, 229, 88, 17, 0, 237, 229, 185, 36, 6, 139, 208, 142, 137, 229, 88, 250, 190, 156, 204, 89, 207, 235, 239, 151, 185, 134, 9, 38, 30, 55, 97, 97, 194, 37, 22, 59, 128, 26, 14, 253, 13, 25, 40, 209, 221, 130, 117, 154, 151, 153, 107, 219, 141, 195, 250, 114, 175, 152, 133, 214, 13, 1, 126, 57, 148, 32, 56, 2, 6, 154, 31, 221, 145, 8, 196, 83, 36, 204, 56, 102, 177, 194, 14, 58, 212, 209, 40, 245, 124, 31, 99, 15, 247, 78, 219, 161, 121, 245, 160, 215, 137, 133, 190, 214, 122, 129, 26, 91, 104, 176, 98, 191, 46, 17, 231, 252, 217, 255, 13, 20, 171, 195, 33, 89, 235, 218, 120, 92, 124, 36, 168, 163, 254, 219, 23, 104, 111, 44, 69, 240, 227, 125, 168, 185 + ]) + .unwrap(), + } + } +} + #[cfg(windows)] impl Default for Pku2uConfig { fn default() -> Self { @@ -118,7 +235,7 @@ impl Default for Pku2uConfig { ]) .unwrap(), p2p_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 81, 76, 18, 240, 204, 162, 54, 186, 109, 8, 20, 195, 34, 154, 97, 251, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 48, 53, 48, 57, 50, 49, 52, 52, 90, 23, 13, 50, 50, 49, 48, 48, 53, 49, 48, 50, 54, 52, 52, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 61, 214, 255, 95, 227, 238, 112, 81, 189, 103, 123, 34, 104, 181, 4, 62, 65, 5, 49, 157, 227, 48, 164, 123, 86, 226, 13, 0, 189, 225, 185, 173, 212, 105, 81, 155, 16, 225, 160, 87, 242, 120, 130, 178, 19, 242, 28, 239, 204, 164, 222, 58, 222, 72, 145, 188, 17, 151, 159, 246, 128, 27, 11, 244, 119, 187, 129, 197, 242, 140, 39, 88, 27, 42, 21, 78, 93, 183, 99, 160, 128, 211, 116, 180, 93, 162, 135, 143, 182, 213, 211, 195, 141, 90, 78, 232, 55, 42, 47, 37, 197, 247, 42, 108, 240, 85, 37, 170, 72, 123, 185, 245, 173, 104, 219, 59, 11, 95, 135, 113, 188, 109, 19, 202, 163, 167, 77, 68, 211, 81, 232, 2, 220, 153, 113, 54, 220, 125, 27, 125, 0, 153, 19, 4, 68, 246, 123, 108, 139, 116, 33, 135, 245, 86, 34, 86, 54, 117, 225, 231, 93, 30, 127, 59, 7, 80, 25, 82, 180, 122, 48, 164, 32, 45, 70, 194, 89, 72, 203, 125, 27, 38, 254, 14, 150, 183, 149, 183, 85, 11, 164, 223, 212, 139, 131, 202, 5, 102, 82, 94, 73, 205, 75, 99, 20, 47, 219, 36, 168, 245, 172, 157, 24, 51, 1, 32, 15, 234, 159, 205, 240, 145, 117, 86, 74, 81, 214, 59, 71, 144, 0, 120, 171, 28, 120, 108, 136, 250, 113, 96, 46, 130, 141, 174, 226, 52, 113, 166, 51, 173, 86, 174, 50, 88, 212, 19 + 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 79, 38, 21, 44, 164, 255, 156, 167, 130, 123, 29, 28, 60, 212, 242, 124, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 51, 50, 49, 52, 48, 53, 57, 90, 23, 13, 50, 50, 49, 48, 50, 51, 50, 50, 52, 53, 53, 57, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 62, 48, 214, 170, 131, 166, 29, 214, 158, 53, 168, 108, 74, 143, 55, 188, 93, 63, 132, 103, 117, 132, 69, 132, 238, 40, 254, 48, 126, 93, 190, 96, 2, 79, 83, 248, 249, 79, 41, 230, 97, 115, 39, 90, 145, 222, 19, 31, 8, 57, 166, 113, 251, 166, 225, 24, 23, 14, 111, 57, 19, 97, 96, 251, 109, 46, 38, 181, 19, 6, 187, 27, 224, 58, 199, 116, 169, 123, 172, 63, 199, 92, 3, 174, 79, 232, 55, 207, 41, 200, 232, 51, 158, 250, 57, 199, 200, 164, 8, 143, 83, 77, 204, 217, 37, 230, 81, 227, 242, 117, 18, 153, 230, 208, 14, 179, 72, 79, 71, 52, 203, 22, 90, 193, 45, 70, 152, 29, 182, 9, 18, 45, 149, 223, 42, 207, 0, 79, 49, 143, 91, 178, 67, 86, 136, 114, 200, 104, 15, 131, 111, 211, 0, 2, 126, 27, 124, 218, 73, 77, 39, 107, 156, 82, 127, 208, 188, 234, 230, 23, 143, 106, 129, 106, 115, 116, 115, 113, 212, 132, 167, 166, 1, 227, 114, 245, 70, 229, 209, 7, 223, 144, 146, 85, 221, 9, 35, 43, 118, 225, 113, 54, 174, 26, 166, 45, 253, 97, 7, 54, 151, 35, 116, 190, 41, 218, 74, 248, 10, 113, 2, 155, 68, 138, 217, 41, 56, 28, 85, 121, 33, 189, 9, 34, 158, 234, 99, 72, 236, 105, 39, 110, 205, 48, 54, 8, 101, 90, 168, 17, 238, 96, 114, 27, 218, 134 ]) .unwrap(), p2p_ca_certificate: picky_asn1_der::from_bytes(&[ @@ -289,6 +406,26 @@ xrG+r67m+4UEewwfRSQ0Wb6RmjlYtCy5nQIDAQAB let key = cipher.generate_key_from_password(password.as_bytes(), salt.as_bytes()).unwrap(); - println!("{:?}", cipher.decrypt(&key, 2, &data)); + println!("{:?}", cipher.decrypt(&key, 3, &data)); + } + + #[test] + fn hack2() { + let key = [243, 146, 221, 113, 157, 22, 182, 28, 221, 20, 131, 150, 229, 209, 204, 208, 85, 238, 136, 165, 130, 18, 183, 62, 218, 183, 253, 172, 194, 167, 105, 191]; + let data = [154, 190, 201, 145, 114, 166, 106, 59, 246, 162, 223, 92, 177, 85, 120, 189, 61, 214, 210, 229, 235, 18, 41, 152, 183, 186, 234, 35, 83, 163, 18, 34, 75, 253, 225, 22, 216, 14, 222, 60, 18, 55, 64, 223, 37, 202, 141, 107, 242, 41, 249, 148, 75, 133, 163, 64, 49, 161, 133, 42, 160, 115, 36, 119, 193, 49, 192, 234, 209, 168, 6, 208, 215, 145, 86, 154, 62, 108, 38, 184, 198, 82, 81, 249, 106, 231, 213, 147, 68, 3, 2, 224, 26, 163, 217, 76, 221, 224, 62, 111, 216, 251, 80, 41, 194, 239, 103, 81, 64, 190, 152, 135, 162, 68, 175, 61, 39, 14, 84, 151, 141, 66, 0, 209, 73, 48, 164, 175, 102, 30, 140, 77, 184, 50, 151, 99, 231, 22, 207, 129, 97, 152, 20, 174, 136, 104, 250, 57, 54, 203, 135, 32, 79, 31, 114, 94, 49, 208, 132, 208, 79, 242, 56, 191, 180, 222, 155, 182, 19, 12, 15, 122, 213, 235, 231, 184, 148, 32, 73, 112, 67, 253, 163, 207, 67, 223, 13, 89, 120, 53, 175, 90, 190, 212, 128, 53, 238, 146, 126, 37, 71, 246, 201, 189, 95, 55, 175, 100, 166, 29, 193, 72, 92, 2, 150, 210, 191, 196, 196, 4, 113, 66, 123, 123, 111, 9, 83, 19, 20, 111, 39, 47, 244, 44, 52, 189, 98, 207, 14, 104, 104, 74, 169, 17, 213, 86, 158, 0, 15, 117, 194, 29, 241, 168, 0, 12, 245, 190, 143, 243, 14, 54, 30, 52, 228, 64, 61, 202, 161, 62, 39, 91, 46, 5, 110, 111, 153, 133, 78]; + + let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); + + println!("{:?}", cipher.decrypt(&key, 8, &data)); + } + + #[test] + fn hack3() { + let key = [177, 74, 125, 22, 44, 74, 5, 160, 161, 2, 173, 142, 149, 153, 114, 160, 177, 126, 138, 193, 79, 214, 194, 46, 103, 138, 164, 20, 120, 144, 72, 242]; + let data = [206, 126, 45, 212, 242, 154, 98, 34, 26, 54, 32, 44, 191, 203, 59, 246, 211, 161, 19, 244, 6, 255, 206, 135, 120, 251, 94, 221, 129, 4, 203, 224, 174, 49, 218, 69, 200, 39, 118, 147, 29, 69, 147, 223, 137, 8, 44, 208, 85, 120, 230, 136, 40, 223, 38, 51, 70, 185, 222, 109, 212, 63, 109, 45, 146, 107, 118, 64, 178, 254, 37, 237, 54, 152, 164, 228, 89, 80, 154, 131, 1, 100, 103, 164, 101, 6, 253, 49, 176, 160, 87, 35, 38, 201, 37, 37, 137, 162, 9, 136, 121, 233, 70, 72, 206, 201, 226, 235, 25, 93, 177, 57, 236, 173, 136, 8, 74, 47, 44, 11, 163, 88, 59, 51, 178, 205, 107, 101, 147, 8, 218, 30, 136, 84, 69, 102, 32, 12, 195, 216, 32, 93, 115, 10, 69, 142, 45, 0, 49, 113, 251, 143, 88, 212, 34, 69, 88, 181, 87, 124, 73, 105, 90, 98, 149, 205, 82, 124, 101, 244, 176, 7, 59, 167, 77, 207, 60, 214, 58, 179, 108, 110, 206, 221, 196, 138, 236, 110, 127, 169, 111, 182, 243, 7, 215, 74, 1, 52, 27, 231, 67, 151, 95, 146, 90, 62, 215, 130, 47, 146, 88, 237, 186, 104, 188, 81, 85, 89, 196, 22, 188, 200, 250, 206, 149, 207, 49, 86, 99, 9, 79, 25, 61, 11, 140, 246, 226, 123, 246, 9, 235, 22, 110, 15, 156, 184, 226, 45, 57, 153, 46, 137, 157, 3, 38, 61, 22, 81, 184, 150, 192, 109, 246, 62, 21, 60, 198, 199, 245, 201, 165, 159, 209, 161, 171, 247, 22, 37, 95, 140, 23, 9, 136, 39, 5, 122, 164, 95, 205, 7, 8, 183, 204, 39, 224, 141, 74, 178, 145, 140, 119, 174]; + + let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); + + println!("{:?}", cipher.decrypt(&key, 11, &data)); } } diff --git a/src/sspi/pku2u/extractors.rs b/src/sspi/pku2u/extractors.rs index 11a1832c..09bfb3d7 100644 --- a/src/sspi/pku2u/extractors.rs +++ b/src/sspi/pku2u/extractors.rs @@ -7,10 +7,14 @@ use picky_asn1_der::Asn1RawDer; use picky_asn1_x509::content_info::ContentValue; use picky_asn1_x509::oids::PKINIT_DH_KEY_DATA; use picky_asn1_x509::signed_data::SignedData; -use picky_krb::constants::key_usages::AS_REP_ENC; -use picky_krb::constants::types::PA_PK_AS_REP; -use picky_krb::messages::{AsRep, EncAsRepPart}; -use picky_krb::pkinit::{DhRepInfo, KdcDhKeyInfo, PaPkAsRep}; +use picky_krb::constants::key_usages::{AS_REP_ENC, AP_REQ_AUTHENTICATOR}; +use picky_krb::constants::types::{PA_PK_AS_REP, PA_PK_AS_REQ}; +use picky_krb::crypto::CipherSuite; +use picky_krb::crypto::diffie_hellman::{generate_key, generate_private_key, DhNonce, compute_public_key}; +use picky_krb::data_types::Authenticator; +use picky_krb::messages::{AsRep, EncAsRepPart, AsReq, ApReq}; +use picky_krb::pkinit::{DhRepInfo, KdcDhKeyInfo, PaPkAsRep, PaPkAsReq, AuthPack}; +use rand::rngs::OsRng; use serde::Deserialize; use super::generators::DH_NONCE_LEN; @@ -129,15 +133,92 @@ pub fn extract_session_key_from_as_rep(as_rep: &AsRep, key: &[u8], enc_params: & println!("as rep decrypted!"); let enc_as_rep_part: EncAsRepPart = picky_asn1_der::from_bytes(&enc_data)?; + println!("{:?}", enc_as_rep_part); Ok(enc_as_rep_part.0.key.0.key_value.0.to_vec()) } +pub fn extract_pa_pk_as_req(as_req: &AsReq) -> Result { + Ok(picky_asn1_der::from_bytes( + &as_req + .0 + .padata + .0 + .as_ref() + .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "pa-datas is not present in as rep".into()))? + .iter() + .find(|pa_data| &pa_data.padata_type.0 .0 == &PA_PK_AS_REQ) + .ok_or_else(|| { + Error::new( + ErrorKind::InvalidToken, + "PA_PK_AS_REP is not present in pa-datas of the as rep".into(), + ) + })? + .padata_data + .0 + .0, + )?) +} + +pub fn compute_session_key_from_pa_pk_as_req(pa_pk_as_req: &PaPkAsReq, dh_server_nonce: &[u8]) -> Result<(Vec, Vec)> { + let signed_data: SignedData = picky_asn1_der::from_bytes(&pa_pk_as_req.signed_auth_pack.0)?; + let content = signed_data.content_info.content.unwrap().0; + let auth_pack: AuthPack = picky_asn1_der::from_bytes(match &content { + ContentValue::OctetString(data) => &data.0, + c => unimplemented!("wrong content value: {:?}", c), + })?; + + println!("server: auth pack decoded: {:?}", auth_pack); + + let dh_client_public_info = &auth_pack.client_public_value.0.as_ref().unwrap().0; + + println!("dh_client_public_info: {:?}", dh_client_public_info); + + let g = dh_client_public_info.key_info.key_info.g.0.clone(); + let p = dh_client_public_info.key_info.key_info.p.0.clone(); + let q = dh_client_public_info.key_info.key_info.q.0.clone(); + + println!("try to parse client public: {:?}", dh_client_public_info.key_value.0.inner()); + println!("to decode as int: {:?}", &dh_client_public_info.key_value.0.inner()[1..]); + let dh_client_public: IntegerAsn1 = picky_asn1_der::from_bytes(&dh_client_public_info.key_value.0.inner()[1..])?; + println!("client public parsed"); + let dh_client_public = dh_client_public.0; + + let mut rng = OsRng::default(); + let dh_server_private = generate_private_key(&q, &mut rng); + let dh_server_public = compute_public_key(&dh_server_private, &p, &g); + + let dh_client_nonce = auth_pack.client_dh_nonce.0.as_ref().unwrap().0.0.clone(); + + let session_key = generate_key( + &dh_client_public, + &dh_server_private, + &p, + Some(DhNonce { + client_nonce: &dh_client_nonce, + server_nonce: dh_server_nonce, + }), + CipherSuite::Aes256CtsHmacSha196.cipher().as_ref() + )?; + + Ok((session_key, dh_server_public)) +} + +pub fn extract_sub_session_key_from_ap_req(ap_req: &ApReq, session_key: &[u8]) -> Result> { + let encrypted = &ap_req.0.authenticator.0.cipher.0.0; + let decrypted = CipherSuite::Aes256CtsHmacSha196.cipher().decrypt(session_key, AP_REQ_AUTHENTICATOR, encrypted)?; + println!("sub decrypted"); + let auth: Authenticator = picky_asn1_der::from_bytes(&decrypted)?; + println!("sub parsed"); + Ok(auth.0.subkey.0.unwrap().0.key_value.0.0) +} + #[cfg(test)] mod tests { - use picky_krb::{messages::AsRep, crypto::{CipherSuite, diffie_hellman::{generate_key, DhNonce}}}; + use picky_asn1_der::application_tag::ApplicationTag; + use picky_krb::{messages::{AsRep, AsReq}, crypto::{CipherSuite, diffie_hellman::{generate_key, DhNonce}, ChecksumSuite}, gss_api::KrbMessage, constants::key_usages::AP_REQ_AUTHENTICATOR}; - use crate::kerberos::EncryptionParams; + use crate::{kerberos::EncryptionParams, crypto::compute_sha256, internal::credssp::{SERVER_CLIENT_HASH_MAGIC, CLIENT_SERVER_HASH_MAGIC}}; use super::{extract_krb_rep, extract_session_key_from_as_rep}; @@ -168,4 +249,185 @@ mod tests { println!("{:?}", extract_session_key_from_as_rep(&as_rep, &key, &enc_params).unwrap()); } + + #[test] + fn parse_as_req() { + let data = [96, 130, 9, 48, 6, 6, 43, 6, 1, 5, 2, 7, 5, 0, 106, 130, 9, 34, 48, 130, 9, 30, 161, 3, 2, 1, 5, 162, 3, 2, 1, 10, 163, 130, 7, 252, 48, 130, 7, 248, 48, 130, 7, 244, 161, 3, 2, 1, 16, 162, 130, 7, 235, 4, 130, 7, 231, 48, 130, 7, 227, 128, 130, 7, 223, 48, 130, 7, 219, 2, 1, 3, 49, 11, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 48, 130, 2, 31, 6, 7, 43, 6, 1, 5, 2, 3, 1, 160, 130, 2, 18, 4, 130, 2, 14, 48, 130, 2, 10, 160, 57, 48, 55, 160, 5, 2, 3, 11, 210, 255, 161, 17, 24, 15, 50, 48, 50, 50, 48, 57, 50, 53, 50, 49, 49, 48, 48, 51, 90, 162, 3, 2, 1, 0, 163, 22, 4, 20, 214, 215, 210, 143, 189, 21, 220, 123, 16, 202, 62, 239, 143, 239, 72, 75, 129, 19, 192, 25, 161, 130, 1, 167, 48, 130, 1, 163, 48, 130, 1, 23, 6, 7, 42, 134, 72, 206, 62, 2, 1, 48, 130, 1, 10, 2, 129, 129, 0, 255, 255, 255, 255, 255, 255, 255, 255, 201, 15, 218, 162, 33, 104, 194, 52, 196, 198, 98, 139, 128, 220, 28, 209, 41, 2, 78, 8, 138, 103, 204, 116, 2, 11, 190, 166, 59, 19, 155, 34, 81, 74, 8, 121, 142, 52, 4, 221, 239, 149, 25, 179, 205, 58, 67, 27, 48, 43, 10, 109, 242, 95, 20, 55, 79, 225, 53, 109, 109, 81, 194, 69, 228, 133, 181, 118, 98, 94, 126, 198, 244, 76, 66, 233, 166, 55, 237, 107, 11, 255, 92, 182, 244, 6, 183, 237, 238, 56, 107, 251, 90, 137, 159, 165, 174, 159, 36, 17, 124, 75, 31, 230, 73, 40, 102, 81, 236, 230, 83, 129, 255, 255, 255, 255, 255, 255, 255, 255, 2, 1, 2, 2, 129, 128, 127, 255, 255, 255, 255, 255, 255, 255, 228, 135, 237, 81, 16, 180, 97, 26, 98, 99, 49, 69, 192, 110, 14, 104, 148, 129, 39, 4, 69, 51, 230, 58, 1, 5, 223, 83, 29, 137, 205, 145, 40, 165, 4, 60, 199, 26, 2, 110, 247, 202, 140, 217, 230, 157, 33, 141, 152, 21, 133, 54, 249, 47, 138, 27, 167, 240, 154, 182, 182, 168, 225, 34, 242, 66, 218, 187, 49, 47, 63, 99, 122, 38, 33, 116, 211, 27, 246, 181, 133, 255, 174, 91, 122, 3, 91, 246, 247, 28, 53, 253, 173, 68, 207, 210, 215, 79, 146, 8, 190, 37, 143, 243, 36, 148, 51, 40, 246, 115, 41, 192, 255, 255, 255, 255, 255, 255, 255, 255, 3, 129, 133, 0, 2, 129, 129, 0, 174, 64, 94, 199, 223, 241, 193, 152, 170, 68, 51, 76, 187, 174, 45, 73, 174, 189, 141, 45, 159, 152, 150, 206, 86, 139, 103, 220, 243, 88, 58, 18, 39, 91, 132, 169, 6, 194, 189, 101, 247, 71, 111, 4, 77, 136, 201, 61, 155, 194, 35, 162, 225, 107, 106, 107, 160, 103, 98, 48, 53, 47, 142, 6, 99, 25, 254, 47, 138, 206, 41, 37, 50, 7, 66, 244, 32, 231, 48, 233, 191, 127, 24, 14, 69, 218, 122, 155, 198, 66, 36, 234, 17, 57, 126, 117, 21, 203, 79, 251, 106, 218, 219, 248, 82, 147, 67, 118, 62, 170, 57, 210, 192, 15, 130, 254, 215, 164, 217, 186, 201, 99, 57, 191, 83, 133, 228, 135, 163, 34, 4, 32, 100, 207, 181, 107, 37, 161, 148, 45, 31, 19, 94, 23, 68, 103, 195, 118, 102, 234, 135, 247, 24, 237, 176, 201, 12, 149, 232, 200, 131, 26, 226, 145, 160, 130, 3, 217, 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 2, 123, 121, 8, 93, 157, 174, 124, 206, 149, 168, 96, 188, 78, 65, 73, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 48, 57, 50, 53, 50, 49, 48, 53, 48, 51, 90, 23, 13, 50, 50, 48, 57, 50, 53, 50, 50, 49, 48, 48, 51, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 165, 92, 124, 98, 210, 233, 204, 81, 70, 152, 57, 161, 35, 215, 249, 36, 245, 49, 214, 193, 30, 235, 18, 102, 223, 212, 48, 82, 227, 153, 96, 161, 219, 73, 36, 75, 197, 84, 97, 23, 46, 238, 74, 118, 18, 246, 7, 39, 211, 182, 251, 144, 154, 34, 140, 36, 152, 155, 226, 73, 177, 70, 165, 25, 253, 246, 82, 85, 40, 54, 154, 69, 198, 120, 95, 222, 21, 85, 143, 126, 158, 14, 40, 205, 67, 243, 211, 168, 228, 0, 97, 18, 87, 253, 219, 32, 33, 229, 212, 91, 186, 233, 11, 2, 97, 73, 20, 160, 30, 17, 40, 198, 215, 204, 238, 73, 89, 139, 51, 104, 102, 116, 167, 37, 149, 28, 238, 191, 5, 43, 84, 126, 232, 200, 123, 89, 103, 14, 174, 70, 239, 220, 245, 123, 140, 61, 232, 195, 199, 35, 111, 205, 135, 171, 5, 177, 72, 42, 110, 158, 29, 124, 202, 19, 216, 138, 219, 138, 25, 23, 198, 160, 217, 202, 198, 202, 56, 14, 226, 161, 40, 127, 171, 71, 17, 175, 119, 233, 168, 82, 108, 246, 13, 99, 42, 23, 149, 58, 133, 216, 183, 200, 17, 6, 134, 74, 133, 3, 87, 41, 32, 107, 93, 5, 236, 3, 88, 205, 143, 98, 92, 183, 123, 133, 71, 212, 21, 30, 170, 7, 234, 198, 177, 190, 175, 174, 230, 251, 133, 4, 123, 12, 31, 69, 36, 52, 89, 190, 145, 154, 57, 88, 180, 44, 185, 157, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 31, 128, 225, 83, 187, 164, 76, 137, 246, 121, 91, 174, 72, 27, 173, 155, 58, 241, 57, 126, 140, 204, 205, 87, 3, 1, 30, 40, 235, 137, 47, 62, 201, 134, 157, 209, 89, 17, 140, 131, 88, 222, 173, 48, 242, 196, 105, 87, 100, 2, 218, 70, 239, 199, 176, 123, 233, 245, 75, 226, 58, 66, 85, 235, 41, 187, 135, 253, 189, 111, 164, 94, 89, 39, 200, 50, 154, 201, 165, 200, 73, 195, 115, 122, 112, 169, 18, 118, 5, 66, 231, 9, 183, 240, 76, 17, 82, 127, 200, 66, 78, 186, 69, 78, 20, 60, 191, 228, 101, 14, 33, 153, 250, 46, 27, 203, 23, 188, 202, 111, 164, 122, 50, 42, 188, 187, 13, 32, 182, 9, 175, 13, 62, 60, 18, 96, 29, 50, 15, 235, 159, 254, 48, 164, 92, 98, 93, 97, 191, 63, 250, 14, 144, 210, 176, 58, 233, 186, 238, 82, 92, 45, 103, 189, 103, 19, 13, 115, 49, 215, 119, 55, 220, 104, 245, 107, 48, 78, 133, 106, 101, 151, 150, 107, 16, 247, 137, 193, 35, 144, 195, 229, 209, 136, 108, 18, 40, 197, 61, 152, 57, 97, 83, 231, 1, 252, 205, 242, 149, 100, 128, 224, 122, 251, 87, 81, 185, 99, 83, 232, 201, 122, 113, 153, 126, 108, 156, 64, 37, 230, 139, 235, 139, 14, 252, 42, 10, 20, 34, 184, 20, 75, 33, 31, 52, 0, 224, 64, 219, 167, 7, 172, 35, 103, 186, 184, 49, 130, 1, 199, 48, 130, 1, 195, 2, 1, 1, 48, 97, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 2, 16, 2, 123, 121, 8, 93, 157, 174, 124, 206, 149, 168, 96, 188, 78, 65, 73, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 160, 61, 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 37, 144, 68, 78, 210, 60, 230, 236, 125, 249, 8, 246, 201, 77, 20, 197, 108, 52, 75, 76, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 1, 0, 48, 127, 17, 243, 30, 27, 158, 81, 187, 246, 135, 199, 188, 180, 74, 19, 19, 201, 95, 142, 99, 234, 136, 80, 71, 222, 71, 215, 251, 157, 78, 191, 97, 63, 240, 189, 68, 54, 186, 182, 87, 106, 249, 127, 176, 220, 207, 191, 214, 158, 155, 182, 28, 230, 57, 172, 76, 203, 134, 248, 43, 70, 114, 183, 5, 111, 137, 6, 208, 219, 139, 231, 164, 164, 206, 166, 69, 159, 70, 144, 168, 44, 139, 138, 8, 84, 2, 224, 192, 54, 238, 88, 174, 197, 135, 69, 235, 159, 72, 206, 13, 214, 121, 180, 203, 152, 186, 70, 167, 45, 127, 37, 89, 238, 118, 130, 56, 90, 54, 221, 72, 84, 48, 86, 58, 24, 242, 88, 78, 59, 8, 65, 27, 141, 157, 19, 59, 50, 155, 36, 68, 48, 119, 77, 36, 137, 128, 47, 129, 216, 235, 94, 253, 236, 181, 249, 254, 116, 123, 84, 211, 146, 251, 142, 134, 246, 128, 251, 173, 72, 204, 160, 42, 121, 78, 242, 27, 243, 168, 136, 42, 13, 162, 141, 139, 84, 151, 156, 215, 141, 110, 39, 236, 155, 76, 115, 224, 254, 180, 69, 238, 134, 73, 101, 155, 194, 202, 63, 22, 97, 6, 166, 14, 76, 191, 231, 247, 230, 12, 169, 228, 9, 88, 32, 251, 241, 138, 8, 146, 20, 252, 27, 82, 204, 112, 98, 110, 168, 240, 76, 96, 38, 73, 88, 251, 202, 75, 147, 96, 223, 110, 226, 48, 136, 51, 238, 164, 130, 1, 16, 48, 130, 1, 12, 160, 7, 3, 5, 0, 64, 129, 0, 16, 161, 107, 48, 105, 160, 3, 2, 1, 128, 161, 98, 48, 96, 27, 94, 65, 122, 117, 114, 101, 65, 68, 92, 77, 83, 45, 79, 114, 103, 97, 110, 105, 122, 97, 116, 105, 111, 110, 45, 80, 50, 80, 45, 65, 99, 99, 101, 115, 115, 32, 91, 50, 48, 50, 50, 93, 92, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 162, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 163, 35, 48, 33, 160, 3, 2, 1, 2, 161, 26, 48, 24, 27, 7, 84, 69, 82, 77, 83, 82, 86, 27, 13, 49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 52, 165, 17, 24, 15, 50, 48, 51, 55, 48, 57, 49, 52, 48, 50, 52, 56, 48, 53, 90, 166, 17, 24, 15, 50, 48, 51, 55, 48, 57, 49, 52, 48, 50, 52, 56, 48, 53, 90, 167, 3, 2, 1, 0, 168, 18, 48, 16, 2, 1, 18, 2, 1, 17, 2, 1, 23, 2, 1, 24, 2, 2, 255, 121, 169, 29, 48, 27, 48, 25, 160, 3, 2, 1, 20, 161, 18, 4, 16, 68, 69, 83, 75, 84, 79, 80, 45, 56, 70, 51, 51, 82, 70, 72, 32]; + + // let data: ApplicationTag, 0> = picky_asn1_der::from_bytes(&data).unwrap(); + + println!("{:?}", data); + } + + #[test] + fn decrypt_as_req() { + let data = [203, 146, 230, 11, 20, 98, 198, 51, 49, 122, 91, 183, 216, 48, 207, 19, 122, 99, 223, 121, 139, 21, 32, 115, 96, 67, 129, 28, 181, 111, 33, 28, 74, 101, 53, 34, 144, 147, 253, 250, 126, 46, 91, 81, 48, 85, 2, 33, 106, 34, 22, 234, 179, 20, 247, 197, 113, 237, 243, 9, 32, 244, 114, 237, 120, 215, 57, 68, 157, 38, 234, 141, 115, 33, 252, 161]; + let key = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; + let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); + println!("{:?}", cipher.decrypt(&key, AP_REQ_AUTHENTICATOR, &data)); + } + + #[test] + fn verify_negoex_checksum() { + let data1 = [96, 130, 9, 51, 6, 6, 43, 6, 1, 5, 2, 7, 5, 0, 106, 130, 9, 37, 48, 130, 9, 33, 161, 3, 2, 1, 5, 162, 3, 2, 1, 10, 163, 130, 7, 252, 48, 130, 7, 248, 48, 130, 7, 244, 161, 3, 2, 1, 16, 162, 130, 7, 235, 4, 130, 7, 231, 48, 130, 7, 227, 128, 130, 7, 223, 48, 130, 7, 219, 2, 1, 3, 49, 11, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 48, 130, 2, 31, 6, 7, 43, 6, 1, 5, 2, 3, 1, 160, 130, 2, 18, 4, 130, 2, 14, 48, 130, 2, 10, 160, 57, 48, 55, 160, 5, 2, 3, 13, 97, 192, 161, 17, 24, 15, 50, 48, 50, 50, 49, 48, 49, 56, 49, 50, 48, 52, 48, 49, 90, 162, 3, 2, 1, 0, 163, 22, 4, 20, 45, 173, 122, 150, 137, 139, 32, 235, 244, 130, 94, 92, 244, 22, 245, 234, 197, 252, 242, 134, 161, 130, 1, 167, 48, 130, 1, 163, 48, 130, 1, 23, 6, 7, 42, 134, 72, 206, 62, 2, 1, 48, 130, 1, 10, 2, 129, 129, 0, 255, 255, 255, 255, 255, 255, 255, 255, 201, 15, 218, 162, 33, 104, 194, 52, 196, 198, 98, 139, 128, 220, 28, 209, 41, 2, 78, 8, 138, 103, 204, 116, 2, 11, 190, 166, 59, 19, 155, 34, 81, 74, 8, 121, 142, 52, 4, 221, 239, 149, 25, 179, 205, 58, 67, 27, 48, 43, 10, 109, 242, 95, 20, 55, 79, 225, 53, 109, 109, 81, 194, 69, 228, 133, 181, 118, 98, 94, 126, 198, 244, 76, 66, 233, 166, 55, 237, 107, 11, 255, 92, 182, 244, 6, 183, 237, 238, 56, 107, 251, 90, 137, 159, 165, 174, 159, 36, 17, 124, 75, 31, 230, 73, 40, 102, 81, 236, 230, 83, 129, 255, 255, 255, 255, 255, 255, 255, 255, 2, 1, 2, 2, 129, 128, 127, 255, 255, 255, 255, 255, 255, 255, 228, 135, 237, 81, 16, 180, 97, 26, 98, 99, 49, 69, 192, 110, 14, 104, 148, 129, 39, 4, 69, 51, 230, 58, 1, 5, 223, 83, 29, 137, 205, 145, 40, 165, 4, 60, 199, 26, 2, 110, 247, 202, 140, 217, 230, 157, 33, 141, 152, 21, 133, 54, 249, 47, 138, 27, 167, 240, 154, 182, 182, 168, 225, 34, 242, 66, 218, 187, 49, 47, 63, 99, 122, 38, 33, 116, 211, 27, 246, 181, 133, 255, 174, 91, 122, 3, 91, 246, 247, 28, 53, 253, 173, 68, 207, 210, 215, 79, 146, 8, 190, 37, 143, 243, 36, 148, 51, 40, 246, 115, 41, 192, 255, 255, 255, 255, 255, 255, 255, 255, 3, 129, 133, 0, 2, 129, 129, 0, 151, 24, 52, 147, 118, 138, 92, 6, 45, 3, 236, 27, 46, 7, 29, 189, 183, 96, 220, 161, 165, 69, 55, 26, 141, 164, 139, 110, 121, 229, 65, 150, 169, 35, 144, 154, 91, 94, 100, 216, 78, 173, 87, 120, 81, 222, 166, 35, 206, 48, 39, 64, 165, 128, 126, 207, 91, 150, 190, 208, 45, 175, 210, 107, 74, 32, 132, 95, 7, 125, 180, 28, 7, 12, 101, 208, 162, 126, 88, 206, 7, 231, 64, 29, 7, 148, 38, 148, 3, 63, 169, 139, 204, 15, 85, 204, 3, 2, 106, 76, 93, 174, 17, 155, 201, 238, 92, 76, 234, 48, 188, 53, 111, 5, 240, 190, 208, 189, 10, 237, 138, 155, 74, 3, 68, 67, 186, 159, 163, 34, 4, 32, 125, 155, 92, 183, 4, 93, 208, 163, 208, 162, 127, 191, 223, 96, 159, 119, 126, 174, 127, 34, 149, 135, 1, 192, 164, 184, 189, 38, 80, 226, 112, 146, 160, 130, 3, 217, 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 14, 210, 35, 212, 198, 27, 116, 144, 237, 113, 88, 109, 15, 25, 113, 249, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 49, 56, 49, 49, 53, 57, 48, 49, 90, 23, 13, 50, 50, 49, 48, 49, 56, 49, 51, 48, 52, 48, 49, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 173, 251, 243, 19, 51, 228, 187, 103, 173, 45, 14, 235, 229, 200, 184, 172, 79, 101, 201, 157, 201, 28, 66, 14, 158, 45, 219, 105, 95, 152, 174, 49, 150, 40, 19, 65, 17, 108, 238, 224, 35, 114, 196, 224, 57, 138, 186, 30, 154, 220, 113, 212, 240, 226, 40, 102, 231, 178, 168, 200, 254, 55, 130, 79, 202, 19, 203, 158, 160, 153, 66, 120, 43, 72, 185, 153, 90, 140, 93, 204, 197, 248, 133, 218, 101, 85, 214, 133, 112, 242, 95, 101, 132, 118, 241, 62, 101, 94, 198, 55, 12, 244, 156, 9, 57, 32, 171, 252, 27, 58, 183, 252, 199, 118, 236, 129, 92, 74, 22, 145, 135, 98, 104, 171, 145, 216, 106, 228, 69, 227, 29, 85, 162, 25, 78, 99, 70, 43, 96, 105, 5, 17, 56, 131, 111, 185, 129, 91, 89, 144, 122, 165, 51, 244, 85, 236, 235, 10, 238, 185, 197, 191, 22, 94, 2, 213, 174, 248, 243, 23, 164, 21, 248, 128, 94, 112, 93, 116, 73, 61, 29, 5, 108, 9, 252, 248, 195, 109, 232, 95, 78, 146, 94, 100, 39, 127, 18, 128, 181, 89, 125, 228, 158, 77, 228, 44, 148, 176, 130, 207, 100, 66, 128, 103, 211, 73, 239, 134, 34, 150, 243, 150, 24, 131, 109, 11, 37, 245, 68, 108, 214, 29, 58, 79, 31, 218, 36, 88, 40, 146, 38, 202, 97, 1, 106, 114, 20, 76, 42, 77, 62, 65, 86, 8, 230, 217, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 47, 111, 124, 21, 189, 180, 98, 44, 39, 253, 124, 31, 82, 162, 161, 55, 248, 125, 72, 204, 73, 174, 205, 120, 249, 57, 81, 43, 124, 21, 192, 8, 222, 60, 204, 90, 206, 239, 21, 24, 53, 20, 166, 233, 245, 47, 165, 153, 216, 69, 143, 243, 221, 24, 4, 249, 81, 156, 233, 26, 254, 10, 54, 195, 176, 55, 169, 73, 111, 161, 133, 91, 149, 130, 86, 75, 47, 119, 188, 185, 39, 108, 102, 123, 19, 193, 103, 106, 155, 223, 113, 128, 39, 57, 38, 171, 163, 128, 56, 171, 128, 222, 135, 10, 210, 129, 246, 179, 48, 237, 219, 233, 195, 170, 146, 88, 226, 54, 96, 81, 245, 32, 48, 163, 119, 105, 147, 137, 97, 226, 27, 53, 72, 131, 205, 110, 216, 191, 76, 103, 108, 121, 147, 234, 149, 189, 207, 166, 72, 112, 6, 155, 136, 180, 199, 135, 167, 137, 113, 199, 32, 63, 173, 152, 87, 55, 126, 215, 113, 188, 207, 253, 237, 169, 178, 9, 238, 221, 59, 6, 45, 212, 69, 7, 221, 54, 5, 56, 56, 247, 52, 185, 132, 172, 158, 100, 94, 122, 192, 80, 103, 113, 95, 31, 181, 38, 145, 61, 137, 0, 87, 241, 10, 143, 134, 99, 164, 100, 77, 155, 181, 96, 65, 233, 181, 179, 6, 56, 216, 63, 114, 102, 69, 95, 62, 57, 174, 176, 183, 78, 132, 59, 33, 207, 196, 197, 155, 88, 44, 173, 128, 197, 116, 80, 221, 225, 49, 130, 1, 199, 48, 130, 1, 195, 2, 1, 1, 48, 97, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 2, 16, 14, 210, 35, 212, 198, 27, 116, 144, 237, 113, 88, 109, 15, 25, 113, 249, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 160, 61, 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 218, 28, 219, 222, 185, 242, 160, 207, 42, 202, 3, 49, 215, 53, 191, 207, 29, 110, 18, 227, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 1, 0, 64, 139, 117, 205, 62, 31, 170, 243, 112, 128, 128, 222, 92, 12, 120, 42, 94, 228, 127, 152, 126, 118, 156, 227, 18, 211, 70, 236, 128, 223, 122, 156, 50, 31, 198, 191, 244, 170, 17, 250, 206, 16, 37, 213, 238, 223, 2, 215, 221, 116, 68, 57, 26, 31, 234, 115, 37, 34, 203, 185, 17, 134, 12, 225, 234, 157, 246, 53, 223, 40, 148, 232, 57, 165, 148, 217, 61, 24, 205, 114, 171, 212, 4, 2, 210, 57, 93, 9, 177, 191, 125, 237, 238, 235, 101, 187, 54, 32, 68, 71, 120, 20, 177, 42, 176, 128, 172, 169, 134, 112, 211, 136, 36, 156, 28, 104, 251, 42, 33, 255, 168, 182, 212, 150, 103, 111, 121, 133, 116, 183, 202, 149, 220, 93, 191, 97, 49, 245, 48, 11, 215, 98, 175, 212, 15, 132, 128, 109, 182, 91, 254, 73, 14, 28, 158, 152, 44, 167, 75, 18, 111, 196, 232, 15, 168, 130, 70, 129, 204, 16, 208, 133, 123, 28, 252, 96, 219, 123, 148, 150, 101, 24, 59, 156, 7, 178, 36, 175, 110, 37, 4, 0, 71, 135, 170, 42, 43, 72, 94, 87, 250, 137, 23, 246, 87, 226, 209, 225, 207, 254, 45, 86, 79, 188, 155, 164, 134, 144, 98, 25, 34, 230, 247, 64, 141, 174, 140, 187, 19, 176, 254, 188, 196, 216, 23, 95, 240, 66, 58, 169, 223, 150, 157, 23, 3, 64, 114, 34, 128, 18, 114, 167, 74, 233, 229, 53, 164, 130, 1, 19, 48, 130, 1, 15, 160, 7, 3, 5, 0, 64, 129, 0, 16, 161, 107, 48, 105, 160, 3, 2, 1, 128, 161, 98, 48, 96, 27, 94, 65, 122, 117, 114, 101, 65, 68, 92, 77, 83, 45, 79, 114, 103, 97, 110, 105, 122, 97, 116, 105, 111, 110, 45, 80, 50, 80, 45, 65, 99, 99, 101, 115, 115, 32, 91, 50, 48, 50, 50, 93, 92, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 162, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 163, 38, 48, 36, 160, 3, 2, 1, 2, 161, 29, 48, 27, 27, 7, 84, 69, 82, 77, 83, 82, 86, 27, 16, 100, 101, 115, 116, 46, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 165, 17, 24, 15, 50, 48, 51, 55, 48, 57, 49, 52, 48, 50, 52, 56, 48, 53, 90, 166, 17, 24, 15, 50, 48, 51, 55, 48, 57, 49, 52, 48, 50, 52, 56, 48, 53, 90, 167, 3, 2, 1, 0, 168, 18, 48, 16, 2, 1, 18, 2, 1, 17, 2, 1, 23, 2, 1, 24, 2, 2, 255, 121, 169, 29, 48, 27, 48, 25, 160, 3, 2, 1, 20, 161, 18, 4, 16, 68, 69, 83, 75, 84, 79, 80, 45, 56, 70, 51, 51, 82, 70, 72, 32, 96, 130, 11, 132, 6, 6, 43, 6, 1, 5, 2, 7, 6, 0, 107, 130, 11, 118, 48, 130, 11, 114, 160, 3, 2, 1, 5, 161, 3, 2, 1, 11, 162, 130, 6, 106, 48, 130, 6, 102, 48, 130, 6, 98, 161, 3, 2, 1, 17, 162, 130, 6, 89, 4, 130, 6, 85, 160, 130, 6, 81, 48, 130, 6, 77, 128, 130, 6, 37, 48, 130, 6, 33, 2, 1, 3, 49, 11, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 48, 129, 161, 6, 7, 43, 6, 1, 5, 2, 3, 2, 160, 129, 149, 4, 129, 146, 48, 129, 143, 160, 129, 135, 3, 129, 132, 0, 2, 129, 128, 215, 117, 217, 80, 121, 91, 18, 25, 68, 12, 147, 62, 133, 153, 19, 222, 155, 87, 168, 85, 31, 146, 8, 189, 73, 209, 35, 10, 182, 72, 13, 88, 225, 198, 131, 113, 8, 2, 72, 53, 24, 223, 241, 117, 172, 53, 145, 188, 244, 131, 183, 21, 214, 0, 179, 123, 4, 229, 117, 142, 111, 140, 166, 98, 97, 227, 161, 149, 168, 231, 254, 87, 240, 162, 184, 2, 21, 29, 242, 144, 112, 198, 60, 231, 48, 81, 77, 94, 127, 113, 144, 99, 24, 45, 33, 248, 161, 232, 94, 81, 89, 217, 203, 104, 84, 89, 165, 170, 157, 139, 250, 42, 141, 107, 128, 243, 42, 108, 205, 252, 99, 183, 249, 186, 147, 13, 102, 119, 161, 3, 2, 1, 0, 160, 130, 3, 158, 48, 130, 3, 154, 48, 130, 2, 130, 160, 3, 2, 1, 2, 2, 16, 62, 39, 192, 20, 152, 7, 29, 243, 143, 63, 80, 234, 220, 89, 56, 82, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 49, 56, 48, 54, 52, 51, 53, 48, 90, 23, 13, 50, 50, 49, 48, 49, 57, 48, 54, 52, 56, 53, 48, 90, 48, 101, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 45, 48, 43, 6, 3, 85, 4, 3, 12, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 94, 48, 92, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 24, 6, 3, 85, 29, 17, 4, 17, 48, 15, 130, 13, 49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 57, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 179, 0, 255, 32, 22, 238, 125, 85, 247, 225, 180, 111, 84, 165, 58, 193, 187, 225, 232, 171, 9, 43, 70, 138, 135, 196, 123, 59, 5, 215, 119, 225, 79, 156, 122, 254, 154, 205, 114, 165, 193, 251, 144, 217, 247, 15, 212, 222, 56, 5, 246, 164, 238, 254, 202, 170, 52, 206, 4, 93, 197, 184, 66, 74, 165, 157, 67, 82, 197, 143, 21, 82, 216, 219, 192, 125, 22, 32, 197, 14, 179, 206, 3, 229, 132, 134, 58, 161, 188, 105, 225, 44, 154, 42, 118, 53, 3, 104, 66, 210, 119, 0, 44, 160, 14, 28, 209, 18, 110, 44, 254, 156, 180, 211, 107, 109, 209, 82, 153, 164, 234, 62, 155, 185, 104, 124, 33, 29, 48, 110, 231, 50, 118, 48, 16, 120, 154, 31, 238, 193, 206, 155, 162, 155, 34, 90, 254, 170, 185, 49, 6, 100, 189, 107, 207, 34, 134, 35, 115, 148, 122, 202, 239, 59, 172, 148, 44, 65, 28, 65, 169, 68, 76, 251, 218, 121, 145, 110, 253, 15, 18, 235, 102, 45, 176, 93, 14, 169, 253, 50, 64, 208, 115, 48, 56, 123, 106, 95, 91, 104, 230, 70, 7, 108, 188, 3, 219, 161, 74, 153, 172, 229, 22, 201, 229, 143, 87, 76, 15, 129, 22, 158, 190, 18, 39, 130, 144, 12, 22, 144, 62, 36, 172, 123, 107, 194, 70, 109, 206, 19, 135, 215, 132, 225, 142, 207, 194, 33, 83, 164, 245, 163, 19, 186, 247, 209, 49, 130, 1, 199, 48, 130, 1, 195, 2, 1, 1, 48, 97, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 2, 16, 62, 39, 192, 20, 152, 7, 29, 243, 143, 63, 80, 234, 220, 89, 56, 82, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 160, 61, 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 235, 101, 242, 9, 158, 189, 205, 170, 36, 132, 253, 172, 15, 194, 194, 92, 66, 96, 113, 177, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 1, 0, 25, 24, 14, 151, 120, 16, 99, 122, 206, 186, 7, 208, 41, 217, 24, 63, 124, 107, 174, 252, 129, 63, 236, 84, 172, 239, 37, 223, 254, 41, 188, 222, 11, 193, 134, 130, 145, 53, 196, 50, 38, 29, 76, 235, 228, 46, 12, 157, 67, 163, 228, 80, 83, 199, 59, 84, 57, 22, 103, 255, 176, 1, 244, 121, 140, 174, 31, 235, 14, 189, 27, 2, 37, 10, 78, 172, 32, 225, 162, 19, 101, 109, 224, 46, 4, 122, 10, 141, 13, 152, 101, 52, 31, 238, 241, 150, 253, 186, 224, 121, 190, 6, 209, 70, 180, 236, 172, 39, 17, 217, 253, 164, 117, 26, 229, 34, 147, 200, 51, 133, 196, 251, 106, 63, 15, 204, 31, 162, 230, 177, 102, 8, 30, 186, 91, 221, 115, 53, 211, 22, 16, 22, 231, 59, 159, 73, 145, 40, 19, 68, 174, 66, 42, 242, 146, 102, 51, 136, 208, 228, 163, 46, 187, 56, 101, 155, 246, 241, 76, 176, 65, 158, 74, 49, 244, 194, 89, 226, 193, 61, 171, 6, 74, 102, 94, 213, 18, 130, 243, 91, 163, 46, 91, 189, 23, 121, 85, 94, 116, 109, 10, 78, 242, 155, 169, 241, 60, 68, 79, 80, 147, 152, 239, 210, 182, 59, 94, 112, 62, 95, 2, 169, 64, 29, 144, 42, 118, 149, 89, 97, 180, 12, 156, 56, 127, 151, 158, 253, 152, 147, 201, 232, 198, 217, 206, 19, 8, 129, 219, 220, 169, 181, 181, 167, 220, 6, 161, 34, 4, 32, 142, 91, 149, 4, 44, 55, 103, 6, 75, 168, 207, 165, 162, 197, 172, 27, 2, 108, 166, 10, 240, 52, 179, 24, 56, 73, 137, 103, 160, 81, 236, 230, 163, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 164, 35, 48, 33, 160, 3, 2, 1, 128, 161, 26, 48, 24, 27, 22, 65, 122, 117, 114, 101, 65, 68, 92, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 165, 130, 3, 166, 97, 130, 3, 162, 48, 130, 3, 158, 160, 3, 2, 1, 5, 161, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 162, 38, 48, 36, 160, 3, 2, 1, 2, 161, 29, 48, 27, 27, 7, 84, 69, 82, 77, 83, 82, 86, 27, 16, 100, 101, 115, 116, 46, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 163, 130, 3, 90, 48, 130, 3, 86, 160, 3, 2, 1, 18, 162, 130, 3, 77, 4, 130, 3, 73, 211, 68, 200, 157, 66, 82, 128, 82, 220, 246, 214, 194, 27, 126, 129, 98, 58, 221, 245, 200, 112, 218, 4, 68, 97, 0, 222, 203, 69, 31, 41, 86, 106, 196, 62, 240, 167, 246, 248, 193, 104, 59, 22, 204, 24, 99, 193, 25, 94, 201, 86, 198, 11, 100, 155, 58, 22, 14, 173, 195, 112, 223, 23, 161, 48, 80, 40, 189, 52, 81, 213, 229, 176, 161, 14, 85, 128, 46, 151, 112, 93, 183, 164, 240, 98, 133, 6, 224, 79, 41, 127, 15, 65, 143, 127, 154, 182, 50, 91, 134, 38, 116, 244, 228, 187, 205, 75, 146, 35, 228, 38, 136, 152, 24, 116, 41, 119, 147, 20, 242, 111, 224, 9, 236, 174, 193, 254, 96, 89, 84, 214, 95, 130, 60, 213, 229, 73, 173, 34, 144, 149, 15, 58, 63, 163, 199, 138, 204, 45, 163, 152, 36, 75, 26, 241, 237, 88, 241, 124, 80, 154, 114, 99, 20, 24, 82, 105, 219, 61, 226, 81, 196, 171, 182, 111, 160, 207, 97, 246, 217, 128, 35, 79, 72, 79, 30, 46, 3, 243, 180, 0, 42, 153, 219, 218, 96, 13, 16, 98, 61, 38, 4, 76, 63, 77, 242, 129, 16, 71, 39, 250, 84, 42, 179, 188, 5, 3, 137, 127, 203, 110, 37, 135, 246, 251, 26, 154, 6, 116, 200, 240, 199, 205, 105, 182, 201, 75, 63, 71, 29, 111, 140, 30, 24, 78, 47, 38, 97, 45, 24, 130, 141, 22, 103, 199, 110, 160, 163, 11, 147, 127, 90, 93, 135, 202, 191, 7, 90, 109, 66, 127, 148, 61, 219, 191, 178, 203, 162, 218, 241, 235, 89, 10, 138, 101, 44, 70, 26, 64, 177, 170, 253, 124, 192, 185, 192, 148, 172, 109, 58, 207, 7, 89, 130, 53, 73, 103, 223, 28, 228, 57, 199, 168, 136, 44, 27, 202, 10, 73, 49, 137, 246, 98, 164, 197, 127, 230, 147, 168, 210, 23, 17, 63, 106, 157, 113, 20, 7, 146, 174, 79, 242, 241, 22, 6, 134, 1, 225, 222, 124, 254, 22, 139, 72, 156, 224, 73, 101, 179, 168, 34, 245, 221, 122, 35, 61, 115, 35, 96, 19, 199, 149, 176, 54, 147, 108, 225, 73, 149, 204, 100, 1, 177, 205, 139, 138, 134, 133, 225, 119, 111, 84, 104, 167, 146, 163, 254, 56, 86, 233, 162, 4, 145, 161, 228, 122, 201, 16, 92, 171, 164, 237, 146, 210, 143, 127, 233, 184, 148, 110, 238, 253, 103, 98, 0, 96, 96, 12, 113, 168, 99, 137, 37, 124, 76, 108, 188, 200, 82, 199, 169, 192, 229, 34, 232, 198, 107, 217, 54, 60, 152, 198, 234, 110, 87, 50, 200, 237, 67, 226, 214, 208, 178, 100, 118, 240, 242, 212, 25, 149, 80, 2, 202, 143, 52, 140, 235, 222, 211, 54, 169, 228, 164, 136, 35, 62, 16, 53, 63, 55, 58, 144, 11, 32, 68, 79, 6, 35, 178, 147, 228, 21, 103, 27, 111, 22, 103, 77, 181, 230, 252, 90, 156, 47, 75, 171, 246, 217, 173, 55, 94, 241, 157, 143, 231, 92, 90, 114, 50, 210, 97, 152, 254, 49, 135, 116, 248, 220, 42, 5, 236, 41, 44, 112, 134, 29, 180, 186, 250, 220, 152, 27, 227, 28, 61, 194, 125, 162, 254, 168, 51, 59, 43, 134, 56, 202, 226, 51, 207, 243, 88, 169, 114, 101, 83, 97, 201, 39, 215, 123, 9, 6, 182, 125, 167, 189, 57, 221, 73, 28, 0, 198, 243, 75, 115, 232, 83, 119, 145, 193, 152, 25, 43, 116, 110, 193, 96, 178, 156, 156, 189, 51, 50, 231, 80, 236, 201, 236, 151, 211, 149, 56, 141, 37, 196, 209, 178, 94, 62, 151, 129, 214, 215, 227, 216, 92, 87, 131, 105, 101, 186, 99, 18, 168, 83, 55, 190, 108, 132, 217, 179, 77, 43, 189, 230, 43, 208, 213, 46, 46, 239, 40, 166, 93, 149, 65, 92, 109, 213, 99, 202, 249, 197, 34, 84, 171, 2, 75, 47, 134, 22, 114, 10, 251, 55, 98, 90, 163, 225, 69, 1, 142, 86, 189, 30, 248, 31, 11, 117, 3, 145, 87, 65, 247, 185, 59, 28, 13, 159, 197, 134, 36, 142, 48, 187, 210, 221, 225, 38, 89, 7, 23, 58, 191, 2, 217, 182, 175, 144, 9, 229, 218, 113, 88, 191, 30, 249, 234, 43, 143, 202, 105, 58, 79, 57, 215, 15, 56, 48, 175, 33, 100, 229, 96, 226, 104, 200, 255, 105, 151, 106, 248, 228, 23, 209, 34, 252, 24, 136, 156, 194, 117, 199, 48, 221, 251, 98, 15, 248, 61, 136, 110, 151, 173, 55, 134, 246, 166, 72, 254, 73, 181, 43, 71, 132, 132, 120, 244, 151, 161, 36, 52, 218, 247, 227, 218, 110, 10, 172, 41, 139, 88, 227, 175, 244, 200, 112, 24, 20, 122, 23, 168, 77, 16, 42, 74, 119, 188, 130, 198, 132, 102, 45, 152, 131, 201, 200, 49, 243, 171, 128, 166, 130, 1, 20, 48, 130, 1, 16, 160, 3, 2, 1, 18, 162, 130, 1, 7, 4, 130, 1, 3, 20, 63, 216, 86, 128, 71, 187, 136, 100, 232, 71, 187, 238, 143, 53, 1, 46, 136, 55, 255, 102, 54, 121, 86, 193, 116, 51, 68, 0, 240, 62, 202, 237, 52, 202, 53, 130, 205, 195, 106, 61, 74, 203, 103, 135, 188, 98, 253, 207, 213, 255, 133, 52, 63, 163, 241, 156, 44, 123, 158, 8, 194, 46, 220, 69, 64, 211, 23, 251, 153, 192, 236, 50, 165, 132, 215, 77, 253, 190, 206, 109, 101, 231, 107, 152, 87, 86, 176, 148, 211, 196, 144, 152, 211, 26, 24, 254, 248, 148, 10, 51, 57, 182, 237, 185, 88, 132, 250, 9, 94, 208, 54, 103, 169, 174, 77, 146, 168, 255, 138, 53, 244, 11, 200, 90, 49, 249, 39, 180, 100, 176, 244, 36, 10, 114, 6, 97, 212, 241, 39, 24, 182, 6, 154, 147, 44, 166, 61, 215, 241, 144, 111, 50, 176, 88, 197, 204, 193, 49, 242, 193, 158, 143, 51, 68, 137, 129, 17, 162, 169, 128, 78, 248, 226, 77, 71, 11, 57, 77, 22, 223, 53, 191, 232, 121, 85, 246, 161, 252, 140, 129, 0, 88, 156, 194, 115, 149, 161, 9, 80, 50, 216, 153, 87, 15, 92, 35, 128, 111, 23, 200, 82, 78, 179, 155, 88, 71, 101, 133, 124, 223, 201, 217, 243, 6, 171, 225, 20, 249, 125, 108, 195, 56, 59, 43, 123, 173, 186, 240, 1, 233, 74, 233, 59, 158, 244, 242, 227, 104, 234, 218, 145, 180, 53, 133, 195, 98, 134, 29]; + + let key1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; + let key2 = [124, 14, 77, 177, 242, 71, 223, 200, 3, 193, 30, 184, 45, 24, 54, 44, 105, 209, 144, 224, 1, 1, 38, 244, 91, 82, 209, 250, 7, 247, 168, 193]; + + let checksum = [225, 29, 207, 202, 14, 201, 88, 44, 83, 206, 195, 32]; + + let hmacker = ChecksumSuite::HmacSha196Aes256.hasher(); + + // println!("{}", &checksum == hmacker.checksum(&key1, 23, &data1).unwrap().as_slice()); + println!("{}", &checksum == hmacker.checksum(&key1, 41, &data1).unwrap().as_slice()); + println!("{}", &checksum == hmacker.checksum(&key2, 41, &data1).unwrap().as_slice()); + + for i in 1..100 { + if &checksum == hmacker.checksum(&key1, i, &data1).unwrap().as_slice() { + println!("found in key 1: {}", i); + } + if &checksum == hmacker.checksum(&key2, i, &data1).unwrap().as_slice() { + println!("found in key 2: {}", i); + } + } + // println!("{}", &checksum == hmacker.checksum(&key2, 25, &data1).unwrap().as_slice()); + + // println!("{}", &checksum == hmacker.checksum(&key1, 23, &data2).unwrap().as_slice()); + // println!("{}", &checksum == hmacker.checksum(&key1, 25, &data2).unwrap().as_slice()); + // println!("{}", &checksum == hmacker.checksum(&key2, 23, &data2).unwrap().as_slice()); + // println!("{}", &checksum == hmacker.checksum(&key2, 25, &data2).unwrap().as_slice()); + + // println!("{}", &checksum == hmacker.checksum(&key1, 23, &data3).unwrap().as_slice()); + // println!("{}", &checksum == hmacker.checksum(&key1, 25, &data3).unwrap().as_slice()); + // println!("{}", &checksum == hmacker.checksum(&key2, 23, &data3).unwrap().as_slice()); + // println!("{}", &checksum == hmacker.checksum(&key2, 25, &data3).unwrap().as_slice()); + + // println!("{}", &checksum == hmacker.checksum(&key1, 23, &data4).unwrap().as_slice()); + // println!("{}", &checksum == hmacker.checksum(&key1, 25, &data4).unwrap().as_slice()); + // println!("{}", &checksum == hmacker.checksum(&key2, 23, &data4).unwrap().as_slice()); + // println!("{}", &checksum == hmacker.checksum(&key2, 25, &data4).unwrap().as_slice()); + } + + #[test] + fn verify_authenticator_checksum() { + let data1 = [48, 78, 48, 76, 160, 3, 2, 1, 1, 161, 69, 4, 67, 48, 65, 48, 63, 160, 4, 2, 2, 0, 141, 161, 55, 4, 53, 48, 51, 48, 49, 160, 3, 2, 1, 0, 161, 42, 4, 40, 1, 0, 0, 0, 0, 32, 0, 0, 92, 95, 64, 72, 191, 160, 228, 23, 98, 35, 78, 151, 207, 227, 96, 126, 97, 180, 15, 98, 127, 211, 90, 177, 119, 132, 45, 113, 206, 90, 169, 124]; + let key1 = [198, 211, 172, 206, 204, 190, 143, 153, 82, 144, 117, 94, 153, 99, 144, 212, 211, 135, 176, 70, 134, 241, 23, 87, 4, 202, 88, 5, 233, 195, 37, 230]; + let key2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; + let checksum = [18, 161, 21, 144, 10, 142, 30, 103, 57, 75, 246, 6]; + + let hmacker = ChecksumSuite::HmacSha196Aes256.hasher(); + + for i in 1..100 { + if &checksum == hmacker.checksum(&key1, i, &data1).unwrap().as_slice() { + println!("here: {}", i); + } + } + + for i in 1..100 { + if &checksum == hmacker.checksum(&key2, i, &data1).unwrap().as_slice() { + println!("here: {}", i); + } + } + } + + #[test] + fn decrypt_pub_key_auth() { + let data = [203, 146, 230, 11, 20, 98, 198, 51, 49, 122, 91, 183, 216, 48, 207, 19, 122, 99, 223, 121, 139, 21, 32, 115, 96, 67, 129, 28, 181, 111, 33, 28, 74, 101, 53, 34, 144, 147, 253, 250, 126, 46, 91, 81, 48, 85, 2, 33, 106, 34, 22, 234, 179, 20, 247, 197, 113, 237, 243, 9, 32, 244, 114, 237, 120, 215, 57, 68, 157, 38, 234, 141, 115, 33, 252, 161]; + let mut data_rotated = data.to_vec(); + data_rotated.rotate_left(28); + // ap_rep + let key_1 = [2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + // auth + // let key_2 = [74, 16, 199, 49, 172, 146, 171, 169, 116, 211, 209, 113, 64, 193, 179, 35, 216, 179, 2, 158, 60, 239, 52, 8, 62, 13, 246, 126, 8, 158, 57, 231]; + // session + // let key_3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; + // dh + // let key_4 = [13, 188, 89, 204, 0, 181, 160, 234, 215, 132, 88, 4, 250, 41, 12, 126, 159, 182, 237, 139, 20, 51, 109, 42, 19, 146, 238, 236, 255, 32, 159, 84]; + + let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); + + if let Ok(data) = cipher.decrypt(&key_1, 24, &data_rotated) { + println!("r: using key_1 and {}: {:?}", 24, data); + } + } + + #[test] + fn validate_pub_key_auth() { + let sha256_hash = [29, 126, 187, 134, 84, 154, 168, 80, 159, 1, 45, 85, 188, 181, 91, 197, 39, 187, 68, 54, 244, 182, 97, 132, 232, 127, 110, 123, 164, 103, 245, 84]; + + let client_nonce = [151, 82, 26, 188, 144, 54, 149, 18, 67, 21, 87, 56, 80, 202, 149, 20, 9, 148, 199, 138, 63, 18, 197, 114, 65, 153, 37, 40, 185, 237, 186, 230]; + // let public_key = [48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1]; + let public_key = [48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1]; + + let mut payload_1 = SERVER_CLIENT_HASH_MAGIC.to_vec(); + payload_1.extend_from_slice(&client_nonce); + payload_1.extend_from_slice(&public_key); + + let mut payload_2 = CLIENT_SERVER_HASH_MAGIC.to_vec(); + payload_2.extend_from_slice(&client_nonce); + payload_2.extend_from_slice(&public_key); + + println!("{}", &sha256_hash == compute_sha256(&payload_1).as_slice()); + println!("{}", &sha256_hash == compute_sha256(&payload_2).as_slice()); + } + + fn try_it(vs: Vec>) { + let hash = [137, 141, 156, 76, 74, 183, 58, 112, 102, 14, 242, 197, 28, 2, 101, 120, 62, 52, 39, 216, 21, 192, 15, 232, 108, 119, 155, 30, 16, 113, 14, 70]; + + let is = [ + [0, 1, 2, 3], + // [0, 1, 3, 2], + [0, 2, 1, 3], + // [0, 2, 3, 1], + // [0, 3, 1, 2], + // [0, 3, 2, 1], + [1, 0, 2, 3], + // [1, 0, 3, 2], + [1, 2, 0, 3], + // [1, 2, 3, 0], + // [1, 3, 0, 2], + // [1, 3, 2, 0], + [2, 0, 1, 3], + // [2, 0, 3, 1], + [2, 1, 0, 3], + // [2, 1, 3, 0], + // [2, 3, 0, 1], + // [2, 3, 1, 0], + // [3, 0, 1, 2], + // [3, 0, 2, 1], + // [3, 1, 0, 2], + // [3, 1, 2, 0], + // [3, 2, 0, 1], + // [3, 2, 1, 0], + ]; + + for i in is { + let mut payload = vs[i[0]].clone(); + payload.extend_from_slice(&vs[i[1]]); + payload.extend_from_slice(&vs[i[2]]); + // payload.extend_from_slice(&vs[i[3]]); + + if &hash == compute_sha256(&payload).as_slice() { + println!("I WIN!"); + } + } + } + + #[test] + fn hack() { + // client nonce + let p1 = [167, 160, 86, 46, 171, 207, 115, 77, 182, 219, 18, 73, 205, 150, 2, 5, 23, 21, 226, 217, 76, 248, 10, 115, 192, 95, 101, 60, 104, 159, 173, 21]; + // pk + let p2 = [48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1]; + // client negoex nonce + let p3 = [85, 64, 105, 87, 129, 69, 222, 254, 36, 159, 112, 18, 249, 74, 108, 135, 146, 132, 49, 72, 193, 144, 183, 119, 47, 81, 105, 196, 254, 190, 221, 87]; + // server negoex nonce + let p4 = [10, 209, 111, 101, 206, 151, 53, 222, 225, 32, 241, 24, 15, 201, 210, 38, 133, 175, 97, 251, 27, 195, 152, 39, 9, 97, 115, 227, 194, 196, 54, 245]; + + let m1 = SERVER_CLIENT_HASH_MAGIC.to_vec(); + let m2 = CLIENT_SERVER_HASH_MAGIC.to_vec(); + + + println!("not win?"); + } } diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index d0dbfe2e..b63adef1 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -2,7 +2,7 @@ use std::convert::TryFrom; use std::fmt::Debug; use std::str::FromStr; -use chrono::Utc; +use chrono::{Utc, Duration}; use oid::ObjectIdentifier; use picky_asn1::bit_string::BitString; use picky_asn1::date::GeneralizedTime; @@ -10,13 +10,13 @@ use picky_asn1::restricted_string::{BMPString, IA5String}; use picky_asn1::wrapper::{ Asn1SequenceOf, Asn1SetOf, BMPStringAsn1, BitStringAsn1, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2, ExplicitContextTag3, ImplicitContextTag0, IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, - Optional, + Optional, ExplicitContextTag8, ExplicitContextTag4, ExplicitContextTag5, ExplicitContextTag6, ExplicitContextTag7, ExplicitContextTag10, ExplicitContextTag9, GeneralizedTimeAsn1, }; use picky_asn1_der::application_tag::ApplicationTag; use picky_asn1_der::Asn1RawDer; use picky_asn1_x509::cmsversion::CmsVersion; use picky_asn1_x509::content_info::EncapsulatedContentInfo; -use picky_asn1_x509::oids::{AT_COMMON_NAME, DIFFIE_HELLMAN, GSS_PKU2U, NEGOEX, NTLM_SSP, PKINIT_AUTH_DATA, SPNEGO}; +use picky_asn1_x509::oids::{AT_COMMON_NAME, DIFFIE_HELLMAN, GSS_PKU2U, NEGOEX, NTLM_SSP, PKINIT_AUTH_DATA, SPNEGO, PKINIT_DH_KEY_DATA}; use picky_asn1_x509::signed_data::{ CertificateChoices, CertificateSet, DigestAlgorithmIdentifiers, SignedData, SignersInfos, }; @@ -28,26 +28,29 @@ use picky_asn1_x509::{ AlgorithmIdentifier, Attribute, AttributeValues, Certificate, ShaVariant, }; -use picky_krb::constants::gss_api::ACCEPT_INCOMPLETE; -use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REQ}; +use picky_krb::constants::gss_api::{ACCEPT_INCOMPLETE, AUTHENTICATOR_CHECKSUM_TYPE, ACCEPT_COMPLETE}; +use picky_krb::constants::key_usages::{AS_REP_ENC, AP_REP_ENC}; +use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REQ, AD_AUTH_DATA_AP_OPTION_TYPE, KERB_AP_OPTIONS_CBT, PA_PK_AS_REP}; +use picky_krb::crypto::CipherSuite; use picky_krb::crypto::diffie_hellman::{compute_public_key, generate_private_key}; -use picky_krb::data_types::{KerberosStringAsn1, KerberosTime, PaData, PrincipalName, Realm}; +use picky_krb::data_types::{KerberosStringAsn1, KerberosTime, PaData, PrincipalName, Realm, Authenticator, AuthorizationDataInner, AuthorizationData, AuthenticatorInner, EncryptionKey, Checksum, Ticket, EncryptedData, LastReq, LastReqInner, TicketInner, KerbAdRestrictionEntry, LsapTokenInfoIntegrity, EncApRepPart, EncApRepPartInner}; use picky_krb::gss_api::{ - ApplicationTag0, GssApiNegInit, KrbMessage, MechType, MechTypeList, NegTokenInit, NegTokenTarg, + ApplicationTag0, GssApiNegInit, KrbMessage, MechType, MechTypeList, NegTokenInit, NegTokenTarg, NegTokenTarg1, }; -use picky_krb::messages::KdcReqBody; +use picky_krb::messages::{KdcReqBody, AsRep, KdcRep, EncAsRepPart, EncKdcRepPart, ApRep, ApRepInner}; use picky_krb::pkinit::{ AuthPack, DhDomainParameters, DhReqInfo, DhReqKeyInfo, PaPkAsReq, PkAuthenticator, Pku2uNegoBody, Pku2uNegoReq, - Pku2uNegoReqMetadata, + Pku2uNegoReqMetadata, PaPkAsRep, DhRepInfo, KdcDhKeyInfo, }; use rand::rngs::OsRng; use rsa::{Hash, PaddingScheme, RsaPrivateKey}; use sha1::{Digest, Sha1}; use super::{DhParameters, Pku2uConfig}; -use crate::kerberos::client::generators::MAX_MICROSECONDS_IN_SECOND; +use crate::crypto::compute_md5_channel_bindings_hash; +use crate::kerberos::client::generators::{MAX_MICROSECONDS_IN_SECOND, GenerateAuthenticatorOptions, ChecksumOptions}; use crate::kerberos::SERVICE_NAME; -use crate::Result; +use crate::{Result, ErrorKind, Error, KERBEROS_VERSION}; /// [The PKU2U Realm Name](https://datatracker.ietf.org/doc/html/draft-zhu-pku2u-09#section-3) /// The PKU2U realm name is defined as a reserved Kerberos realm name, and it has the value of "WELLKNOWN:PKU2U". @@ -81,7 +84,7 @@ pub fn generate_pku2u_nego_req(_username: &str, config: &Pku2uConfig) -> Result< KerberosStringAsn1::from(IA5String::from_str(SERVICE_NAME)?), // KerberosStringAsn1::from(IA5String::from_str(username).unwrap()), // for the debugging - KerberosStringAsn1::from(IA5String::from_str("192.168.0.117")?), + KerberosStringAsn1::from(IA5String::from_str("dest.dataans.com")?), ])), }), }), @@ -100,6 +103,15 @@ pub fn generate_neg_token_init(mech_token: Vec) -> Result) -> Result { + Ok(ExplicitContextTag1::from(NegTokenTarg { + neg_result: Optional::from(Some(ExplicitContextTag0::from(Asn1RawDer(vec![0x0a, 0x01, 0x01])))), + supported_mech: Optional::from(Some(ExplicitContextTag1::from(MechType::from(ObjectIdentifier::try_from(NEGOEX).unwrap())))), + response_token: Optional::from(Some(ExplicitContextTag2::from(OctetStringAsn1::from(mech_token)))), + mech_list_mic: Optional::from(None), + })) +} + pub fn generate_neg_token_targ(token: Vec) -> Result> { Ok(ExplicitContextTag1::from(NegTokenTarg { neg_result: Optional::from(Some(ExplicitContextTag0::from(Asn1RawDer(ACCEPT_INCOMPLETE.to_vec())))), @@ -109,13 +121,14 @@ pub fn generate_neg_token_targ(token: Vec) -> Result CmsVersion { -// match v { -// Version::V1 => CmsVersion::V1, -// Version::V2 => CmsVersion::V2, -// Version::V3 => CmsVersion::V3, -// } -// } +pub fn generate_neg_token_completed(token: Vec) -> Result> { + Ok(ExplicitContextTag1::from(NegTokenTarg { + neg_result: Optional::from(Some(ExplicitContextTag0::from(Asn1RawDer(ACCEPT_COMPLETE.to_vec())))), + supported_mech: Optional::from(None), + response_token: Optional::from(Some(ExplicitContextTag2::from(OctetStringAsn1::from(token)))), + mech_list_mic: Optional::from(None), + })) +} pub fn generate_signer_info( p2p_cert: &Certificate, @@ -184,6 +197,21 @@ pub fn get_default_parameters() -> (Vec, Vec, Vec) { ) } +pub fn generate_server_dh_parameters() -> Result { + Ok(DhParameters { + base: Vec::new(), + modulus: Vec::new(), + q: Vec::new(), + private_key: Vec::new(), + other_public_key: None, + server_nonce: Some([ + 142, 91, 149, 4, 44, 55, 103, 6, 75, 168, 207, 165, 162, 197, 172, 27, 2, 108, 166, 10, 240, 52, 179, 24, + 56, 73, 137, 103, 160, 81, 236, 230, + ]), + client_nonce: None, + }) +} + pub fn generate_client_dh_parameters() -> Result { let (p, g, q) = get_default_parameters(); @@ -209,7 +237,6 @@ pub fn generate_client_dh_parameters() -> Result { pub fn generate_pa_datas_for_as_req( p2p_cert: &Certificate, - p2p_ca_cert: &Certificate, kdc_req_body: &KdcReqBody, auth_nonce: u32, dh_parameters: &DhParameters, @@ -260,15 +287,6 @@ pub fn generate_pa_datas_for_as_req( picky_asn1_der::to_vec(&IntegerAsn1::from( public_value, ))? - // vec![ - // 2, 129, 129, 0, 249, 88, 64, 57, 194, 169, 38, 81, 23, 108, 110, 192, 241, 51, 44, 113, 50, 16, - // 179, 173, 72, 57, 1, 65, 37, 199, 206, 229, 194, 186, 223, 122, 110, 117, 97, 237, 76, 86, 102, - // 153, 66, 47, 52, 176, 243, 60, 14, 170, 4, 193, 138, 1, 193, 17, 154, 245, 113, 70, 182, 157, 112, - // 20, 178, 250, 176, 201, 248, 194, 226, 23, 111, 177, 147, 141, 23, 77, 151, 226, 57, 213, 242, 172, - // 56, 40, 47, 191, 10, 135, 217, 26, 111, 24, 45, 196, 40, 228, 106, 72, 173, 249, 255, 19, 254, 97, - // 184, 175, 205, 84, 209, 200, 11, 137, 117, 233, 218, 62, 190, 76, 27, 110, 224, 185, 213, 207, 159, - // 52, 106, 94, - // ], )), }))), supported_cms_types: Optional::from(None), @@ -329,6 +347,281 @@ pub fn generate_neg( }) } +fn conv(s: &str) -> Vec { + let mut d = Vec::new(); + + for b in s.bytes() { + d.push(b); + d.push(0x00); + } + + d +} + +pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result { + let GenerateAuthenticatorOptions { + kdc_rep, + seq_num, + sub_key, + checksum, + channel_bindings, + extension, + } = options; + + let current_date = Utc::now(); + let mut microseconds = current_date.timestamp_subsec_micros(); + if microseconds > MAX_MICROSECONDS_IN_SECOND { + microseconds = MAX_MICROSECONDS_IN_SECOND; + } + + let lsap_token = LsapTokenInfoIntegrity { + flags: 1, + token_il: 0x00002000, + machine_id: [92, 95, 64, 72, 191, 160, 228, 23, 98, 35, 78, 151, 207, 227, 96, 126, 97, 180, 15, 98, 127, 211, 90, 177, 119, 132, 45, 113, 206, 90, 169, 124], + }; + + let mut encoded_lsap_token = Vec::with_capacity(40); + lsap_token.encode(&mut encoded_lsap_token)?; + + let restriction_entry = KerbAdRestrictionEntry { + restriction_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0])), + restriction: ExplicitContextTag1::from(OctetStringAsn1::from(encoded_lsap_token)), + }; + + let authorization_data = Optional::from(Some(ExplicitContextTag8::from(AuthorizationData::from(vec![ + AuthorizationDataInner { + ad_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x01])), + ad_data: ExplicitContextTag1::from(OctetStringAsn1::from( + picky_asn1_der::to_vec(&Asn1SequenceOf::from(vec![AuthorizationDataInner { + ad_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x00, 0x8d])), + ad_data: ExplicitContextTag1::from(OctetStringAsn1::from( + picky_asn1_der::to_vec(&Asn1SequenceOf::from(vec![restriction_entry]))? + )), + }]))? + )), + }, + ])))); + + let cksum = if let Some(ChecksumOptions { + checksum_type, + mut checksum_value, + }) = checksum + { + if checksum_type == AUTHENTICATOR_CHECKSUM_TYPE && channel_bindings.is_some() { + if checksum_value.len() < 20 { + return Err(Error::new( + ErrorKind::InternalError, + format!( + "Invalid authenticator checksum length: expected >= 20 but got {}. ", + checksum_value.len() + ), + )); + } + // [Authenticator Checksum](https://datatracker.ietf.org/doc/html/rfc4121#section-4.1.1) + // 4..19 - Channel binding information (19 inclusive). + checksum_value[4..20] + .copy_from_slice(&compute_md5_channel_bindings_hash(channel_bindings.as_ref().unwrap())); + } + checksum_value = vec![16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 64, 0, 0, 0, 0, 0, 2, 0, 0, 0, 27, 48, 25, 161, 23, 48, 21, 160, 3, 2, 1, 16, 161, 14, 4, 12]; + checksum_value.extend_from_slice(&extension); + println!("checksum_value: {:?} {:?}", checksum_value, checksum_value.len()); + Optional::from(Some(ExplicitContextTag3::from(Checksum { + cksumtype: ExplicitContextTag0::from(IntegerAsn1::from(checksum_type)), + checksum: ExplicitContextTag1::from(OctetStringAsn1::from(checksum_value)), + }))) + } else { + Optional::from(None) + }; + + Ok(Authenticator::from(AuthenticatorInner { + authenticator_bno: ExplicitContextTag0::from(IntegerAsn1::from(vec![KERBEROS_VERSION])), + crealm: ExplicitContextTag1::from(kdc_rep.crealm.0.clone()), + cname: ExplicitContextTag2::from(kdc_rep.cname.0.clone()), + cksum, + // cusec: ExplicitContextTag4::from(IntegerAsn1::from(microseconds.to_be_bytes().to_vec())), + cusec: ExplicitContextTag4::from(IntegerAsn1::from(vec![0x08])), + ctime: ExplicitContextTag5::from(KerberosTime::from(GeneralizedTime::from(current_date))), + subkey: Optional::from(sub_key.map(|sub_key| { + ExplicitContextTag6::from(EncryptionKey { + key_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![CipherSuite::Aes256CtsHmacSha196.into()])), + key_value: ExplicitContextTag1::from(OctetStringAsn1::from(sub_key)), + }) + })), + seq_number: Optional::from(seq_num.map(|seq_num| { + ExplicitContextTag7::from(IntegerAsn1::from_bytes_be_unsigned( + // seq_num.to_be_bytes().to_vec() + vec![0x1e, 0xcb, 0x01, 0x27] + // vec![0x00] + )) + })), + authorization_data, + })) +} + +pub fn generate_pa_datas_for_as_rep( + p2p_cert: &Certificate, + dh_server_nonce: &[u8], + dh_public_key: &[u8], + private_key: &RsaPrivateKey, +) -> Result> { + let kdc_dh_key_info = KdcDhKeyInfo { + subject_public_key: ExplicitContextTag0::from(BitStringAsn1::from(BitString::with_bytes( + picky_asn1_der::to_vec(&IntegerAsn1::from(dh_public_key.to_vec()))? + ))), + nonce: ExplicitContextTag1::from(IntegerAsn1::from(vec![0])), + dh_key_expiration: Optional::from(None), + }; + + let encoded_auth_pack = picky_asn1_der::to_vec(&kdc_dh_key_info)?; + + let mut sha1 = Sha1::new(); + sha1.update(&encoded_auth_pack); + + let digest = sha1.finalize().to_vec(); + println!("digest: {:?}", digest); + + let signed_data = SignedData { + version: CmsVersion::V3, + digest_algorithms: DigestAlgorithmIdentifiers(Asn1SetOf::from(vec![AlgorithmIdentifier::new_sha1()])), + content_info: EncapsulatedContentInfo::new( + ObjectIdentifier::try_from(PKINIT_DH_KEY_DATA).unwrap(), + Some(encoded_auth_pack), + ), + certificates: Optional::from(CertificateSet(vec![CertificateChoices::Certificate(Asn1RawDer( + picky_asn1_der::to_vec(p2p_cert)?, + ))])), + crls: None, + signers_infos: SignersInfos(Asn1SetOf::from(vec![generate_signer_info( + p2p_cert, + digest, + private_key, + )?])), + }; + + let pa_pk_as_rep = PaPkAsRep::DhInfo(ExplicitContextTag0::from(DhRepInfo { + dh_signed_data: ImplicitContextTag0::from(OctetStringAsn1::from(picky_asn1_der::to_vec(&signed_data)?)), + server_dh_nonce: Optional::from(Some(ExplicitContextTag1::from(OctetStringAsn1::from(dh_server_nonce.to_vec())))), + })); + + Ok(vec![PaData { + padata_type: ExplicitContextTag1::from(IntegerAsn1::from(PA_PK_AS_REP.to_vec())), + padata_data: ExplicitContextTag2::from(OctetStringAsn1::from(picky_asn1_der::to_vec(&pa_pk_as_rep)?)), + }]) +} + +pub fn get_bad_ticket() -> Ticket { + ApplicationTag::from(TicketInner { + tkt_vno: ExplicitContextTag0::from(IntegerAsn1::from(vec![5])), + realm: ExplicitContextTag1::from(KerberosStringAsn1::from(IA5String::from_str("WELLKNOWN:PKU2U").unwrap())), + sname: ExplicitContextTag2::from(PrincipalName { + name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![2])), + name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![ + KerberosStringAsn1::from(IA5String::from_str("TERMSRV").unwrap()), + // KerberosStringAsn1::from(IA5String::from_str("192.168.0.117").unwrap()), + KerberosStringAsn1::from(IA5String::from_str("dest.dataans.com").unwrap()), + ])), + }), + enc_part: ExplicitContextTag3::from(EncryptedData { + etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![18])), + kvno: Optional::from(None), + cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![211, 68, 200, 157, 66, 82, 128, 82, 220, 246, 214, 194, 27, 126, 129, 98, 58, 221, 245, 200, 112, 218, 4, 68, 97, 0, 222, 203, 69, 31, 41, 86, 106, 196, 62, 240, 167, 246, 248, 193, 104, 59, 22, 204, 24, 99, 193, 25, 94, 201, 86, 198, 11, 100, 155, 58, 22, 14, 173, 195, 112, 223, 23, 161, 48, 80, 40, 189, 52, 81, 213, 229, 176, 161, 14, 85, 128, 46, 151, 112, 93, 183, 164, 240, 98, 133, 6, 224, 79, 41, 127, 15, 65, 143, 127, 154, 182, 50, 91, 134, 38, 116, 244, 228, 187, 205, 75, 146, 35, 228, 38, 136, 152, 24, 116, 41, 119, 147, 20, 242, 111, 224, 9, 236, 174, 193, 254, 96, 89, 84, 214, 95, 130, 60, 213, 229, 73, 173, 34, 144, 149, 15, 58, 63, 163, 199, 138, 204, 45, 163, 152, 36, 75, 26, 241, 237, 88, 241, 124, 80, 154, 114, 99, 20, 24, 82, 105, 219, 61, 226, 81, 196, 171, 182, 111, 160, 207, 97, 246, 217, 128, 35, 79, 72, 79, 30, 46, 3, 243, 180, 0, 42, 153, 219, 218, 96, 13, 16, 98, 61, 38, 4, 76, 63, 77, 242, 129, 16, 71, 39, 250, 84, 42, 179, 188, 5, 3, 137, 127, 203, 110, 37, 135, 246, 251, 26, 154, 6, 116, 200, 240, 199, 205, 105, 182, 201, 75, 63, 71, 29, 111, 140, 30, 24, 78, 47, 38, 97, 45, 24, 130, 141, 22, 103, 199, 110, 160, 163, 11, 147, 127, 90, 93, 135, 202, 191, 7, 90, 109, 66, 127, 148, 61, 219, 191, 178, 203, 162, 218, 241, 235, 89, 10, 138, 101, 44, 70, 26, 64, 177, 170, 253, 124, 192, 185, 192, 148, 172, 109, 58, 207, 7, 89, 130, 53, 73, 103, 223, 28, 228, 57, 199, 168, 136, 44, 27, 202, 10, 73, 49, 137, 246, 98, 164, 197, 127, 230, 147, 168, 210, 23, 17, 63, 106, 157, 113, 20, 7, 146, 174, 79, 242, 241, 22, 6, 134, 1, 225, 222, 124, 254, 22, 139, 72, 156, 224, 73, 101, 179, 168, 34, 245, 221, 122, 35, 61, 115, 35, 96, 19, 199, 149, 176, 54, 147, 108, 225, 73, 149, 204, 100, 1, 177, 205, 139, 138, 134, 133, 225, 119, 111, 84, 104, 167, 146, 163, 254, 56, 86, 233, 162, 4, 145, 161, 228, 122, 201, 16, 92, 171, 164, 237, 146, 210, 143, 127, 233, 184, 148, 110, 238, 253, 103, 98, 0, 96, 96, 12, 113, 168, 99, 137, 37, 124, 76, 108, 188, 200, 82, 199, 169, 192, 229, 34, 232, 198, 107, 217, 54, 60, 152, 198, 234, 110, 87, 50, 200, 237, 67, 226, 214, 208, 178, 100, 118, 240, 242, 212, 25, 149, 80, 2, 202, 143, 52, 140, 235, 222, 211, 54, 169, 228, 164, 136, 35, 62, 16, 53, 63, 55, 58, 144, 11, 32, 68, 79, 6, 35, 178, 147, 228, 21, 103, 27, 111, 22, 103, 77, 181, 230, 252, 90, 156, 47, 75, 171, 246, 217, 173, 55, 94, 241, 157, 143, 231, 92, 90, 114, 50, 210, 97, 152, 254, 49, 135, 116, 248, 220, 42, 5, 236, 41, 44, 112, 134, 29, 180, 186, 250, 220, 152, 27, 227, 28, 61, 194, 125, 162, 254, 168, 51, 59, 43, 134, 56, 202, 226, 51, 207, 243, 88, 169, 114, 101, 83, 97, 201, 39, 215, 123, 9, 6, 182, 125, 167, 189, 57, 221, 73, 28, 0, 198, 243, 75, 115, 232, 83, 119, 145, 193, 152, 25, 43, 116, 110, 193, 96, 178, 156, 156, 189, 51, 50, 231, 80, 236, 201, 236, 151, 211, 149, 56, 141, 37, 196, 209, 178, 94, 62, 151, 129, 214, 215, 227, 216, 92, 87, 131, 105, 101, 186, 99, 18, 168, 83, 55, 190, 108, 132, 217, 179, 77, 43, 189, 230, 43, 208, 213, 46, 46, 239, 40, 166, 93, 149, 65, 92, 109, 213, 99, 202, 249, 197, 34, 84, 171, 2, 75, 47, 134, 22, 114, 10, 251, 55, 98, 90, 163, 225, 69, 1, 142, 86, 189, 30, 248, 31, 11, 117, 3, 145, 87, 65, 247, 185, 59, 28, 13, 159, 197, 134, 36, 142, 48, 187, 210, 221, 225, 38, 89, 7, 23, 58, 191, 2, 217, 182, 175, 144, 9, 229, 218, 113, 88, 191, 30, 249, 234, 43, 143, 202, 105, 58, 79, 57, 215, 15, 56, 48, 175, 33, 100, 229, 96, 226, 104, 200, 255, 105, 151, 106, 248, 228, 23, 209, 34, 252, 24, 136, 156, 194, 117, 199, 48, 221, 251, 98, 15, 248, 61, 136, 110, 151, 173, 55, 134, 246, 166, 72, 254, 73, 181, 43, 71, 132, 132, 120, 244, 151, 161, 36, 52, 218, 247, 227, 218, 110, 10, 172, 41, 139, 88, 227, 175, 244, 200, 112, 24, 20, 122, 23, 168, 77, 16, 42, 74, 119, 188, 130, 198, 132, 102, 45, 152, 131, 201, 200, 49, 243, 171, 128])), + }), + }) +} + +pub fn generate_as_rep(pa_datas: Vec, session_key: &[u8], new_key: Vec) -> Result { + let lt_req = Utc::now() + .checked_sub_signed(Duration::hours(1)) + .unwrap(); + + let now = Utc::now(); + let end_time = now.clone().checked_add_signed(Duration::hours(1)).unwrap(); + + let enc_part = EncAsRepPart::from(EncKdcRepPart { + key: ExplicitContextTag0::from(EncryptionKey { + key_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![18])), + key_value: ExplicitContextTag1::from(OctetStringAsn1::from(new_key)), + }), + last_req: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![ + LastReqInner { + lr_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0])), + lr_value: ExplicitContextTag1::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(lt_req))), + } + ])), + nonce: ExplicitContextTag2::from(IntegerAsn1::from(vec![0])), + key_expiration: Optional::from(None), + flags: ExplicitContextTag4::from(BitStringAsn1::from(BitString::with_bytes(vec![0, 64, 224, 0, 0]))), + auth_time: ExplicitContextTag5::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(now.clone()))), + start_time: Optional::from(Some(ExplicitContextTag6::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(now))))), + end_time: ExplicitContextTag7::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(end_time.clone()))), + renew_till: Optional::from(Some(ExplicitContextTag8::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(end_time))))), + srealm: ExplicitContextTag9::from( + KerberosStringAsn1::from(IA5String::from_str("WELLKNOWN:PKU2U").unwrap()), + ), + sname: ExplicitContextTag10::from(PrincipalName { + name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![2])), + name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![ + KerberosStringAsn1::from(IA5String::from_str("TERMSRV").unwrap()), + // KerberosStringAsn1::from(IA5String::from_str("192.168.0.117").unwrap()), + KerberosStringAsn1::from(IA5String::from_str("dest.dataans.com").unwrap()), + ])), + }), + caadr: Optional::from(None), + encrypted_pa_data: Optional::from(None), + }); + let enc_encoded = picky_asn1_der::to_vec(&enc_part)?; + + let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); + let enc_encrypted = cipher.encrypt(&session_key, AS_REP_ENC, &enc_encoded)?; + + Ok(AsRep::from(KdcRep { + pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![5])), + msg_type: ExplicitContextTag1::from(IntegerAsn1::from(vec![11])), + padata: Optional::from(Some(ExplicitContextTag2::from(Asn1SequenceOf::from(pa_datas)))), + crealm: ExplicitContextTag3::from(KerberosStringAsn1::from(IA5String::from_str(WELLKNOWN_REALM).unwrap())), + cname: ExplicitContextTag4::from(PrincipalName { + name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x80])), + name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![ + KerberosStringAsn1::from(IA5String::from_str("AzureAD\\s7@dataans.com").unwrap()), + ])), + }), + ticket: ExplicitContextTag5::from(get_bad_ticket()), + enc_part: ExplicitContextTag6::from(EncryptedData { + etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x12])), + kvno: Optional::from(None), + cipher: ExplicitContextTag2::from(OctetStringAsn1::from(enc_encrypted)), + }), + })) +} + +pub fn generate_ap_rep(session_key: &[u8], new_key: &[u8]) -> ApRep { + let now = Utc::now(); + + let ap_rep_enc_part = EncApRepPart::from(EncApRepPartInner { + ctime: ExplicitContextTag0::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(now))), + cusec: ExplicitContextTag1::from(IntegerAsn1::from(vec![8])), + subkey: Optional::from(Some(ExplicitContextTag2::from(EncryptionKey { + key_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![18])), + key_value: ExplicitContextTag1::from(OctetStringAsn1::from(new_key.to_vec())), + }))), + seq_number: Optional::from(Some(ExplicitContextTag3::from(IntegerAsn1::from(vec![49, 95, 171, 251])))), + }); + let encoded_ap_rep_enc_part = picky_asn1_der::to_vec(&ap_rep_enc_part).unwrap(); + println!("encoded_ap_rep_enc_part: {:?}", encoded_ap_rep_enc_part); + let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); + let cipher_data = cipher.encrypt(session_key, AP_REP_ENC, &encoded_ap_rep_enc_part).unwrap(); + + ApRep::from(ApRepInner { + pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![5])), + msg_type: ExplicitContextTag1::from(IntegerAsn1::from(vec![15])), + enc_part: ExplicitContextTag2::from(EncryptedData { + etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![18])), + kvno: Optional::from(None), + cipher: ExplicitContextTag2::from(OctetStringAsn1::from(cipher_data)), + }), + }) +} + #[cfg(test)] mod tests { use oid::ObjectIdentifier; From 94ac25a0668dc73f7e87d9945a5c7443448fcb9f Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 24 Oct 2022 13:56:58 +0300 Subject: [PATCH 12/36] sspi: pku2u: irefactoring; add more validation --- Cargo.toml | 2 + src/sspi/pku2u.rs | 58 ++++-------------- src/sspi/pku2u/cert_utils.rs | 112 +++++++++++++++++++++++++++++++++++ src/sspi/pku2u/config.rs | 2 +- src/sspi/pku2u/extractors.rs | 32 ++-------- src/sspi/pku2u/generators.rs | 16 +---- src/sspi/pku2u/validate.rs | 29 +++++++++ 7 files changed, 161 insertions(+), 90 deletions(-) create mode 100644 src/sspi/pku2u/cert_utils.rs create mode 100644 src/sspi/pku2u/validate.rs diff --git a/Cargo.toml b/Cargo.toml index d76ee0b0..f6309661 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,8 @@ lazy_static = "1.2" serde = "1.0" serde_derive = "1.0" schannel = "0.1.20" +windows-sys = { version = "0.42.0", features = ["Win32_Security_Cryptography", "Win32_Foundation"] } +num-bigint = "0.4.3" winapi = { version = "0.3", features = ["sspi", "rpcdce", "impl-default", "timezoneapi", "wincrypt"] } url = "2.2.2" reqwest = { version = "0.11", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], optional = true, default-features = false } diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index b00439ef..b6b0ba55 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -1,8 +1,10 @@ +mod cert_utils; mod config; mod extractors; mod generators; #[macro_use] mod macros; +mod validate; use std::io::{Read, Write}; use std::str::FromStr; @@ -22,6 +24,8 @@ use picky_krb::negoex::{NegoexMessage, RANDOM_ARRAY_SIZE}; use picky_krb::pkinit::PaPkAsRep; use rand::rngs::OsRng; use rand::Rng; +use rsa::{RsaPublicKey, PublicKey, PaddingScheme, Hash}; +use sha1::{Sha1, Digest}; use uuid::Uuid; use self::generators::{ @@ -36,11 +40,13 @@ use crate::kerberos::client::generators::{ }; use crate::kerberos::server::extractors::extract_sub_session_key_from_ap_rep; use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE, MAX_SIGNATURE, RRC, SECURITY_TRAILER, SERVICE_NAME}; +use crate::sspi::pku2u::cert_utils::validate_server_p2p_certificate; use crate::sspi::pku2u::extractors::{ extract_krb_rep, extract_pa_pk_as_rep, extract_server_dh_public_key, extract_server_nonce, extract_session_key_from_as_rep, extract_pa_pk_as_req, compute_session_key_from_pa_pk_as_req, extract_sub_session_key_from_ap_req, }; use crate::sspi::pku2u::generators::{generate_authenticator, generate_neg_token_init_s, generate_pa_datas_for_as_rep, generate_as_rep, generate_ap_rep, generate_neg_token_completed}; +use crate::sspi::pku2u::validate::validate_signed_data; use crate::sspi::{self, PACKAGE_ID_NONE}; use crate::utils::utf16_bytes_to_utf8_string; use crate::{ @@ -121,7 +127,7 @@ impl Pku2u { Ok(Self { config, state: Pku2uState::Preauthentication, - encryption_params: EncryptionParams::default_for_client(), + encryption_params: EncryptionParams::default_for_server(), auth_identity: None, // conversation_id: Uuid::new_v4(), // for the debugging @@ -153,9 +159,7 @@ impl Pku2u { state: Pku2uState::Negotiate, encryption_params: EncryptionParams::default_for_client(), auth_identity: None, - // conversation_id: Uuid::new_v4(), - // for the debugging - conversation_id: Uuid::from_str("e2506b43-4f8f-3534-f0e4-5ddf02b7f7c4").unwrap(), + conversation_id: Uuid::new_v4(), auth_scheme: None, seq_number: 0, // realm: None, @@ -422,8 +426,6 @@ impl SspiImpl for Pku2u { ); nego.encode(&mut mech_token)?; - // nego.encode(&mut self.negoex_messages)?; - let exchange = Exchange::new( MessageType::InitiatorMetaData, self.conversation_id, @@ -434,7 +436,6 @@ impl SspiImpl for Pku2u { exchange.encode(&mut mech_token)?; self.negoex_messages.extend_from_slice(&mech_token); - // exchange.encode(&mut self.negoex_messages)?; let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; output_token @@ -463,16 +464,12 @@ impl SspiImpl for Pku2u { .0 .0; - println!("buffer: {:?}", buffer); - self.negoex_messages.extend_from_slice(&buffer); let mut reader: Box = Box::new(buffer.as_slice()); let acceptor_nego = Nego::decode(&mut reader, &buffer)?; - println!("acceptor_nego: {:?}", acceptor_nego); - check_conversation_id!(acceptor_nego.header.conversation_id.0, self.conversation_id); check_sequence_number!(acceptor_nego.header.sequence_num, self.next_seq_number()); @@ -497,31 +494,13 @@ impl SspiImpl for Pku2u { } let acceptor_exchange_data = &buffer[(acceptor_nego.header.message_len as usize)..]; - println!("acceptor_exchage data: {:?}", acceptor_exchange_data); let mut reader: Box = Box::new(acceptor_exchange_data); - let acceptor_exchange = Exchange::decode(&mut reader, acceptor_exchange_data)?; - println!("acceptor_exchange: {:?}", acceptor_exchange); - check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); check_sequence_number!(acceptor_exchange.header.sequence_num, self.next_seq_number()); check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); - println!("all parsed and verified"); - - let credentials = builder - .credentials_handle - .as_ref() - .unwrap() - .as_ref() - .ok_or_else(|| Error { - error_type: ErrorKind::NoCredentials, - description: "No credentials provided".to_owned(), - })?; - - let _username = utf16_bytes_to_utf8_string(&credentials.user); - let mut mech_token = Vec::new(); let kdc_req_body = generate_as_req_kdc_body(&GenerateAsReqOptions { @@ -545,7 +524,6 @@ impl SspiImpl for Pku2u { let exchange_data = picky_asn1_der::to_vec(&generate_neg(generate_as_req(&pa_datas, kdc_req_body), AS_REQ_TOKEN_ID))?; - println!("exchange_data: {:?}", exchange_data); self.gss_api_messages.extend_from_slice(&exchange_data); let exchange = Exchange::new( @@ -560,7 +538,6 @@ impl SspiImpl for Pku2u { self.negoex_messages.extend_from_slice(&mech_token); let response_token = picky_asn1_der::to_vec(&generate_neg_token_targ(mech_token)?)?; - // println!("response_token: {:?}", response_token); let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; output_token.buffer.write_all(&response_token)?; @@ -587,8 +564,6 @@ impl SspiImpl for Pku2u { .0 .0; - // println!("AsExchange buffer: {:?}", buffer); - self.negoex_messages.extend_from_slice(&buffer); let acceptor_exchange = Exchange::decode(buffer.as_slice(), &buffer)?; @@ -602,8 +577,6 @@ impl SspiImpl for Pku2u { let (as_rep, _): (AsRep, _) = extract_krb_rep(&acceptor_exchange.exchange)?; - // todo: validate server's certificate - let dh_rep_info = match extract_pa_pk_as_rep(&as_rep)? { PaPkAsRep::DhInfo(dh) => dh.0, PaPkAsRep::EncKeyPack(_) => { @@ -614,19 +587,16 @@ impl SspiImpl for Pku2u { } }; - println!("dh_rep_info: {:?}", dh_rep_info); - let server_nonce = extract_server_nonce(&dh_rep_info)?; - println!("server_nonce: {:?}", server_nonce); - self.dh_parameters.server_nonce = Some(server_nonce); let signed_data: SignedData = picky_asn1_der::from_bytes(&dh_rep_info.dh_signed_data.0)?; - // validate server's signature + // todo: validate server's certificate + let rsa_public_key = validate_server_p2p_certificate(&signed_data, &self.config.p2p_ca_certificate)?; + validate_signed_data(&signed_data, &rsa_public_key)?; let public_key = extract_server_dh_public_key(&signed_data)?; - println!("public key: {:?}", public_key); self.dh_parameters.other_public_key = Some(public_key); self.encryption_params.encryption_type = @@ -646,14 +616,12 @@ impl SspiImpl for Pku2u { .cipher() .as_ref(), )?); - println!("session key: {:?}", self.encryption_params.session_key); self.encryption_params.session_key = Some(extract_session_key_from_as_rep( &as_rep, self.encryption_params.session_key.as_ref().unwrap(), &self.encryption_params, )?); - println!("session key: {:?}", self.encryption_params.session_key); let exchange_seq_number = self.next_seq_number(); let verify_seq_number = self.next_seq_number(); @@ -689,16 +657,12 @@ impl SspiImpl for Pku2u { self.auth_scheme.unwrap(), picky_asn1_der::to_vec(&generate_neg(ap_req, AP_REQ_TOKEN_ID))?, ); - println!("exchange: {:?}", exchange); exchange.encode(&mut mech_token)?; exchange.encode(&mut self.negoex_messages)?; - // println!("negoex messages: {:?}", self.negoex_messages); - let c2 = ChecksumSuite::HmacSha196Aes256.hasher().checksum( &test_session_key, - // self.encryption_params.session_key.as_ref().unwrap(), 25, &self.negoex_messages, )?; diff --git a/src/sspi/pku2u/cert_utils.rs b/src/sspi/pku2u/cert_utils.rs new file mode 100644 index 00000000..11401720 --- /dev/null +++ b/src/sspi/pku2u/cert_utils.rs @@ -0,0 +1,112 @@ +use picky_asn1_x509::{ + signed_data::{CertificateChoices, SignedData}, + Certificate, PublicKey, +}; +use rsa::{BigUint, RsaPublicKey}; +use schannel::cert_store::CertStore; +use winapi::um::wincrypt::CryptExportKey; + +use crate::{Error, ErrorKind, Result}; + +/// Tries to find the device certificate and its private key +/// Requirements for the device certificate: +/// 1. Issuer CN = MS-Organization-Access +/// 2. Issuer OU = 82dbaca4-3e81-46ca-9c73-0950c1eaca97 +pub fn extract_device_certificate() -> Result<()> { + let cert_store = CertStore::open_local_machine("My").unwrap(); + let certs = cert_store.certs(); + + for cert in certs { + let certificate: Certificate = picky_asn1_der::from_bytes(cert.to_der())?; + let mut cn = false; + let mut ou = false; + + for issuer_info in certificate.tbs_certificate.issuer.0 .0 { + for is in issuer_info.0 { + println!("is: {:?}", is); + } + } + + if cn && ou { + println!("found"); + let private_key = cert.private_key().acquire().unwrap(); + // let p = cert. + + use schannel::key_handle::KeyHandle; + + let mut v1 = vec![0; 5000]; + let mut len = 0; + + match private_key { + KeyHandle::CryptProv(key_handle) => { + // key_handle. + unsafe { + // + let result = CryptExportKey(0, 0, 0, 0, v1.as_mut_ptr(), &mut len); + } + } + KeyHandle::NcryptKey(ncrypt) => { + // let r = ncrypt.borrow_mut(); + } + } + } + println!("==============="); + } + + Ok(()) +} + +/// validates server's p2p certificate. +/// If certificate is valid then return its public key. +pub fn validate_server_p2p_certificate(signed_data: &SignedData, _ca_cert: &Certificate) -> Result { + let certificates = &signed_data.certificates.0 .0; + + for certificate in certificates { + let cert: Certificate = match certificate { + CertificateChoices::Certificate(cert) => picky_asn1_der::from_bytes(&cert.0)?, + _ => { + return Err(Error::new( + ErrorKind::CertificateUnknown, + "Received unknown certificate format".into(), + )) + } + }; + + let public_key = match cert.tbs_certificate.subject_public_key_info.subject_public_key { + PublicKey::Rsa(rsa) => rsa, + _ => { + return Err(Error::new( + ErrorKind::CertificateUnknown, + "Received certificate has unsupported public key type. Only RSA is supported.".into(), + )) + } + } + .0; + + return Ok(RsaPublicKey::new( + BigUint::from_bytes_be(&public_key.modulus.0), + BigUint::from_bytes_be(&public_key.public_exponent.0), + ) + .map_err(|err| { + Error::new( + ErrorKind::InvalidToken, + format!("Invalid certificate public key: {:?}", err), + ) + })?); + } + + Err(Error::new( + ErrorKind::CertificateUnknown, + "Received invalid server certificates".into(), + )) +} + +#[cfg(test)] +mod tests { + use super::extract_device_certificate; + + #[test] + fn ts() { + extract_device_certificate().unwrap(); + } +} diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index fdb21232..b069f6ec 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -235,7 +235,7 @@ impl Default for Pku2uConfig { ]) .unwrap(), p2p_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 79, 38, 21, 44, 164, 255, 156, 167, 130, 123, 29, 28, 60, 212, 242, 124, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 51, 50, 49, 52, 48, 53, 57, 90, 23, 13, 50, 50, 49, 48, 50, 51, 50, 50, 52, 53, 53, 57, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 62, 48, 214, 170, 131, 166, 29, 214, 158, 53, 168, 108, 74, 143, 55, 188, 93, 63, 132, 103, 117, 132, 69, 132, 238, 40, 254, 48, 126, 93, 190, 96, 2, 79, 83, 248, 249, 79, 41, 230, 97, 115, 39, 90, 145, 222, 19, 31, 8, 57, 166, 113, 251, 166, 225, 24, 23, 14, 111, 57, 19, 97, 96, 251, 109, 46, 38, 181, 19, 6, 187, 27, 224, 58, 199, 116, 169, 123, 172, 63, 199, 92, 3, 174, 79, 232, 55, 207, 41, 200, 232, 51, 158, 250, 57, 199, 200, 164, 8, 143, 83, 77, 204, 217, 37, 230, 81, 227, 242, 117, 18, 153, 230, 208, 14, 179, 72, 79, 71, 52, 203, 22, 90, 193, 45, 70, 152, 29, 182, 9, 18, 45, 149, 223, 42, 207, 0, 79, 49, 143, 91, 178, 67, 86, 136, 114, 200, 104, 15, 131, 111, 211, 0, 2, 126, 27, 124, 218, 73, 77, 39, 107, 156, 82, 127, 208, 188, 234, 230, 23, 143, 106, 129, 106, 115, 116, 115, 113, 212, 132, 167, 166, 1, 227, 114, 245, 70, 229, 209, 7, 223, 144, 146, 85, 221, 9, 35, 43, 118, 225, 113, 54, 174, 26, 166, 45, 253, 97, 7, 54, 151, 35, 116, 190, 41, 218, 74, 248, 10, 113, 2, 155, 68, 138, 217, 41, 56, 28, 85, 121, 33, 189, 9, 34, 158, 234, 99, 72, 236, 105, 39, 110, 205, 48, 54, 8, 101, 90, 168, 17, 238, 96, 114, 27, 218, 134 + 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 56, 199, 138, 113, 113, 58, 21, 17, 37, 104, 118, 83, 148, 160, 63, 193, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 52, 49, 48, 51, 50, 48, 57, 90, 23, 13, 50, 50, 49, 48, 50, 52, 49, 49, 51, 55, 48, 57, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 55, 35, 124, 33, 205, 22, 227, 239, 173, 71, 4, 177, 223, 179, 191, 96, 63, 112, 49, 209, 74, 130, 56, 189, 89, 66, 38, 42, 201, 244, 199, 93, 54, 247, 191, 227, 198, 165, 243, 179, 77, 213, 212, 12, 86, 66, 47, 202, 1, 128, 17, 77, 164, 244, 124, 93, 140, 37, 98, 28, 199, 238, 208, 108, 88, 81, 58, 182, 228, 252, 219, 210, 156, 107, 110, 242, 51, 126, 194, 199, 232, 88, 5, 81, 115, 240, 21, 11, 29, 135, 87, 104, 255, 151, 172, 242, 199, 48, 174, 7, 163, 25, 1, 219, 101, 151, 149, 173, 173, 217, 228, 16, 48, 61, 93, 228, 110, 176, 86, 193, 176, 23, 27, 158, 246, 199, 238, 85, 204, 161, 202, 170, 224, 3, 118, 133, 222, 120, 175, 152, 241, 112, 245, 8, 47, 175, 229, 140, 69, 100, 201, 59, 160, 202, 181, 88, 221, 90, 93, 244, 89, 6, 128, 201, 19, 110, 22, 241, 121, 57, 250, 9, 120, 50, 136, 113, 20, 243, 114, 47, 114, 76, 140, 250, 153, 218, 105, 42, 230, 101, 118, 48, 96, 201, 87, 163, 44, 137, 238, 101, 161, 189, 229, 155, 142, 80, 189, 200, 35, 120, 4, 255, 101, 174, 65, 166, 92, 70, 40, 119, 39, 32, 36, 43, 122, 186, 4, 95, 170, 66, 98, 152, 112, 80, 152, 211, 57, 14, 244, 39, 27, 5, 112, 49, 66, 30, 199, 129, 82, 103, 245, 184, 76, 142, 16, 221 ]) .unwrap(), p2p_ca_certificate: picky_asn1_der::from_bytes(&[ diff --git a/src/sspi/pku2u/extractors.rs b/src/sspi/pku2u/extractors.rs index 09bfb3d7..f3d90503 100644 --- a/src/sspi/pku2u/extractors.rs +++ b/src/sspi/pku2u/extractors.rs @@ -22,20 +22,7 @@ use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE}; use crate::{Error, ErrorKind, Result}; pub fn extract_krb_rep<'a, T: Deserialize<'a>>(mut data: &'a [u8]) -> Result<(T, &'a [u8])> { - let _oid: ApplicationTag = - picky_asn1_der::from_reader(&mut data).map_err(|e| Error::new(ErrorKind::InvalidToken, format!("{:?}", e)))?; - - // let oid: ObjectIdentifierAsn1 = picky_asn1_der::from_bytes(&oid.0.0)?; - - // let mut token_id = [0, 0]; - // data.read_exact(&mut token_id)?; - - // if token_id != AS_REP_TOKEN_ID { - // return Err(Error::new( - // ErrorKind::InvalidToken, - // format!("Invalid token id: {:?}. Expected: {:?}", token_id, AS_REP_TOKEN_ID), - // )); - // } + let _oid: ApplicationTag = picky_asn1_der::from_reader(&mut data)?; Ok((picky_asn1_der::from_bytes(data)?, data)) } @@ -47,13 +34,13 @@ pub fn extract_pa_pk_as_rep(as_rep: &AsRep) -> Result { .padata .0 .as_ref() - .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "pa-datas is not present in as rep".into()))? + .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "pa-datas is not present in as-rep".into()))? .iter() .find(|pa_data| &pa_data.padata_type.0 .0 == &PA_PK_AS_REP) .ok_or_else(|| { Error::new( ErrorKind::InvalidToken, - "PA_PK_AS_REP is not present in pa-datas of the as rep".into(), + "PA_PK_AS_REP is not present in pa-datas of the as-rep".into(), ) })? .padata_data @@ -130,10 +117,8 @@ pub fn extract_session_key_from_as_rep(as_rep: &AsRep, key: &[u8], enc_params: & let enc_data = cipher .decrypt(&key, AS_REP_ENC, &as_rep.0.enc_part.0.cipher.0 .0)?; - println!("as rep decrypted!"); let enc_as_rep_part: EncAsRepPart = picky_asn1_der::from_bytes(&enc_data)?; - println!("{:?}", enc_as_rep_part); Ok(enc_as_rep_part.0.key.0.key_value.0.to_vec()) } @@ -168,20 +153,13 @@ pub fn compute_session_key_from_pa_pk_as_req(pa_pk_as_req: &PaPkAsReq, dh_server c => unimplemented!("wrong content value: {:?}", c), })?; - println!("server: auth pack decoded: {:?}", auth_pack); - let dh_client_public_info = &auth_pack.client_public_value.0.as_ref().unwrap().0; - println!("dh_client_public_info: {:?}", dh_client_public_info); - let g = dh_client_public_info.key_info.key_info.g.0.clone(); let p = dh_client_public_info.key_info.key_info.p.0.clone(); let q = dh_client_public_info.key_info.key_info.q.0.clone(); - println!("try to parse client public: {:?}", dh_client_public_info.key_value.0.inner()); - println!("to decode as int: {:?}", &dh_client_public_info.key_value.0.inner()[1..]); let dh_client_public: IntegerAsn1 = picky_asn1_der::from_bytes(&dh_client_public_info.key_value.0.inner()[1..])?; - println!("client public parsed"); let dh_client_public = dh_client_public.0; let mut rng = OsRng::default(); @@ -207,9 +185,9 @@ pub fn compute_session_key_from_pa_pk_as_req(pa_pk_as_req: &PaPkAsReq, dh_server pub fn extract_sub_session_key_from_ap_req(ap_req: &ApReq, session_key: &[u8]) -> Result> { let encrypted = &ap_req.0.authenticator.0.cipher.0.0; let decrypted = CipherSuite::Aes256CtsHmacSha196.cipher().decrypt(session_key, AP_REQ_AUTHENTICATOR, encrypted)?; - println!("sub decrypted"); + let auth: Authenticator = picky_asn1_der::from_bytes(&decrypted)?; - println!("sub parsed"); + Ok(auth.0.subkey.0.unwrap().0.key_value.0.0) } diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index b63adef1..f1fc91c5 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -135,12 +135,6 @@ pub fn generate_signer_info( digest: Vec, private_key: &RsaPrivateKey, ) -> Result { - println!("{:x?}", p2p_cert.tbs_certificate.serial_number); - println!( - "{:?}", - picky_asn1_der::to_vec(&p2p_cert.tbs_certificate.serial_number).unwrap() - ); - let signed_attributes = Asn1SetOf::from(vec![ Attribute { ty: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("1.2.840.113549.1.9.3").unwrap()), @@ -168,8 +162,6 @@ pub fn generate_signer_info( ) .unwrap(); - println!("signature: {} {:?}", signature.len(), signature); - Ok(SignerInfo { version: CmsVersion::V1, sid: SignerIdentifier::IssuerAndSerialNumber(IssuerAndSerialNumber { @@ -216,11 +208,8 @@ pub fn generate_client_dh_parameters() -> Result { let (p, g, q) = get_default_parameters(); let mut rng = OsRng::default(); - let private_key = generate_private_key(&q, &mut rng); - println!("dh private_key: {:?}", private_key); - Ok(DhParameters { base: g, modulus: p, @@ -259,12 +248,9 @@ pub fn generate_pa_datas_for_as_req( let public_value = compute_public_key(&dh_parameters.private_key, &dh_parameters.modulus, &dh_parameters.base); - println!("public key value len: {:?} bytes", public_value); - let auth_pack = AuthPack { pk_authenticator: ExplicitContextTag0::from(PkAuthenticator { - // cusec: ExplicitContextTag0::from(IntegerAsn1::from(microseconds.to_be_bytes().to_vec())), - cusec: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x04, 0x4e, 0x14])), + cusec: ExplicitContextTag0::from(IntegerAsn1::from(microseconds.to_be_bytes().to_vec())), ctime: ExplicitContextTag1::from(KerberosTime::from(GeneralizedTime::from(current_date))), // nonce: ExplicitContextTag2::from(IntegerAsn1::from(auth_nonce.to_be_bytes().to_vec())), nonce: ExplicitContextTag2::from(IntegerAsn1::from(vec![0])), diff --git a/src/sspi/pku2u/validate.rs b/src/sspi/pku2u/validate.rs new file mode 100644 index 00000000..e3b95c8a --- /dev/null +++ b/src/sspi/pku2u/validate.rs @@ -0,0 +1,29 @@ +use picky_asn1::wrapper::Asn1SetOf; +use picky_asn1_x509::signed_data::SignedData; +use rsa::{Hash, PaddingScheme, PublicKey, RsaPublicKey}; +use sha1::{Digest, Sha1}; + +use crate::{Error, ErrorKind, Result}; + +pub fn validate_signed_data(signed_data: &SignedData, rsa_public_key: &RsaPublicKey) -> Result<()> { + let signer_info = signed_data + .signers_infos + .0 + .0 + .get(0) + .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "Missing signers_infos in signed data".into()))?; + + let signed_attributes = Asn1SetOf::from(signer_info.signed_attrs.0 .0 .0.clone()); + + let mut sha1 = Sha1::new(); + sha1.update(&picky_asn1_der::to_vec(&signed_attributes)?); + let hashed_signed_attributes = sha1.finalize().to_vec(); + + rsa_public_key + .verify( + PaddingScheme::PKCS1v15Sign { hash: Some(Hash::SHA1) }, + &hashed_signed_attributes, + &signer_info.signature.0 .0, + ) + .map_err(|_| Error::new(ErrorKind::InvalidToken, "Invalid signed data signature".into())) +} From f249e11cab9656f09657477b5fbed81e419808af Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 24 Oct 2022 17:04:23 +0300 Subject: [PATCH 13/36] sspi: pku2u: refactoring; add more validation --- src/sspi/pku2u.rs | 254 +++++++++++++++------------------ src/sspi/pku2u/config.rs | 2 +- src/sspi/pku2u/extractors.rs | 267 +++++------------------------------ src/sspi/pku2u/generators.rs | 207 +++++++++++++++++---------- src/sspi/pku2u/macros.rs | 6 + 5 files changed, 284 insertions(+), 452 deletions(-) diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index b6b0ba55..8cdbac4e 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -12,40 +12,45 @@ use std::str::FromStr; pub use config::Pku2uConfig; use lazy_static::lazy_static; use picky_asn1_x509::signed_data::SignedData; -use picky_krb::constants::gss_api::{AP_REQ_TOKEN_ID, AS_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE, AS_REP_TOKEN_ID, AP_REP_TOKEN_ID}; +use picky_krb::constants::gss_api::{ + AP_REP_TOKEN_ID, AP_REQ_TOKEN_ID, AS_REP_TOKEN_ID, AS_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE, +}; use picky_krb::constants::key_usages::{ACCEPTOR_SIGN, INITIATOR_SIGN}; use picky_krb::crypto::diffie_hellman::{generate_key, DhNonce}; use picky_krb::crypto::{ChecksumSuite, CipherSuite}; -use picky_krb::gss_api::{NegTokenTarg1, WrapToken, ApplicationTag0, GssApiNegInit, NegTokenInit}; -use picky_krb::messages::{ApRep, AsRep, AsReq, ApReq}; +use picky_krb::gss_api::{NegTokenInit, NegTokenTarg1, WrapToken}; +use picky_krb::messages::{ApRep, ApReq, AsRep, AsReq}; use picky_krb::negoex::data_types::MessageType; use picky_krb::negoex::messages::{Exchange, Nego, Verify}; use picky_krb::negoex::{NegoexMessage, RANDOM_ARRAY_SIZE}; use picky_krb::pkinit::PaPkAsRep; use rand::rngs::OsRng; use rand::Rng; -use rsa::{RsaPublicKey, PublicKey, PaddingScheme, Hash}; -use sha1::{Sha1, Digest}; use uuid::Uuid; use self::generators::{ generate_client_dh_parameters, generate_neg, generate_neg_token_init, generate_neg_token_targ, - generate_pa_datas_for_as_req, generate_pku2u_nego_req, DH_NONCE_LEN, WELLKNOWN_REALM, generate_server_dh_parameters, + generate_pa_datas_for_as_req, generate_pku2u_nego_req, generate_server_dh_parameters, DH_NONCE_LEN, + WELLKNOWN_REALM, }; use crate::builders::ChangePassword; use crate::internal::SspiImpl; use crate::kerberos::client::generators::{ - generate_ap_req, generate_as_req, generate_as_req_kdc_body, ChecksumOptions, - GenerateAsReqOptions, GenerateAuthenticatorOptions, AUTHENTICATOR_DEFAULT_CHECKSUM, + generate_ap_req, generate_as_req, generate_as_req_kdc_body, ChecksumOptions, GenerateAsReqOptions, + GenerateAuthenticatorOptions, AUTHENTICATOR_DEFAULT_CHECKSUM, }; use crate::kerberos::server::extractors::extract_sub_session_key_from_ap_rep; use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE, MAX_SIGNATURE, RRC, SECURITY_TRAILER, SERVICE_NAME}; use crate::sspi::pku2u::cert_utils::validate_server_p2p_certificate; use crate::sspi::pku2u::extractors::{ - extract_krb_rep, extract_pa_pk_as_rep, extract_server_dh_public_key, extract_server_nonce, - extract_session_key_from_as_rep, extract_pa_pk_as_req, compute_session_key_from_pa_pk_as_req, extract_sub_session_key_from_ap_req, + compute_session_key_from_pa_pk_as_req, extract_krb_rep, extract_pa_pk_as_rep, extract_pa_pk_as_req, + extract_server_dh_public_key, extract_server_nonce, extract_session_key_from_as_rep, + extract_sub_session_key_from_ap_req, +}; +use crate::sspi::pku2u::generators::{ + generate_ap_rep, generate_as_rep, generate_authenticator, generate_neg_token_completed, generate_neg_token_init_s, + generate_pa_datas_for_as_rep, }; -use crate::sspi::pku2u::generators::{generate_authenticator, generate_neg_token_init_s, generate_pa_datas_for_as_rep, generate_as_rep, generate_ap_rep, generate_neg_token_completed}; use crate::sspi::pku2u::validate::validate_signed_data; use crate::sspi::{self, PACKAGE_ID_NONE}; use crate::utils::utf16_bytes_to_utf8_string; @@ -53,7 +58,7 @@ use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, AuthIdentityBuffers, CertTrustStatus, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, EncryptionFlags, Error, ErrorKind, InitializeSecurityContextResult, PackageCapabilities, PackageInfo, Result, SecurityBuffer, SecurityBufferType, - SecurityPackageType, SecurityStatus, Sspi, SspiEx, ServerResponseFlags, + SecurityPackageType, SecurityStatus, ServerResponseFlags, Sspi, SspiEx, }; pub const PKG_NAME: &str = "Pku2u"; @@ -63,6 +68,14 @@ pub const AZURE_AD_PREFIX: &str = "AzureAD\\"; /// Default NEGOEX authentication scheme pub const AUTH_SCHEME: &str = "0d53335c-f9ea-4d0d-b2ec-4ae3786ec308"; +/// sealed = true +/// other flags = false +pub const CLIENT_WRAP_TOKEN_FLAGS: u8 = 2; +/// sealed = true +/// send by acceptor = true +/// acceptor subkey = false +pub const SERVER_WRAP_TOKEN_FLAGS: u8 = 3; + lazy_static! { pub static ref PACKAGE_INFO: PackageInfo = PackageInfo { capabilities: PackageCapabilities::empty(), @@ -84,6 +97,12 @@ pub enum Pku2uState { Final, } +#[derive(Debug, Clone)] +enum Pku2uMode { + Client, + Server, +} + #[derive(Debug, Clone)] pub struct DhParameters { // g @@ -102,6 +121,7 @@ pub struct DhParameters { #[derive(Debug, Clone)] pub struct Pku2u { + mode: Pku2uMode, config: Pku2uConfig, state: Pku2uState, encryption_params: EncryptionParams, @@ -109,52 +129,45 @@ pub struct Pku2u { conversation_id: Uuid, auth_scheme: Option, seq_number: u32, - // realm: Option, - auth_nonce: u32, dh_parameters: DhParameters, - // all sent and received NEGOEX messages in one vector + // all sent and received NEGOEX messages concatenated in one vector // we need it for the further checksum calculation // https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-NEGOEX/%5bMS-NEGOEX%5d.pdf // The checksum is performed on all previous NEGOEX messages in the context negotiation. negoex_messages: Vec, + // all sent and received GSS-API messages concatenated in one vector + // we need it for the further checksum calculation + // https://datatracker.ietf.org/doc/html/draft-zhu-pku2u-04#section-6 + // The checksum is performed on all previous NEGOEX messages in the context negotiation. gss_api_messages: Vec, - exchange_data: Vec, negoex_random: [u8; RANDOM_ARRAY_SIZE], } impl Pku2u { pub fn new_server_from_config(config: Pku2uConfig) -> Result { Ok(Self { + mode: Pku2uMode::Server, config, state: Pku2uState::Preauthentication, encryption_params: EncryptionParams::default_for_server(), auth_identity: None, - // conversation_id: Uuid::new_v4(), - // for the debugging - conversation_id: Uuid::from_str("e2506b43-4f8f-3534-f0e4-5ddf02b7f7c4").unwrap(), - auth_scheme: Some(Uuid::from_str("0d53335c-f9ea-4d0d-b2ec-4ae3786ec308").unwrap()), + conversation_id: Uuid::default(), + auth_scheme: Some(Uuid::from_str(AUTH_SCHEME).unwrap()), seq_number: 2, - // realm: None, // https://www.rfc-editor.org/rfc/rfc4556.html#section-3.2.3 // Contains the nonce in the pkAuthenticator field in the request if the DH keys are NOT reused, // 0 otherwise. - auth_nonce: 0, // generate dh parameters at the start in order to not waste time during authorization dh_parameters: generate_server_dh_parameters()?, negoex_messages: Vec::new(), gss_api_messages: Vec::new(), - exchange_data: Vec::new(), - // negoex_random: OsRng::default().gen::<[u8; RANDOM_ARRAY_SIZE]>(), - // for the debugging - negoex_random: [ - 10, 209, 111, 101, 206, 151, 53, 222, 225, 32, 241, 24, 15, 201, 210, 38, 133, 175, 97, 251, 27, 195, - 152, 39, 9, 97, 115, 227, 194, 196, 54, 245, - ], + negoex_random: OsRng::default().gen::<[u8; RANDOM_ARRAY_SIZE]>(), }) } pub fn new_client_from_config(config: Pku2uConfig) -> Result { Ok(Self { + mode: Pku2uMode::Client, config, state: Pku2uState::Negotiate, encryption_params: EncryptionParams::default_for_client(), @@ -162,22 +175,14 @@ impl Pku2u { conversation_id: Uuid::new_v4(), auth_scheme: None, seq_number: 0, - // realm: None, // https://www.rfc-editor.org/rfc/rfc4556.html#section-3.2.3 // Contains the nonce in the pkAuthenticator field in the request if the DH keys are NOT reused, // 0 otherwise. - auth_nonce: 0, // generate dh parameters at the start in order to not waste time during authorization dh_parameters: generate_client_dh_parameters()?, negoex_messages: Vec::new(), gss_api_messages: Vec::new(), - exchange_data: Vec::new(), - // negoex_random: OsRng::default().gen::<[u8; RANDOM_ARRAY_SIZE]>(), - // for the debugging - negoex_random: [ - 10, 209, 111, 101, 206, 151, 53, 222, 225, 32, 241, 24, 15, 201, 210, 38, 133, 175, 97, 251, 27, 195, - 152, 39, 9, 97, 115, 227, 194, 196, 54, 245, - ], + negoex_random: OsRng::default().gen::<[u8; RANDOM_ARRAY_SIZE]>(), }) } @@ -222,20 +227,17 @@ impl Sspi for Pku2u { )); }; let key_usage = self.encryption_params.sspi_encrypt_key_usage; - println!("encrypt key {:?} usage: {}", key, key_usage); - // sequence number is always 0 in Pku2u let mut wrap_token = WrapToken::with_seq_number(sequence_number as u64); - wrap_token.flags = 2; - // wrap_token.flags = 3; + wrap_token.flags = match self.mode { + Pku2uMode::Client => CLIENT_WRAP_TOKEN_FLAGS, + Pku2uMode::Server => SERVER_WRAP_TOKEN_FLAGS, + }; let mut payload = data.buffer.to_vec(); payload.extend_from_slice(&wrap_token.header()); - println!("data to encrypt: {:?} {}", payload, sequence_number); - let mut checksum = cipher.encrypt(key, key_usage, &payload)?; - // let mut checksum = cipher.encrypt(key, 22, &payload)?; checksum.rotate_right(RRC.into()); wrap_token.set_rrc(RRC); @@ -269,9 +271,6 @@ impl Sspi for Pku2u { encrypted.extend_from_slice(&data.buffer); - println!("message to decrypt: encrypted mic: {:?}", encrypted); - // panic!("{:?}", encrypted); - let cipher = self .encryption_params .encryption_type @@ -291,15 +290,12 @@ impl Sspi for Pku2u { )); }; let key_usage = self.encryption_params.sspi_decrypt_key_usage; - println!("decrypt key {:?} usage: {}", key, key_usage); let mut wrap_token = WrapToken::decode(encrypted.as_slice())?; - wrap_token.checksum.rotate_left(RRC.into()); let mut decrypted = cipher.decrypt(key, key_usage, &wrap_token.checksum)?; - // let mut decrypted = cipher.decrypt(key, 24, &wrap_token.checksum)?; - println!("decrypted: {:?}", decrypted); + // remove wrap token header decrypted.truncate(decrypted.len() - WrapToken::header_len()); @@ -402,10 +398,10 @@ impl SspiImpl for Pku2u { Pku2uState::Negotiate => { let auth_scheme = Uuid::from_str(AUTH_SCHEME).unwrap(); - let credentials = builder + let credentials = check_if_empty!(builder .credentials_handle - .as_ref() - .unwrap() + .as_ref(), + "credentials are not set") .as_ref() .ok_or_else(|| Error { error_type: ErrorKind::NoCredentials, @@ -517,7 +513,6 @@ impl SspiImpl for Pku2u { let pa_datas = generate_pa_datas_for_as_req( &self.config.p2p_certificate, &kdc_req_body, - self.auth_nonce, &self.dh_parameters, &self.config.device_private_key, )?; @@ -530,7 +525,7 @@ impl SspiImpl for Pku2u { MessageType::ApRequest, self.conversation_id, self.next_seq_number(), - self.auth_scheme.unwrap(), + check_if_empty!(self.auth_scheme, "auth scheme is not set"), exchange_data, ); exchange.encode(&mut mech_token)?; @@ -602,31 +597,33 @@ impl SspiImpl for Pku2u { self.encryption_params.encryption_type = Some(CipherSuite::try_from(as_rep.0.enc_part.0.etype.0 .0.as_slice())?); self.encryption_params.session_key = Some(generate_key( - self.dh_parameters.other_public_key.as_ref().unwrap(), + check_if_empty!(self.dh_parameters.other_public_key.as_ref(), "dh public key is not set"), &self.dh_parameters.private_key, &self.dh_parameters.modulus, Some(DhNonce { - client_nonce: self.dh_parameters.client_nonce.as_ref().unwrap(), - server_nonce: self.dh_parameters.server_nonce.as_ref().unwrap(), + client_nonce: check_if_empty!(self.dh_parameters.client_nonce.as_ref(), "dh client none is not set"), + server_nonce: check_if_empty!(self.dh_parameters.server_nonce.as_ref(), "dh server nonce is not set"), }), - self.encryption_params + check_if_empty!(self.encryption_params .encryption_type - .as_ref() - .unwrap() + .as_ref(), + "encryption type is not set") .cipher() .as_ref(), )?); self.encryption_params.session_key = Some(extract_session_key_from_as_rep( &as_rep, - self.encryption_params.session_key.as_ref().unwrap(), + check_if_empty!(self.encryption_params.session_key.as_ref(), "session key is not set"), &self.encryption_params, )?); let exchange_seq_number = self.next_seq_number(); let verify_seq_number = self.next_seq_number(); - let test_session_key = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; + let test_session_key = [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, + ]; let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, @@ -638,11 +635,13 @@ impl SspiImpl for Pku2u { checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), }), channel_bindings: None, - extension: ChecksumSuite::HmacSha196Aes256.hasher().checksum(&test_session_key, 41, &self.gss_api_messages).unwrap(), + extension: ChecksumSuite::HmacSha196Aes256 + .hasher() + .checksum(&test_session_key, 41, &self.gss_api_messages)?, })?; let ap_req = generate_ap_req( as_rep.0.ticket.0, - self.encryption_params.session_key.as_ref().unwrap(), + check_if_empty!(self.encryption_params.session_key.as_ref(), "session key is not set"), &authenticator, &self.encryption_params, &[0x20, 0x00, 0x00, 0x00], @@ -654,41 +653,26 @@ impl SspiImpl for Pku2u { MessageType::ApRequest, self.conversation_id, exchange_seq_number, - self.auth_scheme.unwrap(), + check_if_empty!(self.auth_scheme, "auth_scheme is not set"), picky_asn1_der::to_vec(&generate_neg(ap_req, AP_REQ_TOKEN_ID))?, ); exchange.encode(&mut mech_token)?; exchange.encode(&mut self.negoex_messages)?; - let c2 = ChecksumSuite::HmacSha196Aes256.hasher().checksum( - &test_session_key, - 25, - &self.negoex_messages, - )?; - let verify = Verify::new( MessageType::Verify, self.conversation_id, verify_seq_number, - self.auth_scheme.unwrap(), - 16, - // self.encryption_params - // .encryption_type - // .as_ref() - // .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) - // .into(), - // ChecksumSuite::HmacSha196Aes256.hasher().checksum( - // self.encryption_params.session_key.as_ref().unwrap(), - // ACCEPTOR_SIGN, - // &self.negoex_messages, - // )?, - c2, + check_if_empty!(self.auth_scheme, "auth_scheme is not set"), + ChecksumSuite::HmacSha196Aes256.into(), + ChecksumSuite::HmacSha196Aes256 + .hasher() + .checksum(&test_session_key, INITIATOR_SIGN, &self.negoex_messages)?, ); verify.encode(&mut mech_token)?; verify.encode(&mut self.negoex_messages)?; - // self.negoex_messages.extend_from_slice(&mech_token); let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; output_token @@ -709,7 +693,7 @@ impl SspiImpl for Pku2u { let neg_token_targ: NegTokenTarg1 = picky_asn1_der::from_bytes(&input_token.buffer)?; // todo: check negResult (should be accept completed: 0) - + let buffer = neg_token_targ .0 .response_token @@ -720,48 +704,36 @@ impl SspiImpl for Pku2u { .0 .0; - println!("ap_exchange buffer: {:?}", buffer); - // self.negoex_messages.extend_from_slice(&buffer); - let mut reader: Box = Box::new(buffer.as_slice()); - let acceptor_exchange = Exchange::decode(&mut reader, &buffer)?; - println!("acceptor exchange: {:?}", acceptor_exchange); check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); check_sequence_number!(acceptor_exchange.header.sequence_num, self.next_seq_number()); check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); - self.negoex_messages.extend_from_slice(&buffer[0..(acceptor_exchange.header.message_len as usize)]); + self.negoex_messages + .extend_from_slice(&buffer[0..(acceptor_exchange.header.message_len as usize)]); let acceptor_verify_data = &buffer[(acceptor_exchange.header.message_len as usize)..]; - println!("buffer for verify: {:?}", acceptor_verify_data); - - let acceptor_verify = - Verify::decode(acceptor_verify_data, acceptor_verify_data)?; - println!("acceptor verify: {:?}", acceptor_verify); + let acceptor_verify = Verify::decode(acceptor_verify_data, acceptor_verify_data)?; check_conversation_id!(acceptor_verify.header.conversation_id.0, self.conversation_id); check_sequence_number!(acceptor_verify.header.sequence_num, self.next_seq_number()); check_auth_scheme!(acceptor_verify.auth_scheme.0, self.auth_scheme); - println!("all verified"); - let (ap_rep, _): (ApRep, _) = extract_krb_rep(&acceptor_exchange.exchange)?; - println!("ap_rep: {:?}", ap_rep); self.encryption_params.sub_session_key = Some(extract_sub_session_key_from_ap_rep( &ap_rep, - self.encryption_params.session_key.as_ref().unwrap(), + check_if_empty!(self.encryption_params.session_key.as_ref(), "session key is not set"), &self.encryption_params, )?); - println!("ap_rep sub session key: {:?}", self.encryption_params.sub_session_key); let acceptor_checksum = ChecksumSuite::try_from(acceptor_verify.checksum.checksum_type as usize)? .hasher() .checksum( - self.encryption_params.sub_session_key.as_ref().unwrap(), - 23, + check_if_empty!(self.encryption_params.sub_session_key.as_ref(), "sub session key is not set"), + ACCEPTOR_SIGN, &self.negoex_messages, )?; if acceptor_verify.checksum.checksum_value != acceptor_checksum { @@ -811,7 +783,7 @@ impl SspiImpl for Pku2u { println!("server: neg init parsed: {:?}", neg_token_init); - let data = neg_token_init.mech_token.0.unwrap().0.0; + let data = neg_token_init.mech_token.0.unwrap().0 .0; let mut reader: Box = Box::new(data.as_slice()); @@ -827,7 +799,6 @@ impl SspiImpl for Pku2u { let initiator_exchange = Exchange::decode(&mut reader, initiator_exchange_data)?; println!("server: acceptor_exchange: {:?}", initiator_exchange); - self.exchange_data.extend_from_slice(&initiator_exchange.exchange); self.conversation_id = initiator_nego.header.conversation_id.0; @@ -850,20 +821,22 @@ impl SspiImpl for Pku2u { self.conversation_id, self.next_seq_number(), auth_scheme, - vec![48, 87, 160, 85, 48, 83, 48, 81, 128, 79, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93], + vec![ + 48, 87, 160, 85, 48, 83, 48, 81, 128, 79, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, + 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, + 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, + 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, + ], ); exchange.encode(&mut mech_token)?; self.negoex_messages.extend_from_slice(&mech_token); - self.exchange_data.extend_from_slice(&exchange.exchange); let result_token = picky_asn1_der::to_vec(&generate_neg_token_init_s(mech_token)?)?; self.gss_api_messages.extend_from_slice(&result_token); let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; - output_token - .buffer - .write_all(&result_token)?; + output_token.buffer.write_all(&result_token)?; self.state = Pku2uState::AsExchange; @@ -877,12 +850,11 @@ impl SspiImpl for Pku2u { let nego_token: NegTokenTarg1 = picky_asn1_der::from_bytes(&input_token.buffer)?; - let buffer = nego_token.0.response_token.0.unwrap().0.0; - + let buffer = nego_token.0.response_token.0.unwrap().0 .0; + self.negoex_messages.extend_from_slice(&buffer); let acceptor_exchange = Exchange::decode(buffer.as_slice(), &buffer)?; - self.exchange_data.extend_from_slice(&acceptor_exchange.exchange); self.next_seq_number(); @@ -902,22 +874,24 @@ impl SspiImpl for Pku2u { self.encryption_params.session_key = Some(session_key); - let new_key = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; + let new_key = vec![ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, + ]; println!("server's session key: {:?}", new_key); let pa_datas = generate_pa_datas_for_as_rep( &self.config.p2p_certificate, self.dh_parameters.server_nonce.as_ref().unwrap(), - &dh_server_public, &self.config.device_private_key, + &dh_server_public, + &self.config.device_private_key, )?; let as_rep = generate_as_rep( pa_datas, self.encryption_params.session_key.as_ref().unwrap(), - new_key.clone() + new_key.clone(), )?; - let exchange_data = - picky_asn1_der::to_vec(&generate_neg(as_rep, AS_REP_TOKEN_ID))?; + let exchange_data = picky_asn1_der::to_vec(&generate_neg(as_rep, AS_REP_TOKEN_ID))?; println!("exchange_data: {:?}", exchange_data); let mut mech_token = Vec::new(); @@ -932,7 +906,6 @@ impl SspiImpl for Pku2u { exchange.encode(&mut mech_token)?; self.negoex_messages.extend_from_slice(&mech_token); - self.exchange_data.extend_from_slice(&exchange.exchange); let response_token = picky_asn1_der::to_vec(&generate_neg_token_targ(mech_token)?)?; self.gss_api_messages.extend_from_slice(&response_token); @@ -956,9 +929,6 @@ impl SspiImpl for Pku2u { let mut f = std::fs::File::create("gss_api_messages.txt").unwrap(); f.write_all(format!("{:?}", self.gss_api_messages).as_bytes()).unwrap(); - let mut f = std::fs::File::create("exchange_data.txt").unwrap(); - f.write_all(format!("{:?}", self.exchange_data).as_bytes()).unwrap(); - // let new_key = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; // println!("checksum: {:?}", ChecksumSuite::HmacSha196Aes256.hasher().checksum(&new_key, 41, &self.gss_api_messages)); @@ -971,38 +941,44 @@ impl SspiImpl for Pku2u { let nego_token: NegTokenTarg1 = picky_asn1_der::from_bytes(&input_token.buffer)?; - let buffer = nego_token.0.response_token.0.unwrap().0.0; - + let buffer = nego_token.0.response_token.0.unwrap().0 .0; let initiator_exchange = Exchange::decode(buffer.as_slice(), &buffer)?; - self.exchange_data.extend_from_slice(&initiator_exchange.exchange); self.next_seq_number(); let initiator_verify_data = &buffer[(initiator_exchange.header.message_len as usize)..]; println!("buffer for verify: {:?}", initiator_verify_data); - let initiator_verify = - Verify::decode(initiator_verify_data, initiator_verify_data)?; + let initiator_verify = Verify::decode(initiator_verify_data, initiator_verify_data)?; println!("initiator verify: {:?}", initiator_verify); - self.negoex_messages.extend_from_slice(&buffer[0..(initiator_exchange.header.message_len as usize)]); + self.negoex_messages + .extend_from_slice(&buffer[0..(initiator_exchange.header.message_len as usize)]); let (ap_req, _): (ApReq, _) = extract_krb_rep(&initiator_exchange.exchange)?; println!("ap_req: {:?}", ap_req); - let sub_session_key = extract_sub_session_key_from_ap_req(&ap_req, self.encryption_params.session_key.as_ref().unwrap())?; + let sub_session_key = + extract_sub_session_key_from_ap_req(&ap_req, self.encryption_params.session_key.as_ref().unwrap())?; println!("ap_req authenticator key: {:?}", sub_session_key); - if initiator_verify.checksum.checksum_value != ChecksumSuite::HmacSha196Aes256.hasher().checksum(&sub_session_key, 25, &self.negoex_messages)? { + if initiator_verify.checksum.checksum_value + != ChecksumSuite::HmacSha196Aes256 + .hasher() + .checksum(&sub_session_key, 25, &self.negoex_messages)? + { println!("bad initiator checksum"); } else { println!("good initiator checksum"); } - self.negoex_messages.extend_from_slice(&buffer[(initiator_exchange.header.message_len as usize)..]); - + self.negoex_messages + .extend_from_slice(&buffer[(initiator_exchange.header.message_len as usize)..]); + self.next_seq_number(); - let test_sub_session_key = [2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + let test_sub_session_key = [ + 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, + ]; self.encryption_params.sub_session_key = Some(test_sub_session_key.to_vec()); println!("ap_rep enc part key: {:?}", test_sub_session_key); @@ -1051,9 +1027,7 @@ impl SspiImpl for Pku2u { println!("resp_token: {:?}", resp_token); let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; - output_token - .buffer - .write_all(&resp_token)?; + output_token.buffer.write_all(&resp_token)?; self.state = Pku2uState::PubKeyAuth; diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index b069f6ec..ac92a1b0 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -235,7 +235,7 @@ impl Default for Pku2uConfig { ]) .unwrap(), p2p_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 56, 199, 138, 113, 113, 58, 21, 17, 37, 104, 118, 83, 148, 160, 63, 193, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 52, 49, 48, 51, 50, 48, 57, 90, 23, 13, 50, 50, 49, 48, 50, 52, 49, 49, 51, 55, 48, 57, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 55, 35, 124, 33, 205, 22, 227, 239, 173, 71, 4, 177, 223, 179, 191, 96, 63, 112, 49, 209, 74, 130, 56, 189, 89, 66, 38, 42, 201, 244, 199, 93, 54, 247, 191, 227, 198, 165, 243, 179, 77, 213, 212, 12, 86, 66, 47, 202, 1, 128, 17, 77, 164, 244, 124, 93, 140, 37, 98, 28, 199, 238, 208, 108, 88, 81, 58, 182, 228, 252, 219, 210, 156, 107, 110, 242, 51, 126, 194, 199, 232, 88, 5, 81, 115, 240, 21, 11, 29, 135, 87, 104, 255, 151, 172, 242, 199, 48, 174, 7, 163, 25, 1, 219, 101, 151, 149, 173, 173, 217, 228, 16, 48, 61, 93, 228, 110, 176, 86, 193, 176, 23, 27, 158, 246, 199, 238, 85, 204, 161, 202, 170, 224, 3, 118, 133, 222, 120, 175, 152, 241, 112, 245, 8, 47, 175, 229, 140, 69, 100, 201, 59, 160, 202, 181, 88, 221, 90, 93, 244, 89, 6, 128, 201, 19, 110, 22, 241, 121, 57, 250, 9, 120, 50, 136, 113, 20, 243, 114, 47, 114, 76, 140, 250, 153, 218, 105, 42, 230, 101, 118, 48, 96, 201, 87, 163, 44, 137, 238, 101, 161, 189, 229, 155, 142, 80, 189, 200, 35, 120, 4, 255, 101, 174, 65, 166, 92, 70, 40, 119, 39, 32, 36, 43, 122, 186, 4, 95, 170, 66, 98, 152, 112, 80, 152, 211, 57, 14, 244, 39, 27, 5, 112, 49, 66, 30, 199, 129, 82, 103, 245, 184, 76, 142, 16, 221 + 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 29, 250, 89, 25, 100, 204, 227, 4, 210, 215, 17, 17, 106, 144, 65, 118, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 52, 49, 51, 53, 55, 53, 55, 90, 23, 13, 50, 50, 49, 48, 50, 52, 49, 53, 48, 50, 53, 55, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 52, 210, 190, 57, 104, 3, 101, 186, 127, 188, 25, 81, 109, 224, 125, 7, 57, 165, 166, 229, 61, 227, 183, 172, 247, 179, 4, 67, 144, 192, 131, 222, 73, 40, 230, 241, 16, 41, 105, 174, 192, 56, 169, 8, 43, 145, 132, 192, 178, 113, 127, 178, 65, 203, 179, 137, 72, 92, 199, 122, 200, 241, 128, 0, 186, 142, 111, 194, 31, 4, 203, 197, 200, 104, 98, 111, 20, 171, 141, 212, 154, 58, 93, 214, 248, 222, 56, 124, 222, 128, 137, 122, 242, 12, 154, 82, 199, 12, 62, 214, 194, 215, 170, 143, 148, 55, 115, 173, 192, 59, 54, 51, 209, 221, 52, 0, 76, 29, 184, 239, 193, 244, 5, 114, 223, 87, 215, 48, 8, 213, 36, 22, 115, 219, 59, 6, 79, 136, 89, 191, 90, 16, 36, 72, 29, 22, 187, 123, 0, 149, 142, 131, 252, 151, 146, 81, 157, 171, 54, 132, 105, 17, 108, 83, 85, 106, 169, 144, 244, 101, 204, 81, 142, 34, 90, 226, 167, 26, 1, 212, 10, 196, 68, 63, 227, 138, 146, 70, 114, 6, 242, 223, 14, 28, 82, 151, 201, 186, 0, 123, 54, 252, 97, 224, 84, 182, 207, 147, 77, 68, 141, 125, 177, 104, 229, 216, 187, 32, 37, 69, 177, 103, 80, 101, 16, 26, 28, 39, 25, 20, 151, 136, 151, 245, 238, 218, 160, 187, 227, 114, 12, 240, 58, 12, 195, 230, 126, 24, 139, 203, 236, 201, 231, 53, 84, 134 ]) .unwrap(), p2p_ca_certificate: picky_asn1_der::from_bytes(&[ diff --git a/src/sspi/pku2u/extractors.rs b/src/sspi/pku2u/extractors.rs index f3d90503..0fcf81f5 100644 --- a/src/sspi/pku2u/extractors.rs +++ b/src/sspi/pku2u/extractors.rs @@ -7,13 +7,13 @@ use picky_asn1_der::Asn1RawDer; use picky_asn1_x509::content_info::ContentValue; use picky_asn1_x509::oids::PKINIT_DH_KEY_DATA; use picky_asn1_x509::signed_data::SignedData; -use picky_krb::constants::key_usages::{AS_REP_ENC, AP_REQ_AUTHENTICATOR}; +use picky_krb::constants::key_usages::{AP_REQ_AUTHENTICATOR, AS_REP_ENC}; use picky_krb::constants::types::{PA_PK_AS_REP, PA_PK_AS_REQ}; +use picky_krb::crypto::diffie_hellman::{compute_public_key, generate_key, generate_private_key, DhNonce}; use picky_krb::crypto::CipherSuite; -use picky_krb::crypto::diffie_hellman::{generate_key, generate_private_key, DhNonce, compute_public_key}; use picky_krb::data_types::Authenticator; -use picky_krb::messages::{AsRep, EncAsRepPart, AsReq, ApReq}; -use picky_krb::pkinit::{DhRepInfo, KdcDhKeyInfo, PaPkAsRep, PaPkAsReq, AuthPack}; +use picky_krb::messages::{ApReq, AsRep, AsReq, EncAsRepPart}; +use picky_krb::pkinit::{AuthPack, DhRepInfo, KdcDhKeyInfo, PaPkAsRep, PaPkAsReq}; use rand::rngs::OsRng; use serde::Deserialize; @@ -115,8 +115,7 @@ pub fn extract_session_key_from_as_rep(as_rep: &AsRep, key: &[u8], enc_params: & .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) .cipher(); - let enc_data = cipher - .decrypt(&key, AS_REP_ENC, &as_rep.0.enc_part.0.cipher.0 .0)?; + let enc_data = cipher.decrypt(&key, AS_REP_ENC, &as_rep.0.enc_part.0.cipher.0 .0)?; let enc_as_rep_part: EncAsRepPart = picky_asn1_der::from_bytes(&enc_data)?; @@ -145,15 +144,32 @@ pub fn extract_pa_pk_as_req(as_req: &AsReq) -> Result { )?) } -pub fn compute_session_key_from_pa_pk_as_req(pa_pk_as_req: &PaPkAsReq, dh_server_nonce: &[u8]) -> Result<(Vec, Vec)> { +pub fn compute_session_key_from_pa_pk_as_req( + pa_pk_as_req: &PaPkAsReq, + dh_server_nonce: &[u8], +) -> Result<(Vec, Vec)> { let signed_data: SignedData = picky_asn1_der::from_bytes(&pa_pk_as_req.signed_auth_pack.0)?; - let content = signed_data.content_info.content.unwrap().0; + let content = signed_data + .content_info + .content + .ok_or_else(|| { + Error::new( + ErrorKind::InvalidToken, + "Content of the EncapsulatedContentInfo is not present".into(), + ) + })? + .0; let auth_pack: AuthPack = picky_asn1_der::from_bytes(match &content { ContentValue::OctetString(data) => &data.0, c => unimplemented!("wrong content value: {:?}", c), })?; - let dh_client_public_info = &auth_pack.client_public_value.0.as_ref().unwrap().0; + let dh_client_public_info = &auth_pack + .client_public_value + .0 + .as_ref() + .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "DH public key is not present".into()))? + .0; let g = dh_client_public_info.key_info.key_info.g.0.clone(); let p = dh_client_public_info.key_info.key_info.p.0.clone(); @@ -166,7 +182,7 @@ pub fn compute_session_key_from_pa_pk_as_req(pa_pk_as_req: &PaPkAsReq, dh_server let dh_server_private = generate_private_key(&q, &mut rng); let dh_server_public = compute_public_key(&dh_server_private, &p, &g); - let dh_client_nonce = auth_pack.client_dh_nonce.0.as_ref().unwrap().0.0.clone(); + let dh_client_nonce = auth_pack.client_dh_nonce.0.as_ref().unwrap().0 .0.clone(); let session_key = generate_key( &dh_client_public, @@ -176,236 +192,19 @@ pub fn compute_session_key_from_pa_pk_as_req(pa_pk_as_req: &PaPkAsReq, dh_server client_nonce: &dh_client_nonce, server_nonce: dh_server_nonce, }), - CipherSuite::Aes256CtsHmacSha196.cipher().as_ref() + CipherSuite::Aes256CtsHmacSha196.cipher().as_ref(), )?; Ok((session_key, dh_server_public)) } pub fn extract_sub_session_key_from_ap_req(ap_req: &ApReq, session_key: &[u8]) -> Result> { - let encrypted = &ap_req.0.authenticator.0.cipher.0.0; - let decrypted = CipherSuite::Aes256CtsHmacSha196.cipher().decrypt(session_key, AP_REQ_AUTHENTICATOR, encrypted)?; - - let auth: Authenticator = picky_asn1_der::from_bytes(&decrypted)?; - - Ok(auth.0.subkey.0.unwrap().0.key_value.0.0) -} - -#[cfg(test)] -mod tests { - use picky_asn1_der::application_tag::ApplicationTag; - use picky_krb::{messages::{AsRep, AsReq}, crypto::{CipherSuite, diffie_hellman::{generate_key, DhNonce}, ChecksumSuite}, gss_api::KrbMessage, constants::key_usages::AP_REQ_AUTHENTICATOR}; - - use crate::{kerberos::EncryptionParams, crypto::compute_sha256, internal::credssp::{SERVER_CLIENT_HASH_MAGIC, CLIENT_SERVER_HASH_MAGIC}}; - - use super::{extract_krb_rep, extract_session_key_from_as_rep}; - - #[test] - fn as_rep_extraction() { - let enc_type = CipherSuite::Aes256CtsHmacSha196; - - let as_rep: AsRep = picky_asn1_der::from_bytes(&[]).unwrap(); - - let enc_params = EncryptionParams { - encryption_type: Some(enc_type.clone()), - session_key: None, - sub_session_key: None, - sspi_encrypt_key_usage: 0, - sspi_decrypt_key_usage: 0, - }; - - let key = generate_key( - &[], - &[], - &[], - Some(DhNonce { - client_nonce: &[142, 91, 149, 4, 44, 55, 103, 6, 75, 168, 207, 165, 162, 197, 172, 27, 2, 108, 166, 10, 240, 52, 179, 24, 56, 73, 137, 103, 160, 81, 236, 230], - server_nonce: &[], - }), - enc_type.cipher().as_ref(), - ).unwrap(); - - println!("{:?}", extract_session_key_from_as_rep(&as_rep, &key, &enc_params).unwrap()); - } - - #[test] - fn parse_as_req() { - let data = [96, 130, 9, 48, 6, 6, 43, 6, 1, 5, 2, 7, 5, 0, 106, 130, 9, 34, 48, 130, 9, 30, 161, 3, 2, 1, 5, 162, 3, 2, 1, 10, 163, 130, 7, 252, 48, 130, 7, 248, 48, 130, 7, 244, 161, 3, 2, 1, 16, 162, 130, 7, 235, 4, 130, 7, 231, 48, 130, 7, 227, 128, 130, 7, 223, 48, 130, 7, 219, 2, 1, 3, 49, 11, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 48, 130, 2, 31, 6, 7, 43, 6, 1, 5, 2, 3, 1, 160, 130, 2, 18, 4, 130, 2, 14, 48, 130, 2, 10, 160, 57, 48, 55, 160, 5, 2, 3, 11, 210, 255, 161, 17, 24, 15, 50, 48, 50, 50, 48, 57, 50, 53, 50, 49, 49, 48, 48, 51, 90, 162, 3, 2, 1, 0, 163, 22, 4, 20, 214, 215, 210, 143, 189, 21, 220, 123, 16, 202, 62, 239, 143, 239, 72, 75, 129, 19, 192, 25, 161, 130, 1, 167, 48, 130, 1, 163, 48, 130, 1, 23, 6, 7, 42, 134, 72, 206, 62, 2, 1, 48, 130, 1, 10, 2, 129, 129, 0, 255, 255, 255, 255, 255, 255, 255, 255, 201, 15, 218, 162, 33, 104, 194, 52, 196, 198, 98, 139, 128, 220, 28, 209, 41, 2, 78, 8, 138, 103, 204, 116, 2, 11, 190, 166, 59, 19, 155, 34, 81, 74, 8, 121, 142, 52, 4, 221, 239, 149, 25, 179, 205, 58, 67, 27, 48, 43, 10, 109, 242, 95, 20, 55, 79, 225, 53, 109, 109, 81, 194, 69, 228, 133, 181, 118, 98, 94, 126, 198, 244, 76, 66, 233, 166, 55, 237, 107, 11, 255, 92, 182, 244, 6, 183, 237, 238, 56, 107, 251, 90, 137, 159, 165, 174, 159, 36, 17, 124, 75, 31, 230, 73, 40, 102, 81, 236, 230, 83, 129, 255, 255, 255, 255, 255, 255, 255, 255, 2, 1, 2, 2, 129, 128, 127, 255, 255, 255, 255, 255, 255, 255, 228, 135, 237, 81, 16, 180, 97, 26, 98, 99, 49, 69, 192, 110, 14, 104, 148, 129, 39, 4, 69, 51, 230, 58, 1, 5, 223, 83, 29, 137, 205, 145, 40, 165, 4, 60, 199, 26, 2, 110, 247, 202, 140, 217, 230, 157, 33, 141, 152, 21, 133, 54, 249, 47, 138, 27, 167, 240, 154, 182, 182, 168, 225, 34, 242, 66, 218, 187, 49, 47, 63, 99, 122, 38, 33, 116, 211, 27, 246, 181, 133, 255, 174, 91, 122, 3, 91, 246, 247, 28, 53, 253, 173, 68, 207, 210, 215, 79, 146, 8, 190, 37, 143, 243, 36, 148, 51, 40, 246, 115, 41, 192, 255, 255, 255, 255, 255, 255, 255, 255, 3, 129, 133, 0, 2, 129, 129, 0, 174, 64, 94, 199, 223, 241, 193, 152, 170, 68, 51, 76, 187, 174, 45, 73, 174, 189, 141, 45, 159, 152, 150, 206, 86, 139, 103, 220, 243, 88, 58, 18, 39, 91, 132, 169, 6, 194, 189, 101, 247, 71, 111, 4, 77, 136, 201, 61, 155, 194, 35, 162, 225, 107, 106, 107, 160, 103, 98, 48, 53, 47, 142, 6, 99, 25, 254, 47, 138, 206, 41, 37, 50, 7, 66, 244, 32, 231, 48, 233, 191, 127, 24, 14, 69, 218, 122, 155, 198, 66, 36, 234, 17, 57, 126, 117, 21, 203, 79, 251, 106, 218, 219, 248, 82, 147, 67, 118, 62, 170, 57, 210, 192, 15, 130, 254, 215, 164, 217, 186, 201, 99, 57, 191, 83, 133, 228, 135, 163, 34, 4, 32, 100, 207, 181, 107, 37, 161, 148, 45, 31, 19, 94, 23, 68, 103, 195, 118, 102, 234, 135, 247, 24, 237, 176, 201, 12, 149, 232, 200, 131, 26, 226, 145, 160, 130, 3, 217, 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 2, 123, 121, 8, 93, 157, 174, 124, 206, 149, 168, 96, 188, 78, 65, 73, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 48, 57, 50, 53, 50, 49, 48, 53, 48, 51, 90, 23, 13, 50, 50, 48, 57, 50, 53, 50, 50, 49, 48, 48, 51, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 165, 92, 124, 98, 210, 233, 204, 81, 70, 152, 57, 161, 35, 215, 249, 36, 245, 49, 214, 193, 30, 235, 18, 102, 223, 212, 48, 82, 227, 153, 96, 161, 219, 73, 36, 75, 197, 84, 97, 23, 46, 238, 74, 118, 18, 246, 7, 39, 211, 182, 251, 144, 154, 34, 140, 36, 152, 155, 226, 73, 177, 70, 165, 25, 253, 246, 82, 85, 40, 54, 154, 69, 198, 120, 95, 222, 21, 85, 143, 126, 158, 14, 40, 205, 67, 243, 211, 168, 228, 0, 97, 18, 87, 253, 219, 32, 33, 229, 212, 91, 186, 233, 11, 2, 97, 73, 20, 160, 30, 17, 40, 198, 215, 204, 238, 73, 89, 139, 51, 104, 102, 116, 167, 37, 149, 28, 238, 191, 5, 43, 84, 126, 232, 200, 123, 89, 103, 14, 174, 70, 239, 220, 245, 123, 140, 61, 232, 195, 199, 35, 111, 205, 135, 171, 5, 177, 72, 42, 110, 158, 29, 124, 202, 19, 216, 138, 219, 138, 25, 23, 198, 160, 217, 202, 198, 202, 56, 14, 226, 161, 40, 127, 171, 71, 17, 175, 119, 233, 168, 82, 108, 246, 13, 99, 42, 23, 149, 58, 133, 216, 183, 200, 17, 6, 134, 74, 133, 3, 87, 41, 32, 107, 93, 5, 236, 3, 88, 205, 143, 98, 92, 183, 123, 133, 71, 212, 21, 30, 170, 7, 234, 198, 177, 190, 175, 174, 230, 251, 133, 4, 123, 12, 31, 69, 36, 52, 89, 190, 145, 154, 57, 88, 180, 44, 185, 157, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 31, 128, 225, 83, 187, 164, 76, 137, 246, 121, 91, 174, 72, 27, 173, 155, 58, 241, 57, 126, 140, 204, 205, 87, 3, 1, 30, 40, 235, 137, 47, 62, 201, 134, 157, 209, 89, 17, 140, 131, 88, 222, 173, 48, 242, 196, 105, 87, 100, 2, 218, 70, 239, 199, 176, 123, 233, 245, 75, 226, 58, 66, 85, 235, 41, 187, 135, 253, 189, 111, 164, 94, 89, 39, 200, 50, 154, 201, 165, 200, 73, 195, 115, 122, 112, 169, 18, 118, 5, 66, 231, 9, 183, 240, 76, 17, 82, 127, 200, 66, 78, 186, 69, 78, 20, 60, 191, 228, 101, 14, 33, 153, 250, 46, 27, 203, 23, 188, 202, 111, 164, 122, 50, 42, 188, 187, 13, 32, 182, 9, 175, 13, 62, 60, 18, 96, 29, 50, 15, 235, 159, 254, 48, 164, 92, 98, 93, 97, 191, 63, 250, 14, 144, 210, 176, 58, 233, 186, 238, 82, 92, 45, 103, 189, 103, 19, 13, 115, 49, 215, 119, 55, 220, 104, 245, 107, 48, 78, 133, 106, 101, 151, 150, 107, 16, 247, 137, 193, 35, 144, 195, 229, 209, 136, 108, 18, 40, 197, 61, 152, 57, 97, 83, 231, 1, 252, 205, 242, 149, 100, 128, 224, 122, 251, 87, 81, 185, 99, 83, 232, 201, 122, 113, 153, 126, 108, 156, 64, 37, 230, 139, 235, 139, 14, 252, 42, 10, 20, 34, 184, 20, 75, 33, 31, 52, 0, 224, 64, 219, 167, 7, 172, 35, 103, 186, 184, 49, 130, 1, 199, 48, 130, 1, 195, 2, 1, 1, 48, 97, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 2, 16, 2, 123, 121, 8, 93, 157, 174, 124, 206, 149, 168, 96, 188, 78, 65, 73, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 160, 61, 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 37, 144, 68, 78, 210, 60, 230, 236, 125, 249, 8, 246, 201, 77, 20, 197, 108, 52, 75, 76, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 1, 0, 48, 127, 17, 243, 30, 27, 158, 81, 187, 246, 135, 199, 188, 180, 74, 19, 19, 201, 95, 142, 99, 234, 136, 80, 71, 222, 71, 215, 251, 157, 78, 191, 97, 63, 240, 189, 68, 54, 186, 182, 87, 106, 249, 127, 176, 220, 207, 191, 214, 158, 155, 182, 28, 230, 57, 172, 76, 203, 134, 248, 43, 70, 114, 183, 5, 111, 137, 6, 208, 219, 139, 231, 164, 164, 206, 166, 69, 159, 70, 144, 168, 44, 139, 138, 8, 84, 2, 224, 192, 54, 238, 88, 174, 197, 135, 69, 235, 159, 72, 206, 13, 214, 121, 180, 203, 152, 186, 70, 167, 45, 127, 37, 89, 238, 118, 130, 56, 90, 54, 221, 72, 84, 48, 86, 58, 24, 242, 88, 78, 59, 8, 65, 27, 141, 157, 19, 59, 50, 155, 36, 68, 48, 119, 77, 36, 137, 128, 47, 129, 216, 235, 94, 253, 236, 181, 249, 254, 116, 123, 84, 211, 146, 251, 142, 134, 246, 128, 251, 173, 72, 204, 160, 42, 121, 78, 242, 27, 243, 168, 136, 42, 13, 162, 141, 139, 84, 151, 156, 215, 141, 110, 39, 236, 155, 76, 115, 224, 254, 180, 69, 238, 134, 73, 101, 155, 194, 202, 63, 22, 97, 6, 166, 14, 76, 191, 231, 247, 230, 12, 169, 228, 9, 88, 32, 251, 241, 138, 8, 146, 20, 252, 27, 82, 204, 112, 98, 110, 168, 240, 76, 96, 38, 73, 88, 251, 202, 75, 147, 96, 223, 110, 226, 48, 136, 51, 238, 164, 130, 1, 16, 48, 130, 1, 12, 160, 7, 3, 5, 0, 64, 129, 0, 16, 161, 107, 48, 105, 160, 3, 2, 1, 128, 161, 98, 48, 96, 27, 94, 65, 122, 117, 114, 101, 65, 68, 92, 77, 83, 45, 79, 114, 103, 97, 110, 105, 122, 97, 116, 105, 111, 110, 45, 80, 50, 80, 45, 65, 99, 99, 101, 115, 115, 32, 91, 50, 48, 50, 50, 93, 92, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 162, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 163, 35, 48, 33, 160, 3, 2, 1, 2, 161, 26, 48, 24, 27, 7, 84, 69, 82, 77, 83, 82, 86, 27, 13, 49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 52, 165, 17, 24, 15, 50, 48, 51, 55, 48, 57, 49, 52, 48, 50, 52, 56, 48, 53, 90, 166, 17, 24, 15, 50, 48, 51, 55, 48, 57, 49, 52, 48, 50, 52, 56, 48, 53, 90, 167, 3, 2, 1, 0, 168, 18, 48, 16, 2, 1, 18, 2, 1, 17, 2, 1, 23, 2, 1, 24, 2, 2, 255, 121, 169, 29, 48, 27, 48, 25, 160, 3, 2, 1, 20, 161, 18, 4, 16, 68, 69, 83, 75, 84, 79, 80, 45, 56, 70, 51, 51, 82, 70, 72, 32]; - - // let data: ApplicationTag, 0> = picky_asn1_der::from_bytes(&data).unwrap(); - - println!("{:?}", data); - } - - #[test] - fn decrypt_as_req() { - let data = [203, 146, 230, 11, 20, 98, 198, 51, 49, 122, 91, 183, 216, 48, 207, 19, 122, 99, 223, 121, 139, 21, 32, 115, 96, 67, 129, 28, 181, 111, 33, 28, 74, 101, 53, 34, 144, 147, 253, 250, 126, 46, 91, 81, 48, 85, 2, 33, 106, 34, 22, 234, 179, 20, 247, 197, 113, 237, 243, 9, 32, 244, 114, 237, 120, 215, 57, 68, 157, 38, 234, 141, 115, 33, 252, 161]; - let key = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; - let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); - println!("{:?}", cipher.decrypt(&key, AP_REQ_AUTHENTICATOR, &data)); - } - - #[test] - fn verify_negoex_checksum() { - let data1 = [96, 130, 9, 51, 6, 6, 43, 6, 1, 5, 2, 7, 5, 0, 106, 130, 9, 37, 48, 130, 9, 33, 161, 3, 2, 1, 5, 162, 3, 2, 1, 10, 163, 130, 7, 252, 48, 130, 7, 248, 48, 130, 7, 244, 161, 3, 2, 1, 16, 162, 130, 7, 235, 4, 130, 7, 231, 48, 130, 7, 227, 128, 130, 7, 223, 48, 130, 7, 219, 2, 1, 3, 49, 11, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 48, 130, 2, 31, 6, 7, 43, 6, 1, 5, 2, 3, 1, 160, 130, 2, 18, 4, 130, 2, 14, 48, 130, 2, 10, 160, 57, 48, 55, 160, 5, 2, 3, 13, 97, 192, 161, 17, 24, 15, 50, 48, 50, 50, 49, 48, 49, 56, 49, 50, 48, 52, 48, 49, 90, 162, 3, 2, 1, 0, 163, 22, 4, 20, 45, 173, 122, 150, 137, 139, 32, 235, 244, 130, 94, 92, 244, 22, 245, 234, 197, 252, 242, 134, 161, 130, 1, 167, 48, 130, 1, 163, 48, 130, 1, 23, 6, 7, 42, 134, 72, 206, 62, 2, 1, 48, 130, 1, 10, 2, 129, 129, 0, 255, 255, 255, 255, 255, 255, 255, 255, 201, 15, 218, 162, 33, 104, 194, 52, 196, 198, 98, 139, 128, 220, 28, 209, 41, 2, 78, 8, 138, 103, 204, 116, 2, 11, 190, 166, 59, 19, 155, 34, 81, 74, 8, 121, 142, 52, 4, 221, 239, 149, 25, 179, 205, 58, 67, 27, 48, 43, 10, 109, 242, 95, 20, 55, 79, 225, 53, 109, 109, 81, 194, 69, 228, 133, 181, 118, 98, 94, 126, 198, 244, 76, 66, 233, 166, 55, 237, 107, 11, 255, 92, 182, 244, 6, 183, 237, 238, 56, 107, 251, 90, 137, 159, 165, 174, 159, 36, 17, 124, 75, 31, 230, 73, 40, 102, 81, 236, 230, 83, 129, 255, 255, 255, 255, 255, 255, 255, 255, 2, 1, 2, 2, 129, 128, 127, 255, 255, 255, 255, 255, 255, 255, 228, 135, 237, 81, 16, 180, 97, 26, 98, 99, 49, 69, 192, 110, 14, 104, 148, 129, 39, 4, 69, 51, 230, 58, 1, 5, 223, 83, 29, 137, 205, 145, 40, 165, 4, 60, 199, 26, 2, 110, 247, 202, 140, 217, 230, 157, 33, 141, 152, 21, 133, 54, 249, 47, 138, 27, 167, 240, 154, 182, 182, 168, 225, 34, 242, 66, 218, 187, 49, 47, 63, 99, 122, 38, 33, 116, 211, 27, 246, 181, 133, 255, 174, 91, 122, 3, 91, 246, 247, 28, 53, 253, 173, 68, 207, 210, 215, 79, 146, 8, 190, 37, 143, 243, 36, 148, 51, 40, 246, 115, 41, 192, 255, 255, 255, 255, 255, 255, 255, 255, 3, 129, 133, 0, 2, 129, 129, 0, 151, 24, 52, 147, 118, 138, 92, 6, 45, 3, 236, 27, 46, 7, 29, 189, 183, 96, 220, 161, 165, 69, 55, 26, 141, 164, 139, 110, 121, 229, 65, 150, 169, 35, 144, 154, 91, 94, 100, 216, 78, 173, 87, 120, 81, 222, 166, 35, 206, 48, 39, 64, 165, 128, 126, 207, 91, 150, 190, 208, 45, 175, 210, 107, 74, 32, 132, 95, 7, 125, 180, 28, 7, 12, 101, 208, 162, 126, 88, 206, 7, 231, 64, 29, 7, 148, 38, 148, 3, 63, 169, 139, 204, 15, 85, 204, 3, 2, 106, 76, 93, 174, 17, 155, 201, 238, 92, 76, 234, 48, 188, 53, 111, 5, 240, 190, 208, 189, 10, 237, 138, 155, 74, 3, 68, 67, 186, 159, 163, 34, 4, 32, 125, 155, 92, 183, 4, 93, 208, 163, 208, 162, 127, 191, 223, 96, 159, 119, 126, 174, 127, 34, 149, 135, 1, 192, 164, 184, 189, 38, 80, 226, 112, 146, 160, 130, 3, 217, 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 14, 210, 35, 212, 198, 27, 116, 144, 237, 113, 88, 109, 15, 25, 113, 249, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 49, 56, 49, 49, 53, 57, 48, 49, 90, 23, 13, 50, 50, 49, 48, 49, 56, 49, 51, 48, 52, 48, 49, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 173, 251, 243, 19, 51, 228, 187, 103, 173, 45, 14, 235, 229, 200, 184, 172, 79, 101, 201, 157, 201, 28, 66, 14, 158, 45, 219, 105, 95, 152, 174, 49, 150, 40, 19, 65, 17, 108, 238, 224, 35, 114, 196, 224, 57, 138, 186, 30, 154, 220, 113, 212, 240, 226, 40, 102, 231, 178, 168, 200, 254, 55, 130, 79, 202, 19, 203, 158, 160, 153, 66, 120, 43, 72, 185, 153, 90, 140, 93, 204, 197, 248, 133, 218, 101, 85, 214, 133, 112, 242, 95, 101, 132, 118, 241, 62, 101, 94, 198, 55, 12, 244, 156, 9, 57, 32, 171, 252, 27, 58, 183, 252, 199, 118, 236, 129, 92, 74, 22, 145, 135, 98, 104, 171, 145, 216, 106, 228, 69, 227, 29, 85, 162, 25, 78, 99, 70, 43, 96, 105, 5, 17, 56, 131, 111, 185, 129, 91, 89, 144, 122, 165, 51, 244, 85, 236, 235, 10, 238, 185, 197, 191, 22, 94, 2, 213, 174, 248, 243, 23, 164, 21, 248, 128, 94, 112, 93, 116, 73, 61, 29, 5, 108, 9, 252, 248, 195, 109, 232, 95, 78, 146, 94, 100, 39, 127, 18, 128, 181, 89, 125, 228, 158, 77, 228, 44, 148, 176, 130, 207, 100, 66, 128, 103, 211, 73, 239, 134, 34, 150, 243, 150, 24, 131, 109, 11, 37, 245, 68, 108, 214, 29, 58, 79, 31, 218, 36, 88, 40, 146, 38, 202, 97, 1, 106, 114, 20, 76, 42, 77, 62, 65, 86, 8, 230, 217, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 47, 111, 124, 21, 189, 180, 98, 44, 39, 253, 124, 31, 82, 162, 161, 55, 248, 125, 72, 204, 73, 174, 205, 120, 249, 57, 81, 43, 124, 21, 192, 8, 222, 60, 204, 90, 206, 239, 21, 24, 53, 20, 166, 233, 245, 47, 165, 153, 216, 69, 143, 243, 221, 24, 4, 249, 81, 156, 233, 26, 254, 10, 54, 195, 176, 55, 169, 73, 111, 161, 133, 91, 149, 130, 86, 75, 47, 119, 188, 185, 39, 108, 102, 123, 19, 193, 103, 106, 155, 223, 113, 128, 39, 57, 38, 171, 163, 128, 56, 171, 128, 222, 135, 10, 210, 129, 246, 179, 48, 237, 219, 233, 195, 170, 146, 88, 226, 54, 96, 81, 245, 32, 48, 163, 119, 105, 147, 137, 97, 226, 27, 53, 72, 131, 205, 110, 216, 191, 76, 103, 108, 121, 147, 234, 149, 189, 207, 166, 72, 112, 6, 155, 136, 180, 199, 135, 167, 137, 113, 199, 32, 63, 173, 152, 87, 55, 126, 215, 113, 188, 207, 253, 237, 169, 178, 9, 238, 221, 59, 6, 45, 212, 69, 7, 221, 54, 5, 56, 56, 247, 52, 185, 132, 172, 158, 100, 94, 122, 192, 80, 103, 113, 95, 31, 181, 38, 145, 61, 137, 0, 87, 241, 10, 143, 134, 99, 164, 100, 77, 155, 181, 96, 65, 233, 181, 179, 6, 56, 216, 63, 114, 102, 69, 95, 62, 57, 174, 176, 183, 78, 132, 59, 33, 207, 196, 197, 155, 88, 44, 173, 128, 197, 116, 80, 221, 225, 49, 130, 1, 199, 48, 130, 1, 195, 2, 1, 1, 48, 97, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 2, 16, 14, 210, 35, 212, 198, 27, 116, 144, 237, 113, 88, 109, 15, 25, 113, 249, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 160, 61, 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 218, 28, 219, 222, 185, 242, 160, 207, 42, 202, 3, 49, 215, 53, 191, 207, 29, 110, 18, 227, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 1, 0, 64, 139, 117, 205, 62, 31, 170, 243, 112, 128, 128, 222, 92, 12, 120, 42, 94, 228, 127, 152, 126, 118, 156, 227, 18, 211, 70, 236, 128, 223, 122, 156, 50, 31, 198, 191, 244, 170, 17, 250, 206, 16, 37, 213, 238, 223, 2, 215, 221, 116, 68, 57, 26, 31, 234, 115, 37, 34, 203, 185, 17, 134, 12, 225, 234, 157, 246, 53, 223, 40, 148, 232, 57, 165, 148, 217, 61, 24, 205, 114, 171, 212, 4, 2, 210, 57, 93, 9, 177, 191, 125, 237, 238, 235, 101, 187, 54, 32, 68, 71, 120, 20, 177, 42, 176, 128, 172, 169, 134, 112, 211, 136, 36, 156, 28, 104, 251, 42, 33, 255, 168, 182, 212, 150, 103, 111, 121, 133, 116, 183, 202, 149, 220, 93, 191, 97, 49, 245, 48, 11, 215, 98, 175, 212, 15, 132, 128, 109, 182, 91, 254, 73, 14, 28, 158, 152, 44, 167, 75, 18, 111, 196, 232, 15, 168, 130, 70, 129, 204, 16, 208, 133, 123, 28, 252, 96, 219, 123, 148, 150, 101, 24, 59, 156, 7, 178, 36, 175, 110, 37, 4, 0, 71, 135, 170, 42, 43, 72, 94, 87, 250, 137, 23, 246, 87, 226, 209, 225, 207, 254, 45, 86, 79, 188, 155, 164, 134, 144, 98, 25, 34, 230, 247, 64, 141, 174, 140, 187, 19, 176, 254, 188, 196, 216, 23, 95, 240, 66, 58, 169, 223, 150, 157, 23, 3, 64, 114, 34, 128, 18, 114, 167, 74, 233, 229, 53, 164, 130, 1, 19, 48, 130, 1, 15, 160, 7, 3, 5, 0, 64, 129, 0, 16, 161, 107, 48, 105, 160, 3, 2, 1, 128, 161, 98, 48, 96, 27, 94, 65, 122, 117, 114, 101, 65, 68, 92, 77, 83, 45, 79, 114, 103, 97, 110, 105, 122, 97, 116, 105, 111, 110, 45, 80, 50, 80, 45, 65, 99, 99, 101, 115, 115, 32, 91, 50, 48, 50, 50, 93, 92, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 162, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 163, 38, 48, 36, 160, 3, 2, 1, 2, 161, 29, 48, 27, 27, 7, 84, 69, 82, 77, 83, 82, 86, 27, 16, 100, 101, 115, 116, 46, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 165, 17, 24, 15, 50, 48, 51, 55, 48, 57, 49, 52, 48, 50, 52, 56, 48, 53, 90, 166, 17, 24, 15, 50, 48, 51, 55, 48, 57, 49, 52, 48, 50, 52, 56, 48, 53, 90, 167, 3, 2, 1, 0, 168, 18, 48, 16, 2, 1, 18, 2, 1, 17, 2, 1, 23, 2, 1, 24, 2, 2, 255, 121, 169, 29, 48, 27, 48, 25, 160, 3, 2, 1, 20, 161, 18, 4, 16, 68, 69, 83, 75, 84, 79, 80, 45, 56, 70, 51, 51, 82, 70, 72, 32, 96, 130, 11, 132, 6, 6, 43, 6, 1, 5, 2, 7, 6, 0, 107, 130, 11, 118, 48, 130, 11, 114, 160, 3, 2, 1, 5, 161, 3, 2, 1, 11, 162, 130, 6, 106, 48, 130, 6, 102, 48, 130, 6, 98, 161, 3, 2, 1, 17, 162, 130, 6, 89, 4, 130, 6, 85, 160, 130, 6, 81, 48, 130, 6, 77, 128, 130, 6, 37, 48, 130, 6, 33, 2, 1, 3, 49, 11, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 48, 129, 161, 6, 7, 43, 6, 1, 5, 2, 3, 2, 160, 129, 149, 4, 129, 146, 48, 129, 143, 160, 129, 135, 3, 129, 132, 0, 2, 129, 128, 215, 117, 217, 80, 121, 91, 18, 25, 68, 12, 147, 62, 133, 153, 19, 222, 155, 87, 168, 85, 31, 146, 8, 189, 73, 209, 35, 10, 182, 72, 13, 88, 225, 198, 131, 113, 8, 2, 72, 53, 24, 223, 241, 117, 172, 53, 145, 188, 244, 131, 183, 21, 214, 0, 179, 123, 4, 229, 117, 142, 111, 140, 166, 98, 97, 227, 161, 149, 168, 231, 254, 87, 240, 162, 184, 2, 21, 29, 242, 144, 112, 198, 60, 231, 48, 81, 77, 94, 127, 113, 144, 99, 24, 45, 33, 248, 161, 232, 94, 81, 89, 217, 203, 104, 84, 89, 165, 170, 157, 139, 250, 42, 141, 107, 128, 243, 42, 108, 205, 252, 99, 183, 249, 186, 147, 13, 102, 119, 161, 3, 2, 1, 0, 160, 130, 3, 158, 48, 130, 3, 154, 48, 130, 2, 130, 160, 3, 2, 1, 2, 2, 16, 62, 39, 192, 20, 152, 7, 29, 243, 143, 63, 80, 234, 220, 89, 56, 82, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 49, 56, 48, 54, 52, 51, 53, 48, 90, 23, 13, 50, 50, 49, 48, 49, 57, 48, 54, 52, 56, 53, 48, 90, 48, 101, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 45, 48, 43, 6, 3, 85, 4, 3, 12, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 94, 48, 92, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 24, 6, 3, 85, 29, 17, 4, 17, 48, 15, 130, 13, 49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 57, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 179, 0, 255, 32, 22, 238, 125, 85, 247, 225, 180, 111, 84, 165, 58, 193, 187, 225, 232, 171, 9, 43, 70, 138, 135, 196, 123, 59, 5, 215, 119, 225, 79, 156, 122, 254, 154, 205, 114, 165, 193, 251, 144, 217, 247, 15, 212, 222, 56, 5, 246, 164, 238, 254, 202, 170, 52, 206, 4, 93, 197, 184, 66, 74, 165, 157, 67, 82, 197, 143, 21, 82, 216, 219, 192, 125, 22, 32, 197, 14, 179, 206, 3, 229, 132, 134, 58, 161, 188, 105, 225, 44, 154, 42, 118, 53, 3, 104, 66, 210, 119, 0, 44, 160, 14, 28, 209, 18, 110, 44, 254, 156, 180, 211, 107, 109, 209, 82, 153, 164, 234, 62, 155, 185, 104, 124, 33, 29, 48, 110, 231, 50, 118, 48, 16, 120, 154, 31, 238, 193, 206, 155, 162, 155, 34, 90, 254, 170, 185, 49, 6, 100, 189, 107, 207, 34, 134, 35, 115, 148, 122, 202, 239, 59, 172, 148, 44, 65, 28, 65, 169, 68, 76, 251, 218, 121, 145, 110, 253, 15, 18, 235, 102, 45, 176, 93, 14, 169, 253, 50, 64, 208, 115, 48, 56, 123, 106, 95, 91, 104, 230, 70, 7, 108, 188, 3, 219, 161, 74, 153, 172, 229, 22, 201, 229, 143, 87, 76, 15, 129, 22, 158, 190, 18, 39, 130, 144, 12, 22, 144, 62, 36, 172, 123, 107, 194, 70, 109, 206, 19, 135, 215, 132, 225, 142, 207, 194, 33, 83, 164, 245, 163, 19, 186, 247, 209, 49, 130, 1, 199, 48, 130, 1, 195, 2, 1, 1, 48, 97, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 2, 16, 62, 39, 192, 20, 152, 7, 29, 243, 143, 63, 80, 234, 220, 89, 56, 82, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 160, 61, 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 235, 101, 242, 9, 158, 189, 205, 170, 36, 132, 253, 172, 15, 194, 194, 92, 66, 96, 113, 177, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 1, 0, 25, 24, 14, 151, 120, 16, 99, 122, 206, 186, 7, 208, 41, 217, 24, 63, 124, 107, 174, 252, 129, 63, 236, 84, 172, 239, 37, 223, 254, 41, 188, 222, 11, 193, 134, 130, 145, 53, 196, 50, 38, 29, 76, 235, 228, 46, 12, 157, 67, 163, 228, 80, 83, 199, 59, 84, 57, 22, 103, 255, 176, 1, 244, 121, 140, 174, 31, 235, 14, 189, 27, 2, 37, 10, 78, 172, 32, 225, 162, 19, 101, 109, 224, 46, 4, 122, 10, 141, 13, 152, 101, 52, 31, 238, 241, 150, 253, 186, 224, 121, 190, 6, 209, 70, 180, 236, 172, 39, 17, 217, 253, 164, 117, 26, 229, 34, 147, 200, 51, 133, 196, 251, 106, 63, 15, 204, 31, 162, 230, 177, 102, 8, 30, 186, 91, 221, 115, 53, 211, 22, 16, 22, 231, 59, 159, 73, 145, 40, 19, 68, 174, 66, 42, 242, 146, 102, 51, 136, 208, 228, 163, 46, 187, 56, 101, 155, 246, 241, 76, 176, 65, 158, 74, 49, 244, 194, 89, 226, 193, 61, 171, 6, 74, 102, 94, 213, 18, 130, 243, 91, 163, 46, 91, 189, 23, 121, 85, 94, 116, 109, 10, 78, 242, 155, 169, 241, 60, 68, 79, 80, 147, 152, 239, 210, 182, 59, 94, 112, 62, 95, 2, 169, 64, 29, 144, 42, 118, 149, 89, 97, 180, 12, 156, 56, 127, 151, 158, 253, 152, 147, 201, 232, 198, 217, 206, 19, 8, 129, 219, 220, 169, 181, 181, 167, 220, 6, 161, 34, 4, 32, 142, 91, 149, 4, 44, 55, 103, 6, 75, 168, 207, 165, 162, 197, 172, 27, 2, 108, 166, 10, 240, 52, 179, 24, 56, 73, 137, 103, 160, 81, 236, 230, 163, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 164, 35, 48, 33, 160, 3, 2, 1, 128, 161, 26, 48, 24, 27, 22, 65, 122, 117, 114, 101, 65, 68, 92, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 165, 130, 3, 166, 97, 130, 3, 162, 48, 130, 3, 158, 160, 3, 2, 1, 5, 161, 17, 27, 15, 87, 69, 76, 76, 75, 78, 79, 87, 78, 58, 80, 75, 85, 50, 85, 162, 38, 48, 36, 160, 3, 2, 1, 2, 161, 29, 48, 27, 27, 7, 84, 69, 82, 77, 83, 82, 86, 27, 16, 100, 101, 115, 116, 46, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 163, 130, 3, 90, 48, 130, 3, 86, 160, 3, 2, 1, 18, 162, 130, 3, 77, 4, 130, 3, 73, 211, 68, 200, 157, 66, 82, 128, 82, 220, 246, 214, 194, 27, 126, 129, 98, 58, 221, 245, 200, 112, 218, 4, 68, 97, 0, 222, 203, 69, 31, 41, 86, 106, 196, 62, 240, 167, 246, 248, 193, 104, 59, 22, 204, 24, 99, 193, 25, 94, 201, 86, 198, 11, 100, 155, 58, 22, 14, 173, 195, 112, 223, 23, 161, 48, 80, 40, 189, 52, 81, 213, 229, 176, 161, 14, 85, 128, 46, 151, 112, 93, 183, 164, 240, 98, 133, 6, 224, 79, 41, 127, 15, 65, 143, 127, 154, 182, 50, 91, 134, 38, 116, 244, 228, 187, 205, 75, 146, 35, 228, 38, 136, 152, 24, 116, 41, 119, 147, 20, 242, 111, 224, 9, 236, 174, 193, 254, 96, 89, 84, 214, 95, 130, 60, 213, 229, 73, 173, 34, 144, 149, 15, 58, 63, 163, 199, 138, 204, 45, 163, 152, 36, 75, 26, 241, 237, 88, 241, 124, 80, 154, 114, 99, 20, 24, 82, 105, 219, 61, 226, 81, 196, 171, 182, 111, 160, 207, 97, 246, 217, 128, 35, 79, 72, 79, 30, 46, 3, 243, 180, 0, 42, 153, 219, 218, 96, 13, 16, 98, 61, 38, 4, 76, 63, 77, 242, 129, 16, 71, 39, 250, 84, 42, 179, 188, 5, 3, 137, 127, 203, 110, 37, 135, 246, 251, 26, 154, 6, 116, 200, 240, 199, 205, 105, 182, 201, 75, 63, 71, 29, 111, 140, 30, 24, 78, 47, 38, 97, 45, 24, 130, 141, 22, 103, 199, 110, 160, 163, 11, 147, 127, 90, 93, 135, 202, 191, 7, 90, 109, 66, 127, 148, 61, 219, 191, 178, 203, 162, 218, 241, 235, 89, 10, 138, 101, 44, 70, 26, 64, 177, 170, 253, 124, 192, 185, 192, 148, 172, 109, 58, 207, 7, 89, 130, 53, 73, 103, 223, 28, 228, 57, 199, 168, 136, 44, 27, 202, 10, 73, 49, 137, 246, 98, 164, 197, 127, 230, 147, 168, 210, 23, 17, 63, 106, 157, 113, 20, 7, 146, 174, 79, 242, 241, 22, 6, 134, 1, 225, 222, 124, 254, 22, 139, 72, 156, 224, 73, 101, 179, 168, 34, 245, 221, 122, 35, 61, 115, 35, 96, 19, 199, 149, 176, 54, 147, 108, 225, 73, 149, 204, 100, 1, 177, 205, 139, 138, 134, 133, 225, 119, 111, 84, 104, 167, 146, 163, 254, 56, 86, 233, 162, 4, 145, 161, 228, 122, 201, 16, 92, 171, 164, 237, 146, 210, 143, 127, 233, 184, 148, 110, 238, 253, 103, 98, 0, 96, 96, 12, 113, 168, 99, 137, 37, 124, 76, 108, 188, 200, 82, 199, 169, 192, 229, 34, 232, 198, 107, 217, 54, 60, 152, 198, 234, 110, 87, 50, 200, 237, 67, 226, 214, 208, 178, 100, 118, 240, 242, 212, 25, 149, 80, 2, 202, 143, 52, 140, 235, 222, 211, 54, 169, 228, 164, 136, 35, 62, 16, 53, 63, 55, 58, 144, 11, 32, 68, 79, 6, 35, 178, 147, 228, 21, 103, 27, 111, 22, 103, 77, 181, 230, 252, 90, 156, 47, 75, 171, 246, 217, 173, 55, 94, 241, 157, 143, 231, 92, 90, 114, 50, 210, 97, 152, 254, 49, 135, 116, 248, 220, 42, 5, 236, 41, 44, 112, 134, 29, 180, 186, 250, 220, 152, 27, 227, 28, 61, 194, 125, 162, 254, 168, 51, 59, 43, 134, 56, 202, 226, 51, 207, 243, 88, 169, 114, 101, 83, 97, 201, 39, 215, 123, 9, 6, 182, 125, 167, 189, 57, 221, 73, 28, 0, 198, 243, 75, 115, 232, 83, 119, 145, 193, 152, 25, 43, 116, 110, 193, 96, 178, 156, 156, 189, 51, 50, 231, 80, 236, 201, 236, 151, 211, 149, 56, 141, 37, 196, 209, 178, 94, 62, 151, 129, 214, 215, 227, 216, 92, 87, 131, 105, 101, 186, 99, 18, 168, 83, 55, 190, 108, 132, 217, 179, 77, 43, 189, 230, 43, 208, 213, 46, 46, 239, 40, 166, 93, 149, 65, 92, 109, 213, 99, 202, 249, 197, 34, 84, 171, 2, 75, 47, 134, 22, 114, 10, 251, 55, 98, 90, 163, 225, 69, 1, 142, 86, 189, 30, 248, 31, 11, 117, 3, 145, 87, 65, 247, 185, 59, 28, 13, 159, 197, 134, 36, 142, 48, 187, 210, 221, 225, 38, 89, 7, 23, 58, 191, 2, 217, 182, 175, 144, 9, 229, 218, 113, 88, 191, 30, 249, 234, 43, 143, 202, 105, 58, 79, 57, 215, 15, 56, 48, 175, 33, 100, 229, 96, 226, 104, 200, 255, 105, 151, 106, 248, 228, 23, 209, 34, 252, 24, 136, 156, 194, 117, 199, 48, 221, 251, 98, 15, 248, 61, 136, 110, 151, 173, 55, 134, 246, 166, 72, 254, 73, 181, 43, 71, 132, 132, 120, 244, 151, 161, 36, 52, 218, 247, 227, 218, 110, 10, 172, 41, 139, 88, 227, 175, 244, 200, 112, 24, 20, 122, 23, 168, 77, 16, 42, 74, 119, 188, 130, 198, 132, 102, 45, 152, 131, 201, 200, 49, 243, 171, 128, 166, 130, 1, 20, 48, 130, 1, 16, 160, 3, 2, 1, 18, 162, 130, 1, 7, 4, 130, 1, 3, 20, 63, 216, 86, 128, 71, 187, 136, 100, 232, 71, 187, 238, 143, 53, 1, 46, 136, 55, 255, 102, 54, 121, 86, 193, 116, 51, 68, 0, 240, 62, 202, 237, 52, 202, 53, 130, 205, 195, 106, 61, 74, 203, 103, 135, 188, 98, 253, 207, 213, 255, 133, 52, 63, 163, 241, 156, 44, 123, 158, 8, 194, 46, 220, 69, 64, 211, 23, 251, 153, 192, 236, 50, 165, 132, 215, 77, 253, 190, 206, 109, 101, 231, 107, 152, 87, 86, 176, 148, 211, 196, 144, 152, 211, 26, 24, 254, 248, 148, 10, 51, 57, 182, 237, 185, 88, 132, 250, 9, 94, 208, 54, 103, 169, 174, 77, 146, 168, 255, 138, 53, 244, 11, 200, 90, 49, 249, 39, 180, 100, 176, 244, 36, 10, 114, 6, 97, 212, 241, 39, 24, 182, 6, 154, 147, 44, 166, 61, 215, 241, 144, 111, 50, 176, 88, 197, 204, 193, 49, 242, 193, 158, 143, 51, 68, 137, 129, 17, 162, 169, 128, 78, 248, 226, 77, 71, 11, 57, 77, 22, 223, 53, 191, 232, 121, 85, 246, 161, 252, 140, 129, 0, 88, 156, 194, 115, 149, 161, 9, 80, 50, 216, 153, 87, 15, 92, 35, 128, 111, 23, 200, 82, 78, 179, 155, 88, 71, 101, 133, 124, 223, 201, 217, 243, 6, 171, 225, 20, 249, 125, 108, 195, 56, 59, 43, 123, 173, 186, 240, 1, 233, 74, 233, 59, 158, 244, 242, 227, 104, 234, 218, 145, 180, 53, 133, 195, 98, 134, 29]; - - let key1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; - let key2 = [124, 14, 77, 177, 242, 71, 223, 200, 3, 193, 30, 184, 45, 24, 54, 44, 105, 209, 144, 224, 1, 1, 38, 244, 91, 82, 209, 250, 7, 247, 168, 193]; - - let checksum = [225, 29, 207, 202, 14, 201, 88, 44, 83, 206, 195, 32]; - - let hmacker = ChecksumSuite::HmacSha196Aes256.hasher(); - - // println!("{}", &checksum == hmacker.checksum(&key1, 23, &data1).unwrap().as_slice()); - println!("{}", &checksum == hmacker.checksum(&key1, 41, &data1).unwrap().as_slice()); - println!("{}", &checksum == hmacker.checksum(&key2, 41, &data1).unwrap().as_slice()); - - for i in 1..100 { - if &checksum == hmacker.checksum(&key1, i, &data1).unwrap().as_slice() { - println!("found in key 1: {}", i); - } - if &checksum == hmacker.checksum(&key2, i, &data1).unwrap().as_slice() { - println!("found in key 2: {}", i); - } - } - // println!("{}", &checksum == hmacker.checksum(&key2, 25, &data1).unwrap().as_slice()); - - // println!("{}", &checksum == hmacker.checksum(&key1, 23, &data2).unwrap().as_slice()); - // println!("{}", &checksum == hmacker.checksum(&key1, 25, &data2).unwrap().as_slice()); - // println!("{}", &checksum == hmacker.checksum(&key2, 23, &data2).unwrap().as_slice()); - // println!("{}", &checksum == hmacker.checksum(&key2, 25, &data2).unwrap().as_slice()); - - // println!("{}", &checksum == hmacker.checksum(&key1, 23, &data3).unwrap().as_slice()); - // println!("{}", &checksum == hmacker.checksum(&key1, 25, &data3).unwrap().as_slice()); - // println!("{}", &checksum == hmacker.checksum(&key2, 23, &data3).unwrap().as_slice()); - // println!("{}", &checksum == hmacker.checksum(&key2, 25, &data3).unwrap().as_slice()); - - // println!("{}", &checksum == hmacker.checksum(&key1, 23, &data4).unwrap().as_slice()); - // println!("{}", &checksum == hmacker.checksum(&key1, 25, &data4).unwrap().as_slice()); - // println!("{}", &checksum == hmacker.checksum(&key2, 23, &data4).unwrap().as_slice()); - // println!("{}", &checksum == hmacker.checksum(&key2, 25, &data4).unwrap().as_slice()); - } - - #[test] - fn verify_authenticator_checksum() { - let data1 = [48, 78, 48, 76, 160, 3, 2, 1, 1, 161, 69, 4, 67, 48, 65, 48, 63, 160, 4, 2, 2, 0, 141, 161, 55, 4, 53, 48, 51, 48, 49, 160, 3, 2, 1, 0, 161, 42, 4, 40, 1, 0, 0, 0, 0, 32, 0, 0, 92, 95, 64, 72, 191, 160, 228, 23, 98, 35, 78, 151, 207, 227, 96, 126, 97, 180, 15, 98, 127, 211, 90, 177, 119, 132, 45, 113, 206, 90, 169, 124]; - let key1 = [198, 211, 172, 206, 204, 190, 143, 153, 82, 144, 117, 94, 153, 99, 144, 212, 211, 135, 176, 70, 134, 241, 23, 87, 4, 202, 88, 5, 233, 195, 37, 230]; - let key2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; - let checksum = [18, 161, 21, 144, 10, 142, 30, 103, 57, 75, 246, 6]; - - let hmacker = ChecksumSuite::HmacSha196Aes256.hasher(); - - for i in 1..100 { - if &checksum == hmacker.checksum(&key1, i, &data1).unwrap().as_slice() { - println!("here: {}", i); - } - } - - for i in 1..100 { - if &checksum == hmacker.checksum(&key2, i, &data1).unwrap().as_slice() { - println!("here: {}", i); - } - } - } - - #[test] - fn decrypt_pub_key_auth() { - let data = [203, 146, 230, 11, 20, 98, 198, 51, 49, 122, 91, 183, 216, 48, 207, 19, 122, 99, 223, 121, 139, 21, 32, 115, 96, 67, 129, 28, 181, 111, 33, 28, 74, 101, 53, 34, 144, 147, 253, 250, 126, 46, 91, 81, 48, 85, 2, 33, 106, 34, 22, 234, 179, 20, 247, 197, 113, 237, 243, 9, 32, 244, 114, 237, 120, 215, 57, 68, 157, 38, 234, 141, 115, 33, 252, 161]; - let mut data_rotated = data.to_vec(); - data_rotated.rotate_left(28); - // ap_rep - let key_1 = [2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9]; - // auth - // let key_2 = [74, 16, 199, 49, 172, 146, 171, 169, 116, 211, 209, 113, 64, 193, 179, 35, 216, 179, 2, 158, 60, 239, 52, 8, 62, 13, 246, 126, 8, 158, 57, 231]; - // session - // let key_3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; - // dh - // let key_4 = [13, 188, 89, 204, 0, 181, 160, 234, 215, 132, 88, 4, 250, 41, 12, 126, 159, 182, 237, 139, 20, 51, 109, 42, 19, 146, 238, 236, 255, 32, 159, 84]; - - let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); - - if let Ok(data) = cipher.decrypt(&key_1, 24, &data_rotated) { - println!("r: using key_1 and {}: {:?}", 24, data); - } - } - - #[test] - fn validate_pub_key_auth() { - let sha256_hash = [29, 126, 187, 134, 84, 154, 168, 80, 159, 1, 45, 85, 188, 181, 91, 197, 39, 187, 68, 54, 244, 182, 97, 132, 232, 127, 110, 123, 164, 103, 245, 84]; - - let client_nonce = [151, 82, 26, 188, 144, 54, 149, 18, 67, 21, 87, 56, 80, 202, 149, 20, 9, 148, 199, 138, 63, 18, 197, 114, 65, 153, 37, 40, 185, 237, 186, 230]; - // let public_key = [48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1]; - let public_key = [48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1]; - - let mut payload_1 = SERVER_CLIENT_HASH_MAGIC.to_vec(); - payload_1.extend_from_slice(&client_nonce); - payload_1.extend_from_slice(&public_key); - - let mut payload_2 = CLIENT_SERVER_HASH_MAGIC.to_vec(); - payload_2.extend_from_slice(&client_nonce); - payload_2.extend_from_slice(&public_key); - - println!("{}", &sha256_hash == compute_sha256(&payload_1).as_slice()); - println!("{}", &sha256_hash == compute_sha256(&payload_2).as_slice()); - } - - fn try_it(vs: Vec>) { - let hash = [137, 141, 156, 76, 74, 183, 58, 112, 102, 14, 242, 197, 28, 2, 101, 120, 62, 52, 39, 216, 21, 192, 15, 232, 108, 119, 155, 30, 16, 113, 14, 70]; - - let is = [ - [0, 1, 2, 3], - // [0, 1, 3, 2], - [0, 2, 1, 3], - // [0, 2, 3, 1], - // [0, 3, 1, 2], - // [0, 3, 2, 1], - [1, 0, 2, 3], - // [1, 0, 3, 2], - [1, 2, 0, 3], - // [1, 2, 3, 0], - // [1, 3, 0, 2], - // [1, 3, 2, 0], - [2, 0, 1, 3], - // [2, 0, 3, 1], - [2, 1, 0, 3], - // [2, 1, 3, 0], - // [2, 3, 0, 1], - // [2, 3, 1, 0], - // [3, 0, 1, 2], - // [3, 0, 2, 1], - // [3, 1, 0, 2], - // [3, 1, 2, 0], - // [3, 2, 0, 1], - // [3, 2, 1, 0], - ]; - - for i in is { - let mut payload = vs[i[0]].clone(); - payload.extend_from_slice(&vs[i[1]]); - payload.extend_from_slice(&vs[i[2]]); - // payload.extend_from_slice(&vs[i[3]]); - - if &hash == compute_sha256(&payload).as_slice() { - println!("I WIN!"); - } - } - } - - #[test] - fn hack() { - // client nonce - let p1 = [167, 160, 86, 46, 171, 207, 115, 77, 182, 219, 18, 73, 205, 150, 2, 5, 23, 21, 226, 217, 76, 248, 10, 115, 192, 95, 101, 60, 104, 159, 173, 21]; - // pk - let p2 = [48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1]; - // client negoex nonce - let p3 = [85, 64, 105, 87, 129, 69, 222, 254, 36, 159, 112, 18, 249, 74, 108, 135, 146, 132, 49, 72, 193, 144, 183, 119, 47, 81, 105, 196, 254, 190, 221, 87]; - // server negoex nonce - let p4 = [10, 209, 111, 101, 206, 151, 53, 222, 225, 32, 241, 24, 15, 201, 210, 38, 133, 175, 97, 251, 27, 195, 152, 39, 9, 97, 115, 227, 194, 196, 54, 245]; - - let m1 = SERVER_CLIENT_HASH_MAGIC.to_vec(); - let m2 = CLIENT_SERVER_HASH_MAGIC.to_vec(); + let encrypted = &ap_req.0.authenticator.0.cipher.0 .0; + let decrypted = CipherSuite::Aes256CtsHmacSha196 + .cipher() + .decrypt(session_key, AP_REQ_AUTHENTICATOR, encrypted)?; + let auth: Authenticator = picky_asn1_der::from_bytes(&decrypted)?; - println!("not win?"); - } + Ok(auth.0.subkey.0.unwrap().0.key_value.0 .0) } diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index f1fc91c5..2133cff2 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -2,21 +2,24 @@ use std::convert::TryFrom; use std::fmt::Debug; use std::str::FromStr; -use chrono::{Utc, Duration}; +use chrono::{Duration, Utc}; use oid::ObjectIdentifier; use picky_asn1::bit_string::BitString; use picky_asn1::date::GeneralizedTime; -use picky_asn1::restricted_string::{BMPString, IA5String}; +use picky_asn1::restricted_string::IA5String; use picky_asn1::wrapper::{ - Asn1SequenceOf, Asn1SetOf, BMPStringAsn1, BitStringAsn1, ExplicitContextTag0, ExplicitContextTag1, - ExplicitContextTag2, ExplicitContextTag3, ImplicitContextTag0, IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, - Optional, ExplicitContextTag8, ExplicitContextTag4, ExplicitContextTag5, ExplicitContextTag6, ExplicitContextTag7, ExplicitContextTag10, ExplicitContextTag9, GeneralizedTimeAsn1, + Asn1SequenceOf, Asn1SetOf, BitStringAsn1, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag10, + ExplicitContextTag2, ExplicitContextTag3, ExplicitContextTag4, ExplicitContextTag5, ExplicitContextTag6, + ExplicitContextTag7, ExplicitContextTag8, ExplicitContextTag9, GeneralizedTimeAsn1, ImplicitContextTag0, + IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, Optional, }; use picky_asn1_der::application_tag::ApplicationTag; use picky_asn1_der::Asn1RawDer; use picky_asn1_x509::cmsversion::CmsVersion; use picky_asn1_x509::content_info::EncapsulatedContentInfo; -use picky_asn1_x509::oids::{AT_COMMON_NAME, DIFFIE_HELLMAN, GSS_PKU2U, NEGOEX, NTLM_SSP, PKINIT_AUTH_DATA, SPNEGO, PKINIT_DH_KEY_DATA}; +use picky_asn1_x509::oids::{ + DIFFIE_HELLMAN, GSS_PKU2U, NEGOEX, NTLM_SSP, PKINIT_AUTH_DATA, PKINIT_DH_KEY_DATA, SPNEGO, +}; use picky_asn1_x509::signed_data::{ CertificateChoices, CertificateSet, DigestAlgorithmIdentifiers, SignedData, SignersInfos, }; @@ -24,23 +27,24 @@ use picky_asn1_x509::signer_info::{ Attributes, CertificateSerialNumber, DigestAlgorithmIdentifier, IssuerAndSerialNumber, SignatureAlgorithmIdentifier, SignatureValue, SignerIdentifier, SignerInfo, UnsignedAttributes, }; -use picky_asn1_x509::{ - AlgorithmIdentifier, Attribute, AttributeValues, - Certificate, ShaVariant, -}; -use picky_krb::constants::gss_api::{ACCEPT_INCOMPLETE, AUTHENTICATOR_CHECKSUM_TYPE, ACCEPT_COMPLETE}; -use picky_krb::constants::key_usages::{AS_REP_ENC, AP_REP_ENC}; -use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REQ, AD_AUTH_DATA_AP_OPTION_TYPE, KERB_AP_OPTIONS_CBT, PA_PK_AS_REP}; -use picky_krb::crypto::CipherSuite; +use picky_asn1_x509::{AlgorithmIdentifier, Attribute, AttributeValues, Certificate, ShaVariant}; +use picky_krb::constants::gss_api::{ACCEPT_COMPLETE, ACCEPT_INCOMPLETE, AUTHENTICATOR_CHECKSUM_TYPE}; +use picky_krb::constants::key_usages::{AP_REP_ENC, AS_REP_ENC}; +use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REP, PA_PK_AS_REQ}; use picky_krb::crypto::diffie_hellman::{compute_public_key, generate_private_key}; -use picky_krb::data_types::{KerberosStringAsn1, KerberosTime, PaData, PrincipalName, Realm, Authenticator, AuthorizationDataInner, AuthorizationData, AuthenticatorInner, EncryptionKey, Checksum, Ticket, EncryptedData, LastReq, LastReqInner, TicketInner, KerbAdRestrictionEntry, LsapTokenInfoIntegrity, EncApRepPart, EncApRepPartInner}; +use picky_krb::crypto::CipherSuite; +use picky_krb::data_types::{ + Authenticator, AuthenticatorInner, AuthorizationData, AuthorizationDataInner, Checksum, EncApRepPart, + EncApRepPartInner, EncryptedData, EncryptionKey, KerbAdRestrictionEntry, KerberosStringAsn1, KerberosTime, LastReq, + LastReqInner, LsapTokenInfoIntegrity, PaData, PrincipalName, Realm, Ticket, TicketInner, +}; use picky_krb::gss_api::{ ApplicationTag0, GssApiNegInit, KrbMessage, MechType, MechTypeList, NegTokenInit, NegTokenTarg, NegTokenTarg1, }; -use picky_krb::messages::{KdcReqBody, AsRep, KdcRep, EncAsRepPart, EncKdcRepPart, ApRep, ApRepInner}; +use picky_krb::messages::{ApRep, ApRepInner, AsRep, EncAsRepPart, EncKdcRepPart, KdcRep, KdcReqBody}; use picky_krb::pkinit::{ - AuthPack, DhDomainParameters, DhReqInfo, DhReqKeyInfo, PaPkAsReq, PkAuthenticator, Pku2uNegoBody, Pku2uNegoReq, - Pku2uNegoReqMetadata, PaPkAsRep, DhRepInfo, KdcDhKeyInfo, + AuthPack, DhDomainParameters, DhRepInfo, DhReqInfo, DhReqKeyInfo, KdcDhKeyInfo, PaPkAsRep, PaPkAsReq, + PkAuthenticator, Pku2uNegoBody, Pku2uNegoReq, Pku2uNegoReqMetadata, }; use rand::rngs::OsRng; use rsa::{Hash, PaddingScheme, RsaPrivateKey}; @@ -48,9 +52,9 @@ use sha1::{Digest, Sha1}; use super::{DhParameters, Pku2uConfig}; use crate::crypto::compute_md5_channel_bindings_hash; -use crate::kerberos::client::generators::{MAX_MICROSECONDS_IN_SECOND, GenerateAuthenticatorOptions, ChecksumOptions}; +use crate::kerberos::client::generators::{ChecksumOptions, GenerateAuthenticatorOptions, MAX_MICROSECONDS_IN_SECOND}; use crate::kerberos::SERVICE_NAME; -use crate::{Result, ErrorKind, Error, KERBEROS_VERSION}; +use crate::{Error, ErrorKind, Result, KERBEROS_VERSION}; /// [The PKU2U Realm Name](https://datatracker.ietf.org/doc/html/draft-zhu-pku2u-09#section-3) /// The PKU2U realm name is defined as a reserved Kerberos realm name, and it has the value of "WELLKNOWN:PKU2U". @@ -69,7 +73,7 @@ pub fn get_mech_list() -> MechTypeList { ]) } -pub fn generate_pku2u_nego_req(_username: &str, config: &Pku2uConfig) -> Result { +pub fn generate_pku2u_nego_req(service_name: &str, config: &Pku2uConfig) -> Result { Ok(Pku2uNegoReq { metadata: ExplicitContextTag0::from(Asn1SequenceOf::from(vec![Pku2uNegoReqMetadata { inner: ImplicitContextTag0::from(OctetStringAsn1::from(picky_asn1_der::to_vec( @@ -106,7 +110,9 @@ pub fn generate_neg_token_init(mech_token: Vec) -> Result) -> Result { Ok(ExplicitContextTag1::from(NegTokenTarg { neg_result: Optional::from(Some(ExplicitContextTag0::from(Asn1RawDer(vec![0x0a, 0x01, 0x01])))), - supported_mech: Optional::from(Some(ExplicitContextTag1::from(MechType::from(ObjectIdentifier::try_from(NEGOEX).unwrap())))), + supported_mech: Optional::from(Some(ExplicitContextTag1::from(MechType::from( + ObjectIdentifier::try_from(NEGOEX).unwrap(), + )))), response_token: Optional::from(Some(ExplicitContextTag2::from(OctetStringAsn1::from(mech_token)))), mech_list_mic: Optional::from(None), })) @@ -180,11 +186,21 @@ pub fn generate_signer_info( pub fn get_default_parameters() -> (Vec, Vec, Vec) { ( vec![ - 0, 255, 255, 255, 255, 255, 255, 255, 255, 201, 15, 218, 162, 33, 104, 194, 52, 196, 198, 98, 139, 128, 220, 28, 209, 41, 2, 78, 8, 138, 103, 204, 116, 2, 11, 190, 166, 59, 19, 155, 34, 81, 74, 8, 121, 142, 52, 4, 221, 239, 149, 25, 179, 205, 58, 67, 27, 48, 43, 10, 109, 242, 95, 20, 55, 79, 225, 53, 109, 109, 81, 194, 69, 228, 133, 181, 118, 98, 94, 126, 198, 244, 76, 66, 233, 166, 55, 237, 107, 11, 255, 92, 182, 244, 6, 183, 237, 238, 56, 107, 251, 90, 137, 159, 165, 174, 159, 36, 17, 124, 75, 31, 230, 73, 40, 102, 81, 236, 230, 83, 129, 255, 255, 255, 255, 255, 255, 255, 255 + 0, 255, 255, 255, 255, 255, 255, 255, 255, 201, 15, 218, 162, 33, 104, 194, 52, 196, 198, 98, 139, 128, + 220, 28, 209, 41, 2, 78, 8, 138, 103, 204, 116, 2, 11, 190, 166, 59, 19, 155, 34, 81, 74, 8, 121, 142, 52, + 4, 221, 239, 149, 25, 179, 205, 58, 67, 27, 48, 43, 10, 109, 242, 95, 20, 55, 79, 225, 53, 109, 109, 81, + 194, 69, 228, 133, 181, 118, 98, 94, 126, 198, 244, 76, 66, 233, 166, 55, 237, 107, 11, 255, 92, 182, 244, + 6, 183, 237, 238, 56, 107, 251, 90, 137, 159, 165, 174, 159, 36, 17, 124, 75, 31, 230, 73, 40, 102, 81, + 236, 230, 83, 129, 255, 255, 255, 255, 255, 255, 255, 255, ], vec![2], vec![ - 127, 255, 255, 255, 255, 255, 255, 255, 228, 135, 237, 81, 16, 180, 97, 26, 98, 99, 49, 69, 192, 110, 14, 104, 148, 129, 39, 4, 69, 51, 230, 58, 1, 5, 223, 83, 29, 137, 205, 145, 40, 165, 4, 60, 199, 26, 2, 110, 247, 202, 140, 217, 230, 157, 33, 141, 152, 21, 133, 54, 249, 47, 138, 27, 167, 240, 154, 182, 182, 168, 225, 34, 242, 66, 218, 187, 49, 47, 63, 99, 122, 38, 33, 116, 211, 27, 246, 181, 133, 255, 174, 91, 122, 3, 91, 246, 247, 28, 53, 253, 173, 68, 207, 210, 215, 79, 146, 8, 190, 37, 143, 243, 36, 148, 51, 40, 246, 115, 41, 192, 255, 255, 255, 255, 255, 255, 255, 255 + 127, 255, 255, 255, 255, 255, 255, 255, 228, 135, 237, 81, 16, 180, 97, 26, 98, 99, 49, 69, 192, 110, 14, + 104, 148, 129, 39, 4, 69, 51, 230, 58, 1, 5, 223, 83, 29, 137, 205, 145, 40, 165, 4, 60, 199, 26, 2, 110, + 247, 202, 140, 217, 230, 157, 33, 141, 152, 21, 133, 54, 249, 47, 138, 27, 167, 240, 154, 182, 182, 168, + 225, 34, 242, 66, 218, 187, 49, 47, 63, 99, 122, 38, 33, 116, 211, 27, 246, 181, 133, 255, 174, 91, 122, 3, + 91, 246, 247, 28, 53, 253, 173, 68, 207, 210, 215, 79, 146, 8, 190, 37, 143, 243, 36, 148, 51, 40, 246, + 115, 41, 192, 255, 255, 255, 255, 255, 255, 255, 255, ], ) } @@ -227,7 +243,6 @@ pub fn generate_client_dh_parameters() -> Result { pub fn generate_pa_datas_for_as_req( p2p_cert: &Certificate, kdc_req_body: &KdcReqBody, - auth_nonce: u32, dh_parameters: &DhParameters, private_key: &RsaPrivateKey, ) -> Result> { @@ -252,7 +267,7 @@ pub fn generate_pa_datas_for_as_req( pk_authenticator: ExplicitContextTag0::from(PkAuthenticator { cusec: ExplicitContextTag0::from(IntegerAsn1::from(microseconds.to_be_bytes().to_vec())), ctime: ExplicitContextTag1::from(KerberosTime::from(GeneralizedTime::from(current_date))), - // nonce: ExplicitContextTag2::from(IntegerAsn1::from(auth_nonce.to_be_bytes().to_vec())), + // always 0 in Pku2u nonce: ExplicitContextTag2::from(IntegerAsn1::from(vec![0])), pa_checksum: Optional::from(Some(ExplicitContextTag3::from(OctetStringAsn1::from( kdc_req_body_sha1_hash, @@ -269,11 +284,9 @@ pub fn generate_pa_datas_for_as_req( validation_params: Optional::from(None), }, }, - key_value: BitStringAsn1::from(BitString::with_bytes( - picky_asn1_der::to_vec(&IntegerAsn1::from( - public_value, - ))? - )), + key_value: BitStringAsn1::from(BitString::with_bytes(picky_asn1_der::to_vec(&IntegerAsn1::from( + public_value, + ))?)), }))), supported_cms_types: Optional::from(None), client_dh_nonce: Optional::from( @@ -290,7 +303,6 @@ pub fn generate_pa_datas_for_as_req( sha1.update(&encoded_auth_pack); let digest = sha1.finalize().to_vec(); - println!("digest: {:?}", digest); let signed_data = SignedData { version: CmsVersion::V3, @@ -333,17 +345,6 @@ pub fn generate_neg( }) } -fn conv(s: &str) -> Vec { - let mut d = Vec::new(); - - for b in s.bytes() { - d.push(b); - d.push(0x00); - } - - d -} - pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result { let GenerateAuthenticatorOptions { kdc_rep, @@ -363,7 +364,10 @@ pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result Result Result Result Result> { let kdc_dh_key_info = KdcDhKeyInfo { subject_public_key: ExplicitContextTag0::from(BitStringAsn1::from(BitString::with_bytes( - picky_asn1_der::to_vec(&IntegerAsn1::from(dh_public_key.to_vec()))? + picky_asn1_der::to_vec(&IntegerAsn1::from(dh_public_key.to_vec()))?, ))), nonce: ExplicitContextTag1::from(IntegerAsn1::from(vec![0])), dh_key_expiration: Optional::from(None), @@ -486,7 +492,9 @@ pub fn generate_pa_datas_for_as_rep( let pa_pk_as_rep = PaPkAsRep::DhInfo(ExplicitContextTag0::from(DhRepInfo { dh_signed_data: ImplicitContextTag0::from(OctetStringAsn1::from(picky_asn1_der::to_vec(&signed_data)?)), - server_dh_nonce: Optional::from(Some(ExplicitContextTag1::from(OctetStringAsn1::from(dh_server_nonce.to_vec())))), + server_dh_nonce: Optional::from(Some(ExplicitContextTag1::from(OctetStringAsn1::from( + dh_server_nonce.to_vec(), + )))), })); Ok(vec![PaData { @@ -498,7 +506,9 @@ pub fn generate_pa_datas_for_as_rep( pub fn get_bad_ticket() -> Ticket { ApplicationTag::from(TicketInner { tkt_vno: ExplicitContextTag0::from(IntegerAsn1::from(vec![5])), - realm: ExplicitContextTag1::from(KerberosStringAsn1::from(IA5String::from_str("WELLKNOWN:PKU2U").unwrap())), + realm: ExplicitContextTag1::from(KerberosStringAsn1::from( + IA5String::from_str("WELLKNOWN:PKU2U").unwrap(), + )), sname: ExplicitContextTag2::from(PrincipalName { name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![2])), name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![ @@ -510,15 +520,52 @@ pub fn get_bad_ticket() -> Ticket { enc_part: ExplicitContextTag3::from(EncryptedData { etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![18])), kvno: Optional::from(None), - cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![211, 68, 200, 157, 66, 82, 128, 82, 220, 246, 214, 194, 27, 126, 129, 98, 58, 221, 245, 200, 112, 218, 4, 68, 97, 0, 222, 203, 69, 31, 41, 86, 106, 196, 62, 240, 167, 246, 248, 193, 104, 59, 22, 204, 24, 99, 193, 25, 94, 201, 86, 198, 11, 100, 155, 58, 22, 14, 173, 195, 112, 223, 23, 161, 48, 80, 40, 189, 52, 81, 213, 229, 176, 161, 14, 85, 128, 46, 151, 112, 93, 183, 164, 240, 98, 133, 6, 224, 79, 41, 127, 15, 65, 143, 127, 154, 182, 50, 91, 134, 38, 116, 244, 228, 187, 205, 75, 146, 35, 228, 38, 136, 152, 24, 116, 41, 119, 147, 20, 242, 111, 224, 9, 236, 174, 193, 254, 96, 89, 84, 214, 95, 130, 60, 213, 229, 73, 173, 34, 144, 149, 15, 58, 63, 163, 199, 138, 204, 45, 163, 152, 36, 75, 26, 241, 237, 88, 241, 124, 80, 154, 114, 99, 20, 24, 82, 105, 219, 61, 226, 81, 196, 171, 182, 111, 160, 207, 97, 246, 217, 128, 35, 79, 72, 79, 30, 46, 3, 243, 180, 0, 42, 153, 219, 218, 96, 13, 16, 98, 61, 38, 4, 76, 63, 77, 242, 129, 16, 71, 39, 250, 84, 42, 179, 188, 5, 3, 137, 127, 203, 110, 37, 135, 246, 251, 26, 154, 6, 116, 200, 240, 199, 205, 105, 182, 201, 75, 63, 71, 29, 111, 140, 30, 24, 78, 47, 38, 97, 45, 24, 130, 141, 22, 103, 199, 110, 160, 163, 11, 147, 127, 90, 93, 135, 202, 191, 7, 90, 109, 66, 127, 148, 61, 219, 191, 178, 203, 162, 218, 241, 235, 89, 10, 138, 101, 44, 70, 26, 64, 177, 170, 253, 124, 192, 185, 192, 148, 172, 109, 58, 207, 7, 89, 130, 53, 73, 103, 223, 28, 228, 57, 199, 168, 136, 44, 27, 202, 10, 73, 49, 137, 246, 98, 164, 197, 127, 230, 147, 168, 210, 23, 17, 63, 106, 157, 113, 20, 7, 146, 174, 79, 242, 241, 22, 6, 134, 1, 225, 222, 124, 254, 22, 139, 72, 156, 224, 73, 101, 179, 168, 34, 245, 221, 122, 35, 61, 115, 35, 96, 19, 199, 149, 176, 54, 147, 108, 225, 73, 149, 204, 100, 1, 177, 205, 139, 138, 134, 133, 225, 119, 111, 84, 104, 167, 146, 163, 254, 56, 86, 233, 162, 4, 145, 161, 228, 122, 201, 16, 92, 171, 164, 237, 146, 210, 143, 127, 233, 184, 148, 110, 238, 253, 103, 98, 0, 96, 96, 12, 113, 168, 99, 137, 37, 124, 76, 108, 188, 200, 82, 199, 169, 192, 229, 34, 232, 198, 107, 217, 54, 60, 152, 198, 234, 110, 87, 50, 200, 237, 67, 226, 214, 208, 178, 100, 118, 240, 242, 212, 25, 149, 80, 2, 202, 143, 52, 140, 235, 222, 211, 54, 169, 228, 164, 136, 35, 62, 16, 53, 63, 55, 58, 144, 11, 32, 68, 79, 6, 35, 178, 147, 228, 21, 103, 27, 111, 22, 103, 77, 181, 230, 252, 90, 156, 47, 75, 171, 246, 217, 173, 55, 94, 241, 157, 143, 231, 92, 90, 114, 50, 210, 97, 152, 254, 49, 135, 116, 248, 220, 42, 5, 236, 41, 44, 112, 134, 29, 180, 186, 250, 220, 152, 27, 227, 28, 61, 194, 125, 162, 254, 168, 51, 59, 43, 134, 56, 202, 226, 51, 207, 243, 88, 169, 114, 101, 83, 97, 201, 39, 215, 123, 9, 6, 182, 125, 167, 189, 57, 221, 73, 28, 0, 198, 243, 75, 115, 232, 83, 119, 145, 193, 152, 25, 43, 116, 110, 193, 96, 178, 156, 156, 189, 51, 50, 231, 80, 236, 201, 236, 151, 211, 149, 56, 141, 37, 196, 209, 178, 94, 62, 151, 129, 214, 215, 227, 216, 92, 87, 131, 105, 101, 186, 99, 18, 168, 83, 55, 190, 108, 132, 217, 179, 77, 43, 189, 230, 43, 208, 213, 46, 46, 239, 40, 166, 93, 149, 65, 92, 109, 213, 99, 202, 249, 197, 34, 84, 171, 2, 75, 47, 134, 22, 114, 10, 251, 55, 98, 90, 163, 225, 69, 1, 142, 86, 189, 30, 248, 31, 11, 117, 3, 145, 87, 65, 247, 185, 59, 28, 13, 159, 197, 134, 36, 142, 48, 187, 210, 221, 225, 38, 89, 7, 23, 58, 191, 2, 217, 182, 175, 144, 9, 229, 218, 113, 88, 191, 30, 249, 234, 43, 143, 202, 105, 58, 79, 57, 215, 15, 56, 48, 175, 33, 100, 229, 96, 226, 104, 200, 255, 105, 151, 106, 248, 228, 23, 209, 34, 252, 24, 136, 156, 194, 117, 199, 48, 221, 251, 98, 15, 248, 61, 136, 110, 151, 173, 55, 134, 246, 166, 72, 254, 73, 181, 43, 71, 132, 132, 120, 244, 151, 161, 36, 52, 218, 247, 227, 218, 110, 10, 172, 41, 139, 88, 227, 175, 244, 200, 112, 24, 20, 122, 23, 168, 77, 16, 42, 74, 119, 188, 130, 198, 132, 102, 45, 152, 131, 201, 200, 49, 243, 171, 128])), + cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![ + 211, 68, 200, 157, 66, 82, 128, 82, 220, 246, 214, 194, 27, 126, 129, 98, 58, 221, 245, 200, 112, 218, + 4, 68, 97, 0, 222, 203, 69, 31, 41, 86, 106, 196, 62, 240, 167, 246, 248, 193, 104, 59, 22, 204, 24, + 99, 193, 25, 94, 201, 86, 198, 11, 100, 155, 58, 22, 14, 173, 195, 112, 223, 23, 161, 48, 80, 40, 189, + 52, 81, 213, 229, 176, 161, 14, 85, 128, 46, 151, 112, 93, 183, 164, 240, 98, 133, 6, 224, 79, 41, 127, + 15, 65, 143, 127, 154, 182, 50, 91, 134, 38, 116, 244, 228, 187, 205, 75, 146, 35, 228, 38, 136, 152, + 24, 116, 41, 119, 147, 20, 242, 111, 224, 9, 236, 174, 193, 254, 96, 89, 84, 214, 95, 130, 60, 213, + 229, 73, 173, 34, 144, 149, 15, 58, 63, 163, 199, 138, 204, 45, 163, 152, 36, 75, 26, 241, 237, 88, + 241, 124, 80, 154, 114, 99, 20, 24, 82, 105, 219, 61, 226, 81, 196, 171, 182, 111, 160, 207, 97, 246, + 217, 128, 35, 79, 72, 79, 30, 46, 3, 243, 180, 0, 42, 153, 219, 218, 96, 13, 16, 98, 61, 38, 4, 76, 63, + 77, 242, 129, 16, 71, 39, 250, 84, 42, 179, 188, 5, 3, 137, 127, 203, 110, 37, 135, 246, 251, 26, 154, + 6, 116, 200, 240, 199, 205, 105, 182, 201, 75, 63, 71, 29, 111, 140, 30, 24, 78, 47, 38, 97, 45, 24, + 130, 141, 22, 103, 199, 110, 160, 163, 11, 147, 127, 90, 93, 135, 202, 191, 7, 90, 109, 66, 127, 148, + 61, 219, 191, 178, 203, 162, 218, 241, 235, 89, 10, 138, 101, 44, 70, 26, 64, 177, 170, 253, 124, 192, + 185, 192, 148, 172, 109, 58, 207, 7, 89, 130, 53, 73, 103, 223, 28, 228, 57, 199, 168, 136, 44, 27, + 202, 10, 73, 49, 137, 246, 98, 164, 197, 127, 230, 147, 168, 210, 23, 17, 63, 106, 157, 113, 20, 7, + 146, 174, 79, 242, 241, 22, 6, 134, 1, 225, 222, 124, 254, 22, 139, 72, 156, 224, 73, 101, 179, 168, + 34, 245, 221, 122, 35, 61, 115, 35, 96, 19, 199, 149, 176, 54, 147, 108, 225, 73, 149, 204, 100, 1, + 177, 205, 139, 138, 134, 133, 225, 119, 111, 84, 104, 167, 146, 163, 254, 56, 86, 233, 162, 4, 145, + 161, 228, 122, 201, 16, 92, 171, 164, 237, 146, 210, 143, 127, 233, 184, 148, 110, 238, 253, 103, 98, + 0, 96, 96, 12, 113, 168, 99, 137, 37, 124, 76, 108, 188, 200, 82, 199, 169, 192, 229, 34, 232, 198, + 107, 217, 54, 60, 152, 198, 234, 110, 87, 50, 200, 237, 67, 226, 214, 208, 178, 100, 118, 240, 242, + 212, 25, 149, 80, 2, 202, 143, 52, 140, 235, 222, 211, 54, 169, 228, 164, 136, 35, 62, 16, 53, 63, 55, + 58, 144, 11, 32, 68, 79, 6, 35, 178, 147, 228, 21, 103, 27, 111, 22, 103, 77, 181, 230, 252, 90, 156, + 47, 75, 171, 246, 217, 173, 55, 94, 241, 157, 143, 231, 92, 90, 114, 50, 210, 97, 152, 254, 49, 135, + 116, 248, 220, 42, 5, 236, 41, 44, 112, 134, 29, 180, 186, 250, 220, 152, 27, 227, 28, 61, 194, 125, + 162, 254, 168, 51, 59, 43, 134, 56, 202, 226, 51, 207, 243, 88, 169, 114, 101, 83, 97, 201, 39, 215, + 123, 9, 6, 182, 125, 167, 189, 57, 221, 73, 28, 0, 198, 243, 75, 115, 232, 83, 119, 145, 193, 152, 25, + 43, 116, 110, 193, 96, 178, 156, 156, 189, 51, 50, 231, 80, 236, 201, 236, 151, 211, 149, 56, 141, 37, + 196, 209, 178, 94, 62, 151, 129, 214, 215, 227, 216, 92, 87, 131, 105, 101, 186, 99, 18, 168, 83, 55, + 190, 108, 132, 217, 179, 77, 43, 189, 230, 43, 208, 213, 46, 46, 239, 40, 166, 93, 149, 65, 92, 109, + 213, 99, 202, 249, 197, 34, 84, 171, 2, 75, 47, 134, 22, 114, 10, 251, 55, 98, 90, 163, 225, 69, 1, + 142, 86, 189, 30, 248, 31, 11, 117, 3, 145, 87, 65, 247, 185, 59, 28, 13, 159, 197, 134, 36, 142, 48, + 187, 210, 221, 225, 38, 89, 7, 23, 58, 191, 2, 217, 182, 175, 144, 9, 229, 218, 113, 88, 191, 30, 249, + 234, 43, 143, 202, 105, 58, 79, 57, 215, 15, 56, 48, 175, 33, 100, 229, 96, 226, 104, 200, 255, 105, + 151, 106, 248, 228, 23, 209, 34, 252, 24, 136, 156, 194, 117, 199, 48, 221, 251, 98, 15, 248, 61, 136, + 110, 151, 173, 55, 134, 246, 166, 72, 254, 73, 181, 43, 71, 132, 132, 120, 244, 151, 161, 36, 52, 218, + 247, 227, 218, 110, 10, 172, 41, 139, 88, 227, 175, 244, 200, 112, 24, 20, 122, 23, 168, 77, 16, 42, + 74, 119, 188, 130, 198, 132, 102, 45, 152, 131, 201, 200, 49, 243, 171, 128, + ])), }), }) } pub fn generate_as_rep(pa_datas: Vec, session_key: &[u8], new_key: Vec) -> Result { - let lt_req = Utc::now() - .checked_sub_signed(Duration::hours(1)) - .unwrap(); + let lt_req = Utc::now().checked_sub_signed(Duration::hours(1)).unwrap(); let now = Utc::now(); let end_time = now.clone().checked_add_signed(Duration::hours(1)).unwrap(); @@ -528,22 +575,24 @@ pub fn generate_as_rep(pa_datas: Vec, session_key: &[u8], new_key: Vec, session_key: &[u8], new_key: Vec ApRep { key_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![18])), key_value: ExplicitContextTag1::from(OctetStringAsn1::from(new_key.to_vec())), }))), - seq_number: Optional::from(Some(ExplicitContextTag3::from(IntegerAsn1::from(vec![49, 95, 171, 251])))), + seq_number: Optional::from(Some(ExplicitContextTag3::from(IntegerAsn1::from(vec![ + 49, 95, 171, 251, + ])))), }); let encoded_ap_rep_enc_part = picky_asn1_der::to_vec(&ap_rep_enc_part).unwrap(); println!("encoded_ap_rep_enc_part: {:?}", encoded_ap_rep_enc_part); let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); - let cipher_data = cipher.encrypt(session_key, AP_REP_ENC, &encoded_ap_rep_enc_part).unwrap(); + let cipher_data = cipher + .encrypt(session_key, AP_REP_ENC, &encoded_ap_rep_enc_part) + .unwrap(); ApRep::from(ApRepInner { pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![5])), diff --git a/src/sspi/pku2u/macros.rs b/src/sspi/pku2u/macros.rs index 09581fa4..a5a9f9ce 100644 --- a/src/sspi/pku2u/macros.rs +++ b/src/sspi/pku2u/macros.rs @@ -44,3 +44,9 @@ macro_rules! check_sequence_number { } }; } + +macro_rules! check_if_empty { + ($actual:expr, $msg:expr) => { + $actual.ok_or_else(|| Error::new(ErrorKind::InternalError, $msg.into()))? + }; +} From dc3f351415ea718e81f57aa02dbec1224834c2eb Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Tue, 25 Oct 2022 11:23:56 +0300 Subject: [PATCH 14/36] sspi: pku2u: refactoring; replace hardcoded data; sspi: negotiate: improve negotiation algorithm; --- src/sspi/internal/credssp.rs | 30 +---- src/sspi/internal/credssp/ts_request/test.rs | 76 ----------- src/sspi/kerberos.rs | 6 +- src/sspi/kerberos/client/generators.rs | 9 +- src/sspi/kerberos/server/extractors.rs | 10 +- src/sspi/negotiate.rs | 18 ++- src/sspi/pku2u.rs | 105 ++++++++-------- src/sspi/pku2u/cert_utils.rs | 125 +++++++++++++------ src/sspi/pku2u/config.rs | 2 +- src/sspi/pku2u/generators.rs | 125 ++++++++++++------- src/utils.rs | 8 +- 11 files changed, 251 insertions(+), 263 deletions(-) diff --git a/src/sspi/internal/credssp.rs b/src/sspi/internal/credssp.rs index 87b11814..70ce9a36 100644 --- a/src/sspi/internal/credssp.rs +++ b/src/sspi/internal/credssp.rs @@ -193,7 +193,6 @@ impl CredSspClient { state: CredSspState::NegoToken, context: None, credentials, - // public_key: vec![48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1], public_key, cred_ssp_mode, client_nonce: OsRng::default().gen::<[u8; NONCE_SIZE]>(), @@ -216,7 +215,6 @@ impl CredSspClient { state: CredSspState::NegoToken, context: None, credentials, - // public_key: vec![48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1], public_key, cred_ssp_mode, client_nonce: OsRng::default().gen::<[u8; NONCE_SIZE]>(), @@ -282,8 +280,6 @@ impl CredSspClient { ts_request.nego_tokens = Some(output_token.remove(0).buffer); if result.status == SecurityStatus::Ok { - println!("start auth info"); - println!("public key: {:?}", self.public_key); let peer_version = self.context.as_ref().unwrap().peer_version.expect( "An encrypt public key client function cannot be fired without any incoming TSRequest", @@ -302,7 +298,6 @@ impl CredSspClient { Ok(ClientState::ReplyNeeded(ts_request)) } CredSspState::AuthInfo => { - println!("got pub key auth reply. start credentials transferring"); ts_request.nego_tokens = None; let pub_key_auth = ts_request.pub_key_auth.take().ok_or_else(|| { @@ -368,12 +363,11 @@ pub struct CredSspServer> impl> CredSspServer { pub fn new(public_key: Vec, credentials: C, client_mode: ClientMode) -> sspi::Result { - println!("server's public key: {:?}", public_key); Ok(Self { state: CredSspState::NegoToken, context: None, credentials, - public_key: vec![48, 130, 1, 10, 2, 130, 1, 1, 0, 205, 145, 202, 14, 211, 90, 9, 57, 201, 82, 174, 149, 31, 144, 56, 21, 255, 170, 18, 31, 144, 135, 109, 251, 163, 28, 59, 223, 208, 158, 196, 250, 235, 72, 119, 207, 27, 111, 174, 26, 191, 111, 119, 254, 246, 121, 105, 241, 139, 246, 224, 36, 79, 243, 64, 59, 121, 255, 77, 254, 198, 138, 194, 237, 252, 149, 123, 7, 230, 18, 178, 118, 194, 47, 128, 5, 199, 153, 59, 90, 147, 77, 117, 0, 254, 85, 14, 197, 132, 169, 142, 94, 250, 217, 89, 82, 175, 157, 44, 174, 96, 169, 202, 110, 170, 184, 128, 245, 14, 74, 254, 10, 132, 168, 46, 43, 48, 162, 113, 66, 120, 53, 83, 219, 172, 67, 28, 175, 176, 38, 97, 154, 53, 210, 137, 170, 241, 184, 156, 124, 175, 142, 172, 19, 0, 16, 77, 121, 115, 59, 31, 42, 84, 105, 121, 113, 199, 177, 124, 100, 73, 151, 42, 96, 229, 100, 158, 250, 34, 18, 125, 245, 73, 180, 154, 236, 64, 109, 130, 187, 83, 115, 15, 251, 21, 235, 147, 15, 96, 61, 6, 248, 7, 83, 60, 123, 178, 187, 116, 102, 99, 121, 134, 233, 14, 142, 1, 28, 214, 57, 144, 104, 15, 159, 157, 235, 241, 240, 145, 131, 145, 109, 35, 203, 21, 245, 176, 130, 140, 121, 77, 230, 215, 176, 176, 107, 190, 173, 87, 116, 34, 184, 136, 214, 44, 153, 173, 67, 113, 219, 216, 128, 121, 25, 244, 141, 2, 3, 1, 0, 1], + public_key, credentials_handle: None, ts_request_version: TS_REQUEST_VERSION, context_config: client_mode, @@ -448,19 +442,16 @@ impl> CredSspServer { ts_request ); - println!("auth_info: {:?}", auth_info); - let read_credentials = try_cred_ssp_server!( self.context.as_mut().unwrap().decrypt_ts_credentials(&auth_info), ts_request ); - panic!("creds: {:?}", read_credentials); + self.state = CredSspState::Final; Ok(ServerState::Finished(read_credentials.into())) } CredSspState::NegoToken => { - println!("public key: {:?}", self.public_key); // let input = try_cred_ssp_server!( // ts_request // .nego_tokens @@ -477,8 +468,6 @@ impl> CredSspServer { let input_token = SecurityBuffer::new(input, SecurityBufferType::Token); let mut output_token = vec![SecurityBuffer::new(Vec::with_capacity(1024), SecurityBufferType::Token)]; - println!("ts_request: {:?}", ts_request); - let mut credentials_handle = self.credentials_handle.take(); match try_cred_ssp_server!( self.context @@ -498,14 +487,10 @@ impl> CredSspServer { ts_request.nego_tokens = Some(output_token.remove(0).buffer); } AcceptSecurityContextResult { status, .. } if status == SecurityStatus::CompleteNeeded => { - println!("I'M HERE: TS_REQUEST: {:?}", ts_request); - println!("--------------------------------"); - let ContextNames { username, domain } = try_cred_ssp_server!( self.context.as_mut().unwrap().sspi_context.query_context_names(), ts_request ); - println!("context names here"); let auth_data = try_cred_ssp_server!( self.credentials .auth_data_by_user(username, domain) @@ -517,7 +502,6 @@ impl> CredSspServer { .unwrap() .sspi_context .custom_set_auth_identity(auth_data); - println!("custom auth identity are set"); try_cred_ssp_server!( self.context.as_mut().unwrap().sspi_context.complete_auth_token(&mut []), @@ -864,9 +848,7 @@ impl CredSspContext { hash_magic: &[u8], client_nonce: &[u8], ) -> sspi::Result<()> { - println!("start decrypt"); let decrypted_public_key = self.decrypt_message(encrypted_public_key)?; - println!("finish decrypt"); let mut data = hash_magic.to_vec(); data.extend(client_nonce); @@ -874,13 +856,10 @@ impl CredSspContext { let expected_public_key = compute_sha256(&data); if expected_public_key.as_ref() != decrypted_public_key.as_slice() { - println!("hashes are not the same"); return Err(sspi::Error::new( sspi::ErrorKind::MessageAltered, String::from("Could not verify a public key hash"), )); - } else { - println!("yes, they are the same"); } Ok(()) @@ -891,14 +870,11 @@ impl CredSspContext { credentials: &AuthIdentityBuffers, cred_ssp_mode: CredSspMode, ) -> sspi::Result> { - let encoded_ts_creds = ts_request::write_ts_credentials(credentials, cred_ssp_mode)?; - println!("encoded_ts_creds: {:?}", encoded_ts_creds); - self.encrypt_message(&encoded_ts_creds) + self.encrypt_message(&ts_request::write_ts_credentials(credentials, cred_ssp_mode)?) } fn decrypt_ts_credentials(&mut self, auth_info: &[u8]) -> sspi::Result { let ts_credentials_buffer = self.decrypt_message(auth_info)?; - println!("decrypted creds: {:?}", ts_credentials_buffer); Ok(ts_request::read_ts_credentials(ts_credentials_buffer.as_slice())?) } diff --git a/src/sspi/internal/credssp/ts_request/test.rs b/src/sspi/internal/credssp/ts_request/test.rs index 7d3c7ca3..15f70323 100644 --- a/src/sspi/internal/credssp/ts_request/test.rs +++ b/src/sspi/internal/credssp/ts_request/test.rs @@ -600,79 +600,3 @@ fn buffer_len_correct_returns_len_with_garbage() { assert_eq!((buffer.len() - garbage_len) as u16, ts_request.buffer_len()); } - -use crate::{internal::credssp::{CredSspClient, ClientMode, CredSspServer, ClientState, ServerState}, Pku2uConfig}; - -use super::TsRequest; - -fn send_to_server(client_state: ClientState, server: &mut CredSspServer) -> TsRequest { - match client_state { - ClientState::ReplyNeeded(ts_request) => { - match server.process(ts_request).unwrap() { - ServerState::ReplyNeeded(ts) => ts, - a => panic!("{:?}", a), - } - }, - ClientState::FinalMessage(ts_request) => { - match server.process(ts_request).unwrap() { - ServerState::ReplyNeeded(ts) => ts, - a => panic!("{:?}", a), - } - }, - } -} - -#[test] -pub fn auth() { - let mut client = CredSspClient::new( - Vec::new(), - AuthIdentity { - username: "AzureAD\\s7@dataans.com".into(), - password: "wwwWWW222@@@".into(), - domain: None, - }, - CredSspMode::WithCredentials, - ClientMode::Pku2u(Pku2uConfig::default()), - "TERMSRV/dest.dataans.com".into(), - ).unwrap(); - let mut server = CredSspServer::new( - Vec::new(), - AuthIdentity { - username: "AzureAD\\s7@dataans.com".into(), - password: "wwwWWW222@@@".into(), - domain: None, - }, - ClientMode::Pku2u(Pku2uConfig::default_server_config()), - ).unwrap(); - - // nego/preauth - let ts_request = TsRequest::default(); - let client_state = client.process(ts_request).unwrap(); - println!("=========> NEGO CLIENT PROCESSED"); - - let ts_request = send_to_server(client_state, &mut server); - println!("=========> NEGO SERVER PROCESSED"); - - // as exchange - let client_state = client.process(ts_request).unwrap(); - println!("=========> AS_REQ CLIENT PROCESSED"); - - let ts_request = send_to_server(client_state, &mut server); - println!("=========> AS_REP SERVER PROCESSED"); - - // ap exchange - let client_state = client.process(ts_request).unwrap(); - println!("=========> AP_REQ CLIENT PROCESSED"); - - let ts_request = send_to_server(client_state, &mut server); - println!("=========> AP_REP SERVER PROCESSED"); - - // pub key auth - let client_state = client.process(ts_request).unwrap(); - println!("=========> PUB KEY AUTH CLIENT PROCESSED"); - - let ts_request = send_to_server(client_state, &mut server); - println!("=========> PUB KEY AUTH SERVER PROCESSED"); - - println!("wow, we're here"); -} diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 39aba90d..9f140648 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -387,7 +387,7 @@ impl Sspi for Kerberos { sub_key: Some(OsRng::default().gen::<[u8; 32]>().to_vec()), checksum: None, channel_bindings: self.channel_bindings.as_ref(), - extension: vec![], + extensions: Vec::new(), })?; let krb_priv = generate_krb_priv_request( @@ -546,7 +546,7 @@ impl SspiImpl for Kerberos { sub_key: None, checksum: None, channel_bindings: self.channel_bindings.as_ref(), - extension: vec![], + extensions: Vec::new(), })?; let session_key_1 = @@ -589,7 +589,7 @@ impl SspiImpl for Kerberos { checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), }), channel_bindings: self.channel_bindings.as_ref(), - extension: vec![], + extensions: Vec::new(), })?; let ap_req = generate_ap_req( diff --git a/src/sspi/kerberos/client/generators.rs b/src/sspi/kerberos/client/generators.rs index 5647f8e6..33cb18de 100644 --- a/src/sspi/kerberos/client/generators.rs +++ b/src/sspi/kerberos/client/generators.rs @@ -320,13 +320,18 @@ pub struct ChecksumOptions { pub checksum_value: Vec, } +pub struct AuthenticatorChecksumExtension { + pub extension_type: u32, + pub extension_value: Vec, +} + pub struct GenerateAuthenticatorOptions<'a> { pub kdc_rep: &'a KdcRep, pub seq_num: Option, pub sub_key: Option>, pub checksum: Option, pub channel_bindings: Option<&'a ChannelBindings>, - pub extension: Vec, + pub extensions: Vec, } pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result { @@ -336,7 +341,7 @@ pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result Result = - picky_asn1_der::from_reader(&mut data).map_err(|e| Error::new(ErrorKind::InternalError, format!("{:?}", e)))?; + let _oid: ApplicationTag = picky_asn1_der::from_reader(&mut data)?; let mut t = [0, 0]; data.read_exact(&mut t)?; @@ -52,12 +51,7 @@ pub fn extract_sub_session_key_from_ap_rep( description: format!("Cannot decrypt ap_rep.enc_part: {:?}", err), })?; - println!("ap_rep_enc_part: {:?}", res); - - let ap_rep_enc_part: EncApRepPart = - picky_asn1_der::from_bytes(&res).map_err(|e| Error::new(ErrorKind::InvalidToken, format!("{:?}", e)))?; - - println!("ap_rep_enc_part: {:?}", ap_rep_enc_part); + let ap_rep_enc_part: EncApRepPart = picky_asn1_der::from_bytes(&res)?; Ok(ap_rep_enc_part .0 diff --git a/src/sspi/negotiate.rs b/src/sspi/negotiate.rs index f4abd4ea..9013a9da 100644 --- a/src/sspi/negotiate.rs +++ b/src/sspi/negotiate.rs @@ -18,7 +18,7 @@ use crate::kerberos::SSPI_KDC_URL_ENV; use crate::sspi::{Result, PACKAGE_ID_NONE}; #[cfg(feature = "network_client")] use crate::utils::get_domain_from_fqdn; -use crate::utils::is_azure_ad_username; +use crate::utils::is_azure_ad_domain; #[cfg(feature = "network_client")] use crate::utils::resolve_kdc_host; use crate::{ @@ -118,9 +118,9 @@ impl Negotiate { }) } - fn negotiate_protocol(&mut self, username: &[u8]) -> Result<()> { + fn negotiate_protocol(&mut self, username: &[u8], domain: &[u8]) -> Result<()> { if let NegotiatedProtocol::Ntlm(_) = &self.protocol { - if is_azure_ad_username(username) { + if is_azure_ad_domain(domain) { self.protocol = NegotiatedProtocol::Pku2u(Pku2u::new_client_from_config(Pku2uConfig::default())?); return Ok(()); } @@ -216,7 +216,10 @@ impl Sspi for Negotiate { } fn change_password(&mut self, change_password: builders::ChangePassword) -> Result<()> { - self.negotiate_protocol(change_password.account_name.as_bytes())?; + self.negotiate_protocol( + change_password.account_name.as_bytes(), + change_password.domain_name.as_bytes(), + )?; match &mut self.protocol { NegotiatedProtocol::Pku2u(pku2u) => pku2u.change_password(change_password), @@ -242,7 +245,10 @@ impl SspiImpl for Negotiate { } if let Some(identity) = builder.auth_data { - self.negotiate_protocol(identity.username.as_bytes())?; + self.negotiate_protocol( + identity.username.as_bytes(), + identity.domain.as_ref().map(|d| d.as_str()).unwrap_or("").as_bytes(), + )?; } self.auth_identity = builder.auth_data.cloned().map(AuthIdentityBuffers::from); @@ -264,7 +270,7 @@ impl SspiImpl for Negotiate { builder: &mut builders::FilledInitializeSecurityContext<'a, Self::CredentialsHandle>, ) -> Result { if let Some(Some(identity)) = builder.credentials_handle { - self.negotiate_protocol(&identity.user)?; + self.negotiate_protocol(&identity.user, &identity.domain)?; } if let NegotiatedProtocol::Kerberos(kerberos) = &mut self.protocol { diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 8cdbac4e..754f4ca8 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -40,7 +40,7 @@ use crate::kerberos::client::generators::{ GenerateAuthenticatorOptions, AUTHENTICATOR_DEFAULT_CHECKSUM, }; use crate::kerberos::server::extractors::extract_sub_session_key_from_ap_rep; -use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE, MAX_SIGNATURE, RRC, SECURITY_TRAILER, SERVICE_NAME}; +use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE, MAX_SIGNATURE, RRC, SECURITY_TRAILER}; use crate::sspi::pku2u::cert_utils::validate_server_p2p_certificate; use crate::sspi::pku2u::extractors::{ compute_session_key_from_pa_pk_as_req, extract_krb_rep, extract_pa_pk_as_rep, extract_pa_pk_as_req, @@ -48,12 +48,11 @@ use crate::sspi::pku2u::extractors::{ extract_sub_session_key_from_ap_req, }; use crate::sspi::pku2u::generators::{ - generate_ap_rep, generate_as_rep, generate_authenticator, generate_neg_token_completed, generate_neg_token_init_s, - generate_pa_datas_for_as_rep, + generate_ap_rep, generate_as_rep, generate_authenticator, generate_authenticator_extension, + generate_neg_token_completed, generate_neg_token_init_s, generate_pa_datas_for_as_rep, }; use crate::sspi::pku2u::validate::validate_signed_data; use crate::sspi::{self, PACKAGE_ID_NONE}; -use crate::utils::utf16_bytes_to_utf8_string; use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, AuthIdentityBuffers, CertTrustStatus, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, EncryptionFlags, Error, ErrorKind, @@ -63,7 +62,7 @@ use crate::{ pub const PKG_NAME: &str = "Pku2u"; -pub const AZURE_AD_PREFIX: &str = "AzureAD\\"; +pub const AZURE_AD_DOMAIN: &str = "AzureAD"; /// Default NEGOEX authentication scheme pub const AUTH_SCHEME: &str = "0d53335c-f9ea-4d0d-b2ec-4ae3786ec308"; @@ -76,6 +75,8 @@ pub const CLIENT_WRAP_TOKEN_FLAGS: u8 = 2; /// acceptor subkey = false pub const SERVER_WRAP_TOKEN_FLAGS: u8 = 3; +const DEFAULT_AP_REQ_OPTIONS: [u8; 4] = [0x20, 0x00, 0x00, 0x00]; + lazy_static! { pub static ref PACKAGE_INFO: PackageInfo = PackageInfo { capabilities: PackageCapabilities::empty(), @@ -145,6 +146,8 @@ pub struct Pku2u { impl Pku2u { pub fn new_server_from_config(config: Pku2uConfig) -> Result { + let mut rng = OsRng::default(); + Ok(Self { mode: Pku2uMode::Server, config, @@ -158,14 +161,16 @@ impl Pku2u { // Contains the nonce in the pkAuthenticator field in the request if the DH keys are NOT reused, // 0 otherwise. // generate dh parameters at the start in order to not waste time during authorization - dh_parameters: generate_server_dh_parameters()?, + dh_parameters: generate_server_dh_parameters(&mut rng)?, negoex_messages: Vec::new(), gss_api_messages: Vec::new(), - negoex_random: OsRng::default().gen::<[u8; RANDOM_ARRAY_SIZE]>(), + negoex_random: rng.gen::<[u8; RANDOM_ARRAY_SIZE]>(), }) } pub fn new_client_from_config(config: Pku2uConfig) -> Result { + let mut rng = OsRng::default(); + Ok(Self { mode: Pku2uMode::Client, config, @@ -179,10 +184,10 @@ impl Pku2u { // Contains the nonce in the pkAuthenticator field in the request if the DH keys are NOT reused, // 0 otherwise. // generate dh parameters at the start in order to not waste time during authorization - dh_parameters: generate_client_dh_parameters()?, + dh_parameters: generate_client_dh_parameters(&mut rng)?, negoex_messages: Vec::new(), gss_api_messages: Vec::new(), - negoex_random: OsRng::default().gen::<[u8; RANDOM_ARRAY_SIZE]>(), + negoex_random: rng.gen::<[u8; RANDOM_ARRAY_SIZE]>(), }) } @@ -398,20 +403,12 @@ impl SspiImpl for Pku2u { Pku2uState::Negotiate => { let auth_scheme = Uuid::from_str(AUTH_SCHEME).unwrap(); - let credentials = check_if_empty!(builder - .credentials_handle - .as_ref(), - "credentials are not set") - .as_ref() - .ok_or_else(|| Error { - error_type: ErrorKind::NoCredentials, - description: "No credentials provided".to_owned(), - })?; - - let username = utf16_bytes_to_utf8_string(&credentials.user); - let mut mech_token = Vec::new(); + let snames = check_if_empty!(builder.target_name, "service target name is not provided") + .split('/') + .collect(); + let nego = Nego::new( MessageType::InitiatorNego, self.conversation_id, @@ -427,7 +424,7 @@ impl SspiImpl for Pku2u { self.conversation_id, self.next_seq_number(), auth_scheme, - picky_asn1_der::to_vec(&generate_pku2u_nego_req(&username, &self.config)?)?, + picky_asn1_der::to_vec(&generate_pku2u_nego_req(snames, &self.config)?)?, ); exchange.encode(&mut mech_token)?; @@ -499,16 +496,15 @@ impl SspiImpl for Pku2u { let mut mech_token = Vec::new(); + let snames = check_if_empty!(builder.target_name, "service target name is not provided") + .split('/') + .collect::>(); + let kdc_req_body = generate_as_req_kdc_body(&GenerateAsReqOptions { realm: WELLKNOWN_REALM, username: "AzureAD\\MS-Organization-P2P-Access [2022]\\S-1-12-1-3653211022-1339006422-2627573900-1560734919", cname_type: 0x80, - snames: &[ - SERVICE_NAME, - // &username, - // "192.168.0.117", - "dest.dataans.com", - ], + snames: &snames, })?; let pa_datas = generate_pa_datas_for_as_req( &self.config.p2p_certificate, @@ -567,7 +563,6 @@ impl SspiImpl for Pku2u { check_sequence_number!(acceptor_exchange.header.sequence_num, self.next_seq_number()); check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); - println!("as. after checks. exchange: {:?}", acceptor_exchange.exchange); self.gss_api_messages.extend_from_slice(&acceptor_exchange.exchange); let (as_rep, _): (AsRep, _) = extract_krb_rep(&acceptor_exchange.exchange)?; @@ -587,7 +582,6 @@ impl SspiImpl for Pku2u { let signed_data: SignedData = picky_asn1_der::from_bytes(&dh_rep_info.dh_signed_data.0)?; - // todo: validate server's certificate let rsa_public_key = validate_server_p2p_certificate(&signed_data, &self.config.p2p_ca_certificate)?; validate_signed_data(&signed_data, &rsa_public_key)?; @@ -601,15 +595,21 @@ impl SspiImpl for Pku2u { &self.dh_parameters.private_key, &self.dh_parameters.modulus, Some(DhNonce { - client_nonce: check_if_empty!(self.dh_parameters.client_nonce.as_ref(), "dh client none is not set"), - server_nonce: check_if_empty!(self.dh_parameters.server_nonce.as_ref(), "dh server nonce is not set"), + client_nonce: check_if_empty!( + self.dh_parameters.client_nonce.as_ref(), + "dh client none is not set" + ), + server_nonce: check_if_empty!( + self.dh_parameters.server_nonce.as_ref(), + "dh server nonce is not set" + ), }), - check_if_empty!(self.encryption_params - .encryption_type - .as_ref(), - "encryption type is not set") - .cipher() - .as_ref(), + check_if_empty!( + self.encryption_params.encryption_type.as_ref(), + "encryption type is not set" + ) + .cipher() + .as_ref(), )?); self.encryption_params.session_key = Some(extract_session_key_from_as_rep( @@ -621,30 +621,28 @@ impl SspiImpl for Pku2u { let exchange_seq_number = self.next_seq_number(); let verify_seq_number = self.next_seq_number(); - let test_session_key = [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, - ]; + let authenticator_seb_key = OsRng::default().gen::<[u8; 32]>().to_vec(); let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, seq_num: Some(exchange_seq_number), - // sub_key: Some(OsRng::default().gen::<[u8; 32]>().to_vec()), - sub_key: Some(test_session_key.to_vec()), + sub_key: Some(authenticator_seb_key.clone()), checksum: Some(ChecksumOptions { checksum_type: AUTHENTICATOR_CHECKSUM_TYPE.to_vec(), checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), }), channel_bindings: None, - extension: ChecksumSuite::HmacSha196Aes256 - .hasher() - .checksum(&test_session_key, 41, &self.gss_api_messages)?, + extensions: vec![generate_authenticator_extension( + &authenticator_seb_key, + &self.gss_api_messages, + )?], })?; let ap_req = generate_ap_req( as_rep.0.ticket.0, check_if_empty!(self.encryption_params.session_key.as_ref(), "session key is not set"), &authenticator, &self.encryption_params, - &[0x20, 0x00, 0x00, 0x00], + &DEFAULT_AP_REQ_OPTIONS, )?; let mut mech_token = Vec::new(); @@ -666,9 +664,11 @@ impl SspiImpl for Pku2u { verify_seq_number, check_if_empty!(self.auth_scheme, "auth_scheme is not set"), ChecksumSuite::HmacSha196Aes256.into(), - ChecksumSuite::HmacSha196Aes256 - .hasher() - .checksum(&test_session_key, INITIATOR_SIGN, &self.negoex_messages)?, + ChecksumSuite::HmacSha196Aes256.hasher().checksum( + &authenticator_seb_key, + INITIATOR_SIGN, + &self.negoex_messages, + )?, ); verify.encode(&mut mech_token)?; @@ -732,7 +732,10 @@ impl SspiImpl for Pku2u { let acceptor_checksum = ChecksumSuite::try_from(acceptor_verify.checksum.checksum_type as usize)? .hasher() .checksum( - check_if_empty!(self.encryption_params.sub_session_key.as_ref(), "sub session key is not set"), + check_if_empty!( + self.encryption_params.sub_session_key.as_ref(), + "sub session key is not set" + ), ACCEPTOR_SIGN, &self.negoex_messages, )?; diff --git a/src/sspi/pku2u/cert_utils.rs b/src/sspi/pku2u/cert_utils.rs index 11401720..034ea157 100644 --- a/src/sspi/pku2u/cert_utils.rs +++ b/src/sspi/pku2u/cert_utils.rs @@ -1,59 +1,110 @@ +use std::{ptr::{null, null_mut}, ffi::OsStr, os::windows::prelude::OsStrExt, slice::from_raw_parts}; + use picky_asn1_x509::{ signed_data::{CertificateChoices, SignedData}, Certificate, PublicKey, }; use rsa::{BigUint, RsaPublicKey}; -use schannel::cert_store::CertStore; -use winapi::um::wincrypt::CryptExportKey; +use winapi::{um::wincrypt::{ + CertOpenStore, CryptExportKey, CERT_STORE_PROV_SYSTEM_W, CERT_SYSTEM_STORE_LOCAL_MACHINE_ID, + CERT_SYSTEM_STORE_LOCATION_SHIFT, CertEnumCertificatesInStore, CryptAcquireCertificatePrivateKey, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE, CERT_NCRYPT_KEY_SPEC, +}, shared::bcrypt::BCRYPT_RSAFULLPRIVATE_BLOB}; +use windows_sys::Win32::{Security::Cryptography::{CERT_KEY_SPEC, NCryptExportKey}, Foundation}; -use crate::{Error, ErrorKind, Result}; +use crate::{Error, ErrorKind, Result, utils::string_to_utf16}; /// Tries to find the device certificate and its private key /// Requirements for the device certificate: /// 1. Issuer CN = MS-Organization-Access /// 2. Issuer OU = 82dbaca4-3e81-46ca-9c73-0950c1eaca97 pub fn extract_device_certificate() -> Result<()> { - let cert_store = CertStore::open_local_machine("My").unwrap(); - let certs = cert_store.certs(); - - for cert in certs { - let certificate: Certificate = picky_asn1_der::from_bytes(cert.to_der())?; - let mut cn = false; - let mut ou = false; - - for issuer_info in certificate.tbs_certificate.issuer.0 .0 { - for is in issuer_info.0 { - println!("is: {:?}", is); - } + unsafe { + let which = "My"; + let data = OsStr::new(which) + .encode_wide() + .chain(Some(0)) + .collect::>(); + let cert_store = CertOpenStore( + CERT_STORE_PROV_SYSTEM_W, + 0, + 0, + CERT_SYSTEM_STORE_LOCAL_MACHINE_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT, + data.as_ptr() as *mut _, + ); + + if cert_store.is_null() { + return Err(Error::new( + ErrorKind::InternalError, + "Cannot initialize certificate store: permission denied".into(), + )); } - if cn && ou { - println!("found"); - let private_key = cert.private_key().acquire().unwrap(); - // let p = cert. - - use schannel::key_handle::KeyHandle; - - let mut v1 = vec![0; 5000]; - let mut len = 0; - - match private_key { - KeyHandle::CryptProv(key_handle) => { - // key_handle. - unsafe { - // - let result = CryptExportKey(0, 0, 0, 0, v1.as_mut_ptr(), &mut len); - } - } - KeyHandle::NcryptKey(ncrypt) => { - // let r = ncrypt.borrow_mut(); + println!("cert_store: {:?}", cert_store); + + let mut certificate = CertEnumCertificatesInStore( + cert_store, + null_mut(), + ); + + println!("cert: {:?}", certificate); + + while !certificate.is_null() { + println!("loop: {:?}", certificate); + + println!("{:?}", (*certificate).pbCertEncoded); + println!("{:?}", (*certificate).cbCertEncoded); + + let cert_der = from_raw_parts((*certificate).pbCertEncoded, (*certificate).cbCertEncoded as usize); + let cert: Certificate = picky_asn1_der::from_bytes(cert_der)?; + + let mut private_key_handle = HCRYPTPROV_OR_NCRYPT_KEY_HANDLE::default(); + let mut spec = CERT_KEY_SPEC::default(); + let mut free = Foundation::BOOL::default(); + + // extract private key + let status = CryptAcquireCertificatePrivateKey( + certificate, + CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, + null_mut(), + &mut private_key_handle, + &mut spec, + &mut free, + ); + + println!("status: {}, free: {:?}, handle: {}", status, free, private_key_handle); + + if status != 0 && private_key_handle != 0 { + println!("try export private key"); + + let mut key_blob = null_mut(); + let mut result_len = 0; + + let blob_type_wide = string_to_utf16(BCRYPT_RSAFULLPRIVATE_BLOB); + + if spec & CERT_NCRYPT_KEY_SPEC != 0 { + println!("ncrypt"); + let status = NCryptExportKey( + private_key_handle as _, + 0, + blob_type_wide.as_ptr() as *const _, + null(), + key_blob, + 0, + &mut result_len, + 0, + ); + + println!("status: {}, key_blob: {:?}, result_len: {}", status, key_blob, result_len); + } else { + println!("crypt"); } } + + certificate = CertEnumCertificatesInStore(cert_store, certificate); } - println!("==============="); } - Ok(()) + Err(Error::new(ErrorKind::InternalError, "Cannot find appropriate device certificate".into())) } /// validates server's p2p certificate. diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index ac92a1b0..f52862df 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -235,7 +235,7 @@ impl Default for Pku2uConfig { ]) .unwrap(), p2p_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 29, 250, 89, 25, 100, 204, 227, 4, 210, 215, 17, 17, 106, 144, 65, 118, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 52, 49, 51, 53, 55, 53, 55, 90, 23, 13, 50, 50, 49, 48, 50, 52, 49, 53, 48, 50, 53, 55, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 52, 210, 190, 57, 104, 3, 101, 186, 127, 188, 25, 81, 109, 224, 125, 7, 57, 165, 166, 229, 61, 227, 183, 172, 247, 179, 4, 67, 144, 192, 131, 222, 73, 40, 230, 241, 16, 41, 105, 174, 192, 56, 169, 8, 43, 145, 132, 192, 178, 113, 127, 178, 65, 203, 179, 137, 72, 92, 199, 122, 200, 241, 128, 0, 186, 142, 111, 194, 31, 4, 203, 197, 200, 104, 98, 111, 20, 171, 141, 212, 154, 58, 93, 214, 248, 222, 56, 124, 222, 128, 137, 122, 242, 12, 154, 82, 199, 12, 62, 214, 194, 215, 170, 143, 148, 55, 115, 173, 192, 59, 54, 51, 209, 221, 52, 0, 76, 29, 184, 239, 193, 244, 5, 114, 223, 87, 215, 48, 8, 213, 36, 22, 115, 219, 59, 6, 79, 136, 89, 191, 90, 16, 36, 72, 29, 22, 187, 123, 0, 149, 142, 131, 252, 151, 146, 81, 157, 171, 54, 132, 105, 17, 108, 83, 85, 106, 169, 144, 244, 101, 204, 81, 142, 34, 90, 226, 167, 26, 1, 212, 10, 196, 68, 63, 227, 138, 146, 70, 114, 6, 242, 223, 14, 28, 82, 151, 201, 186, 0, 123, 54, 252, 97, 224, 84, 182, 207, 147, 77, 68, 141, 125, 177, 104, 229, 216, 187, 32, 37, 69, 177, 103, 80, 101, 16, 26, 28, 39, 25, 20, 151, 136, 151, 245, 238, 218, 160, 187, 227, 114, 12, 240, 58, 12, 195, 230, 126, 24, 139, 203, 236, 201, 231, 53, 84, 134 + 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 51, 207, 59, 83, 186, 122, 125, 103, 157, 228, 225, 84, 159, 209, 130, 233, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 53, 48, 55, 51, 57, 52, 54, 90, 23, 13, 50, 50, 49, 48, 50, 53, 48, 56, 52, 52, 52, 54, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 5, 187, 195, 97, 55, 255, 107, 47, 56, 163, 10, 163, 65, 4, 75, 48, 109, 180, 165, 8, 66, 98, 68, 33, 49, 169, 118, 221, 230, 46, 52, 0, 127, 204, 192, 1, 116, 111, 93, 82, 253, 124, 35, 7, 215, 245, 170, 27, 209, 153, 80, 107, 55, 178, 71, 84, 113, 42, 18, 127, 154, 140, 214, 180, 1, 166, 8, 0, 36, 8, 164, 166, 51, 221, 212, 27, 125, 136, 29, 67, 224, 121, 66, 145, 130, 194, 233, 226, 199, 136, 119, 73, 30, 226, 204, 230, 179, 89, 141, 231, 177, 46, 158, 245, 130, 205, 140, 168, 230, 142, 252, 7, 30, 168, 227, 230, 171, 56, 102, 107, 99, 215, 212, 170, 5, 36, 14, 195, 21, 162, 105, 104, 165, 153, 177, 203, 231, 47, 229, 172, 144, 135, 185, 194, 243, 26, 255, 41, 208, 129, 178, 112, 240, 74, 78, 47, 183, 95, 15, 39, 16, 21, 200, 157, 93, 225, 167, 17, 152, 127, 249, 177, 98, 127, 45, 44, 222, 114, 52, 21, 149, 126, 80, 9, 74, 143, 108, 142, 250, 68, 154, 130, 109, 210, 152, 38, 229, 131, 130, 32, 65, 73, 139, 36, 183, 120, 195, 132, 84, 39, 136, 73, 236, 5, 12, 92, 208, 165, 110, 223, 218, 209, 26, 71, 99, 120, 62, 188, 83, 39, 123, 245, 183, 62, 220, 118, 241, 223, 118, 44, 255, 189, 190, 13, 20, 101, 85, 95, 171, 40, 2, 60, 83, 239, 116, 64 ]) .unwrap(), p2p_ca_certificate: picky_asn1_der::from_bytes(&[ diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index 2133cff2..94c94e9f 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -29,31 +29,34 @@ use picky_asn1_x509::signer_info::{ }; use picky_asn1_x509::{AlgorithmIdentifier, Attribute, AttributeValues, Certificate, ShaVariant}; use picky_krb::constants::gss_api::{ACCEPT_COMPLETE, ACCEPT_INCOMPLETE, AUTHENTICATOR_CHECKSUM_TYPE}; -use picky_krb::constants::key_usages::{AP_REP_ENC, AS_REP_ENC}; +use picky_krb::constants::key_usages::{AP_REP_ENC, AS_REP_ENC, KEY_USAGE_FINISHED}; use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REP, PA_PK_AS_REQ}; use picky_krb::crypto::diffie_hellman::{compute_public_key, generate_private_key}; -use picky_krb::crypto::CipherSuite; +use picky_krb::crypto::{ChecksumSuite, CipherSuite}; use picky_krb::data_types::{ Authenticator, AuthenticatorInner, AuthorizationData, AuthorizationDataInner, Checksum, EncApRepPart, - EncApRepPartInner, EncryptedData, EncryptionKey, KerbAdRestrictionEntry, KerberosStringAsn1, KerberosTime, LastReq, + EncApRepPartInner, EncryptedData, EncryptionKey, KerbAdRestrictionEntry, KerberosStringAsn1, KerberosTime, LastReqInner, LsapTokenInfoIntegrity, PaData, PrincipalName, Realm, Ticket, TicketInner, }; use picky_krb::gss_api::{ ApplicationTag0, GssApiNegInit, KrbMessage, MechType, MechTypeList, NegTokenInit, NegTokenTarg, NegTokenTarg1, }; use picky_krb::messages::{ApRep, ApRepInner, AsRep, EncAsRepPart, EncKdcRepPart, KdcRep, KdcReqBody}; +use picky_krb::negoex::RANDOM_ARRAY_SIZE; use picky_krb::pkinit::{ - AuthPack, DhDomainParameters, DhRepInfo, DhReqInfo, DhReqKeyInfo, KdcDhKeyInfo, PaPkAsRep, PaPkAsReq, + AuthPack, DhDomainParameters, DhRepInfo, DhReqInfo, DhReqKeyInfo, KdcDhKeyInfo, KrbFinished, PaPkAsRep, PaPkAsReq, PkAuthenticator, Pku2uNegoBody, Pku2uNegoReq, Pku2uNegoReqMetadata, }; use rand::rngs::OsRng; +use rand::Rng; use rsa::{Hash, PaddingScheme, RsaPrivateKey}; use sha1::{Digest, Sha1}; use super::{DhParameters, Pku2uConfig}; use crate::crypto::compute_md5_channel_bindings_hash; -use crate::kerberos::client::generators::{ChecksumOptions, GenerateAuthenticatorOptions, MAX_MICROSECONDS_IN_SECOND}; -use crate::kerberos::SERVICE_NAME; +use crate::kerberos::client::generators::{ + AuthenticatorChecksumExtension, ChecksumOptions, GenerateAuthenticatorOptions, MAX_MICROSECONDS_IN_SECOND, +}; use crate::{Error, ErrorKind, Result, KERBEROS_VERSION}; /// [The PKU2U Realm Name](https://datatracker.ietf.org/doc/html/draft-zhu-pku2u-09#section-3) @@ -65,6 +68,26 @@ pub const WELLKNOWN_REALM: &str = "WELLKNOWN:PKU2U"; /// Key length of Aes256 is equal to 32 pub const DH_NONCE_LEN: usize = 32; +/// [The GSS-API Binding for PKU2U](https://datatracker.ietf.org/doc/html/draft-zhu-pku2u-04#section-6) +/// The type for the checksum extension. +/// GSS_EXTS_FINISHED 2 +const GSS_EXTS_FINISHED: u32 = 2; + +/// [2.2.5 LSAP_TOKEN_INFO_INTEGRITY](https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-KILE/%5bMS-KILE%5d.pdf) +/// indicating the token information type +/// 0x00000001 = User Account Control (UAC) restricted token +const LSAP_TOKEN_INFO_INTEGRITY_FLAG: u32 = 1; +/// [2.2.5 LSAP_TOKEN_INFO_INTEGRITY](https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-KILE/%5bMS-KILE%5d.pdf) +/// indicating the integrity level of the calling process +/// 0x00002000 = Medium. +const LSAP_TOKEN_INFO_INTEGRITY_TOKEN_IL: u32 = 0x00002000; +/// [3.1.1.4 Machine ID](https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-KILE/%5bMS-KILE%5d.pdf) +/// KILE implements a 32-byte binary random string machine ID. +const MACHINE_ID: [u8; 32] = [ + 92, 95, 64, 72, 191, 160, 228, 23, 98, 35, 78, 151, 207, 227, 96, 126, 97, 180, 15, 98, 127, 211, 90, 177, 119, + 132, 45, 113, 206, 90, 169, 124, +]; + // returns supported authentication types pub fn get_mech_list() -> MechTypeList { MechTypeList::from(vec![ @@ -73,7 +96,12 @@ pub fn get_mech_list() -> MechTypeList { ]) } -pub fn generate_pku2u_nego_req(service_name: &str, config: &Pku2uConfig) -> Result { +pub fn generate_pku2u_nego_req(service_names: Vec<&str>, config: &Pku2uConfig) -> Result { + let mut snames = Vec::with_capacity(service_names.len()); + for sname in service_names { + snames.push(KerberosStringAsn1::from(IA5String::from_str(sname)?)); + } + Ok(Pku2uNegoReq { metadata: ExplicitContextTag0::from(Asn1SequenceOf::from(vec![Pku2uNegoReqMetadata { inner: ImplicitContextTag0::from(OctetStringAsn1::from(picky_asn1_der::to_vec( @@ -84,12 +112,7 @@ pub fn generate_pku2u_nego_req(service_name: &str, config: &Pku2uConfig) -> Resu realm: ExplicitContextTag0::from(Realm::from(IA5String::from_str(WELLKNOWN_REALM)?)), sname: ExplicitContextTag1::from(PrincipalName { name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![NT_SRV_INST])), - name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![ - KerberosStringAsn1::from(IA5String::from_str(SERVICE_NAME)?), - // KerberosStringAsn1::from(IA5String::from_str(username).unwrap()), - // for the debugging - KerberosStringAsn1::from(IA5String::from_str("dest.dataans.com")?), - ])), + name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(snames)), }), }), }) @@ -205,26 +228,22 @@ pub fn get_default_parameters() -> (Vec, Vec, Vec) { ) } -pub fn generate_server_dh_parameters() -> Result { +pub fn generate_server_dh_parameters(rng: &mut OsRng) -> Result { Ok(DhParameters { base: Vec::new(), modulus: Vec::new(), q: Vec::new(), private_key: Vec::new(), other_public_key: None, - server_nonce: Some([ - 142, 91, 149, 4, 44, 55, 103, 6, 75, 168, 207, 165, 162, 197, 172, 27, 2, 108, 166, 10, 240, 52, 179, 24, - 56, 73, 137, 103, 160, 81, 236, 230, - ]), + server_nonce: Some(rng.gen::<[u8; RANDOM_ARRAY_SIZE]>()), client_nonce: None, }) } -pub fn generate_client_dh_parameters() -> Result { +pub fn generate_client_dh_parameters(rng: &mut OsRng) -> Result { let (p, g, q) = get_default_parameters(); - let mut rng = OsRng::default(); - let private_key = generate_private_key(&q, &mut rng); + let private_key = generate_private_key(&q, rng); Ok(DhParameters { base: g, @@ -232,10 +251,7 @@ pub fn generate_client_dh_parameters() -> Result { q, private_key, other_public_key: None, - client_nonce: Some([ - 142, 91, 149, 4, 44, 55, 103, 6, 75, 168, 207, 165, 162, 197, 172, 27, 2, 108, 166, 10, 240, 52, 179, 24, - 56, 73, 137, 103, 160, 81, 236, 230, - ]), + client_nonce: Some(rng.gen::<[u8; RANDOM_ARRAY_SIZE]>()), server_nonce: None, }) } @@ -345,6 +361,26 @@ pub fn generate_neg( }) } +pub fn generate_authenticator_extension(key: &[u8], payload: &[u8]) -> Result { + let hasher = ChecksumSuite::HmacSha196Aes256.hasher(); + + let krb_finished = KrbFinished { + gss_mic: ExplicitContextTag1::from(Checksum { + cksumtype: ExplicitContextTag0::from(IntegerAsn1::from(vec![ChecksumSuite::HmacSha196Aes256.into()])), + checksum: ExplicitContextTag1::from(OctetStringAsn1::from(hasher.checksum( + &key, + KEY_USAGE_FINISHED, + &payload, + )?)), + }), + }; + + Ok(AuthenticatorChecksumExtension { + extension_type: GSS_EXTS_FINISHED, + extension_value: picky_asn1_der::to_vec(&krb_finished)?, + }) +} + pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result { let GenerateAuthenticatorOptions { kdc_rep, @@ -352,7 +388,7 @@ pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result Result Result Result Result Ticket { ApplicationTag::from(TicketInner { tkt_vno: ExplicitContextTag0::from(IntegerAsn1::from(vec![5])), realm: ExplicitContextTag1::from(KerberosStringAsn1::from( - IA5String::from_str("WELLKNOWN:PKU2U").unwrap(), + IA5String::from_str(WELLKNOWN_REALM).unwrap(), )), sname: ExplicitContextTag2::from(PrincipalName { name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![2])), @@ -644,7 +676,7 @@ pub fn generate_ap_rep(session_key: &[u8], new_key: &[u8]) -> ApRep { ])))), }); let encoded_ap_rep_enc_part = picky_asn1_der::to_vec(&ap_rep_enc_part).unwrap(); - println!("encoded_ap_rep_enc_part: {:?}", encoded_ap_rep_enc_part); + let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); let cipher_data = cipher .encrypt(session_key, AP_REP_ENC, &encoded_ap_rep_enc_part) @@ -667,7 +699,6 @@ mod tests { use picky_asn1::bit_string::BitString; use picky_asn1::wrapper::{BitStringAsn1, ObjectIdentifierAsn1}; use picky_asn1_x509::oids::NEGOEX; - use picky_krb::crypto::CipherSuite; use sha1::{Digest, Sha1}; use super::generate_pku2u_nego_req; @@ -676,7 +707,7 @@ mod tests { #[test] fn _neg_token_init_generation() { - let token = generate_pku2u_nego_req("", &Pku2uConfig::default()).unwrap(); + let token = generate_pku2u_nego_req(vec![""], &Pku2uConfig::default()).unwrap(); println!("{:?}", picky_asn1_der::to_vec(&token).unwrap()); } diff --git a/src/utils.rs b/src/utils.rs index 53a2757b..47b295ec 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,6 @@ use byteorder::{LittleEndian, ReadBytesExt}; -use crate::sspi::pku2u::AZURE_AD_PREFIX; +use crate::sspi::pku2u::AZURE_AD_DOMAIN; pub fn string_to_utf16(value: &str) -> Vec { value @@ -25,10 +25,8 @@ pub fn get_domain_from_fqdn(fqdm: &[u8]) -> Option { fqdm.find('@').map(|index| fqdm.split_off(index + 1)) } -pub fn is_azure_ad_username(username: &[u8]) -> bool { - let username = bytes_to_utf16_string(username); - - username.starts_with(AZURE_AD_PREFIX) && username.contains('@') +pub fn is_azure_ad_domain(domain: &[u8]) -> bool { + bytes_to_utf16_string(domain) == AZURE_AD_DOMAIN } pub fn utf16_bytes_to_utf8_string(data: &[u8]) -> String { From 72355ba180b7db36941fb79c1239d52c5f3c9f2d Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Wed, 26 Oct 2022 17:07:31 +0300 Subject: [PATCH 15/36] sspi: pku2u: improve cert_utils and Pku2uConfig; ffi: add Pku2u package support; --- ffi/src/sec_handle.rs | 4 + src/lib.rs | 2 +- src/sspi/internal/credssp.rs | 18 -- src/sspi/negotiate.rs | 2 +- src/sspi/ntlm.rs | 9 - src/sspi/pku2u.rs | 2 +- src/sspi/pku2u/cert_utils.rs | 354 ++++++++++++++++++++++++++--------- src/sspi/pku2u/config.rs | 236 ++--------------------- src/sspi/pku2u/generators.rs | 2 +- 9 files changed, 291 insertions(+), 338 deletions(-) diff --git a/ffi/src/sec_handle.rs b/ffi/src/sec_handle.rs index fcded776..2fe97db0 100644 --- a/ffi/src/sec_handle.rs +++ b/ffi/src/sec_handle.rs @@ -9,6 +9,7 @@ use sspi::internal::credssp::SspiContext; use sspi::internal::SspiImpl; use sspi::kerberos::config::KerberosConfig; use sspi::kerberos::network_client::reqwest_network_client::ReqwestNetworkClient; +use sspi::{pku2u, Pku2u, Pku2uConfig}; use sspi::{ kerberos, negotiate, ntlm, AuthIdentityBuffers, ClientRequestFlags, DataRepresentation, Error, ErrorKind, Kerberos, Negotiate, NegotiateConfig, Ntlm, Result, Sspi, @@ -84,6 +85,9 @@ pub(crate) unsafe fn p_ctxt_handle_to_sspi_context( SspiContext::Negotiate(Negotiate::new(NegotiateConfig::default())?) } } + pku2u::PKG_NAME => { + SspiContext::Pku2u(Pku2u::new_client_from_config(Pku2uConfig::default_client_config()?)?) + } kerberos::PKG_NAME => { if let Some(settings) = &attributes.kdc_proxy_settings { SspiContext::Kerberos(Kerberos::new_client_from_config(KerberosConfig::from_kdc_url( diff --git a/src/lib.rs b/src/lib.rs index edb9ba86..73e9368f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,7 +88,7 @@ pub use utils::resolve_kdc_host; pub use crate::sspi::kerberos::config::KerberosConfig; pub use crate::sspi::kerberos::{Kerberos, KERBEROS_VERSION, PACKAGE_INFO as KERBEROS_PACKAGE_INFO}; pub use crate::sspi::negotiate::{Negotiate, NegotiateConfig}; -pub use crate::sspi::pku2u::{Pku2u, PACKAGE_INFO as PKU2U_PACKAGE_INFO, Pku2uConfig}; +pub use crate::sspi::pku2u::{self, Pku2u, PACKAGE_INFO as PKU2U_PACKAGE_INFO, Pku2uConfig}; #[cfg(windows)] pub use crate::sspi::winapi; pub use crate::sspi::{ diff --git a/src/sspi/internal/credssp.rs b/src/sspi/internal/credssp.rs index 70ce9a36..265b47a6 100644 --- a/src/sspi/internal/credssp.rs +++ b/src/sspi/internal/credssp.rs @@ -320,12 +320,6 @@ impl CredSspClient { peer_version, )?; - self.credentials = AuthIdentity { - username: "s7@dataans.com".into(), - password: "wwwWWW222@@@".into(), - domain: Some("AzureAD".into()), - }; - ts_request.auth_info = Some( self.context .as_mut() @@ -452,18 +446,6 @@ impl> CredSspServer { Ok(ServerState::Finished(read_credentials.into())) } CredSspState::NegoToken => { - // let input = try_cred_ssp_server!( - // ts_request - // .nego_tokens - // .take() - // .ok_or_else(|| { - // sspi::Error::new( - // sspi::ErrorKind::InvalidToken, - // String::from("Got empty nego_tokens field"), - // ) - // }), - // ts_request - // ); let input = ts_request.nego_tokens.take().unwrap_or(Vec::new()); let input_token = SecurityBuffer::new(input, SecurityBufferType::Token); let mut output_token = vec![SecurityBuffer::new(Vec::with_capacity(1024), SecurityBufferType::Token)]; diff --git a/src/sspi/negotiate.rs b/src/sspi/negotiate.rs index 9013a9da..9471081e 100644 --- a/src/sspi/negotiate.rs +++ b/src/sspi/negotiate.rs @@ -121,7 +121,7 @@ impl Negotiate { fn negotiate_protocol(&mut self, username: &[u8], domain: &[u8]) -> Result<()> { if let NegotiatedProtocol::Ntlm(_) = &self.protocol { if is_azure_ad_domain(domain) { - self.protocol = NegotiatedProtocol::Pku2u(Pku2u::new_client_from_config(Pku2uConfig::default())?); + self.protocol = NegotiatedProtocol::Pku2u(Pku2u::new_client_from_config(Pku2uConfig::default_client_config()?)?); return Ok(()); } diff --git a/src/sspi/ntlm.rs b/src/sspi/ntlm.rs index 9d52cb69..3806072b 100644 --- a/src/sspi/ntlm.rs +++ b/src/sspi/ntlm.rs @@ -12,7 +12,6 @@ use serde_derive::{Deserialize, Serialize}; use super::channel_bindings::ChannelBindings; use crate::crypto::{compute_hmac_md5, Rc4, HASH_SIZE}; -use crate::internal::credssp::CredentialsProxy; use crate::sspi::internal::SspiImpl; use crate::sspi::{ self, CertTrustStatus, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, @@ -464,14 +463,6 @@ pub struct AuthIdentity { pub domain: Option, } -impl CredentialsProxy for AuthIdentity { - type AuthenticationData = AuthIdentity; - - fn auth_data_by_user(&mut self, username: String, domain: Option) -> io::Result { - Ok(self.clone()) - } -} - #[derive(Debug, Clone, Eq, PartialEq, Default)] pub struct AuthIdentityBuffers { pub user: Vec, diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 754f4ca8..5888502b 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -582,7 +582,7 @@ impl SspiImpl for Pku2u { let signed_data: SignedData = picky_asn1_der::from_bytes(&dh_rep_info.dh_signed_data.0)?; - let rsa_public_key = validate_server_p2p_certificate(&signed_data, &self.config.p2p_ca_certificate)?; + let rsa_public_key = validate_server_p2p_certificate(&signed_data)?; validate_signed_data(&signed_data, &rsa_public_key)?; let public_key = extract_server_dh_public_key(&signed_data)?; diff --git a/src/sspi/pku2u/cert_utils.rs b/src/sspi/pku2u/cert_utils.rs index 034ea157..a7e97af2 100644 --- a/src/sspi/pku2u/cert_utils.rs +++ b/src/sspi/pku2u/cert_utils.rs @@ -1,29 +1,229 @@ -use std::{ptr::{null, null_mut}, ffi::OsStr, os::windows::prelude::OsStrExt, slice::from_raw_parts}; +use std::{ + ffi::{c_void, OsStr}, + io::Read, + os::windows::prelude::OsStrExt, + ptr::{null, null_mut}, + slice::from_raw_parts, +}; +use byteorder::{LittleEndian, ReadBytesExt}; +use oid::ObjectIdentifier; use picky_asn1_x509::{ signed_data::{CertificateChoices, SignedData}, - Certificate, PublicKey, + AttributeTypeAndValueParameters, Certificate, ExtensionView, PublicKey, +}; +use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; +use winapi::{ + shared::bcrypt::{BCRYPT_RSAFULLPRIVATE_BLOB, BCRYPT_RSAPUBLIC_MAGIC}, + um::{ + ncrypt::NCryptFreeObject, + wincrypt::{ + CertEnumCertificatesInStore, CertOpenStore, CryptAcquireCertificatePrivateKey, CERT_CONTEXT, + CERT_STORE_PROV_SYSTEM_W, CERT_SYSTEM_STORE_LOCAL_MACHINE_ID, CERT_SYSTEM_STORE_LOCATION_SHIFT, + CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE, + }, + }, +}; +use windows_sys::Win32::{ + Foundation, + Security::Cryptography::{NCryptExportKey, CERT_KEY_SPEC}, }; -use rsa::{BigUint, RsaPublicKey}; -use winapi::{um::wincrypt::{ - CertOpenStore, CryptExportKey, CERT_STORE_PROV_SYSTEM_W, CERT_SYSTEM_STORE_LOCAL_MACHINE_ID, - CERT_SYSTEM_STORE_LOCATION_SHIFT, CertEnumCertificatesInStore, CryptAcquireCertificatePrivateKey, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE, CERT_NCRYPT_KEY_SPEC, -}, shared::bcrypt::BCRYPT_RSAFULLPRIVATE_BLOB}; -use windows_sys::Win32::{Security::Cryptography::{CERT_KEY_SPEC, NCryptExportKey}, Foundation}; -use crate::{Error, ErrorKind, Result, utils::string_to_utf16}; +use crate::{utils::string_to_utf16, Error, ErrorKind, Result}; + +/// [BCRYPT_RSAKEY_BLOB](https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_rsakey_blob) +/// ```not_rust +/// typedef struct _BCRYPT_RSAKEY_BLOB { +/// ULONG Magic; +/// ULONG BitLength; +/// ULONG cbPublicExp; +/// ULONG cbModulus; +/// ULONG cbPrime1; +/// ULONG cbPrime2; +/// } BCRYPT_RSAKEY_BLOB; +/// ``` +#[derive(Debug)] +struct BcryptRsaKeyBlob { + pub magic: u32, + pub bit_len: u32, + pub public_exp: u32, + pub modulus: u32, + pub prime1: u32, + pub prime2: u32, +} + +impl BcryptRsaKeyBlob { + pub fn from_read(mut data: impl Read) -> Result { + Ok(Self { + magic: data.read_u32::()?, + bit_len: data.read_u32::()?, + public_exp: data.read_u32::()?, + modulus: data.read_u32::()?, + prime1: data.read_u32::()?, + prime2: data.read_u32::()?, + }) + } +} + +fn decode_private_key(mut buffer: impl Read) -> Result { + let rsa_key_blob = BcryptRsaKeyBlob::from_read(&mut buffer)?; + + if rsa_key_blob.magic == BCRYPT_RSAPUBLIC_MAGIC { + return Err(Error::new( + ErrorKind::InternalError, + "Cannot extract certificate private key".into(), + )); + } + + let mut public_exp = vec![0; rsa_key_blob.public_exp as usize]; + buffer.read_exact(&mut public_exp)?; + + let mut modulus = vec![0; rsa_key_blob.modulus as usize]; + buffer.read_exact(&mut modulus)?; + + let mut prime1 = vec![0; rsa_key_blob.prime1 as usize]; + buffer.read_exact(&mut prime1)?; + + let mut prime2 = vec![0; rsa_key_blob.prime2 as usize]; + buffer.read_exact(&mut prime2)?; + + let mut exp = vec![0; rsa_key_blob.prime1 as usize]; + buffer.read_exact(&mut exp)?; + + let mut exp = vec![0; rsa_key_blob.prime2 as usize]; + buffer.read_exact(&mut exp)?; + + let mut coef = vec![0; rsa_key_blob.prime1 as usize]; + buffer.read_exact(&mut coef)?; + + let mut private_exp = vec![0; (rsa_key_blob.bit_len / 8) as usize]; + buffer.read_exact(&mut private_exp)?; -/// Tries to find the device certificate and its private key + let rsa_private_key = RsaPrivateKey::from_components( + BigUint::from_bytes_be(&modulus), + BigUint::from_bytes_be(&public_exp), + BigUint::from_bytes_be(&private_exp), + vec![BigUint::from_bytes_be(&prime1), BigUint::from_bytes_be(&prime2)], + ); + + Ok(rsa_private_key) +} + +/// Validates the device certificate /// Requirements for the device certificate: -/// 1. Issuer CN = MS-Organization-Access -/// 2. Issuer OU = 82dbaca4-3e81-46ca-9c73-0950c1eaca97 -pub fn extract_device_certificate() -> Result<()> { +/// 1. Subject CN starts with 'MS-Organization-P2P-Access' +/// 2. ClientAuth extended key usage present +fn validate_client_p2p_certificate(certificate: &Certificate) -> bool { + let mut cn = false; + + for attr_type_and_value in certificate.tbs_certificate.issuer.0 .0.iter() { + for v in attr_type_and_value.0.iter() { + if v.ty.0 == ObjectIdentifier::try_from("2.5.4.3").unwrap() { + if let AttributeTypeAndValueParameters::CommonName(name) = &v.value { + if name.to_utf8_lossy().starts_with("MS-Organization-P2P-Access") { + cn = true; + } + } + } + } + } + + let mut client_auth = false; + + for extension in &certificate.tbs_certificate.extensions.0 .0 { + if extension.extn_id().0 == ObjectIdentifier::try_from("2.5.29.37").unwrap() { + if let ExtensionView::ExtendedKeyUsage(ext_key_usage) = extension.extn_value() { + if ext_key_usage.contains(ObjectIdentifier::try_from("1.3.6.1.5.5.7.3.2").unwrap()) { + client_auth = true; + } + } + } + } + + cn && client_auth +} + +unsafe fn export_certificate_private_key(cert: *const CERT_CONTEXT) -> Result { + let mut private_key_handle = HCRYPTPROV_OR_NCRYPT_KEY_HANDLE::default(); + let mut spec = CERT_KEY_SPEC::default(); + let mut free = Foundation::BOOL::default(); + + let status = CryptAcquireCertificatePrivateKey( + cert, + CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, + null_mut(), + &mut private_key_handle, + &mut spec, + &mut free, + ); + + if status == 0 || private_key_handle == 0 { + return Err(Error::new( + ErrorKind::InternalError, + "Cannot extract certificate private key".into(), + )); + } + + let mut key_blob = vec![0; 5000]; + let mut result_len = 0; + + let blob_type_wide = string_to_utf16(BCRYPT_RSAFULLPRIVATE_BLOB); + + let status = NCryptExportKey( + private_key_handle as _, + 0, + blob_type_wide.as_ptr() as *const _, + null(), + key_blob.as_mut_ptr(), + key_blob.len() as _, + &mut result_len, + 0, + ); + + if status != 0 { + return Err(Error::new( + ErrorKind::InternalError, + "Cannot extract certificate private key".into(), + )); + } + + let private_key = decode_private_key(&key_blob[0..result_len as usize])?; + + NCryptFreeObject(private_key_handle); + + return Ok(private_key); +} + +unsafe fn extract_client_p2p_certificate(cert_store: *mut c_void) -> Result<(Certificate, RsaPrivateKey)> { + let mut certificate = CertEnumCertificatesInStore(cert_store, null_mut()); + + while !certificate.is_null() { + let cert_der = from_raw_parts((*certificate).pbCertEncoded, (*certificate).cbCertEncoded as usize); + let cert: Certificate = picky_asn1_der::from_bytes(cert_der)?; + + if !validate_client_p2p_certificate(&cert) { + certificate = CertEnumCertificatesInStore(cert_store, certificate); + + continue; + } + + println!("found suitable"); + + let private_key = export_certificate_private_key(certificate)?; + + return Ok((cert, private_key)); + } + + Err(Error::new( + ErrorKind::InternalError, + "Cannot find appropriate device certificate".into(), + )) +} + +pub fn extract_client_p2p_cert_and_key() -> Result<(Certificate, RsaPrivateKey)> { unsafe { let which = "My"; - let data = OsStr::new(which) - .encode_wide() - .chain(Some(0)) - .collect::>(); + let data = OsStr::new(which).encode_wide().chain(Some(0)).collect::>(); let cert_store = CertOpenStore( CERT_STORE_PROV_SYSTEM_W, 0, @@ -39,77 +239,13 @@ pub fn extract_device_certificate() -> Result<()> { )); } - println!("cert_store: {:?}", cert_store); - - let mut certificate = CertEnumCertificatesInStore( - cert_store, - null_mut(), - ); - - println!("cert: {:?}", certificate); - - while !certificate.is_null() { - println!("loop: {:?}", certificate); - - println!("{:?}", (*certificate).pbCertEncoded); - println!("{:?}", (*certificate).cbCertEncoded); - - let cert_der = from_raw_parts((*certificate).pbCertEncoded, (*certificate).cbCertEncoded as usize); - let cert: Certificate = picky_asn1_der::from_bytes(cert_der)?; - - let mut private_key_handle = HCRYPTPROV_OR_NCRYPT_KEY_HANDLE::default(); - let mut spec = CERT_KEY_SPEC::default(); - let mut free = Foundation::BOOL::default(); - - // extract private key - let status = CryptAcquireCertificatePrivateKey( - certificate, - CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, - null_mut(), - &mut private_key_handle, - &mut spec, - &mut free, - ); - - println!("status: {}, free: {:?}, handle: {}", status, free, private_key_handle); - - if status != 0 && private_key_handle != 0 { - println!("try export private key"); - - let mut key_blob = null_mut(); - let mut result_len = 0; - - let blob_type_wide = string_to_utf16(BCRYPT_RSAFULLPRIVATE_BLOB); - - if spec & CERT_NCRYPT_KEY_SPEC != 0 { - println!("ncrypt"); - let status = NCryptExportKey( - private_key_handle as _, - 0, - blob_type_wide.as_ptr() as *const _, - null(), - key_blob, - 0, - &mut result_len, - 0, - ); - - println!("status: {}, key_blob: {:?}, result_len: {}", status, key_blob, result_len); - } else { - println!("crypt"); - } - } - - certificate = CertEnumCertificatesInStore(cert_store, certificate); - } + extract_client_p2p_certificate(cert_store) } - - Err(Error::new(ErrorKind::InternalError, "Cannot find appropriate device certificate".into())) } /// validates server's p2p certificate. /// If certificate is valid then return its public key. -pub fn validate_server_p2p_certificate(signed_data: &SignedData, _ca_cert: &Certificate) -> Result { +pub fn validate_server_p2p_certificate(signed_data: &SignedData) -> Result { let certificates = &signed_data.certificates.0 .0; for certificate in certificates { @@ -154,10 +290,56 @@ pub fn validate_server_p2p_certificate(signed_data: &SignedData, _ca_cert: &Cert #[cfg(test)] mod tests { - use super::extract_device_certificate; + use picky_asn1_x509::Certificate; + + use crate::pku2u::cert_utils::validate_client_p2p_certificate; #[test] - fn ts() { - extract_device_certificate().unwrap(); + fn test_client_p2p_certificate_validation() { + let certificate: Certificate = picky_asn1_der::from_bytes(&[ + 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 51, 247, 184, 98, 224, 162, 21, 50, 174, 177, + 189, 96, 58, 124, 107, 164, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, + 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, + 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, + 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 54, 49, 51, + 50, 51, 53, 56, 90, 23, 13, 50, 50, 49, 48, 50, 54, 49, 52, 50, 56, 53, 56, 90, 48, 129, 142, 49, 52, 48, + 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, + 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, + 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, + 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, + 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, + 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, + 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, + 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, + 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, + 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, + 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, + 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, + 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, + 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, + 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, + 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, + 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, + 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, + 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, + 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, + 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, + 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, + 130, 1, 1, 0, 71, 217, 65, 65, 121, 161, 60, 132, 114, 210, 31, 169, 34, 170, 87, 169, 50, 137, 52, 187, + 116, 98, 61, 8, 255, 89, 197, 131, 73, 33, 17, 136, 188, 42, 180, 22, 239, 101, 126, 28, 138, 35, 108, 101, + 138, 50, 54, 5, 105, 17, 85, 172, 239, 78, 21, 202, 246, 237, 51, 210, 17, 184, 39, 190, 135, 109, 73, 210, + 243, 138, 142, 72, 67, 206, 58, 129, 133, 215, 161, 103, 57, 97, 99, 131, 85, 45, 160, 129, 144, 5, 184, + 191, 7, 114, 24, 7, 237, 81, 246, 242, 94, 232, 161, 230, 108, 97, 184, 185, 182, 200, 178, 44, 7, 76, 10, + 47, 156, 88, 110, 198, 193, 125, 190, 84, 225, 93, 53, 87, 183, 14, 49, 118, 233, 217, 171, 139, 75, 131, + 8, 222, 241, 87, 3, 146, 243, 55, 69, 62, 204, 146, 92, 118, 241, 104, 209, 178, 228, 246, 199, 220, 104, + 32, 189, 125, 84, 82, 250, 215, 218, 10, 9, 21, 185, 251, 180, 51, 254, 67, 144, 78, 230, 201, 78, 127, 92, + 159, 26, 51, 223, 195, 192, 177, 251, 137, 234, 64, 37, 65, 76, 246, 118, 216, 224, 83, 152, 110, 67, 117, + 201, 2, 253, 173, 128, 73, 76, 26, 179, 93, 24, 227, 242, 121, 254, 170, 226, 31, 88, 196, 194, 58, 86, + 255, 192, 36, 221, 100, 20, 198, 221, 242, 249, 196, 211, 98, 111, 198, 220, 135, 239, 82, 74, 139, 243, 2, + 25, 215, + ]) + .unwrap(); + + assert!(validate_client_p2p_certificate(&certificate)); } } diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index f52862df..d6fede75 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -1,136 +1,27 @@ use picky_asn1_x509::Certificate; use rsa::pkcs1::DecodeRsaPrivateKey; -use rsa::pkcs8::DecodePrivateKey; use rsa::RsaPrivateKey; +use super::cert_utils::extract_client_p2p_cert_and_key; +use crate::Result; + #[derive(Debug, Clone)] pub struct Pku2uConfig { - pub device_certificate: Certificate, pub p2p_certificate: Certificate, - pub p2p_ca_certificate: Certificate, pub device_private_key: RsaPrivateKey, } impl Pku2uConfig { - pub fn default_server_config() -> Self { - Self { - device_private_key: RsaPrivateKey::from_pkcs1_der(&[ - 48, 130, 4, 165, 2, 1, 0, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, - 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, - 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, - 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, - 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, - 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, - 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, - 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, - 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, - 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, - 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, - 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, - 1, 2, 130, 1, 1, 0, 178, 100, 113, 112, 83, 117, 20, 63, 122, 193, 220, 139, 33, 125, 192, 43, 177, 21, - 73, 211, 19, 185, 156, 118, 207, 73, 129, 192, 247, 51, 158, 195, 136, 5, 172, 74, 184, 177, 186, 122, - 237, 139, 78, 252, 182, 87, 192, 192, 77, 118, 229, 137, 49, 38, 209, 247, 17, 157, 81, 12, 230, 106, - 251, 51, 249, 143, 104, 96, 46, 172, 243, 245, 1, 50, 76, 45, 78, 7, 124, 39, 154, 210, 203, 152, 22, - 233, 32, 40, 58, 181, 148, 56, 109, 47, 82, 91, 87, 29, 152, 222, 103, 131, 74, 240, 136, 153, 216, 37, - 69, 139, 116, 176, 2, 68, 83, 195, 189, 56, 108, 213, 40, 14, 135, 90, 152, 90, 78, 38, 229, 107, 54, - 252, 110, 117, 3, 112, 160, 108, 229, 3, 134, 204, 214, 191, 152, 126, 249, 36, 155, 78, 97, 103, 237, - 230, 138, 248, 84, 3, 34, 49, 203, 13, 164, 86, 10, 202, 94, 130, 87, 200, 189, 49, 172, 188, 188, 47, - 235, 200, 96, 125, 17, 109, 170, 32, 215, 71, 8, 96, 245, 83, 239, 39, 109, 70, 187, 58, 121, 243, 179, - 33, 46, 74, 48, 152, 249, 31, 211, 187, 234, 68, 22, 229, 223, 192, 70, 160, 33, 51, 33, 141, 231, 191, - 193, 245, 182, 154, 93, 29, 179, 172, 169, 96, 159, 37, 159, 38, 140, 138, 152, 58, 186, 185, 25, 167, - 44, 165, 186, 154, 216, 239, 40, 255, 73, 166, 213, 161, 2, 129, 129, 0, 206, 19, 212, 71, 145, 69, - 123, 105, 175, 72, 169, 243, 189, 229, 3, 31, 87, 12, 12, 36, 187, 203, 30, 253, 241, 36, 63, 106, 76, - 219, 159, 75, 119, 134, 97, 40, 29, 131, 21, 132, 122, 5, 167, 85, 135, 221, 116, 118, 27, 210, 167, - 98, 157, 232, 42, 248, 159, 82, 155, 166, 95, 216, 236, 85, 231, 201, 90, 175, 220, 38, 197, 150, 54, - 139, 123, 200, 81, 29, 190, 118, 179, 194, 54, 100, 207, 117, 10, 10, 195, 68, 131, 61, 163, 27, 187, - 12, 249, 219, 101, 130, 228, 95, 247, 106, 1, 175, 141, 203, 28, 139, 41, 166, 91, 128, 158, 134, 108, - 11, 136, 45, 6, 171, 236, 237, 15, 150, 117, 95, 2, 129, 129, 0, 247, 129, 4, 52, 135, 135, 143, 100, - 220, 70, 79, 249, 17, 41, 57, 48, 74, 214, 52, 154, 34, 108, 20, 220, 90, 193, 210, 111, 79, 27, 35, - 148, 111, 200, 241, 155, 141, 14, 175, 35, 56, 216, 209, 3, 218, 231, 171, 210, 186, 196, 183, 67, 83, - 186, 32, 149, 178, 235, 111, 76, 134, 61, 39, 80, 49, 105, 3, 109, 229, 69, 156, 191, 182, 230, 148, - 62, 232, 99, 101, 95, 234, 211, 145, 211, 147, 234, 12, 242, 237, 87, 99, 85, 164, 109, 78, 31, 99, - 144, 116, 97, 55, 103, 77, 29, 249, 69, 69, 134, 88, 189, 232, 240, 150, 61, 212, 193, 250, 40, 135, 9, - 234, 22, 119, 138, 223, 174, 157, 203, 2, 129, 128, 124, 53, 109, 116, 121, 118, 4, 173, 173, 141, 193, - 137, 253, 1, 228, 192, 230, 9, 135, 228, 56, 32, 116, 156, 160, 212, 181, 56, 79, 252, 235, 229, 99, - 180, 102, 40, 244, 168, 198, 182, 99, 137, 182, 211, 17, 162, 4, 9, 16, 58, 6, 211, 164, 211, 131, 218, - 248, 196, 164, 182, 65, 253, 16, 109, 178, 216, 37, 69, 236, 14, 158, 119, 44, 135, 35, 227, 152, 40, - 178, 92, 255, 121, 230, 169, 26, 117, 179, 200, 202, 235, 39, 163, 102, 5, 87, 215, 185, 93, 104, 176, - 221, 15, 142, 163, 161, 66, 123, 215, 89, 107, 243, 125, 166, 151, 62, 117, 76, 248, 34, 106, 233, 35, - 133, 25, 89, 148, 217, 71, 2, 129, 129, 0, 136, 161, 197, 131, 134, 42, 20, 195, 246, 66, 46, 149, 237, - 158, 87, 62, 204, 161, 113, 202, 129, 36, 47, 99, 242, 10, 59, 180, 76, 244, 75, 112, 255, 64, 235, - 248, 22, 39, 188, 17, 114, 169, 102, 193, 125, 16, 21, 175, 176, 129, 54, 54, 73, 187, 95, 143, 164, - 133, 10, 29, 49, 162, 2, 216, 231, 93, 244, 145, 175, 86, 253, 144, 108, 84, 224, 19, 214, 80, 64, 191, - 113, 176, 56, 57, 151, 215, 70, 44, 185, 79, 91, 188, 4, 152, 126, 223, 31, 36, 184, 202, 142, 62, 77, - 185, 53, 73, 195, 118, 197, 248, 152, 230, 111, 218, 84, 96, 125, 75, 240, 56, 77, 236, 247, 51, 72, 6, - 106, 127, 2, 129, 129, 0, 149, 64, 160, 185, 80, 7, 183, 188, 145, 39, 11, 48, 140, 239, 229, 100, 176, - 249, 209, 241, 141, 224, 143, 180, 104, 197, 208, 174, 104, 121, 96, 243, 82, 121, 68, 94, 71, 78, 232, - 206, 19, 70, 69, 110, 43, 66, 13, 16, 132, 63, 6, 115, 26, 56, 165, 174, 101, 190, 241, 247, 21, 150, - 21, 96, 129, 114, 137, 162, 153, 128, 80, 140, 190, 170, 49, 14, 215, 134, 38, 81, 184, 113, 249, 230, - 67, 239, 18, 68, 120, 202, 123, 6, 105, 202, 250, 129, 65, 217, 155, 156, 82, 210, 157, 130, 233, 38, - 238, 208, 32, 242, 29, 27, 254, 49, 143, 91, 50, 163, 81, 16, 2, 227, 182, 144, 234, 118, 212, 40, - ]) - .unwrap(), - device_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 242, 48, 130, 2, 218, 160, 3, 2, 1, 2, 2, 16, 151, 57, 89, 108, 207, 42, 14, 171, 65, 62, - 108, 81, 115, 209, 185, 213, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 120, 49, 118, - 48, 17, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 3, 110, 101, 116, 48, 21, 6, 10, 9, 146, - 38, 137, 147, 242, 44, 100, 1, 25, 22, 7, 119, 105, 110, 100, 111, 119, 115, 48, 29, 6, 3, 85, 4, 3, - 19, 22, 77, 83, 45, 79, 114, 103, 97, 110, 105, 122, 97, 116, 105, 111, 110, 45, 65, 99, 99, 101, 115, - 115, 48, 43, 6, 3, 85, 4, 11, 19, 36, 56, 50, 100, 98, 97, 99, 97, 52, 45, 51, 101, 56, 49, 45, 52, 54, - 99, 97, 45, 57, 99, 55, 51, 45, 48, 57, 53, 48, 99, 49, 101, 97, 99, 97, 57, 55, 48, 30, 23, 13, 50, - 50, 48, 57, 50, 52, 49, 57, 53, 54, 49, 56, 90, 23, 13, 51, 50, 48, 57, 50, 52, 50, 48, 50, 54, 49, 56, - 90, 48, 47, 49, 45, 48, 43, 6, 3, 85, 4, 3, 19, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, - 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, - 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, - 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, - 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, - 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, - 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, - 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, - 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, - 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, - 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, - 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, - 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, - 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, - 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 129, 192, 48, 129, 189, - 48, 12, 6, 3, 85, 29, 19, 1, 1, 255, 4, 2, 48, 0, 48, 22, 6, 3, 85, 29, 37, 1, 1, 255, 4, 12, 48, 10, - 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 34, 6, 11, 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 2, 4, 19, 4, - 129, 16, 221, 203, 182, 201, 240, 211, 195, 74, 152, 121, 224, 174, 59, 97, 189, 148, 48, 34, 6, 11, - 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 3, 4, 19, 4, 129, 16, 69, 148, 59, 128, 155, 126, 130, 76, - 147, 242, 220, 233, 157, 233, 149, 191, 48, 34, 6, 11, 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 5, 4, - 19, 4, 129, 16, 72, 36, 37, 169, 183, 154, 176, 73, 187, 92, 242, 249, 35, 200, 70, 114, 48, 20, 6, 11, - 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 8, 4, 5, 4, 129, 2, 69, 85, 48, 19, 6, 11, 42, 134, 72, 134, - 247, 20, 1, 5, 130, 28, 7, 4, 4, 4, 129, 1, 49, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, - 0, 3, 130, 1, 1, 0, 67, 13, 108, 42, 1, 160, 165, 193, 26, 122, 235, 13, 116, 210, 230, 62, 133, 236, - 164, 204, 73, 214, 202, 141, 168, 17, 115, 121, 37, 179, 151, 87, 25, 75, 141, 49, 31, 202, 184, 84, - 89, 106, 122, 240, 137, 27, 17, 166, 19, 244, 186, 168, 110, 139, 45, 63, 131, 123, 248, 102, 32, 163, - 224, 224, 127, 189, 76, 54, 43, 0, 73, 79, 101, 144, 137, 155, 95, 33, 126, 119, 97, 164, 158, 3, 208, - 4, 241, 50, 251, 83, 10, 49, 42, 3, 95, 24, 35, 28, 251, 74, 244, 187, 247, 97, 188, 64, 82, 234, 157, - 207, 109, 184, 138, 218, 178, 86, 155, 223, 48, 6, 36, 71, 171, 113, 65, 64, 69, 54, 155, 146, 88, 2, - 54, 122, 213, 131, 176, 27, 195, 135, 143, 23, 170, 79, 226, 29, 87, 62, 72, 224, 53, 153, 83, 60, 159, - 56, 185, 255, 247, 69, 153, 177, 93, 233, 242, 168, 65, 191, 1, 204, 93, 72, 103, 91, 231, 38, 149, - 115, 221, 194, 167, 130, 134, 68, 82, 202, 255, 133, 220, 45, 19, 171, 103, 87, 127, 144, 94, 156, 71, - 246, 138, 18, 158, 238, 46, 191, 207, 212, 114, 117, 207, 170, 231, 110, 83, 146, 238, 199, 244, 226, - 209, 172, 245, 134, 211, 166, 151, 128, 64, 18, 2, 67, 104, 142, 206, 111, 151, 80, 100, 232, 49, 204, - 76, 204, 105, 136, 207, 36, 135, 236, 178, 239, 209, 196, 34, 246, - ]) - .unwrap(), - p2p_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 154, 48, 130, 2, 130, 160, 3, 2, 1, 2, 2, 16, 60, 109, 248, 96, 153, 84, 93, 167, 227, 157, 154, 24, 242, 1, 254, 35, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 51, 49, 53, 51, 52, 51, 55, 90, 23, 13, 50, 50, 49, 48, 50, 52, 49, 53, 51, 57, 51, 55, 90, 48, 101, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 45, 48, 43, 6, 3, 85, 4, 3, 12, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 94, 48, 92, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 24, 6, 3, 85, 29, 17, 4, 17, 48, 15, 130, 13, 49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 57, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 175, 83, 189, 222, 20, 148, 46, 36, 168, 75, 200, 211, 109, 120, 6, 149, 61, 74, 49, 198, 33, 86, 3, 11, 136, 226, 121, 180, 159, 141, 98, 194, 235, 199, 249, 60, 107, 8, 47, 104, 56, 133, 210, 193, 127, 70, 248, 207, 56, 63, 37, 12, 169, 64, 36, 7, 227, 231, 226, 70, 157, 70, 65, 171, 182, 109, 170, 128, 30, 212, 44, 177, 225, 37, 73, 152, 196, 105, 162, 8, 251, 77, 23, 244, 14, 202, 90, 248, 178, 144, 236, 4, 120, 181, 168, 105, 117, 229, 48, 245, 36, 17, 235, 172, 221, 140, 125, 39, 241, 97, 235, 195, 98, 109, 40, 12, 72, 113, 95, 40, 188, 98, 160, 57, 222, 79, 102, 168, 85, 98, 124, 73, 57, 98, 77, 241, 142, 11, 69, 230, 15, 122, 119, 140, 200, 183, 130, 42, 55, 231, 119, 199, 213, 235, 133, 107, 125, 28, 54, 102, 173, 132, 176, 218, 90, 174, 195, 255, 70, 179, 87, 119, 102, 233, 209, 27, 230, 182, 112, 70, 184, 243, 64, 186, 168, 246, 106, 95, 50, 193, 253, 55, 83, 241, 244, 157, 252, 224, 251, 253, 131, 17, 224, 200, 39, 174, 206, 231, 64, 144, 24, 198, 75, 192, 171, 128, 135, 100, 102, 253, 13, 56, 28, 197, 255, 13, 16, 233, 136, 40, 131, 53, 73, 211, 217, 48, 103, 242, 65, 20, 173, 214, 133, 233, 214, 194, 209, 44, 239, 231, 37, 245, 138, 44, 108, 83 - ]) - .unwrap(), - p2p_ca_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 69, 48, 130, 2, 45, 160, 3, 2, 1, 2, 2, 16, 22, 50, 104, 218, 241, 214, 154, 131, 67, 50, 108, 181, 181, 208, 215, 142, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 48, 56, 48, 56, 48, 48, 48, 48, 48, 48, 90, 23, 13, 50, 51, 48, 56, 48, 56, 48, 48, 48, 48, 48, 48, 90, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 203, 229, 194, 53, 177, 190, 106, 224, 204, 234, 120, 252, 197, 60, 153, 3, 249, 198, 72, 46, 29, 126, 165, 180, 235, 139, 6, 210, 99, 186, 112, 60, 215, 68, 17, 84, 58, 103, 86, 129, 113, 213, 113, 97, 65, 215, 97, 126, 222, 16, 59, 165, 192, 127, 180, 9, 3, 75, 195, 228, 71, 182, 182, 163, 32, 17, 4, 127, 121, 245, 14, 1, 207, 158, 142, 120, 172, 22, 130, 43, 168, 198, 120, 58, 60, 73, 211, 52, 220, 30, 135, 204, 89, 199, 217, 159, 51, 13, 182, 40, 131, 141, 163, 180, 204, 139, 176, 104, 40, 233, 225, 169, 46, 146, 246, 144, 113, 211, 192, 249, 228, 169, 197, 74, 79, 156, 195, 161, 218, 165, 30, 238, 130, 151, 182, 82, 96, 153, 73, 49, 93, 39, 169, 139, 8, 18, 135, 4, 137, 220, 55, 64, 28, 15, 51, 113, 27, 217, 149, 8, 83, 230, 139, 131, 174, 6, 26, 128, 159, 161, 113, 103, 161, 122, 140, 85, 28, 166, 100, 188, 140, 93, 150, 131, 125, 62, 9, 222, 145, 80, 151, 199, 250, 202, 235, 106, 152, 27, 186, 143, 181, 195, 196, 128, 4, 106, 105, 12, 196, 61, 69, 90, 39, 14, 87, 3, 153, 48, 175, 65, 97, 50, 224, 105, 117, 198, 107, 9, 113, 240, 215, 255, 255, 116, 33, 9, 160, 131, 74, 88, 150, 15, 14, 206, 120, 227, 65, 167, 80, 104, 117, 108, 166, 169, 169, 145, 2, 3, 1, 0, 1, 163, 33, 48, 31, 48, 29, 6, 3, 85, 29, 14, 4, 22, 4, 20, 17, 90, 232, 137, 164, 206, 188, 19, 145, 103, 141, 13, 108, 109, 74, 100, 161, 175, 68, 37, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 88, 161, 67, 230, 91, 182, 227, 143, 148, 61, 244, 147, 62, 149, 14, 105, 227, 243, 179, 74, 31, 184, 56, 195, 133, 140, 235, 199, 215, 77, 62, 35, 148, 213, 35, 138, 126, 108, 13, 95, 61, 170, 129, 230, 150, 106, 8, 28, 219, 252, 196, 134, 152, 9, 229, 46, 249, 247, 113, 193, 28, 212, 252, 45, 178, 145, 155, 9, 83, 247, 238, 42, 59, 191, 1, 220, 155, 13, 210, 18, 179, 168, 40, 87, 87, 202, 220, 205, 46, 43, 23, 41, 102, 161, 66, 72, 165, 83, 107, 138, 159, 130, 28, 60, 143, 225, 85, 114, 158, 41, 101, 118, 229, 88, 17, 0, 237, 229, 185, 36, 6, 139, 208, 142, 137, 229, 88, 250, 190, 156, 204, 89, 207, 235, 239, 151, 185, 134, 9, 38, 30, 55, 97, 97, 194, 37, 22, 59, 128, 26, 14, 253, 13, 25, 40, 209, 221, 130, 117, 154, 151, 153, 107, 219, 141, 195, 250, 114, 175, 152, 133, 214, 13, 1, 126, 57, 148, 32, 56, 2, 6, 154, 31, 221, 145, 8, 196, 83, 36, 204, 56, 102, 177, 194, 14, 58, 212, 209, 40, 245, 124, 31, 99, 15, 247, 78, 219, 161, 121, 245, 160, 215, 137, 133, 190, 214, 122, 129, 26, 91, 104, 176, 98, 191, 46, 17, 231, 252, 217, 255, 13, 20, 171, 195, 33, 89, 235, 218, 120, 92, 124, 36, 168, 163, 254, 219, 23, 104, 111, 44, 69, 240, 227, 125, 168, 185 - ]) - .unwrap(), - } + pub fn default_client_config() -> Result { + let (p2p_certificate, device_private_key) = extract_client_p2p_cert_and_key()?; + + Ok(Self { + p2p_certificate, + device_private_key, + }) } -} -#[cfg(windows)] -impl Default for Pku2uConfig { - fn default() -> Self { + pub fn default_server_config() -> Self { Self { device_private_key: RsaPrivateKey::from_pkcs1_der(&[ 48, 130, 4, 165, 2, 1, 0, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, @@ -188,123 +79,26 @@ impl Default for Pku2uConfig { 238, 208, 32, 242, 29, 27, 254, 49, 143, 91, 50, 163, 81, 16, 2, 227, 182, 144, 234, 118, 212, 40, ]) .unwrap(), - device_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 242, 48, 130, 2, 218, 160, 3, 2, 1, 2, 2, 16, 151, 57, 89, 108, 207, 42, 14, 171, 65, 62, - 108, 81, 115, 209, 185, 213, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 120, 49, 118, - 48, 17, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 3, 110, 101, 116, 48, 21, 6, 10, 9, 146, - 38, 137, 147, 242, 44, 100, 1, 25, 22, 7, 119, 105, 110, 100, 111, 119, 115, 48, 29, 6, 3, 85, 4, 3, - 19, 22, 77, 83, 45, 79, 114, 103, 97, 110, 105, 122, 97, 116, 105, 111, 110, 45, 65, 99, 99, 101, 115, - 115, 48, 43, 6, 3, 85, 4, 11, 19, 36, 56, 50, 100, 98, 97, 99, 97, 52, 45, 51, 101, 56, 49, 45, 52, 54, - 99, 97, 45, 57, 99, 55, 51, 45, 48, 57, 53, 48, 99, 49, 101, 97, 99, 97, 57, 55, 48, 30, 23, 13, 50, - 50, 48, 57, 50, 52, 49, 57, 53, 54, 49, 56, 90, 23, 13, 51, 50, 48, 57, 50, 52, 50, 48, 50, 54, 49, 56, - 90, 48, 47, 49, 45, 48, 43, 6, 3, 85, 4, 3, 19, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, - 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, - 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, - 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, - 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, - 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, - 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, - 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, - 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, - 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, - 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, - 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, - 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, - 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, - 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 129, 192, 48, 129, 189, - 48, 12, 6, 3, 85, 29, 19, 1, 1, 255, 4, 2, 48, 0, 48, 22, 6, 3, 85, 29, 37, 1, 1, 255, 4, 12, 48, 10, - 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 34, 6, 11, 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 2, 4, 19, 4, - 129, 16, 221, 203, 182, 201, 240, 211, 195, 74, 152, 121, 224, 174, 59, 97, 189, 148, 48, 34, 6, 11, - 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 3, 4, 19, 4, 129, 16, 69, 148, 59, 128, 155, 126, 130, 76, - 147, 242, 220, 233, 157, 233, 149, 191, 48, 34, 6, 11, 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 5, 4, - 19, 4, 129, 16, 72, 36, 37, 169, 183, 154, 176, 73, 187, 92, 242, 249, 35, 200, 70, 114, 48, 20, 6, 11, - 42, 134, 72, 134, 247, 20, 1, 5, 130, 28, 8, 4, 5, 4, 129, 2, 69, 85, 48, 19, 6, 11, 42, 134, 72, 134, - 247, 20, 1, 5, 130, 28, 7, 4, 4, 4, 129, 1, 49, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, - 0, 3, 130, 1, 1, 0, 67, 13, 108, 42, 1, 160, 165, 193, 26, 122, 235, 13, 116, 210, 230, 62, 133, 236, - 164, 204, 73, 214, 202, 141, 168, 17, 115, 121, 37, 179, 151, 87, 25, 75, 141, 49, 31, 202, 184, 84, - 89, 106, 122, 240, 137, 27, 17, 166, 19, 244, 186, 168, 110, 139, 45, 63, 131, 123, 248, 102, 32, 163, - 224, 224, 127, 189, 76, 54, 43, 0, 73, 79, 101, 144, 137, 155, 95, 33, 126, 119, 97, 164, 158, 3, 208, - 4, 241, 50, 251, 83, 10, 49, 42, 3, 95, 24, 35, 28, 251, 74, 244, 187, 247, 97, 188, 64, 82, 234, 157, - 207, 109, 184, 138, 218, 178, 86, 155, 223, 48, 6, 36, 71, 171, 113, 65, 64, 69, 54, 155, 146, 88, 2, - 54, 122, 213, 131, 176, 27, 195, 135, 143, 23, 170, 79, 226, 29, 87, 62, 72, 224, 53, 153, 83, 60, 159, - 56, 185, 255, 247, 69, 153, 177, 93, 233, 242, 168, 65, 191, 1, 204, 93, 72, 103, 91, 231, 38, 149, - 115, 221, 194, 167, 130, 134, 68, 82, 202, 255, 133, 220, 45, 19, 171, 103, 87, 127, 144, 94, 156, 71, - 246, 138, 18, 158, 238, 46, 191, 207, 212, 114, 117, 207, 170, 231, 110, 83, 146, 238, 199, 244, 226, - 209, 172, 245, 134, 211, 166, 151, 128, 64, 18, 2, 67, 104, 142, 206, 111, 151, 80, 100, 232, 49, 204, - 76, 204, 105, 136, 207, 36, 135, 236, 178, 239, 209, 196, 34, 246, - ]) - .unwrap(), p2p_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 213, 48, 130, 2, 189, 160, 3, 2, 1, 2, 2, 16, 51, 207, 59, 83, 186, 122, 125, 103, 157, 228, 225, 84, 159, 209, 130, 233, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 53, 48, 55, 51, 57, 52, 54, 90, 23, 13, 50, 50, 49, 48, 50, 53, 48, 56, 52, 52, 52, 54, 90, 48, 129, 142, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 61, 48, 59, 6, 3, 85, 4, 3, 12, 52, 83, 45, 49, 45, 49, 50, 45, 49, 45, 51, 54, 53, 51, 50, 49, 49, 48, 50, 50, 45, 49, 51, 51, 57, 48, 48, 54, 52, 50, 50, 45, 50, 54, 50, 55, 53, 55, 51, 57, 48, 48, 45, 49, 53, 54, 48, 55, 51, 52, 57, 49, 57, 49, 23, 48, 21, 6, 3, 85, 4, 3, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 111, 48, 109, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 41, 6, 3, 85, 29, 17, 4, 34, 48, 32, 160, 30, 6, 10, 43, 6, 1, 4, 1, 130, 55, 20, 2, 3, 160, 16, 12, 14, 115, 55, 64, 100, 97, 116, 97, 97, 110, 115, 46, 99, 111, 109, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 5, 187, 195, 97, 55, 255, 107, 47, 56, 163, 10, 163, 65, 4, 75, 48, 109, 180, 165, 8, 66, 98, 68, 33, 49, 169, 118, 221, 230, 46, 52, 0, 127, 204, 192, 1, 116, 111, 93, 82, 253, 124, 35, 7, 215, 245, 170, 27, 209, 153, 80, 107, 55, 178, 71, 84, 113, 42, 18, 127, 154, 140, 214, 180, 1, 166, 8, 0, 36, 8, 164, 166, 51, 221, 212, 27, 125, 136, 29, 67, 224, 121, 66, 145, 130, 194, 233, 226, 199, 136, 119, 73, 30, 226, 204, 230, 179, 89, 141, 231, 177, 46, 158, 245, 130, 205, 140, 168, 230, 142, 252, 7, 30, 168, 227, 230, 171, 56, 102, 107, 99, 215, 212, 170, 5, 36, 14, 195, 21, 162, 105, 104, 165, 153, 177, 203, 231, 47, 229, 172, 144, 135, 185, 194, 243, 26, 255, 41, 208, 129, 178, 112, 240, 74, 78, 47, 183, 95, 15, 39, 16, 21, 200, 157, 93, 225, 167, 17, 152, 127, 249, 177, 98, 127, 45, 44, 222, 114, 52, 21, 149, 126, 80, 9, 74, 143, 108, 142, 250, 68, 154, 130, 109, 210, 152, 38, 229, 131, 130, 32, 65, 73, 139, 36, 183, 120, 195, 132, 84, 39, 136, 73, 236, 5, 12, 92, 208, 165, 110, 223, 218, 209, 26, 71, 99, 120, 62, 188, 83, 39, 123, 245, 183, 62, 220, 118, 241, 223, 118, 44, 255, 189, 190, 13, 20, 101, 85, 95, 171, 40, 2, 60, 83, 239, 116, 64 - ]) - .unwrap(), - p2p_ca_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 69, 48, 130, 2, 45, 160, 3, 2, 1, 2, 2, 16, 22, 50, 104, 218, 241, 214, 154, 131, 67, 50, - 108, 181, 181, 208, 215, 142, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, - 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, - 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, - 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 48, 56, - 48, 56, 48, 48, 48, 48, 48, 48, 90, 23, 13, 50, 51, 48, 56, 48, 56, 48, 48, 48, 48, 48, 48, 90, 48, 77, - 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, - 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, - 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 130, 1, 34, 48, 13, 6, - 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 203, - 229, 194, 53, 177, 190, 106, 224, 204, 234, 120, 252, 197, 60, 153, 3, 249, 198, 72, 46, 29, 126, 165, - 180, 235, 139, 6, 210, 99, 186, 112, 60, 215, 68, 17, 84, 58, 103, 86, 129, 113, 213, 113, 97, 65, 215, - 97, 126, 222, 16, 59, 165, 192, 127, 180, 9, 3, 75, 195, 228, 71, 182, 182, 163, 32, 17, 4, 127, 121, - 245, 14, 1, 207, 158, 142, 120, 172, 22, 130, 43, 168, 198, 120, 58, 60, 73, 211, 52, 220, 30, 135, - 204, 89, 199, 217, 159, 51, 13, 182, 40, 131, 141, 163, 180, 204, 139, 176, 104, 40, 233, 225, 169, 46, - 146, 246, 144, 113, 211, 192, 249, 228, 169, 197, 74, 79, 156, 195, 161, 218, 165, 30, 238, 130, 151, - 182, 82, 96, 153, 73, 49, 93, 39, 169, 139, 8, 18, 135, 4, 137, 220, 55, 64, 28, 15, 51, 113, 27, 217, - 149, 8, 83, 230, 139, 131, 174, 6, 26, 128, 159, 161, 113, 103, 161, 122, 140, 85, 28, 166, 100, 188, - 140, 93, 150, 131, 125, 62, 9, 222, 145, 80, 151, 199, 250, 202, 235, 106, 152, 27, 186, 143, 181, 195, - 196, 128, 4, 106, 105, 12, 196, 61, 69, 90, 39, 14, 87, 3, 153, 48, 175, 65, 97, 50, 224, 105, 117, - 198, 107, 9, 113, 240, 215, 255, 255, 116, 33, 9, 160, 131, 74, 88, 150, 15, 14, 206, 120, 227, 65, - 167, 80, 104, 117, 108, 166, 169, 169, 145, 2, 3, 1, 0, 1, 163, 33, 48, 31, 48, 29, 6, 3, 85, 29, 14, - 4, 22, 4, 20, 17, 90, 232, 137, 164, 206, 188, 19, 145, 103, 141, 13, 108, 109, 74, 100, 161, 175, 68, - 37, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 88, 161, 67, 230, 91, - 182, 227, 143, 148, 61, 244, 147, 62, 149, 14, 105, 227, 243, 179, 74, 31, 184, 56, 195, 133, 140, 235, - 199, 215, 77, 62, 35, 148, 213, 35, 138, 126, 108, 13, 95, 61, 170, 129, 230, 150, 106, 8, 28, 219, - 252, 196, 134, 152, 9, 229, 46, 249, 247, 113, 193, 28, 212, 252, 45, 178, 145, 155, 9, 83, 247, 238, - 42, 59, 191, 1, 220, 155, 13, 210, 18, 179, 168, 40, 87, 87, 202, 220, 205, 46, 43, 23, 41, 102, 161, - 66, 72, 165, 83, 107, 138, 159, 130, 28, 60, 143, 225, 85, 114, 158, 41, 101, 118, 229, 88, 17, 0, 237, - 229, 185, 36, 6, 139, 208, 142, 137, 229, 88, 250, 190, 156, 204, 89, 207, 235, 239, 151, 185, 134, 9, - 38, 30, 55, 97, 97, 194, 37, 22, 59, 128, 26, 14, 253, 13, 25, 40, 209, 221, 130, 117, 154, 151, 153, - 107, 219, 141, 195, 250, 114, 175, 152, 133, 214, 13, 1, 126, 57, 148, 32, 56, 2, 6, 154, 31, 221, 145, - 8, 196, 83, 36, 204, 56, 102, 177, 194, 14, 58, 212, 209, 40, 245, 124, 31, 99, 15, 247, 78, 219, 161, - 121, 245, 160, 215, 137, 133, 190, 214, 122, 129, 26, 91, 104, 176, 98, 191, 46, 17, 231, 252, 217, - 255, 13, 20, 171, 195, 33, 89, 235, 218, 120, 92, 124, 36, 168, 163, 254, 219, 23, 104, 111, 44, 69, - 240, 227, 125, 168, 185, + 48, 130, 3, 154, 48, 130, 2, 130, 160, 3, 2, 1, 2, 2, 16, 60, 109, 248, 96, 153, 84, 93, 167, 227, 157, 154, 24, 242, 1, 254, 35, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 51, 49, 53, 51, 52, 51, 55, 90, 23, 13, 50, 50, 49, 48, 50, 52, 49, 53, 51, 57, 51, 55, 90, 48, 101, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 45, 48, 43, 6, 3, 85, 4, 3, 12, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 94, 48, 92, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 24, 6, 3, 85, 29, 17, 4, 17, 48, 15, 130, 13, 49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 57, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 175, 83, 189, 222, 20, 148, 46, 36, 168, 75, 200, 211, 109, 120, 6, 149, 61, 74, 49, 198, 33, 86, 3, 11, 136, 226, 121, 180, 159, 141, 98, 194, 235, 199, 249, 60, 107, 8, 47, 104, 56, 133, 210, 193, 127, 70, 248, 207, 56, 63, 37, 12, 169, 64, 36, 7, 227, 231, 226, 70, 157, 70, 65, 171, 182, 109, 170, 128, 30, 212, 44, 177, 225, 37, 73, 152, 196, 105, 162, 8, 251, 77, 23, 244, 14, 202, 90, 248, 178, 144, 236, 4, 120, 181, 168, 105, 117, 229, 48, 245, 36, 17, 235, 172, 221, 140, 125, 39, 241, 97, 235, 195, 98, 109, 40, 12, 72, 113, 95, 40, 188, 98, 160, 57, 222, 79, 102, 168, 85, 98, 124, 73, 57, 98, 77, 241, 142, 11, 69, 230, 15, 122, 119, 140, 200, 183, 130, 42, 55, 231, 119, 199, 213, 235, 133, 107, 125, 28, 54, 102, 173, 132, 176, 218, 90, 174, 195, 255, 70, 179, 87, 119, 102, 233, 209, 27, 230, 182, 112, 70, 184, 243, 64, 186, 168, 246, 106, 95, 50, 193, 253, 55, 83, 241, 244, 157, 252, 224, 251, 253, 131, 17, 224, 200, 39, 174, 206, 231, 64, 144, 24, 198, 75, 192, 171, 128, 135, 100, 102, 253, 13, 56, 28, 197, 255, 13, 16, 233, 136, 40, 131, 53, 73, 211, 217, 48, 103, 242, 65, 20, 173, 214, 133, 233, 214, 194, 209, 44, 239, 231, 37, 245, 138, 44, 108, 83 ]) .unwrap(), } } } -#[cfg(not(windows))] -impl Default for Pku2uConfig { - fn default() -> Self { - Self { - device_certificate: todo!(), - p2p_certificate: todo!(), - p2p_ca_certificate: todo!(), - } - } -} - #[cfg(test)] mod tests { - use picky_asn1_x509::Certificate; use picky_krb::crypto::CipherSuite; use rsa::pkcs1::DecodeRsaPublicKey; - use rsa::{Hash, PaddingScheme, PublicKey, RsaPrivateKey, RsaPublicKey}; + use rsa::{Hash, PaddingScheme, PublicKey, RsaPublicKey}; use sha1::{Digest, Sha1}; use super::Pku2uConfig; #[test] fn p2p_i() { - let config = Pku2uConfig::default(); + let config = Pku2uConfig::default_client_config().unwrap(); println!("{:x?}", config.p2p_certificate.tbs_certificate.serial_number); println!( "{:?}", @@ -314,7 +108,7 @@ mod tests { #[test] fn p2p_c() { - let config = Pku2uConfig::default(); + let config = Pku2uConfig::default_client_config().unwrap(); let signed_attributes = [ 49, 61, 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index 94c94e9f..8db94ebc 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -707,7 +707,7 @@ mod tests { #[test] fn _neg_token_init_generation() { - let token = generate_pku2u_nego_req(vec![""], &Pku2uConfig::default()).unwrap(); + let token = generate_pku2u_nego_req(vec![""], &Pku2uConfig::default_client_config().unwrap()).unwrap(); println!("{:?}", picky_asn1_der::to_vec(&token).unwrap()); } From d247cc677288e5fb1236cbeb26f467986b2bf16b Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Wed, 26 Oct 2022 17:42:52 +0300 Subject: [PATCH 16/36] sspi: format code; fix cargo clippy; ffi: format code; --- ffi/src/sec_handle.rs | 5 +- src/lib.rs | 2 +- src/sspi/internal/credssp.rs | 11 +- src/sspi/kerberos.rs | 2 +- src/sspi/kerberos/client/extractors.rs | 3 +- src/sspi/kerberos/client/generators.rs | 28 +- src/sspi/negotiate.rs | 8 +- src/sspi/pku2u.rs | 315 ++------------------ src/sspi/pku2u/cert_utils.rs | 62 ++-- src/sspi/pku2u/config.rs | 203 ------------- src/sspi/pku2u/extractors.rs | 103 +------ src/sspi/pku2u/generators.rs | 382 +++---------------------- 12 files changed, 107 insertions(+), 1017 deletions(-) diff --git a/ffi/src/sec_handle.rs b/ffi/src/sec_handle.rs index 2fe97db0..7e19f35a 100644 --- a/ffi/src/sec_handle.rs +++ b/ffi/src/sec_handle.rs @@ -9,10 +9,9 @@ use sspi::internal::credssp::SspiContext; use sspi::internal::SspiImpl; use sspi::kerberos::config::KerberosConfig; use sspi::kerberos::network_client::reqwest_network_client::ReqwestNetworkClient; -use sspi::{pku2u, Pku2u, Pku2uConfig}; use sspi::{ - kerberos, negotiate, ntlm, AuthIdentityBuffers, ClientRequestFlags, DataRepresentation, Error, ErrorKind, Kerberos, - Negotiate, NegotiateConfig, Ntlm, Result, Sspi, + kerberos, negotiate, ntlm, pku2u, AuthIdentityBuffers, ClientRequestFlags, DataRepresentation, Error, ErrorKind, + Kerberos, Negotiate, NegotiateConfig, Ntlm, Pku2u, Pku2uConfig, Result, Sspi, }; #[cfg(windows)] use symbol_rename_macro::rename_symbol; diff --git a/src/lib.rs b/src/lib.rs index 73e9368f..b0fc6ca2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,7 +88,7 @@ pub use utils::resolve_kdc_host; pub use crate::sspi::kerberos::config::KerberosConfig; pub use crate::sspi::kerberos::{Kerberos, KERBEROS_VERSION, PACKAGE_INFO as KERBEROS_PACKAGE_INFO}; pub use crate::sspi::negotiate::{Negotiate, NegotiateConfig}; -pub use crate::sspi::pku2u::{self, Pku2u, PACKAGE_INFO as PKU2U_PACKAGE_INFO, Pku2uConfig}; +pub use crate::sspi::pku2u::{self, Pku2u, Pku2uConfig, PACKAGE_INFO as PKU2U_PACKAGE_INFO}; #[cfg(windows)] pub use crate::sspi::winapi; pub use crate::sspi::{ diff --git a/src/sspi/internal/credssp.rs b/src/sspi/internal/credssp.rs index 265b47a6..2c16d4df 100644 --- a/src/sspi/internal/credssp.rs +++ b/src/sspi/internal/credssp.rs @@ -401,9 +401,10 @@ impl> CredSspServer { try_cred_ssp_server!(Kerberos::new_server_from_config(kerberos_config.clone()), ts_request), ))), ClientMode::Ntlm => Some(CredSspContext::new(SspiContext::Ntlm(Ntlm::new()))), - ClientMode::Pku2u(pku2u) => Some(CredSspContext::new(SspiContext::Pku2u( - try_cred_ssp_server!(Pku2u::new_server_from_config(pku2u.clone()), ts_request) - ))), + ClientMode::Pku2u(pku2u) => Some(CredSspContext::new(SspiContext::Pku2u(try_cred_ssp_server!( + Pku2u::new_server_from_config(pku2u.clone()), + ts_request + )))), }; let AcquireCredentialsHandleResult { credentials_handle, .. } = try_cred_ssp_server!( self.context @@ -440,13 +441,13 @@ impl> CredSspServer { self.context.as_mut().unwrap().decrypt_ts_credentials(&auth_info), ts_request ); - + self.state = CredSspState::Final; Ok(ServerState::Finished(read_credentials.into())) } CredSspState::NegoToken => { - let input = ts_request.nego_tokens.take().unwrap_or(Vec::new()); + let input = ts_request.nego_tokens.take().unwrap_or_default(); let input_token = SecurityBuffer::new(input, SecurityBufferType::Token); let mut output_token = vec![SecurityBuffer::new(Vec::with_capacity(1024), SecurityBufferType::Token)]; diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 9f140648..b63697de 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -523,7 +523,7 @@ impl SspiImpl for Kerberos { let as_rep = self.as_exchange( GenerateAsReqOptions { realm, - username: &&username, + username: &username, cname_type, snames: &[TGT_SERVICE_NAME, realm], }, diff --git a/src/sspi/kerberos/client/extractors.rs b/src/sspi/kerberos/client/extractors.rs index 21e9ca2e..c688e1a6 100644 --- a/src/sspi/kerberos/client/extractors.rs +++ b/src/sspi/kerberos/client/extractors.rs @@ -41,8 +41,7 @@ pub fn extract_session_key_from_as_rep( let key = cipher.generate_key_from_password(password.as_bytes(), salt.as_bytes())?; - let enc_data = cipher - .decrypt(&key, AS_REP_ENC, &as_rep.0.enc_part.0.cipher.0 .0)?; + let enc_data = cipher.decrypt(&key, AS_REP_ENC, &as_rep.0.enc_part.0.cipher.0 .0)?; let enc_as_rep_part: EncAsRepPart = picky_asn1_der::from_bytes(&enc_data)?; diff --git a/src/sspi/kerberos/client/generators.rs b/src/sspi/kerberos/client/generators.rs index 33cb18de..4eece45f 100644 --- a/src/sspi/kerberos/client/generators.rs +++ b/src/sspi/kerberos/client/generators.rs @@ -1,9 +1,7 @@ -use std::convert::TryFrom; use std::str::FromStr; use chrono::{Duration, Utc}; use md5::{Digest, Md5}; -use oid::ObjectIdentifier; use picky_asn1::bit_string::BitString; use picky_asn1::date::GeneralizedTime; use picky_asn1::restricted_string::IA5String; @@ -15,7 +13,7 @@ use picky_asn1::wrapper::{ }; use picky_asn1_der::application_tag::ApplicationTag; use picky_asn1_der::Asn1RawDer; -use picky_asn1_x509::oids::{KRB5, KRB5_USER_TO_USER, MS_KRB5, SPNEGO}; +use picky_asn1_x509::oids; use picky_krb::constants::gss_api::{ ACCEPT_COMPLETE, ACCEPT_INCOMPLETE, AP_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE, TGT_REQ_TOKEN_ID, }; @@ -212,11 +210,13 @@ pub fn generate_as_req_kdc_body(options: &GenerateAsReqOptions) -> Result, kdc_req_body: KdcReqBody) -> AsReq { +pub fn generate_as_req(pa_datas: &[PaData], kdc_req_body: KdcReqBody) -> AsReq { AsReq::from(KdcReq { pvno: ExplicitContextTag1::from(IntegerAsn1::from(vec![KERBEROS_VERSION])), msg_type: ExplicitContextTag2::from(IntegerAsn1::from(vec![AS_REQ_MSG_TYPE])), - padata: Optional::from(Some(ExplicitContextTag3::from(Asn1SequenceOf::from(pa_datas.clone())))), + padata: Optional::from(Some(ExplicitContextTag3::from(Asn1SequenceOf::from( + pa_datas.to_owned(), + )))), req_body: ExplicitContextTag4::from(kdc_req_body), }) } @@ -447,13 +447,8 @@ pub fn generate_ap_req( let cipher = encryption_type.cipher(); let encoded_authenticator = picky_asn1_der::to_vec(&authenticator)?; - println!("encoded authenticator: {:?} {}", encoded_authenticator, encoded_authenticator.len()); - let encrypted_authenticator = cipher.encrypt( - session_key, - AP_REQ_AUTHENTICATOR, - &encoded_authenticator, - )?; + let encrypted_authenticator = cipher.encrypt(session_key, AP_REQ_AUTHENTICATOR, &encoded_authenticator)?; // let encrypted_authenticator = vec![80, 58, 178, 30, 181, 48, 100, 50, 91, 8, 248, 83, 53, 188, 200, 102, 243, 158, 83, 177, 114, 25, 52, 239, 62, 75, 30, 27, 36, 28, 89, 25, 245, 73, 139, 74, 148, 218, 247, 99, 184, 143, 51, 70, 243, 20, 101, 219, 128, 55, 188, 223, 241, 26, 161, 134, 42, 224, 42, 71, 37, 6, 8, 126, 244, 71, 108, 57, 43, 198, 18, 79, 134, 236, 3, 44, 47, 126, 8, 31, 138, 167, 110, 190, 74, 2, 67, 240, 102, 227, 87, 148, 113, 230, 206, 156, 133, 116, 179, 151, 234, 27, 46, 3, 156, 89, 138, 49, 9, 191, 81, 78, 20, 229, 204, 148, 29, 246, 108, 161, 126, 173, 237, 116, 50, 189, 133, 89, 161, 156, 144, 228, 215, 254, 152, 133, 240, 154, 17, 242, 0, 5, 77, 249, 61, 171, 226, 114, 6, 220, 162, 247, 108, 14, 249, 30, 46, 81, 226, 239, 2, 131, 64, 220, 63, 44, 119, 17, 55, 197, 60, 83, 218, 165, 66, 185, 96, 154, 144, 37, 155, 243, 48, 104, 170, 28, 198, 61, 210, 91, 110, 19, 32, 7, 211, 1, 29, 40, 222, 231, 246, 102, 131, 90, 174, 60, 104, 87, 185, 216, 160, 250, 147, 206, 185, 140, 222, 162, 79, 249, 249, 206, 171, 15, 181, 200, 161, 10, 82, 52, 253, 242, 14, 85, 96, 198, 20, 105, 241, 1, 231, 132, 92, 240, 125, 25, 70, 159, 183, 181, 232, 135, 144, 112, 177, 168, 192, 205, 8, 123, 94, 139, 75, 12, 182, 20, 197, 235, 109, 41, 254, 14, 109, 118, 84, 178, 27, 134, 164, 121, 81, 126, 167, 5, 61, 223, 187, 149, 210, 146, 44, 96, 144, 224, 239, 55, 28, 247, 29, 159, 36, 235, 107, 213, 24, 79, 212, 193, 139, 187, 35, 157, 160, 135, 102, 181, 156, 123, 23, 203, 70, 184, 59, 20, 67, 253, 105, 147, 213, 54]; Ok(ApReq::from(ApReqInner { @@ -471,15 +466,12 @@ pub fn generate_ap_req( // returns supported authentication types pub fn get_mech_list() -> MechTypeList { - MechTypeList::from(vec![ - MechType::from(ObjectIdentifier::try_from(MS_KRB5).unwrap()), - MechType::from(ObjectIdentifier::try_from(KRB5).unwrap()), - ]) + MechTypeList::from(vec![MechType::from(oids::ms_krb5()), MechType::from(oids::krb5())]) } pub fn generate_neg_token_init(username: &str) -> Result> { let krb5_neg_token_init: ApplicationTag<_, 0> = ApplicationTag::from(KrbMessage { - krb5_oid: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(KRB5_USER_TO_USER).unwrap()), + krb5_oid: ObjectIdentifierAsn1::from(oids::krb5_user_to_user()), krb5_token_id: TGT_REQ_TOKEN_ID, krb_msg: TgtReq { pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![KERBEROS_VERSION])), @@ -495,7 +487,7 @@ pub fn generate_neg_token_init(username: &str) -> Result Result Result> { let krb_blob: ApplicationTag<_, 0> = ApplicationTag(KrbMessage { - krb5_oid: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(KRB5_USER_TO_USER).unwrap()), + krb5_oid: ObjectIdentifierAsn1::from(oids::krb5_user_to_user()), krb5_token_id: AP_REQ_TOKEN_ID, krb_msg: ap_req, }); diff --git a/src/sspi/negotiate.rs b/src/sspi/negotiate.rs index 9471081e..6bf95fba 100644 --- a/src/sspi/negotiate.rs +++ b/src/sspi/negotiate.rs @@ -121,7 +121,8 @@ impl Negotiate { fn negotiate_protocol(&mut self, username: &[u8], domain: &[u8]) -> Result<()> { if let NegotiatedProtocol::Ntlm(_) = &self.protocol { if is_azure_ad_domain(domain) { - self.protocol = NegotiatedProtocol::Pku2u(Pku2u::new_client_from_config(Pku2uConfig::default_client_config()?)?); + self.protocol = + NegotiatedProtocol::Pku2u(Pku2u::new_client_from_config(Pku2uConfig::default_client_config()?)?); return Ok(()); } @@ -129,7 +130,8 @@ impl Negotiate { if let Some(domain) = get_domain_from_fqdn(username) { if let Some(host) = resolve_kdc_host(&domain) { self.protocol = NegotiatedProtocol::Kerberos(Kerberos::new_client_from_config(KerberosConfig { - url: Url::from_str(&host).unwrap(), + url: Url::from_str(&host) + .map_err(|err| Error::new(ErrorKind::InternalError, format!("{:?}", err)))?, kdc_type: KdcType::Kdc, network_client: Box::new(ReqwestNetworkClient::new()), })?) @@ -247,7 +249,7 @@ impl SspiImpl for Negotiate { if let Some(identity) = builder.auth_data { self.negotiate_protocol( identity.username.as_bytes(), - identity.domain.as_ref().map(|d| d.as_str()).unwrap_or("").as_bytes(), + identity.domain.as_deref().unwrap_or_default().as_bytes(), )?; } diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 5888502b..26747baf 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -12,14 +12,12 @@ use std::str::FromStr; pub use config::Pku2uConfig; use lazy_static::lazy_static; use picky_asn1_x509::signed_data::SignedData; -use picky_krb::constants::gss_api::{ - AP_REP_TOKEN_ID, AP_REQ_TOKEN_ID, AS_REP_TOKEN_ID, AS_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE, -}; +use picky_krb::constants::gss_api::{AP_REQ_TOKEN_ID, AS_REQ_TOKEN_ID, AUTHENTICATOR_CHECKSUM_TYPE}; use picky_krb::constants::key_usages::{ACCEPTOR_SIGN, INITIATOR_SIGN}; use picky_krb::crypto::diffie_hellman::{generate_key, DhNonce}; use picky_krb::crypto::{ChecksumSuite, CipherSuite}; -use picky_krb::gss_api::{NegTokenInit, NegTokenTarg1, WrapToken}; -use picky_krb::messages::{ApRep, ApReq, AsRep, AsReq}; +use picky_krb::gss_api::{NegTokenTarg1, WrapToken}; +use picky_krb::messages::{ApRep, AsRep}; use picky_krb::negoex::data_types::MessageType; use picky_krb::negoex::messages::{Exchange, Nego, Verify}; use picky_krb::negoex::{NegoexMessage, RANDOM_ARRAY_SIZE}; @@ -43,21 +41,17 @@ use crate::kerberos::server::extractors::extract_sub_session_key_from_ap_rep; use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE, MAX_SIGNATURE, RRC, SECURITY_TRAILER}; use crate::sspi::pku2u::cert_utils::validate_server_p2p_certificate; use crate::sspi::pku2u::extractors::{ - compute_session_key_from_pa_pk_as_req, extract_krb_rep, extract_pa_pk_as_rep, extract_pa_pk_as_req, - extract_server_dh_public_key, extract_server_nonce, extract_session_key_from_as_rep, - extract_sub_session_key_from_ap_req, -}; -use crate::sspi::pku2u::generators::{ - generate_ap_rep, generate_as_rep, generate_authenticator, generate_authenticator_extension, - generate_neg_token_completed, generate_neg_token_init_s, generate_pa_datas_for_as_rep, + extract_krb_rep, extract_pa_pk_as_rep, extract_server_dh_public_key, extract_server_nonce, + extract_session_key_from_as_rep, }; +use crate::sspi::pku2u::generators::{generate_authenticator, generate_authenticator_extension}; use crate::sspi::pku2u::validate::validate_signed_data; use crate::sspi::{self, PACKAGE_ID_NONE}; use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, AuthIdentityBuffers, CertTrustStatus, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, EncryptionFlags, Error, ErrorKind, InitializeSecurityContextResult, PackageCapabilities, PackageInfo, Result, SecurityBuffer, SecurityBufferType, - SecurityPackageType, SecurityStatus, ServerResponseFlags, Sspi, SspiEx, + SecurityPackageType, SecurityStatus, Sspi, SspiEx, }; pub const PKG_NAME: &str = "Pku2u"; @@ -379,7 +373,7 @@ impl SspiImpl for Pku2u { fn acquire_credentials_handle_impl<'a>( &'a mut self, builder: crate::builders::FilledAcquireCredentialsHandle<'a, Self::CredentialsHandle, Self::AuthenticationData>, - ) -> super::Result> { + ) -> Result> { if builder.credential_use == CredentialUse::Outbound && builder.auth_data.is_none() { return Err(Error::new( ErrorKind::NoCredentials, @@ -398,7 +392,7 @@ impl SspiImpl for Pku2u { fn initialize_security_context_impl<'a>( &mut self, builder: &mut crate::builders::FilledInitializeSecurityContext<'a, Self::CredentialsHandle>, - ) -> super::Result { + ) -> Result { let status = match self.state { Pku2uState::Negotiate => { let auth_scheme = Uuid::from_str(AUTH_SCHEME).unwrap(); @@ -413,7 +407,7 @@ impl SspiImpl for Pku2u { MessageType::InitiatorNego, self.conversation_id, self.next_seq_number(), - self.negoex_random.clone(), + self.negoex_random, vec![auth_scheme], vec![], ); @@ -692,8 +686,6 @@ impl SspiImpl for Pku2u { let neg_token_targ: NegTokenTarg1 = picky_asn1_der::from_bytes(&input_token.buffer)?; - // todo: check negResult (should be accept completed: 0) - let buffer = neg_token_targ .0 .response_token @@ -767,287 +759,12 @@ impl SspiImpl for Pku2u { fn accept_security_context_impl<'a>( &'a mut self, - builder: crate::builders::FilledAcceptSecurityContext<'a, Self::AuthenticationData, Self::CredentialsHandle>, - ) -> super::Result { - println!("accept_security_context_impl"); - let input = builder - .input - .ok_or_else(|| sspi::Error::new(ErrorKind::InvalidToken, "Input buffers must be specified".into()))?; - - let status = match &self.state { - Pku2uState::Preauthentication => { - let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; - println!("server: nego buffer: {:?}", input_token); - - self.gss_api_messages.extend_from_slice(&input_token.buffer); - - println!("server: neg init token: {:?}", &input_token.buffer[16..]); - let neg_token_init: NegTokenInit = picky_asn1_der::from_bytes(&input_token.buffer[16..]).unwrap(); - - println!("server: neg init parsed: {:?}", neg_token_init); - - let data = neg_token_init.mech_token.0.unwrap().0 .0; - - let mut reader: Box = Box::new(data.as_slice()); - - self.negoex_messages.extend_from_slice(&data); - - let initiator_nego = Nego::decode(&mut reader, &data)?; - - let initiator_exchange_data = &data[(initiator_nego.header.message_len as usize)..]; - println!("server: acceptor_exchage data: {:?}", initiator_exchange_data); - - let mut reader: Box = Box::new(initiator_exchange_data); - - let initiator_exchange = Exchange::decode(&mut reader, initiator_exchange_data)?; - - println!("server: acceptor_exchange: {:?}", initiator_exchange); - - self.conversation_id = initiator_nego.header.conversation_id.0; - - let mut mech_token = Vec::new(); - - let auth_scheme = Uuid::from_str(AUTH_SCHEME).unwrap(); - - let nego = Nego::new( - MessageType::AcceptorNego, - self.conversation_id, - self.next_seq_number(), - self.negoex_random.clone(), - vec![auth_scheme], - vec![], - ); - nego.encode(&mut mech_token)?; - - let exchange = Exchange::new( - MessageType::AcceptorMetaData, - self.conversation_id, - self.next_seq_number(), - auth_scheme, - vec![ - 48, 87, 160, 85, 48, 83, 48, 81, 128, 79, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, - 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, - 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, - 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, - ], - ); - exchange.encode(&mut mech_token)?; - - self.negoex_messages.extend_from_slice(&mech_token); - - let result_token = picky_asn1_der::to_vec(&generate_neg_token_init_s(mech_token)?)?; - self.gss_api_messages.extend_from_slice(&result_token); - - let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; - output_token.buffer.write_all(&result_token)?; - - self.state = Pku2uState::AsExchange; - - SecurityStatus::ContinueNeeded - } - Pku2uState::AsExchange => { - let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; - println!("server: as exchange buffer:: {:?}", input_token); - - self.gss_api_messages.extend_from_slice(&input_token.buffer); - - let nego_token: NegTokenTarg1 = picky_asn1_der::from_bytes(&input_token.buffer)?; - - let buffer = nego_token.0.response_token.0.unwrap().0 .0; - - self.negoex_messages.extend_from_slice(&buffer); - - let acceptor_exchange = Exchange::decode(buffer.as_slice(), &buffer)?; - - self.next_seq_number(); - - let (as_req, _): (AsReq, _) = extract_krb_rep(&acceptor_exchange.exchange)?; - println!("server: as_req parsed"); - let pa_pk_as_req = extract_pa_pk_as_req(&as_req)?; - - let mut f = std::fs::File::create("as_req_cert").unwrap(); - f.write_all(&acceptor_exchange.exchange).unwrap(); - - let (session_key, dh_server_public) = compute_session_key_from_pa_pk_as_req( - &pa_pk_as_req, - self.dh_parameters.server_nonce.as_ref().unwrap(), - )?; - - println!("dh session key: {:?}", session_key); - - self.encryption_params.session_key = Some(session_key); - - let new_key = vec![ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, - ]; - println!("server's session key: {:?}", new_key); - - let pa_datas = generate_pa_datas_for_as_rep( - &self.config.p2p_certificate, - self.dh_parameters.server_nonce.as_ref().unwrap(), - &dh_server_public, - &self.config.device_private_key, - )?; - let as_rep = generate_as_rep( - pa_datas, - self.encryption_params.session_key.as_ref().unwrap(), - new_key.clone(), - )?; - - let exchange_data = picky_asn1_der::to_vec(&generate_neg(as_rep, AS_REP_TOKEN_ID))?; - println!("exchange_data: {:?}", exchange_data); - - let mut mech_token = Vec::new(); - - let exchange = Exchange::new( - MessageType::Challenge, - self.conversation_id, - self.next_seq_number(), - self.auth_scheme.unwrap(), - exchange_data, - ); - exchange.encode(&mut mech_token)?; - - self.negoex_messages.extend_from_slice(&mech_token); - - let response_token = picky_asn1_der::to_vec(&generate_neg_token_targ(mech_token)?)?; - self.gss_api_messages.extend_from_slice(&response_token); - // println!("response_token: {:?}", response_token); - - self.encryption_params.session_key = Some(new_key); - - let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; - output_token.buffer.write_all(&response_token)?; - - self.state = Pku2uState::ApExchange; - - SecurityStatus::ContinueNeeded - } - Pku2uState::ApExchange => { - println!("server: ap exchange: {:?}", input); - // println!("negoexmessages: {:?}", self.negoex_messages); - let mut f = std::fs::File::create("negoex_messages.txt").unwrap(); - f.write_all(format!("{:?}", self.negoex_messages).as_bytes()).unwrap(); - - let mut f = std::fs::File::create("gss_api_messages.txt").unwrap(); - f.write_all(format!("{:?}", self.gss_api_messages).as_bytes()).unwrap(); - - // let new_key = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2]; - // println!("checksum: {:?}", ChecksumSuite::HmacSha196Aes256.hasher().checksum(&new_key, 41, &self.gss_api_messages)); - - println!("ap_req: {:?}", input); - - let input_token = SecurityBuffer::find_buffer(input, SecurityBufferType::Token)?; - println!("server: ap_req exchange buffer:: {:?}", input_token); - - // self.gss_api_messages.extend_from_slice(&input_token.buffer); - - let nego_token: NegTokenTarg1 = picky_asn1_der::from_bytes(&input_token.buffer)?; - - let buffer = nego_token.0.response_token.0.unwrap().0 .0; - - let initiator_exchange = Exchange::decode(buffer.as_slice(), &buffer)?; - - self.next_seq_number(); - - let initiator_verify_data = &buffer[(initiator_exchange.header.message_len as usize)..]; - println!("buffer for verify: {:?}", initiator_verify_data); - - let initiator_verify = Verify::decode(initiator_verify_data, initiator_verify_data)?; - println!("initiator verify: {:?}", initiator_verify); - - self.negoex_messages - .extend_from_slice(&buffer[0..(initiator_exchange.header.message_len as usize)]); - - let (ap_req, _): (ApReq, _) = extract_krb_rep(&initiator_exchange.exchange)?; - println!("ap_req: {:?}", ap_req); - let sub_session_key = - extract_sub_session_key_from_ap_req(&ap_req, self.encryption_params.session_key.as_ref().unwrap())?; - println!("ap_req authenticator key: {:?}", sub_session_key); - if initiator_verify.checksum.checksum_value - != ChecksumSuite::HmacSha196Aes256 - .hasher() - .checksum(&sub_session_key, 25, &self.negoex_messages)? - { - println!("bad initiator checksum"); - } else { - println!("good initiator checksum"); - } - - self.negoex_messages - .extend_from_slice(&buffer[(initiator_exchange.header.message_len as usize)..]); - - self.next_seq_number(); - - let test_sub_session_key = [ - 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, - ]; - self.encryption_params.sub_session_key = Some(test_sub_session_key.to_vec()); - println!("ap_rep enc part key: {:?}", test_sub_session_key); - - let ap_rep = generate_ap_rep( - self.encryption_params.session_key.as_ref().unwrap(), - // &sub_session_key, - &test_sub_session_key, - ); - - let mut mech_token = Vec::new(); - - let exchange = Exchange::new( - MessageType::Challenge, - self.conversation_id, - self.next_seq_number(), - self.auth_scheme.unwrap(), - picky_asn1_der::to_vec(&generate_neg(ap_rep, AP_REP_TOKEN_ID))?, - ); - println!("exchange ap_rep: {:?}", exchange); - exchange.encode(&mut mech_token)?; - - exchange.encode(&mut self.negoex_messages)?; - - // println!("negoex messages: {:?}", self.negoex_messages); - - let c2 = ChecksumSuite::HmacSha196Aes256.hasher().checksum( - &test_sub_session_key, - // self.encryption_params.session_key.as_ref().unwrap(), - 23, - &self.negoex_messages, - )?; - - let verify = Verify::new( - MessageType::Verify, - self.conversation_id, - self.next_seq_number(), - self.auth_scheme.unwrap(), - 16, - c2, - ); - verify.encode(&mut mech_token)?; - - verify.encode(&mut self.negoex_messages)?; - - let resp_token = picky_asn1_der::to_vec(&generate_neg_token_completed(mech_token)?)?; - println!("resp_token: {:?}", resp_token); - - let output_token = SecurityBuffer::find_buffer_mut(builder.output, SecurityBufferType::Token)?; - output_token.buffer.write_all(&resp_token)?; - - self.state = Pku2uState::PubKeyAuth; - - SecurityStatus::ContinueNeeded - } - state => { - println!("wow, I'm here: {:?}", state); - - SecurityStatus::CompleteNeeded - } - }; - - Ok(AcceptSecurityContextResult { - status, - flags: ServerResponseFlags::empty(), - expiry: None, - }) + _builder: crate::builders::FilledAcceptSecurityContext<'a, Self::AuthenticationData, Self::CredentialsHandle>, + ) -> Result { + Err(Error::new( + ErrorKind::UnsupportedFunction, + "accept_security_context_impl is not implemented yet".into(), + )) } } diff --git a/src/sspi/pku2u/cert_utils.rs b/src/sspi/pku2u/cert_utils.rs index a7e97af2..577ea06e 100644 --- a/src/sspi/pku2u/cert_utils.rs +++ b/src/sspi/pku2u/cert_utils.rs @@ -1,35 +1,25 @@ -use std::{ - ffi::{c_void, OsStr}, - io::Read, - os::windows::prelude::OsStrExt, - ptr::{null, null_mut}, - slice::from_raw_parts, -}; +use std::ffi::{c_void, OsStr}; +use std::io::Read; +use std::os::windows::prelude::OsStrExt; +use std::ptr::{null, null_mut}; +use std::slice::from_raw_parts; use byteorder::{LittleEndian, ReadBytesExt}; -use oid::ObjectIdentifier; -use picky_asn1_x509::{ - signed_data::{CertificateChoices, SignedData}, - AttributeTypeAndValueParameters, Certificate, ExtensionView, PublicKey, -}; +use picky_asn1_x509::signed_data::{CertificateChoices, SignedData}; +use picky_asn1_x509::{oids, AttributeTypeAndValueParameters, Certificate, ExtensionView, PublicKey}; use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; -use winapi::{ - shared::bcrypt::{BCRYPT_RSAFULLPRIVATE_BLOB, BCRYPT_RSAPUBLIC_MAGIC}, - um::{ - ncrypt::NCryptFreeObject, - wincrypt::{ - CertEnumCertificatesInStore, CertOpenStore, CryptAcquireCertificatePrivateKey, CERT_CONTEXT, - CERT_STORE_PROV_SYSTEM_W, CERT_SYSTEM_STORE_LOCAL_MACHINE_ID, CERT_SYSTEM_STORE_LOCATION_SHIFT, - CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE, - }, - }, -}; -use windows_sys::Win32::{ - Foundation, - Security::Cryptography::{NCryptExportKey, CERT_KEY_SPEC}, +use winapi::shared::bcrypt::{BCRYPT_RSAFULLPRIVATE_BLOB, BCRYPT_RSAPUBLIC_MAGIC}; +use winapi::um::ncrypt::NCryptFreeObject; +use winapi::um::wincrypt::{ + CertEnumCertificatesInStore, CertOpenStore, CryptAcquireCertificatePrivateKey, CERT_CONTEXT, + CERT_STORE_PROV_SYSTEM_W, CERT_SYSTEM_STORE_LOCAL_MACHINE_ID, CERT_SYSTEM_STORE_LOCATION_SHIFT, + CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE, }; +use windows_sys::Win32::Foundation; +use windows_sys::Win32::Security::Cryptography::{NCryptExportKey, CERT_KEY_SPEC}; -use crate::{utils::string_to_utf16, Error, ErrorKind, Result}; +use crate::utils::string_to_utf16; +use crate::{Error, ErrorKind, Result}; /// [BCRYPT_RSAKEY_BLOB](https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_rsakey_blob) /// ```not_rust @@ -118,7 +108,7 @@ fn validate_client_p2p_certificate(certificate: &Certificate) -> bool { for attr_type_and_value in certificate.tbs_certificate.issuer.0 .0.iter() { for v in attr_type_and_value.0.iter() { - if v.ty.0 == ObjectIdentifier::try_from("2.5.4.3").unwrap() { + if v.ty.0 == oids::at_common_name() { if let AttributeTypeAndValueParameters::CommonName(name) = &v.value { if name.to_utf8_lossy().starts_with("MS-Organization-P2P-Access") { cn = true; @@ -131,9 +121,9 @@ fn validate_client_p2p_certificate(certificate: &Certificate) -> bool { let mut client_auth = false; for extension in &certificate.tbs_certificate.extensions.0 .0 { - if extension.extn_id().0 == ObjectIdentifier::try_from("2.5.29.37").unwrap() { + if extension.extn_id().0 == oids::extended_key_usage() { if let ExtensionView::ExtendedKeyUsage(ext_key_usage) = extension.extn_value() { - if ext_key_usage.contains(ObjectIdentifier::try_from("1.3.6.1.5.5.7.3.2").unwrap()) { + if ext_key_usage.contains(oids::kp_client_auth()) { client_auth = true; } } @@ -164,7 +154,7 @@ unsafe fn export_certificate_private_key(cert: *const CERT_CONTEXT) -> Result Result Result<(Certificate, RsaPrivateKey)> { @@ -207,8 +197,6 @@ unsafe fn extract_client_p2p_certificate(cert_store: *mut c_void) -> Result<(Cer continue; } - println!("found suitable"); - let private_key = export_certificate_private_key(certificate)?; return Ok((cert, private_key)); @@ -248,7 +236,7 @@ pub fn extract_client_p2p_cert_and_key() -> Result<(Certificate, RsaPrivateKey)> pub fn validate_server_p2p_certificate(signed_data: &SignedData) -> Result { let certificates = &signed_data.certificates.0 .0; - for certificate in certificates { + if let Some(certificate) = certificates.iter().next() { let cert: Certificate = match certificate { CertificateChoices::Certificate(cert) => picky_asn1_der::from_bytes(&cert.0)?, _ => { @@ -270,7 +258,7 @@ pub fn validate_server_p2p_certificate(signed_data: &SignedData) -> Result Result Self { - Self { - device_private_key: RsaPrivateKey::from_pkcs1_der(&[ - 48, 130, 4, 165, 2, 1, 0, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, - 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, - 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, - 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, - 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, - 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, - 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, - 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, - 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, - 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, - 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, - 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, - 1, 2, 130, 1, 1, 0, 178, 100, 113, 112, 83, 117, 20, 63, 122, 193, 220, 139, 33, 125, 192, 43, 177, 21, - 73, 211, 19, 185, 156, 118, 207, 73, 129, 192, 247, 51, 158, 195, 136, 5, 172, 74, 184, 177, 186, 122, - 237, 139, 78, 252, 182, 87, 192, 192, 77, 118, 229, 137, 49, 38, 209, 247, 17, 157, 81, 12, 230, 106, - 251, 51, 249, 143, 104, 96, 46, 172, 243, 245, 1, 50, 76, 45, 78, 7, 124, 39, 154, 210, 203, 152, 22, - 233, 32, 40, 58, 181, 148, 56, 109, 47, 82, 91, 87, 29, 152, 222, 103, 131, 74, 240, 136, 153, 216, 37, - 69, 139, 116, 176, 2, 68, 83, 195, 189, 56, 108, 213, 40, 14, 135, 90, 152, 90, 78, 38, 229, 107, 54, - 252, 110, 117, 3, 112, 160, 108, 229, 3, 134, 204, 214, 191, 152, 126, 249, 36, 155, 78, 97, 103, 237, - 230, 138, 248, 84, 3, 34, 49, 203, 13, 164, 86, 10, 202, 94, 130, 87, 200, 189, 49, 172, 188, 188, 47, - 235, 200, 96, 125, 17, 109, 170, 32, 215, 71, 8, 96, 245, 83, 239, 39, 109, 70, 187, 58, 121, 243, 179, - 33, 46, 74, 48, 152, 249, 31, 211, 187, 234, 68, 22, 229, 223, 192, 70, 160, 33, 51, 33, 141, 231, 191, - 193, 245, 182, 154, 93, 29, 179, 172, 169, 96, 159, 37, 159, 38, 140, 138, 152, 58, 186, 185, 25, 167, - 44, 165, 186, 154, 216, 239, 40, 255, 73, 166, 213, 161, 2, 129, 129, 0, 206, 19, 212, 71, 145, 69, - 123, 105, 175, 72, 169, 243, 189, 229, 3, 31, 87, 12, 12, 36, 187, 203, 30, 253, 241, 36, 63, 106, 76, - 219, 159, 75, 119, 134, 97, 40, 29, 131, 21, 132, 122, 5, 167, 85, 135, 221, 116, 118, 27, 210, 167, - 98, 157, 232, 42, 248, 159, 82, 155, 166, 95, 216, 236, 85, 231, 201, 90, 175, 220, 38, 197, 150, 54, - 139, 123, 200, 81, 29, 190, 118, 179, 194, 54, 100, 207, 117, 10, 10, 195, 68, 131, 61, 163, 27, 187, - 12, 249, 219, 101, 130, 228, 95, 247, 106, 1, 175, 141, 203, 28, 139, 41, 166, 91, 128, 158, 134, 108, - 11, 136, 45, 6, 171, 236, 237, 15, 150, 117, 95, 2, 129, 129, 0, 247, 129, 4, 52, 135, 135, 143, 100, - 220, 70, 79, 249, 17, 41, 57, 48, 74, 214, 52, 154, 34, 108, 20, 220, 90, 193, 210, 111, 79, 27, 35, - 148, 111, 200, 241, 155, 141, 14, 175, 35, 56, 216, 209, 3, 218, 231, 171, 210, 186, 196, 183, 67, 83, - 186, 32, 149, 178, 235, 111, 76, 134, 61, 39, 80, 49, 105, 3, 109, 229, 69, 156, 191, 182, 230, 148, - 62, 232, 99, 101, 95, 234, 211, 145, 211, 147, 234, 12, 242, 237, 87, 99, 85, 164, 109, 78, 31, 99, - 144, 116, 97, 55, 103, 77, 29, 249, 69, 69, 134, 88, 189, 232, 240, 150, 61, 212, 193, 250, 40, 135, 9, - 234, 22, 119, 138, 223, 174, 157, 203, 2, 129, 128, 124, 53, 109, 116, 121, 118, 4, 173, 173, 141, 193, - 137, 253, 1, 228, 192, 230, 9, 135, 228, 56, 32, 116, 156, 160, 212, 181, 56, 79, 252, 235, 229, 99, - 180, 102, 40, 244, 168, 198, 182, 99, 137, 182, 211, 17, 162, 4, 9, 16, 58, 6, 211, 164, 211, 131, 218, - 248, 196, 164, 182, 65, 253, 16, 109, 178, 216, 37, 69, 236, 14, 158, 119, 44, 135, 35, 227, 152, 40, - 178, 92, 255, 121, 230, 169, 26, 117, 179, 200, 202, 235, 39, 163, 102, 5, 87, 215, 185, 93, 104, 176, - 221, 15, 142, 163, 161, 66, 123, 215, 89, 107, 243, 125, 166, 151, 62, 117, 76, 248, 34, 106, 233, 35, - 133, 25, 89, 148, 217, 71, 2, 129, 129, 0, 136, 161, 197, 131, 134, 42, 20, 195, 246, 66, 46, 149, 237, - 158, 87, 62, 204, 161, 113, 202, 129, 36, 47, 99, 242, 10, 59, 180, 76, 244, 75, 112, 255, 64, 235, - 248, 22, 39, 188, 17, 114, 169, 102, 193, 125, 16, 21, 175, 176, 129, 54, 54, 73, 187, 95, 143, 164, - 133, 10, 29, 49, 162, 2, 216, 231, 93, 244, 145, 175, 86, 253, 144, 108, 84, 224, 19, 214, 80, 64, 191, - 113, 176, 56, 57, 151, 215, 70, 44, 185, 79, 91, 188, 4, 152, 126, 223, 31, 36, 184, 202, 142, 62, 77, - 185, 53, 73, 195, 118, 197, 248, 152, 230, 111, 218, 84, 96, 125, 75, 240, 56, 77, 236, 247, 51, 72, 6, - 106, 127, 2, 129, 129, 0, 149, 64, 160, 185, 80, 7, 183, 188, 145, 39, 11, 48, 140, 239, 229, 100, 176, - 249, 209, 241, 141, 224, 143, 180, 104, 197, 208, 174, 104, 121, 96, 243, 82, 121, 68, 94, 71, 78, 232, - 206, 19, 70, 69, 110, 43, 66, 13, 16, 132, 63, 6, 115, 26, 56, 165, 174, 101, 190, 241, 247, 21, 150, - 21, 96, 129, 114, 137, 162, 153, 128, 80, 140, 190, 170, 49, 14, 215, 134, 38, 81, 184, 113, 249, 230, - 67, 239, 18, 68, 120, 202, 123, 6, 105, 202, 250, 129, 65, 217, 155, 156, 82, 210, 157, 130, 233, 38, - 238, 208, 32, 242, 29, 27, 254, 49, 143, 91, 50, 163, 81, 16, 2, 227, 182, 144, 234, 118, 212, 40, - ]) - .unwrap(), - p2p_certificate: picky_asn1_der::from_bytes(&[ - 48, 130, 3, 154, 48, 130, 2, 130, 160, 3, 2, 1, 2, 2, 16, 60, 109, 248, 96, 153, 84, 93, 167, 227, 157, 154, 24, 242, 1, 254, 35, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 77, 49, 75, 48, 73, 6, 3, 85, 4, 3, 30, 66, 0, 77, 0, 83, 0, 45, 0, 79, 0, 114, 0, 103, 0, 97, 0, 110, 0, 105, 0, 122, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 45, 0, 80, 0, 50, 0, 80, 0, 45, 0, 65, 0, 99, 0, 99, 0, 101, 0, 115, 0, 115, 0, 32, 0, 91, 0, 50, 0, 48, 0, 50, 0, 50, 0, 93, 48, 30, 23, 13, 50, 50, 49, 48, 50, 51, 49, 53, 51, 52, 51, 55, 90, 23, 13, 50, 50, 49, 48, 50, 52, 49, 53, 51, 57, 51, 55, 90, 48, 101, 49, 52, 48, 50, 6, 10, 9, 146, 38, 137, 147, 242, 44, 100, 1, 25, 22, 36, 97, 57, 50, 53, 50, 52, 52, 56, 45, 57, 97, 98, 55, 45, 52, 57, 98, 48, 45, 98, 98, 53, 99, 45, 102, 50, 102, 57, 50, 51, 99, 56, 52, 54, 55, 50, 49, 45, 48, 43, 6, 3, 85, 4, 3, 12, 36, 99, 57, 98, 54, 99, 98, 100, 100, 45, 100, 51, 102, 48, 45, 52, 97, 99, 51, 45, 57, 56, 55, 57, 45, 101, 48, 97, 101, 51, 98, 54, 49, 98, 100, 57, 52, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 199, 60, 253, 49, 157, 172, 15, 185, 180, 104, 241, 218, 22, 185, 120, 213, 135, 223, 222, 100, 75, 148, 218, 177, 71, 131, 140, 8, 195, 173, 7, 244, 41, 200, 45, 77, 173, 68, 205, 213, 27, 72, 246, 147, 167, 184, 52, 81, 44, 28, 143, 238, 201, 186, 143, 111, 62, 224, 73, 86, 69, 249, 239, 44, 79, 115, 37, 185, 243, 1, 23, 234, 116, 28, 244, 221, 99, 62, 177, 39, 128, 239, 115, 47, 184, 135, 25, 43, 109, 246, 200, 11, 116, 38, 99, 167, 136, 48, 59, 187, 188, 40, 216, 85, 133, 246, 5, 130, 177, 220, 6, 210, 34, 164, 15, 207, 125, 223, 42, 190, 77, 109, 69, 224, 132, 147, 115, 110, 39, 205, 112, 140, 44, 215, 43, 252, 206, 89, 55, 161, 210, 166, 234, 223, 0, 198, 24, 70, 158, 56, 78, 23, 76, 249, 86, 198, 95, 207, 53, 220, 75, 246, 91, 138, 99, 193, 186, 97, 57, 207, 115, 14, 1, 251, 111, 180, 121, 41, 132, 254, 82, 109, 66, 202, 11, 20, 14, 31, 242, 55, 225, 112, 210, 220, 229, 155, 152, 202, 92, 54, 223, 38, 153, 248, 173, 168, 180, 70, 146, 219, 186, 166, 251, 234, 149, 41, 18, 61, 227, 148, 13, 141, 229, 1, 49, 212, 128, 67, 225, 120, 7, 122, 41, 102, 241, 223, 249, 198, 117, 89, 37, 177, 142, 85, 24, 136, 230, 160, 136, 43, 89, 66, 41, 220, 85, 85, 2, 3, 1, 0, 1, 163, 94, 48, 92, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 24, 6, 3, 85, 29, 17, 4, 17, 48, 15, 130, 13, 49, 57, 50, 46, 49, 54, 56, 46, 48, 46, 49, 48, 57, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 27, 6, 9, 43, 6, 1, 4, 1, 130, 55, 21, 10, 4, 14, 48, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 175, 83, 189, 222, 20, 148, 46, 36, 168, 75, 200, 211, 109, 120, 6, 149, 61, 74, 49, 198, 33, 86, 3, 11, 136, 226, 121, 180, 159, 141, 98, 194, 235, 199, 249, 60, 107, 8, 47, 104, 56, 133, 210, 193, 127, 70, 248, 207, 56, 63, 37, 12, 169, 64, 36, 7, 227, 231, 226, 70, 157, 70, 65, 171, 182, 109, 170, 128, 30, 212, 44, 177, 225, 37, 73, 152, 196, 105, 162, 8, 251, 77, 23, 244, 14, 202, 90, 248, 178, 144, 236, 4, 120, 181, 168, 105, 117, 229, 48, 245, 36, 17, 235, 172, 221, 140, 125, 39, 241, 97, 235, 195, 98, 109, 40, 12, 72, 113, 95, 40, 188, 98, 160, 57, 222, 79, 102, 168, 85, 98, 124, 73, 57, 98, 77, 241, 142, 11, 69, 230, 15, 122, 119, 140, 200, 183, 130, 42, 55, 231, 119, 199, 213, 235, 133, 107, 125, 28, 54, 102, 173, 132, 176, 218, 90, 174, 195, 255, 70, 179, 87, 119, 102, 233, 209, 27, 230, 182, 112, 70, 184, 243, 64, 186, 168, 246, 106, 95, 50, 193, 253, 55, 83, 241, 244, 157, 252, 224, 251, 253, 131, 17, 224, 200, 39, 174, 206, 231, 64, 144, 24, 198, 75, 192, 171, 128, 135, 100, 102, 253, 13, 56, 28, 197, 255, 13, 16, 233, 136, 40, 131, 53, 73, 211, 217, 48, 103, 242, 65, 20, 173, 214, 133, 233, 214, 194, 209, 44, 239, 231, 37, 245, 138, 44, 108, 83 - ]) - .unwrap(), - } - } -} - -#[cfg(test)] -mod tests { - use picky_krb::crypto::CipherSuite; - use rsa::pkcs1::DecodeRsaPublicKey; - use rsa::{Hash, PaddingScheme, PublicKey, RsaPublicKey}; - use sha1::{Digest, Sha1}; - - use super::Pku2uConfig; - - #[test] - fn p2p_i() { - let config = Pku2uConfig::default_client_config().unwrap(); - println!("{:x?}", config.p2p_certificate.tbs_certificate.serial_number); - println!( - "{:?}", - picky_asn1_der::to_vec(&config.p2p_certificate.tbs_certificate.serial_number).unwrap() - ); - } - - #[test] - fn p2p_c() { - let config = Pku2uConfig::default_client_config().unwrap(); - - let signed_attributes = [ - 49, 61, 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, - 42, 134, 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 37, 144, 68, 78, 210, 60, 230, 236, 125, 249, 8, 246, - 201, 77, 20, 197, 108, 52, 75, 76, - ]; - let mut sha1 = Sha1::new(); - sha1.update(signed_attributes); - let res = sha1.finalize().to_vec(); - - let signature = config - .device_private_key - .sign(PaddingScheme::new_pkcs1v15_sign(Some(rsa::hash::Hash::SHA1)), &res) - .unwrap(); - println!("{:?}", signature); - println!("{}", signature.len()); - - println!( - "{:?}", - config.device_private_key.to_public_key().verify( - PaddingScheme::PKCS1v15Sign { hash: Some(Hash::SHA1) }, - &res, - &signature, - ) - ); - } - - #[test] - fn p2p_s() { - let public_key: RsaPublicKey = RsaPublicKey::from_pkcs1_pem( - "-----BEGIN RSA PUBLIC KEY----- -MIIBCgKCAQEApVx8YtLpzFFGmDmhI9f5JPUx1sEe6xJm39QwUuOZYKHbSSRLxVRh -Fy7uSnYS9gcn07b7kJoijCSYm+JJsUalGf32UlUoNppFxnhf3hVVj36eDijNQ/PT -qOQAYRJX/dsgIeXUW7rpCwJhSRSgHhEoxtfM7klZizNoZnSnJZUc7r8FK1R+6Mh7 -WWcOrkbv3PV7jD3ow8cjb82HqwWxSCpunh18yhPYituKGRfGoNnKxso4DuKhKH+r -RxGvd+moUmz2DWMqF5U6hdi3yBEGhkqFA1cpIGtdBewDWM2PYly3e4VH1BUeqgfq -xrG+r67m+4UEewwfRSQ0Wb6RmjlYtCy5nQIDAQAB ------END RSA PUBLIC KEY-----", - ) - .unwrap(); - - let signed_attributes = [ - 49, 61, 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, - 42, 134, 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 37, 144, 68, 78, 210, 60, 230, 236, 125, 249, 8, 246, - 201, 77, 20, 197, 108, 52, 75, 76, - ]; - - let mut sha1 = Sha1::new(); - sha1.update(signed_attributes); - - let res = sha1.finalize().to_vec(); - - let signature = [ - 48, 127, 17, 243, 30, 27, 158, 81, 187, 246, 135, 199, 188, 180, 74, 19, 19, 201, 95, 142, 99, 234, 136, - 80, 71, 222, 71, 215, 251, 157, 78, 191, 97, 63, 240, 189, 68, 54, 186, 182, 87, 106, 249, 127, 176, 220, - 207, 191, 214, 158, 155, 182, 28, 230, 57, 172, 76, 203, 134, 248, 43, 70, 114, 183, 5, 111, 137, 6, 208, - 219, 139, 231, 164, 164, 206, 166, 69, 159, 70, 144, 168, 44, 139, 138, 8, 84, 2, 224, 192, 54, 238, 88, - 174, 197, 135, 69, 235, 159, 72, 206, 13, 214, 121, 180, 203, 152, 186, 70, 167, 45, 127, 37, 89, 238, 118, - 130, 56, 90, 54, 221, 72, 84, 48, 86, 58, 24, 242, 88, 78, 59, 8, 65, 27, 141, 157, 19, 59, 50, 155, 36, - 68, 48, 119, 77, 36, 137, 128, 47, 129, 216, 235, 94, 253, 236, 181, 249, 254, 116, 123, 84, 211, 146, 251, - 142, 134, 246, 128, 251, 173, 72, 204, 160, 42, 121, 78, 242, 27, 243, 168, 136, 42, 13, 162, 141, 139, 84, - 151, 156, 215, 141, 110, 39, 236, 155, 76, 115, 224, 254, 180, 69, 238, 134, 73, 101, 155, 194, 202, 63, - 22, 97, 6, 166, 14, 76, 191, 231, 247, 230, 12, 169, 228, 9, 88, 32, 251, 241, 138, 8, 146, 20, 252, 27, - 82, 204, 112, 98, 110, 168, 240, 76, 96, 38, 73, 88, 251, 202, 75, 147, 96, 223, 110, 226, 48, 136, 51, - 238, - ]; - - println!( - "{:?}", - public_key.verify( - PaddingScheme::PKCS1v15Sign { hash: Some(Hash::SHA1) }, - &signed_attributes, - &signature, - ) - ); - println!( - "{:?}", - public_key.verify(PaddingScheme::PKCS1v15Sign { hash: Some(Hash::SHA1) }, &res, &signature,) - ); - } - - #[test] - fn hack() { - let data = [35, 111, 126, 23, 87, 190, 91, 115, 200, 160, 49, 19, 149, 223, 17, 183, 196, 209, 202, 166, 164, 175, 68, 100, 199, 205, 149, 86, 193, 231, 139, 142, 89, 21, 134, 214, 169, 241, 98, 172, 70, 134, 41, 83, 82, 214, 164, 12, 251, 197, 62, 76, 69, 22, 199, 80, 136, 206, 246, 164, 246, 215, 183, 122, 254, 21, 44, 251, 83, 58, 71, 59, 191, 89, 101, 186, 162, 78, 32, 54, 154, 137, 69, 23, 27, 114, 157, 125, 239, 158, 211, 89, 145, 211, 190, 134, 49, 235, 63, 88, 22, 222, 8, 167, 113, 117, 158, 163, 236, 93, 163, 125, 205, 68, 77, 229, 125, 250, 34, 125, 230, 199, 6, 49, 158, 5, 36, 246, 0, 175, 25, 130, 150, 116, 39, 101, 76, 177, 180, 48, 166, 23, 203, 187, 83, 254, 174, 247, 243, 136, 125, 128, 84, 184, 136, 180, 239, 3, 194, 87, 17, 214, 208, 9, 254, 108, 120, 87, 197, 74, 237, 155, 34, 190, 54, 132, 171, 249, 218, 79, 246, 254, 224, 158, 162, 230, 234, 71, 151, 95, 163, 208, 124, 42, 183, 2, 247, 116, 49, 40, 142, 122, 20, 202, 65, 19, 155, 215, 80, 101, 46, 87, 44, 57, 25, 15, 17, 123, 150, 106, 146, 34, 237, 141, 164, 104, 125, 154, 109, 132, 1, 45, 171, 247, 226, 40, 0, 168, 123, 250, 223, 165, 29, 244, 152, 216, 148, 176, 142, 255, 135, 59, 24, 125, 140, 210, 227, 165, 93, 98, 240, 108, 15, 153, 253, 172, 192, 132, 174, 156, 195, 226, 206, 103, 230, 203, 206, 209, 223, 152, 15, 212, 139, 19, 160, 28, 15, 119, 49, 159, 38, 148, 240, 186, 243, 30, 246, 118, 105, 135, 22, 108, 106, 189, 169, 105, 164, 21, 61, 174, 81, 113, 62, 174, 5, 173, 121, 51, 207, 181, 171, 171, 110]; - let password = "qweQWE123!@#"; - let salt = "QKATION.COMp3"; - - let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); - - let key = cipher.generate_key_from_password(password.as_bytes(), salt.as_bytes()).unwrap(); - - println!("{:?}", cipher.decrypt(&key, 3, &data)); - } - - #[test] - fn hack2() { - let key = [243, 146, 221, 113, 157, 22, 182, 28, 221, 20, 131, 150, 229, 209, 204, 208, 85, 238, 136, 165, 130, 18, 183, 62, 218, 183, 253, 172, 194, 167, 105, 191]; - let data = [154, 190, 201, 145, 114, 166, 106, 59, 246, 162, 223, 92, 177, 85, 120, 189, 61, 214, 210, 229, 235, 18, 41, 152, 183, 186, 234, 35, 83, 163, 18, 34, 75, 253, 225, 22, 216, 14, 222, 60, 18, 55, 64, 223, 37, 202, 141, 107, 242, 41, 249, 148, 75, 133, 163, 64, 49, 161, 133, 42, 160, 115, 36, 119, 193, 49, 192, 234, 209, 168, 6, 208, 215, 145, 86, 154, 62, 108, 38, 184, 198, 82, 81, 249, 106, 231, 213, 147, 68, 3, 2, 224, 26, 163, 217, 76, 221, 224, 62, 111, 216, 251, 80, 41, 194, 239, 103, 81, 64, 190, 152, 135, 162, 68, 175, 61, 39, 14, 84, 151, 141, 66, 0, 209, 73, 48, 164, 175, 102, 30, 140, 77, 184, 50, 151, 99, 231, 22, 207, 129, 97, 152, 20, 174, 136, 104, 250, 57, 54, 203, 135, 32, 79, 31, 114, 94, 49, 208, 132, 208, 79, 242, 56, 191, 180, 222, 155, 182, 19, 12, 15, 122, 213, 235, 231, 184, 148, 32, 73, 112, 67, 253, 163, 207, 67, 223, 13, 89, 120, 53, 175, 90, 190, 212, 128, 53, 238, 146, 126, 37, 71, 246, 201, 189, 95, 55, 175, 100, 166, 29, 193, 72, 92, 2, 150, 210, 191, 196, 196, 4, 113, 66, 123, 123, 111, 9, 83, 19, 20, 111, 39, 47, 244, 44, 52, 189, 98, 207, 14, 104, 104, 74, 169, 17, 213, 86, 158, 0, 15, 117, 194, 29, 241, 168, 0, 12, 245, 190, 143, 243, 14, 54, 30, 52, 228, 64, 61, 202, 161, 62, 39, 91, 46, 5, 110, 111, 153, 133, 78]; - - let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); - - println!("{:?}", cipher.decrypt(&key, 8, &data)); - } - - #[test] - fn hack3() { - let key = [177, 74, 125, 22, 44, 74, 5, 160, 161, 2, 173, 142, 149, 153, 114, 160, 177, 126, 138, 193, 79, 214, 194, 46, 103, 138, 164, 20, 120, 144, 72, 242]; - let data = [206, 126, 45, 212, 242, 154, 98, 34, 26, 54, 32, 44, 191, 203, 59, 246, 211, 161, 19, 244, 6, 255, 206, 135, 120, 251, 94, 221, 129, 4, 203, 224, 174, 49, 218, 69, 200, 39, 118, 147, 29, 69, 147, 223, 137, 8, 44, 208, 85, 120, 230, 136, 40, 223, 38, 51, 70, 185, 222, 109, 212, 63, 109, 45, 146, 107, 118, 64, 178, 254, 37, 237, 54, 152, 164, 228, 89, 80, 154, 131, 1, 100, 103, 164, 101, 6, 253, 49, 176, 160, 87, 35, 38, 201, 37, 37, 137, 162, 9, 136, 121, 233, 70, 72, 206, 201, 226, 235, 25, 93, 177, 57, 236, 173, 136, 8, 74, 47, 44, 11, 163, 88, 59, 51, 178, 205, 107, 101, 147, 8, 218, 30, 136, 84, 69, 102, 32, 12, 195, 216, 32, 93, 115, 10, 69, 142, 45, 0, 49, 113, 251, 143, 88, 212, 34, 69, 88, 181, 87, 124, 73, 105, 90, 98, 149, 205, 82, 124, 101, 244, 176, 7, 59, 167, 77, 207, 60, 214, 58, 179, 108, 110, 206, 221, 196, 138, 236, 110, 127, 169, 111, 182, 243, 7, 215, 74, 1, 52, 27, 231, 67, 151, 95, 146, 90, 62, 215, 130, 47, 146, 88, 237, 186, 104, 188, 81, 85, 89, 196, 22, 188, 200, 250, 206, 149, 207, 49, 86, 99, 9, 79, 25, 61, 11, 140, 246, 226, 123, 246, 9, 235, 22, 110, 15, 156, 184, 226, 45, 57, 153, 46, 137, 157, 3, 38, 61, 22, 81, 184, 150, 192, 109, 246, 62, 21, 60, 198, 199, 245, 201, 165, 159, 209, 161, 171, 247, 22, 37, 95, 140, 23, 9, 136, 39, 5, 122, 164, 95, 205, 7, 8, 183, 204, 39, 224, 141, 74, 178, 145, 140, 119, 174]; - - let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); - - println!("{:?}", cipher.decrypt(&key, 11, &data)); - } } diff --git a/src/sspi/pku2u/extractors.rs b/src/sspi/pku2u/extractors.rs index 0fcf81f5..1af0e8ad 100644 --- a/src/sspi/pku2u/extractors.rs +++ b/src/sspi/pku2u/extractors.rs @@ -7,14 +7,10 @@ use picky_asn1_der::Asn1RawDer; use picky_asn1_x509::content_info::ContentValue; use picky_asn1_x509::oids::PKINIT_DH_KEY_DATA; use picky_asn1_x509::signed_data::SignedData; -use picky_krb::constants::key_usages::{AP_REQ_AUTHENTICATOR, AS_REP_ENC}; -use picky_krb::constants::types::{PA_PK_AS_REP, PA_PK_AS_REQ}; -use picky_krb::crypto::diffie_hellman::{compute_public_key, generate_key, generate_private_key, DhNonce}; -use picky_krb::crypto::CipherSuite; -use picky_krb::data_types::Authenticator; -use picky_krb::messages::{ApReq, AsRep, AsReq, EncAsRepPart}; -use picky_krb::pkinit::{AuthPack, DhRepInfo, KdcDhKeyInfo, PaPkAsRep, PaPkAsReq}; -use rand::rngs::OsRng; +use picky_krb::constants::key_usages::AS_REP_ENC; +use picky_krb::constants::types::PA_PK_AS_REP; +use picky_krb::messages::{AsRep, EncAsRepPart}; +use picky_krb::pkinit::{DhRepInfo, KdcDhKeyInfo, PaPkAsRep}; use serde::Deserialize; use super::generators::DH_NONCE_LEN; @@ -36,7 +32,7 @@ pub fn extract_pa_pk_as_rep(as_rep: &AsRep) -> Result { .as_ref() .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "pa-datas is not present in as-rep".into()))? .iter() - .find(|pa_data| &pa_data.padata_type.0 .0 == &PA_PK_AS_REP) + .find(|pa_data| pa_data.padata_type.0 .0 == PA_PK_AS_REP) .ok_or_else(|| { Error::new( ErrorKind::InvalidToken, @@ -115,96 +111,9 @@ pub fn extract_session_key_from_as_rep(as_rep: &AsRep, key: &[u8], enc_params: & .unwrap_or(&DEFAULT_ENCRYPTION_TYPE) .cipher(); - let enc_data = cipher.decrypt(&key, AS_REP_ENC, &as_rep.0.enc_part.0.cipher.0 .0)?; + let enc_data = cipher.decrypt(key, AS_REP_ENC, &as_rep.0.enc_part.0.cipher.0 .0)?; let enc_as_rep_part: EncAsRepPart = picky_asn1_der::from_bytes(&enc_data)?; Ok(enc_as_rep_part.0.key.0.key_value.0.to_vec()) } - -pub fn extract_pa_pk_as_req(as_req: &AsReq) -> Result { - Ok(picky_asn1_der::from_bytes( - &as_req - .0 - .padata - .0 - .as_ref() - .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "pa-datas is not present in as rep".into()))? - .iter() - .find(|pa_data| &pa_data.padata_type.0 .0 == &PA_PK_AS_REQ) - .ok_or_else(|| { - Error::new( - ErrorKind::InvalidToken, - "PA_PK_AS_REP is not present in pa-datas of the as rep".into(), - ) - })? - .padata_data - .0 - .0, - )?) -} - -pub fn compute_session_key_from_pa_pk_as_req( - pa_pk_as_req: &PaPkAsReq, - dh_server_nonce: &[u8], -) -> Result<(Vec, Vec)> { - let signed_data: SignedData = picky_asn1_der::from_bytes(&pa_pk_as_req.signed_auth_pack.0)?; - let content = signed_data - .content_info - .content - .ok_or_else(|| { - Error::new( - ErrorKind::InvalidToken, - "Content of the EncapsulatedContentInfo is not present".into(), - ) - })? - .0; - let auth_pack: AuthPack = picky_asn1_der::from_bytes(match &content { - ContentValue::OctetString(data) => &data.0, - c => unimplemented!("wrong content value: {:?}", c), - })?; - - let dh_client_public_info = &auth_pack - .client_public_value - .0 - .as_ref() - .ok_or_else(|| Error::new(ErrorKind::InvalidToken, "DH public key is not present".into()))? - .0; - - let g = dh_client_public_info.key_info.key_info.g.0.clone(); - let p = dh_client_public_info.key_info.key_info.p.0.clone(); - let q = dh_client_public_info.key_info.key_info.q.0.clone(); - - let dh_client_public: IntegerAsn1 = picky_asn1_der::from_bytes(&dh_client_public_info.key_value.0.inner()[1..])?; - let dh_client_public = dh_client_public.0; - - let mut rng = OsRng::default(); - let dh_server_private = generate_private_key(&q, &mut rng); - let dh_server_public = compute_public_key(&dh_server_private, &p, &g); - - let dh_client_nonce = auth_pack.client_dh_nonce.0.as_ref().unwrap().0 .0.clone(); - - let session_key = generate_key( - &dh_client_public, - &dh_server_private, - &p, - Some(DhNonce { - client_nonce: &dh_client_nonce, - server_nonce: dh_server_nonce, - }), - CipherSuite::Aes256CtsHmacSha196.cipher().as_ref(), - )?; - - Ok((session_key, dh_server_public)) -} - -pub fn extract_sub_session_key_from_ap_req(ap_req: &ApReq, session_key: &[u8]) -> Result> { - let encrypted = &ap_req.0.authenticator.0.cipher.0 .0; - let decrypted = CipherSuite::Aes256CtsHmacSha196 - .cipher() - .decrypt(session_key, AP_REQ_AUTHENTICATOR, encrypted)?; - - let auth: Authenticator = picky_asn1_der::from_bytes(&decrypted)?; - - Ok(auth.0.subkey.0.unwrap().0.key_value.0 .0) -} diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index 8db94ebc..45c78bd4 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -1,25 +1,19 @@ -use std::convert::TryFrom; use std::fmt::Debug; use std::str::FromStr; -use chrono::{Duration, Utc}; -use oid::ObjectIdentifier; +use chrono::Utc; use picky_asn1::bit_string::BitString; use picky_asn1::date::GeneralizedTime; use picky_asn1::restricted_string::IA5String; use picky_asn1::wrapper::{ - Asn1SequenceOf, Asn1SetOf, BitStringAsn1, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag10, - ExplicitContextTag2, ExplicitContextTag3, ExplicitContextTag4, ExplicitContextTag5, ExplicitContextTag6, - ExplicitContextTag7, ExplicitContextTag8, ExplicitContextTag9, GeneralizedTimeAsn1, ImplicitContextTag0, - IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, Optional, + Asn1SequenceOf, Asn1SetOf, BitStringAsn1, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2, + ExplicitContextTag3, ExplicitContextTag4, ExplicitContextTag5, ExplicitContextTag6, ExplicitContextTag7, + ExplicitContextTag8, ImplicitContextTag0, IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, Optional, }; use picky_asn1_der::application_tag::ApplicationTag; use picky_asn1_der::Asn1RawDer; use picky_asn1_x509::cmsversion::CmsVersion; use picky_asn1_x509::content_info::EncapsulatedContentInfo; -use picky_asn1_x509::oids::{ - DIFFIE_HELLMAN, GSS_PKU2U, NEGOEX, NTLM_SSP, PKINIT_AUTH_DATA, PKINIT_DH_KEY_DATA, SPNEGO, -}; use picky_asn1_x509::signed_data::{ CertificateChoices, CertificateSet, DigestAlgorithmIdentifiers, SignedData, SignersInfos, }; @@ -27,25 +21,24 @@ use picky_asn1_x509::signer_info::{ Attributes, CertificateSerialNumber, DigestAlgorithmIdentifier, IssuerAndSerialNumber, SignatureAlgorithmIdentifier, SignatureValue, SignerIdentifier, SignerInfo, UnsignedAttributes, }; -use picky_asn1_x509::{AlgorithmIdentifier, Attribute, AttributeValues, Certificate, ShaVariant}; -use picky_krb::constants::gss_api::{ACCEPT_COMPLETE, ACCEPT_INCOMPLETE, AUTHENTICATOR_CHECKSUM_TYPE}; -use picky_krb::constants::key_usages::{AP_REP_ENC, AS_REP_ENC, KEY_USAGE_FINISHED}; -use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REP, PA_PK_AS_REQ}; +use picky_asn1_x509::{oids, AlgorithmIdentifier, Attribute, AttributeValues, Certificate, ShaVariant}; +use picky_krb::constants::gss_api::{ACCEPT_INCOMPLETE, AUTHENTICATOR_CHECKSUM_TYPE}; +use picky_krb::constants::key_usages::KEY_USAGE_FINISHED; +use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REQ}; use picky_krb::crypto::diffie_hellman::{compute_public_key, generate_private_key}; use picky_krb::crypto::{ChecksumSuite, CipherSuite}; use picky_krb::data_types::{ - Authenticator, AuthenticatorInner, AuthorizationData, AuthorizationDataInner, Checksum, EncApRepPart, - EncApRepPartInner, EncryptedData, EncryptionKey, KerbAdRestrictionEntry, KerberosStringAsn1, KerberosTime, - LastReqInner, LsapTokenInfoIntegrity, PaData, PrincipalName, Realm, Ticket, TicketInner, + Authenticator, AuthenticatorInner, AuthorizationData, AuthorizationDataInner, Checksum, EncryptionKey, + KerbAdRestrictionEntry, KerberosStringAsn1, KerberosTime, LsapTokenInfoIntegrity, PaData, PrincipalName, Realm, }; use picky_krb::gss_api::{ - ApplicationTag0, GssApiNegInit, KrbMessage, MechType, MechTypeList, NegTokenInit, NegTokenTarg, NegTokenTarg1, + ApplicationTag0, GssApiNegInit, KrbMessage, MechType, MechTypeList, NegTokenInit, NegTokenTarg, }; -use picky_krb::messages::{ApRep, ApRepInner, AsRep, EncAsRepPart, EncKdcRepPart, KdcRep, KdcReqBody}; +use picky_krb::messages::KdcReqBody; use picky_krb::negoex::RANDOM_ARRAY_SIZE; use picky_krb::pkinit::{ - AuthPack, DhDomainParameters, DhRepInfo, DhReqInfo, DhReqKeyInfo, KdcDhKeyInfo, KrbFinished, PaPkAsRep, PaPkAsReq, - PkAuthenticator, Pku2uNegoBody, Pku2uNegoReq, Pku2uNegoReqMetadata, + AuthPack, DhDomainParameters, DhReqInfo, DhReqKeyInfo, KrbFinished, PaPkAsReq, PkAuthenticator, Pku2uNegoBody, + Pku2uNegoReq, Pku2uNegoReqMetadata, }; use rand::rngs::OsRng; use rand::Rng; @@ -90,10 +83,7 @@ const MACHINE_ID: [u8; 32] = [ // returns supported authentication types pub fn get_mech_list() -> MechTypeList { - MechTypeList::from(vec![ - MechType::from(ObjectIdentifier::try_from(NEGOEX).unwrap()), - MechType::from(ObjectIdentifier::try_from(NTLM_SSP).unwrap()), - ]) + MechTypeList::from(vec![MechType::from(oids::negoex()), MechType::from(oids::ntlm_ssp())]) } pub fn generate_pku2u_nego_req(service_names: Vec<&str>, config: &Pku2uConfig) -> Result { @@ -120,7 +110,7 @@ pub fn generate_pku2u_nego_req(service_names: Vec<&str>, config: &Pku2uConfig) - pub fn generate_neg_token_init(mech_token: Vec) -> Result> { Ok(ApplicationTag0(GssApiNegInit { - oid: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(SPNEGO).unwrap()), + oid: ObjectIdentifierAsn1::from(oids::spnego()), neg_token_init: ExplicitContextTag0::from(NegTokenInit { mech_types: Optional::from(Some(ExplicitContextTag0::from(get_mech_list()))), req_flags: Optional::from(None), @@ -130,17 +120,6 @@ pub fn generate_neg_token_init(mech_token: Vec) -> Result) -> Result { - Ok(ExplicitContextTag1::from(NegTokenTarg { - neg_result: Optional::from(Some(ExplicitContextTag0::from(Asn1RawDer(vec![0x0a, 0x01, 0x01])))), - supported_mech: Optional::from(Some(ExplicitContextTag1::from(MechType::from( - ObjectIdentifier::try_from(NEGOEX).unwrap(), - )))), - response_token: Optional::from(Some(ExplicitContextTag2::from(OctetStringAsn1::from(mech_token)))), - mech_list_mic: Optional::from(None), - })) -} - pub fn generate_neg_token_targ(token: Vec) -> Result> { Ok(ExplicitContextTag1::from(NegTokenTarg { neg_result: Optional::from(Some(ExplicitContextTag0::from(Asn1RawDer(ACCEPT_INCOMPLETE.to_vec())))), @@ -150,15 +129,6 @@ pub fn generate_neg_token_targ(token: Vec) -> Result) -> Result> { - Ok(ExplicitContextTag1::from(NegTokenTarg { - neg_result: Optional::from(Some(ExplicitContextTag0::from(Asn1RawDer(ACCEPT_COMPLETE.to_vec())))), - supported_mech: Optional::from(None), - response_token: Optional::from(Some(ExplicitContextTag2::from(OctetStringAsn1::from(token)))), - mech_list_mic: Optional::from(None), - })) -} - pub fn generate_signer_info( p2p_cert: &Certificate, digest: Vec, @@ -166,13 +136,13 @@ pub fn generate_signer_info( ) -> Result { let signed_attributes = Asn1SetOf::from(vec![ Attribute { - ty: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("1.2.840.113549.1.9.3").unwrap()), + ty: ObjectIdentifierAsn1::from(oids::content_type()), value: AttributeValues::ContentType(Asn1SetOf::from(vec![ObjectIdentifierAsn1::from( - ObjectIdentifier::try_from("1.3.6.1.5.2.3.1").unwrap(), + oids::pkinit_auth_data(), )])), }, Attribute { - ty: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from("1.2.840.113549.1.9.4").unwrap()), + ty: ObjectIdentifierAsn1::from(oids::message_digest()), value: AttributeValues::MessageDigest(Asn1SetOf::from(vec![OctetStringAsn1::from(digest)])), }, ]); @@ -189,7 +159,12 @@ pub fn generate_signer_info( PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA1)), &hashed_signed_attributes, ) - .unwrap(); + .map_err(|err| { + Error::new( + ErrorKind::InternalError, + format!("Cannot calculate signer info signature: {:?}", err), + ) + })?; Ok(SignerInfo { version: CmsVersion::V1, @@ -291,7 +266,7 @@ pub fn generate_pa_datas_for_as_req( }), client_public_value: Optional::from(Some(ExplicitContextTag1::from(DhReqInfo { key_info: DhReqKeyInfo { - identifier: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(DIFFIE_HELLMAN).unwrap()), + identifier: ObjectIdentifierAsn1::from(oids::diffie_hellman()), key_info: DhDomainParameters { p: IntegerAsn1::from(dh_parameters.modulus.clone()), g: IntegerAsn1::from(dh_parameters.base.clone()), @@ -323,10 +298,7 @@ pub fn generate_pa_datas_for_as_req( let signed_data = SignedData { version: CmsVersion::V3, digest_algorithms: DigestAlgorithmIdentifiers(Asn1SetOf::from(vec![AlgorithmIdentifier::new_sha1()])), - content_info: EncapsulatedContentInfo::new( - ObjectIdentifier::try_from(PKINIT_AUTH_DATA).unwrap(), - Some(encoded_auth_pack), - ), + content_info: EncapsulatedContentInfo::new(oids::pkinit_auth_data(), Some(encoded_auth_pack)), certificates: Optional::from(CertificateSet(vec![CertificateChoices::Certificate(Asn1RawDer( picky_asn1_der::to_vec(p2p_cert)?, ))])), @@ -355,7 +327,7 @@ pub fn generate_neg( krb5_token_id: [u8; 2], ) -> ApplicationTag, 0> { ApplicationTag::from(KrbMessage { - krb5_oid: ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(GSS_PKU2U).unwrap()), + krb5_oid: ObjectIdentifierAsn1::from(oids::gss_pku2u()), krb5_token_id, krb_msg, }) @@ -368,9 +340,9 @@ pub fn generate_authenticator_extension(key: &[u8], payload: &[u8]) -> Result Result Result Result> { - let kdc_dh_key_info = KdcDhKeyInfo { - subject_public_key: ExplicitContextTag0::from(BitStringAsn1::from(BitString::with_bytes( - picky_asn1_der::to_vec(&IntegerAsn1::from(dh_public_key.to_vec()))?, - ))), - nonce: ExplicitContextTag1::from(IntegerAsn1::from(vec![0])), - dh_key_expiration: Optional::from(None), - }; - - let encoded_auth_pack = picky_asn1_der::to_vec(&kdc_dh_key_info)?; - - let mut sha1 = Sha1::new(); - sha1.update(&encoded_auth_pack); - - let digest = sha1.finalize().to_vec(); - - let signed_data = SignedData { - version: CmsVersion::V3, - digest_algorithms: DigestAlgorithmIdentifiers(Asn1SetOf::from(vec![AlgorithmIdentifier::new_sha1()])), - content_info: EncapsulatedContentInfo::new( - ObjectIdentifier::try_from(PKINIT_DH_KEY_DATA).unwrap(), - Some(encoded_auth_pack), - ), - certificates: Optional::from(CertificateSet(vec![CertificateChoices::Certificate(Asn1RawDer( - picky_asn1_der::to_vec(p2p_cert)?, - ))])), - crls: None, - signers_infos: SignersInfos(Asn1SetOf::from(vec![generate_signer_info( - p2p_cert, - digest, - private_key, - )?])), - }; - - let pa_pk_as_rep = PaPkAsRep::DhInfo(ExplicitContextTag0::from(DhRepInfo { - dh_signed_data: ImplicitContextTag0::from(OctetStringAsn1::from(picky_asn1_der::to_vec(&signed_data)?)), - server_dh_nonce: Optional::from(Some(ExplicitContextTag1::from(OctetStringAsn1::from( - dh_server_nonce.to_vec(), - )))), - })); - - Ok(vec![PaData { - padata_type: ExplicitContextTag1::from(IntegerAsn1::from(PA_PK_AS_REP.to_vec())), - padata_data: ExplicitContextTag2::from(OctetStringAsn1::from(picky_asn1_der::to_vec(&pa_pk_as_rep)?)), - }]) -} - -pub fn get_bad_ticket() -> Ticket { - ApplicationTag::from(TicketInner { - tkt_vno: ExplicitContextTag0::from(IntegerAsn1::from(vec![5])), - realm: ExplicitContextTag1::from(KerberosStringAsn1::from( - IA5String::from_str(WELLKNOWN_REALM).unwrap(), - )), - sname: ExplicitContextTag2::from(PrincipalName { - name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![2])), - name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![ - KerberosStringAsn1::from(IA5String::from_str("TERMSRV").unwrap()), - // KerberosStringAsn1::from(IA5String::from_str("192.168.0.117").unwrap()), - KerberosStringAsn1::from(IA5String::from_str("dest.dataans.com").unwrap()), - ])), - }), - enc_part: ExplicitContextTag3::from(EncryptedData { - etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![18])), - kvno: Optional::from(None), - cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![ - 211, 68, 200, 157, 66, 82, 128, 82, 220, 246, 214, 194, 27, 126, 129, 98, 58, 221, 245, 200, 112, 218, - 4, 68, 97, 0, 222, 203, 69, 31, 41, 86, 106, 196, 62, 240, 167, 246, 248, 193, 104, 59, 22, 204, 24, - 99, 193, 25, 94, 201, 86, 198, 11, 100, 155, 58, 22, 14, 173, 195, 112, 223, 23, 161, 48, 80, 40, 189, - 52, 81, 213, 229, 176, 161, 14, 85, 128, 46, 151, 112, 93, 183, 164, 240, 98, 133, 6, 224, 79, 41, 127, - 15, 65, 143, 127, 154, 182, 50, 91, 134, 38, 116, 244, 228, 187, 205, 75, 146, 35, 228, 38, 136, 152, - 24, 116, 41, 119, 147, 20, 242, 111, 224, 9, 236, 174, 193, 254, 96, 89, 84, 214, 95, 130, 60, 213, - 229, 73, 173, 34, 144, 149, 15, 58, 63, 163, 199, 138, 204, 45, 163, 152, 36, 75, 26, 241, 237, 88, - 241, 124, 80, 154, 114, 99, 20, 24, 82, 105, 219, 61, 226, 81, 196, 171, 182, 111, 160, 207, 97, 246, - 217, 128, 35, 79, 72, 79, 30, 46, 3, 243, 180, 0, 42, 153, 219, 218, 96, 13, 16, 98, 61, 38, 4, 76, 63, - 77, 242, 129, 16, 71, 39, 250, 84, 42, 179, 188, 5, 3, 137, 127, 203, 110, 37, 135, 246, 251, 26, 154, - 6, 116, 200, 240, 199, 205, 105, 182, 201, 75, 63, 71, 29, 111, 140, 30, 24, 78, 47, 38, 97, 45, 24, - 130, 141, 22, 103, 199, 110, 160, 163, 11, 147, 127, 90, 93, 135, 202, 191, 7, 90, 109, 66, 127, 148, - 61, 219, 191, 178, 203, 162, 218, 241, 235, 89, 10, 138, 101, 44, 70, 26, 64, 177, 170, 253, 124, 192, - 185, 192, 148, 172, 109, 58, 207, 7, 89, 130, 53, 73, 103, 223, 28, 228, 57, 199, 168, 136, 44, 27, - 202, 10, 73, 49, 137, 246, 98, 164, 197, 127, 230, 147, 168, 210, 23, 17, 63, 106, 157, 113, 20, 7, - 146, 174, 79, 242, 241, 22, 6, 134, 1, 225, 222, 124, 254, 22, 139, 72, 156, 224, 73, 101, 179, 168, - 34, 245, 221, 122, 35, 61, 115, 35, 96, 19, 199, 149, 176, 54, 147, 108, 225, 73, 149, 204, 100, 1, - 177, 205, 139, 138, 134, 133, 225, 119, 111, 84, 104, 167, 146, 163, 254, 56, 86, 233, 162, 4, 145, - 161, 228, 122, 201, 16, 92, 171, 164, 237, 146, 210, 143, 127, 233, 184, 148, 110, 238, 253, 103, 98, - 0, 96, 96, 12, 113, 168, 99, 137, 37, 124, 76, 108, 188, 200, 82, 199, 169, 192, 229, 34, 232, 198, - 107, 217, 54, 60, 152, 198, 234, 110, 87, 50, 200, 237, 67, 226, 214, 208, 178, 100, 118, 240, 242, - 212, 25, 149, 80, 2, 202, 143, 52, 140, 235, 222, 211, 54, 169, 228, 164, 136, 35, 62, 16, 53, 63, 55, - 58, 144, 11, 32, 68, 79, 6, 35, 178, 147, 228, 21, 103, 27, 111, 22, 103, 77, 181, 230, 252, 90, 156, - 47, 75, 171, 246, 217, 173, 55, 94, 241, 157, 143, 231, 92, 90, 114, 50, 210, 97, 152, 254, 49, 135, - 116, 248, 220, 42, 5, 236, 41, 44, 112, 134, 29, 180, 186, 250, 220, 152, 27, 227, 28, 61, 194, 125, - 162, 254, 168, 51, 59, 43, 134, 56, 202, 226, 51, 207, 243, 88, 169, 114, 101, 83, 97, 201, 39, 215, - 123, 9, 6, 182, 125, 167, 189, 57, 221, 73, 28, 0, 198, 243, 75, 115, 232, 83, 119, 145, 193, 152, 25, - 43, 116, 110, 193, 96, 178, 156, 156, 189, 51, 50, 231, 80, 236, 201, 236, 151, 211, 149, 56, 141, 37, - 196, 209, 178, 94, 62, 151, 129, 214, 215, 227, 216, 92, 87, 131, 105, 101, 186, 99, 18, 168, 83, 55, - 190, 108, 132, 217, 179, 77, 43, 189, 230, 43, 208, 213, 46, 46, 239, 40, 166, 93, 149, 65, 92, 109, - 213, 99, 202, 249, 197, 34, 84, 171, 2, 75, 47, 134, 22, 114, 10, 251, 55, 98, 90, 163, 225, 69, 1, - 142, 86, 189, 30, 248, 31, 11, 117, 3, 145, 87, 65, 247, 185, 59, 28, 13, 159, 197, 134, 36, 142, 48, - 187, 210, 221, 225, 38, 89, 7, 23, 58, 191, 2, 217, 182, 175, 144, 9, 229, 218, 113, 88, 191, 30, 249, - 234, 43, 143, 202, 105, 58, 79, 57, 215, 15, 56, 48, 175, 33, 100, 229, 96, 226, 104, 200, 255, 105, - 151, 106, 248, 228, 23, 209, 34, 252, 24, 136, 156, 194, 117, 199, 48, 221, 251, 98, 15, 248, 61, 136, - 110, 151, 173, 55, 134, 246, 166, 72, 254, 73, 181, 43, 71, 132, 132, 120, 244, 151, 161, 36, 52, 218, - 247, 227, 218, 110, 10, 172, 41, 139, 88, 227, 175, 244, 200, 112, 24, 20, 122, 23, 168, 77, 16, 42, - 74, 119, 188, 130, 198, 132, 102, 45, 152, 131, 201, 200, 49, 243, 171, 128, - ])), - }), - }) -} - -pub fn generate_as_rep(pa_datas: Vec, session_key: &[u8], new_key: Vec) -> Result { - let lt_req = Utc::now().checked_sub_signed(Duration::hours(1)).unwrap(); - - let now = Utc::now(); - let end_time = now.clone().checked_add_signed(Duration::hours(1)).unwrap(); - - let enc_part = EncAsRepPart::from(EncKdcRepPart { - key: ExplicitContextTag0::from(EncryptionKey { - key_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![18])), - key_value: ExplicitContextTag1::from(OctetStringAsn1::from(new_key)), - }), - last_req: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![LastReqInner { - lr_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0])), - lr_value: ExplicitContextTag1::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(lt_req))), - }])), - nonce: ExplicitContextTag2::from(IntegerAsn1::from(vec![0])), - key_expiration: Optional::from(None), - flags: ExplicitContextTag4::from(BitStringAsn1::from(BitString::with_bytes(vec![0, 64, 224, 0, 0]))), - auth_time: ExplicitContextTag5::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(now.clone()))), - start_time: Optional::from(Some(ExplicitContextTag6::from(GeneralizedTimeAsn1::from( - GeneralizedTime::from(now), - )))), - end_time: ExplicitContextTag7::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(end_time.clone()))), - renew_till: Optional::from(Some(ExplicitContextTag8::from(GeneralizedTimeAsn1::from( - GeneralizedTime::from(end_time), - )))), - srealm: ExplicitContextTag9::from(KerberosStringAsn1::from( - IA5String::from_str("WELLKNOWN:PKU2U").unwrap(), - )), - sname: ExplicitContextTag10::from(PrincipalName { - name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![2])), - name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![ - KerberosStringAsn1::from(IA5String::from_str("TERMSRV").unwrap()), - // KerberosStringAsn1::from(IA5String::from_str("192.168.0.117").unwrap()), - KerberosStringAsn1::from(IA5String::from_str("dest.dataans.com").unwrap()), - ])), - }), - caadr: Optional::from(None), - encrypted_pa_data: Optional::from(None), - }); - let enc_encoded = picky_asn1_der::to_vec(&enc_part)?; - - let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); - let enc_encrypted = cipher.encrypt(&session_key, AS_REP_ENC, &enc_encoded)?; - - Ok(AsRep::from(KdcRep { - pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![5])), - msg_type: ExplicitContextTag1::from(IntegerAsn1::from(vec![11])), - padata: Optional::from(Some(ExplicitContextTag2::from(Asn1SequenceOf::from(pa_datas)))), - crealm: ExplicitContextTag3::from(KerberosStringAsn1::from(IA5String::from_str(WELLKNOWN_REALM).unwrap())), - cname: ExplicitContextTag4::from(PrincipalName { - name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x80])), - name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![KerberosStringAsn1::from( - IA5String::from_str("AzureAD\\s7@dataans.com").unwrap(), - )])), - }), - ticket: ExplicitContextTag5::from(get_bad_ticket()), - enc_part: ExplicitContextTag6::from(EncryptedData { - etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x12])), - kvno: Optional::from(None), - cipher: ExplicitContextTag2::from(OctetStringAsn1::from(enc_encrypted)), - }), - })) -} - -pub fn generate_ap_rep(session_key: &[u8], new_key: &[u8]) -> ApRep { - let now = Utc::now(); - - let ap_rep_enc_part = EncApRepPart::from(EncApRepPartInner { - ctime: ExplicitContextTag0::from(GeneralizedTimeAsn1::from(GeneralizedTime::from(now))), - cusec: ExplicitContextTag1::from(IntegerAsn1::from(vec![8])), - subkey: Optional::from(Some(ExplicitContextTag2::from(EncryptionKey { - key_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![18])), - key_value: ExplicitContextTag1::from(OctetStringAsn1::from(new_key.to_vec())), - }))), - seq_number: Optional::from(Some(ExplicitContextTag3::from(IntegerAsn1::from(vec![ - 49, 95, 171, 251, - ])))), - }); - let encoded_ap_rep_enc_part = picky_asn1_der::to_vec(&ap_rep_enc_part).unwrap(); - - let cipher = CipherSuite::Aes256CtsHmacSha196.cipher(); - let cipher_data = cipher - .encrypt(session_key, AP_REP_ENC, &encoded_ap_rep_enc_part) - .unwrap(); - - ApRep::from(ApRepInner { - pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![5])), - msg_type: ExplicitContextTag1::from(IntegerAsn1::from(vec![15])), - enc_part: ExplicitContextTag2::from(EncryptedData { - etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![18])), - kvno: Optional::from(None), - cipher: ExplicitContextTag2::from(OctetStringAsn1::from(cipher_data)), - }), - }) -} - -#[cfg(test)] -mod tests { - use oid::ObjectIdentifier; - use picky_asn1::bit_string::BitString; - use picky_asn1::wrapper::{BitStringAsn1, ObjectIdentifierAsn1}; - use picky_asn1_x509::oids::NEGOEX; - use sha1::{Digest, Sha1}; - - use super::generate_pku2u_nego_req; - use crate::sspi::pku2u::generators::generate_neg; - use crate::sspi::pku2u::Pku2uConfig; - - #[test] - fn _neg_token_init_generation() { - let token = generate_pku2u_nego_req(vec![""], &Pku2uConfig::default_client_config().unwrap()).unwrap(); - - println!("{:?}", picky_asn1_der::to_vec(&token).unwrap()); - } - - #[test] - fn neg() { - let o = ObjectIdentifierAsn1::from(ObjectIdentifier::try_from(NEGOEX).unwrap()); - - let token = generate_neg(o, [0x05, 0x00]); - - println!("{:?}", picky_asn1_der::to_vec(&token).unwrap()); - } - - #[test] - fn bit() { - let data = [ - 3, 129, 133, 0, 2, 129, 129, 0, 249, 88, 64, 57, 194, 169, 38, 81, 23, 108, 110, 192, 241, 51, 44, 113, 50, - 16, 179, 173, 72, 57, 1, 65, 37, 199, 206, 229, 194, 186, 223, 122, 110, 117, 97, 237, 76, 86, 102, 153, - 66, 47, 52, 176, 243, 60, 14, 170, 4, 193, 138, 1, 193, 17, 154, 245, 113, 70, 182, 157, 112, 20, 178, 250, - 176, 201, 248, 194, 226, 23, 111, 177, 147, 141, 23, 77, 151, 226, 57, 213, 242, 172, 56, 40, 47, 191, 10, - 135, 217, 26, 111, 24, 45, 196, 40, 228, 106, 72, 173, 249, 255, 19, 254, 97, 184, 175, 205, 84, 209, 200, - 11, 137, 117, 233, 218, 62, 190, 76, 27, 110, 224, 185, 213, 207, 159, 52, 106, 94, - ]; - - let b: BitStringAsn1 = picky_asn1_der::from_bytes(&data).unwrap(); - let c = BitStringAsn1::from(BitString::with_bytes(vec![ - 2, 129, 129, 0, 249, 88, 64, 57, 194, 169, 38, 81, 23, 108, 110, 192, 241, 51, 44, 113, 50, 16, 179, 173, - 72, 57, 1, 65, 37, 199, 206, 229, 194, 186, 223, 122, 110, 117, 97, 237, 76, 86, 102, 153, 66, 47, 52, 176, - 243, 60, 14, 170, 4, 193, 138, 1, 193, 17, 154, 245, 113, 70, 182, 157, 112, 20, 178, 250, 176, 201, 248, - 194, 226, 23, 111, 177, 147, 141, 23, 77, 151, 226, 57, 213, 242, 172, 56, 40, 47, 191, 10, 135, 217, 26, - 111, 24, 45, 196, 40, 228, 106, 72, 173, 249, 255, 19, 254, 97, 184, 175, 205, 84, 209, 200, 11, 137, 117, - 233, 218, 62, 190, 76, 27, 110, 224, 185, 213, 207, 159, 52, 106, 94, - ])); - println!("{:?}", b); - println!("{:?}", c); - assert_eq!(b, c); - } - - #[test] - fn s1() { - let data = [ - 48, 22, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 3, 49, 9, 6, 7, 43, 6, 1, 5, 2, 3, 1, 48, 35, 6, 9, 42, 134, - 72, 134, 247, 13, 1, 9, 4, 49, 22, 4, 20, 37, 144, 68, 78, 210, 60, 230, 236, 125, 249, 8, 246, 201, 77, - 20, 197, 108, 52, 75, 76, - ]; - - let mut sha1 = Sha1::new(); - - sha1.update(&data); - - let hash = sha1.finalize().to_vec(); - - println!("hash: {:?}", hash); - - // assert_eq!( - // &[214, 215, 210, 143, 189, 21, 220, 123, 16, 202, 62, 239, 143, 239, 72, 75, 129, 19, 192, 25], - // hash.as_slice(), - // ); - } -} From 630f4b8dfaa97c4a8a4a442da0c3a75e4690be43 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Wed, 26 Oct 2022 17:51:43 +0300 Subject: [PATCH 17/36] sspi: remove unused dependencies --- Cargo.toml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f6309661..68e57e21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,6 @@ num-traits = "0.2" lazy_static = "1.2" serde = "1.0" serde_derive = "1.0" -schannel = "0.1.20" windows-sys = { version = "0.42.0", features = ["Win32_Security_Cryptography", "Win32_Foundation"] } num-bigint = "0.4.3" winapi = { version = "0.3", features = ["sspi", "rpcdce", "impl-default", "timezoneapi", "wincrypt"] } @@ -50,5 +49,4 @@ uuid = "1.1" whoami = "0.5" trust-dns-resolver = { version = "0.21.2", optional = true } portpicker = { version = "0.1.1", optional = true } -rsa = "0.6.1" -kerberos_crypto = "0.3.6" \ No newline at end of file +rsa = "0.6.1" \ No newline at end of file From 435e6a84a4a93c705ee39dea93bcba82e65dfdb2 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Wed, 26 Oct 2022 18:06:50 +0300 Subject: [PATCH 18/36] sspi: small refactoring --- src/sspi/internal/credssp.rs | 8 ++++---- src/sspi/kerberos.rs | 4 ++++ src/sspi/kerberos/client/generators.rs | 10 +++------- src/sspi/pku2u.rs | 2 ++ 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/sspi/internal/credssp.rs b/src/sspi/internal/credssp.rs index 2c16d4df..7e4e5cf0 100644 --- a/src/sspi/internal/credssp.rs +++ b/src/sspi/internal/credssp.rs @@ -37,8 +37,8 @@ use crate::{ pub const EARLY_USER_AUTH_RESULT_PDU_SIZE: usize = 4; const HASH_MAGIC_LEN: usize = 38; -pub const SERVER_CLIENT_HASH_MAGIC: &[u8; HASH_MAGIC_LEN] = b"CredSSP Server-To-Client Binding Hash\0"; -pub const CLIENT_SERVER_HASH_MAGIC: &[u8; HASH_MAGIC_LEN] = b"CredSSP Client-To-Server Binding Hash\0"; +const SERVER_CLIENT_HASH_MAGIC: &[u8; HASH_MAGIC_LEN] = b"CredSSP Server-To-Client Binding Hash\0"; +const CLIENT_SERVER_HASH_MAGIC: &[u8; HASH_MAGIC_LEN] = b"CredSSP Client-To-Server Binding Hash\0"; /// Provides an interface for implementing proxy credentials structures. pub trait CredentialsProxy { @@ -291,7 +291,7 @@ impl CredSspClient { peer_version, )?); ts_request.client_nonce = Some(self.client_nonce); - ts_request.nego_tokens = None; + self.state = CredSspState::AuthInfo; } @@ -527,7 +527,7 @@ impl> CredSspServer { self.state = CredSspState::AuthInfo; } - q => unreachable!("AcceptSecurityContextResult: {:?}", q), + _ => unreachable!(), }; self.credentials_handle = credentials_handle; diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index b63697de..11db0947 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -363,6 +363,8 @@ impl Sspi for Kerberos { username, cname_type, snames: &[KADMIN, CHANGE_PASSWORD_SERVICE_NAME], + // 4 = size of u32 + nonce: &OsRng::default().gen::<[u8; 4]>(), }, GenerateAsPaDataOptions { password, @@ -526,6 +528,8 @@ impl SspiImpl for Kerberos { username: &username, cname_type, snames: &[TGT_SERVICE_NAME, realm], + // 4 = size of u32 + nonce: &OsRng::default().gen::<[u8; 4]>(), }, GenerateAsPaDataOptions { password: &password, diff --git a/src/sspi/kerberos/client/generators.rs b/src/sspi/kerberos/client/generators.rs index 4eece45f..5465fcad 100644 --- a/src/sspi/kerberos/client/generators.rs +++ b/src/sspi/kerberos/client/generators.rs @@ -149,6 +149,7 @@ pub struct GenerateAsReqOptions<'a> { pub username: &'a str, pub cname_type: u8, pub snames: &'a [&'a str], + pub nonce: &'a [u8], } pub fn generate_as_req_kdc_body(options: &GenerateAsReqOptions) -> Result { @@ -157,6 +158,7 @@ pub fn generate_as_req_kdc_body(options: &GenerateAsReqOptions) -> Result Result().to_vec())), - // we don't need a nonce in pku2u - nonce: ExplicitContextTag7::from(IntegerAsn1::from(vec![0])), + nonce: ExplicitContextTag7::from(IntegerAsn1::from(nonce.to_vec())), etype: ExplicitContextTag8::from(Asn1SequenceOf::from(vec![ IntegerAsn1::from(vec![CipherSuite::Aes256CtsHmacSha196.into()]), IntegerAsn1::from(vec![CipherSuite::Aes128CtsHmacSha196.into()]), - IntegerAsn1::from(vec![0x17]), - IntegerAsn1::from(vec![0x18]), - IntegerAsn1::from(vec![0xff, 0x79]), ])), addresses: Optional::from(address), enc_authorization_data: Optional::from(None), @@ -449,7 +446,6 @@ pub fn generate_ap_req( let encoded_authenticator = picky_asn1_der::to_vec(&authenticator)?; let encrypted_authenticator = cipher.encrypt(session_key, AP_REQ_AUTHENTICATOR, &encoded_authenticator)?; - // let encrypted_authenticator = vec![80, 58, 178, 30, 181, 48, 100, 50, 91, 8, 248, 83, 53, 188, 200, 102, 243, 158, 83, 177, 114, 25, 52, 239, 62, 75, 30, 27, 36, 28, 89, 25, 245, 73, 139, 74, 148, 218, 247, 99, 184, 143, 51, 70, 243, 20, 101, 219, 128, 55, 188, 223, 241, 26, 161, 134, 42, 224, 42, 71, 37, 6, 8, 126, 244, 71, 108, 57, 43, 198, 18, 79, 134, 236, 3, 44, 47, 126, 8, 31, 138, 167, 110, 190, 74, 2, 67, 240, 102, 227, 87, 148, 113, 230, 206, 156, 133, 116, 179, 151, 234, 27, 46, 3, 156, 89, 138, 49, 9, 191, 81, 78, 20, 229, 204, 148, 29, 246, 108, 161, 126, 173, 237, 116, 50, 189, 133, 89, 161, 156, 144, 228, 215, 254, 152, 133, 240, 154, 17, 242, 0, 5, 77, 249, 61, 171, 226, 114, 6, 220, 162, 247, 108, 14, 249, 30, 46, 81, 226, 239, 2, 131, 64, 220, 63, 44, 119, 17, 55, 197, 60, 83, 218, 165, 66, 185, 96, 154, 144, 37, 155, 243, 48, 104, 170, 28, 198, 61, 210, 91, 110, 19, 32, 7, 211, 1, 29, 40, 222, 231, 246, 102, 131, 90, 174, 60, 104, 87, 185, 216, 160, 250, 147, 206, 185, 140, 222, 162, 79, 249, 249, 206, 171, 15, 181, 200, 161, 10, 82, 52, 253, 242, 14, 85, 96, 198, 20, 105, 241, 1, 231, 132, 92, 240, 125, 25, 70, 159, 183, 181, 232, 135, 144, 112, 177, 168, 192, 205, 8, 123, 94, 139, 75, 12, 182, 20, 197, 235, 109, 41, 254, 14, 109, 118, 84, 178, 27, 134, 164, 121, 81, 126, 167, 5, 61, 223, 187, 149, 210, 146, 44, 96, 144, 224, 239, 55, 28, 247, 29, 159, 36, 235, 107, 213, 24, 79, 212, 193, 139, 187, 35, 157, 160, 135, 102, 181, 156, 123, 23, 203, 70, 184, 59, 20, 67, 253, 105, 147, 213, 54]; Ok(ApReq::from(ApReqInner { pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![KERBEROS_VERSION])), diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 26747baf..1bf278b2 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -499,6 +499,8 @@ impl SspiImpl for Pku2u { username: "AzureAD\\MS-Organization-P2P-Access [2022]\\S-1-12-1-3653211022-1339006422-2627573900-1560734919", cname_type: 0x80, snames: &snames, + // we don't need the nonce in Pku2u + nonce: &[0], })?; let pa_datas = generate_pa_datas_for_as_req( &self.config.p2p_certificate, From 739c5e2ac28311e0351cdd135421af437ebebfaf Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Fri, 28 Oct 2022 10:22:56 +0300 Subject: [PATCH 19/36] sspi: pku2u & kerberos & negotiate: refactoring --- Cargo.toml | 2 +- src/sspi.rs | 17 ++++++ src/sspi/kerberos.rs | 16 +++-- src/sspi/kerberos/client/generators.rs | 6 +- src/sspi/negotiate.rs | 80 ++++++++++-------------- src/sspi/pku2u.rs | 85 ++++++++++++++------------ src/sspi/pku2u/cert_utils.rs | 6 +- src/sspi/pku2u/config.rs | 14 ++++- src/sspi/pku2u/generators.rs | 6 +- src/utils.rs | 13 ++++ 10 files changed, 142 insertions(+), 103 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 68e57e21..782aa55d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,7 @@ picky-asn1 = { path = "../picky-rs/picky-asn1", features = ["chrono_conversion"] picky-asn1-der = { path = "../picky-rs/picky-asn1-der" } picky-asn1-x509 = { path = "../picky-rs/picky-asn1-x509", features = ["pkcs7"] } oid = "0.2.1" -uuid = "1.1" +uuid = { version = "1.1", features = ["v4"] } whoami = "0.5" trust-dns-resolver = { version = "0.21.2", optional = true } portpicker = { version = "0.1.1", optional = true } diff --git a/src/sspi.rs b/src/sspi.rs index 6a28e5ec..e06a07c5 100644 --- a/src/sspi.rs +++ b/src/sspi.rs @@ -1530,6 +1530,23 @@ impl From for Error { } } +impl From for Error { + fn from(error: picky_krb::crypto::diffie_hellman::DiffieHellmanError) -> Self { + use picky_krb::crypto::diffie_hellman::DiffieHellmanError; + + match error { + DiffieHellmanError::BitLen(description) => Self { + error_type: ErrorKind::InternalError, + description, + }, + error => Self { + error_type: ErrorKind::InternalError, + description: error.to_string(), + }, + } + } +} + impl From for Error { fn from(err: CharSetError) -> Self { Self { diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 11db0947..44d2fbe4 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -42,7 +42,7 @@ use crate::sspi::kerberos::server::extractors::{ use crate::sspi::kerberos::utils::{generate_initiator_raw, validate_mic_token}; use crate::sspi::ntlm::AuthIdentityBuffers; use crate::sspi::{self, Error, ErrorKind, Result, Sspi, SspiEx, SspiImpl, PACKAGE_ID_NONE}; -use crate::utils::utf16_bytes_to_utf8_string; +use crate::utils::{utf16_bytes_to_utf8_string, generate_random_key}; use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, InitializeSecurityContextResult, PackageCapabilities, PackageInfo, @@ -383,10 +383,13 @@ impl Sspi for Kerberos { let seq_num = self.next_seq_number(); + let enc_type = self.encryption_params.encryption_type.as_ref().unwrap_or(&DEFAULT_ENCRYPTION_TYPE); + let authenticator_seb_key = generate_random_key(enc_type, &mut OsRng::default()); + let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, seq_num: Some(seq_num), - sub_key: Some(OsRng::default().gen::<[u8; 32]>().to_vec()), + sub_key: Some((enc_type.clone(), authenticator_seb_key.clone())), checksum: None, channel_bindings: self.channel_bindings.as_ref(), extensions: Vec::new(), @@ -584,10 +587,15 @@ impl SspiImpl for Kerberos { &self.encryption_params, )?); + let seq_num = self.next_seq_number(); + + let enc_type = self.encryption_params.encryption_type.as_ref().unwrap_or(&DEFAULT_ENCRYPTION_TYPE); + let authenticator_seb_key = generate_random_key(enc_type, &mut OsRng::default()); + let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &tgs_rep.0, - seq_num: Some(self.next_seq_number()), - sub_key: Some(OsRng::default().gen::<[u8; 32]>().to_vec()), + seq_num: Some(seq_num), + sub_key: Some((enc_type.clone(), authenticator_seb_key)), checksum: Some(ChecksumOptions { checksum_type: AUTHENTICATOR_CHECKSUM_TYPE.to_vec(), checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), diff --git a/src/sspi/kerberos/client/generators.rs b/src/sspi/kerberos/client/generators.rs index 5465fcad..fd563e16 100644 --- a/src/sspi/kerberos/client/generators.rs +++ b/src/sspi/kerberos/client/generators.rs @@ -325,7 +325,7 @@ pub struct AuthenticatorChecksumExtension { pub struct GenerateAuthenticatorOptions<'a> { pub kdc_rep: &'a KdcRep, pub seq_num: Option, - pub sub_key: Option>, + pub sub_key: Option<(CipherSuite, Vec)>, pub checksum: Option, pub channel_bindings: Option<&'a ChannelBindings>, pub extensions: Vec, @@ -389,9 +389,9 @@ pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result, - pub pku2u_config: Option, -} - -impl NegotiateConfig { - pub fn new() -> Self { - Self { - krb_config: None, - pku2u_config: None, - } - } - - pub fn new_with_kerberos(krb_config: KerberosConfig) -> Self { - Self { - krb_config: Some(krb_config), - pku2u_config: None, - } - } - - pub fn new_with_pku2u(pku2u_config: Pku2uConfig) -> Self { - Self { - krb_config: None, - pku2u_config: Some(pku2u_config), - } - } -} - -impl Default for NegotiateConfig { - fn default() -> Self { - Self::new() - } +pub enum NegotiateConfig { + Pku2u(Pku2uConfig), + Kerberos(KerberosConfig), + Ntlm, + Empty, } #[allow(clippy::large_enum_variant)] @@ -91,25 +64,34 @@ pub struct Negotiate { impl Negotiate { pub fn new(config: NegotiateConfig) -> Result { - let protocol = if let Some(krb_config) = config.krb_config { - Kerberos::new_client_from_config(krb_config) - .map(NegotiatedProtocol::Kerberos) - .unwrap_or_else(|_| NegotiatedProtocol::Ntlm(Ntlm::new())) - } else if let Some(pku2u_config) = config.pku2u_config { - Pku2u::new_client_from_config(pku2u_config) + let protocol = match config { + NegotiateConfig::Pku2u(config) => Pku2u::new_client_from_config(config) .map(NegotiatedProtocol::Pku2u) - .unwrap_or_else(|_| NegotiatedProtocol::Ntlm(Ntlm::new())) - } else { - #[cfg(feature = "network_client")] - if env::var(SSPI_KDC_URL_ENV).is_ok() { - Kerberos::new_client_from_config(KerberosConfig::from_env()) - .map(NegotiatedProtocol::Kerberos) - .unwrap_or_else(|_| NegotiatedProtocol::Ntlm(Ntlm::new())) - } else { - NegotiatedProtocol::Ntlm(Ntlm::new()) + .unwrap_or_else(|_| NegotiatedProtocol::Ntlm(Ntlm::new())), + NegotiateConfig::Kerberos(config) => Kerberos::new_client_from_config(config) + .map(NegotiatedProtocol::Kerberos) + .unwrap_or_else(|_| NegotiatedProtocol::Ntlm(Ntlm::new())), + NegotiateConfig::Ntlm => NegotiatedProtocol::Ntlm(Ntlm::new()), + NegotiateConfig::Empty => { + if let Some(pku2u) = Pku2uConfig::default_client_config() + .ok() + .map(|config| Pku2u::new_client_from_config(config).ok()) + .flatten() + { + NegotiatedProtocol::Pku2u(pku2u) + } else { + #[cfg(feature = "network_client")] + if env::var(SSPI_KDC_URL_ENV).is_ok() { + Kerberos::new_client_from_config(KerberosConfig::from_env()) + .map(NegotiatedProtocol::Kerberos) + .unwrap_or_else(|_| NegotiatedProtocol::Ntlm(Ntlm::new())) + } else { + NegotiatedProtocol::Ntlm(Ntlm::new()) + } + #[cfg(not(feature = "network_client"))] + NegotiatedProtocol::Ntlm(Ntlm::new()) + } } - #[cfg(not(feature = "network_client"))] - NegotiatedProtocol::Ntlm(Ntlm::new()) }; Ok(Negotiate { diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 1bf278b2..69ce85cf 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -1,3 +1,4 @@ +#[cfg(target_os = "windows")] mod cert_utils; mod config; mod extractors; @@ -6,7 +7,7 @@ mod generators; mod macros; mod validate; -use std::io::{Read, Write}; +use std::io::Write; use std::str::FromStr; pub use config::Pku2uConfig; @@ -47,6 +48,7 @@ use crate::sspi::pku2u::extractors::{ use crate::sspi::pku2u::generators::{generate_authenticator, generate_authenticator_extension}; use crate::sspi::pku2u::validate::validate_signed_data; use crate::sspi::{self, PACKAGE_ID_NONE}; +use crate::utils::generate_random_key; use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, AuthIdentityBuffers, CertTrustStatus, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, EncryptionFlags, Error, ErrorKind, @@ -59,7 +61,7 @@ pub const PKG_NAME: &str = "Pku2u"; pub const AZURE_AD_DOMAIN: &str = "AzureAD"; /// Default NEGOEX authentication scheme -pub const AUTH_SCHEME: &str = "0d53335c-f9ea-4d0d-b2ec-4ae3786ec308"; +pub const DEFAULT_NEGOEX_AUTH_SCHEME: &str = "0d53335c-f9ea-4d0d-b2ec-4ae3786ec308"; /// sealed = true /// other flags = false @@ -127,11 +129,11 @@ pub struct Pku2u { dh_parameters: DhParameters, // all sent and received NEGOEX messages concatenated in one vector // we need it for the further checksum calculation - // https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-NEGOEX/%5bMS-NEGOEX%5d.pdf + // https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-negoex/9de2cde2-bd98-40a4-9efa-0f5a1d6cc88e // The checksum is performed on all previous NEGOEX messages in the context negotiation. negoex_messages: Vec, - // all sent and received GSS-API messages concatenated in one vector - // we need it for the further checksum calculation + // two last GSS-API messages concatenated in one vector + // we need it for the further authenticator checksum calculation // https://datatracker.ietf.org/doc/html/draft-zhu-pku2u-04#section-6 // The checksum is performed on all previous NEGOEX messages in the context negotiation. gss_api_messages: Vec, @@ -149,7 +151,7 @@ impl Pku2u { encryption_params: EncryptionParams::default_for_server(), auth_identity: None, conversation_id: Uuid::default(), - auth_scheme: Some(Uuid::from_str(AUTH_SCHEME).unwrap()), + auth_scheme: Some(Uuid::from_str(DEFAULT_NEGOEX_AUTH_SCHEME).unwrap()), seq_number: 2, // https://www.rfc-editor.org/rfc/rfc4556.html#section-3.2.3 // Contains the nonce in the pkAuthenticator field in the request if the DH keys are NOT reused, @@ -247,6 +249,10 @@ impl Sspi for Pku2u { match self.state { Pku2uState::PubKeyAuth | Pku2uState::Credentials => { + if raw_wrap_token.len() < SECURITY_TRAILER { + return Err(Error::new(ErrorKind::EncryptFailure, "Cannot encrypt the data".into())); + } + *data.buffer.as_mut() = raw_wrap_token[SECURITY_TRAILER..].to_vec(); let header = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Token)?; *header.buffer.as_mut() = raw_wrap_token[0..SECURITY_TRAILER].to_vec(); @@ -335,14 +341,10 @@ impl Sspi for Pku2u { domain: identity.domain, }) } else { - Ok(ContextNames { - username: "s7@dataans.com".into(), - domain: Some("AzureAD".into()), - }) - // Err(sspi::Error::new( - // sspi::ErrorKind::NoCredentials, - // String::from("Requested Names, but no credentials were provided"), - // )) + Err(sspi::Error::new( + sspi::ErrorKind::NoCredentials, + String::from("Requested Names, but no credentials were provided"), + )) } } @@ -395,7 +397,7 @@ impl SspiImpl for Pku2u { ) -> Result { let status = match self.state { Pku2uState::Negotiate => { - let auth_scheme = Uuid::from_str(AUTH_SCHEME).unwrap(); + let auth_scheme = Uuid::from_str(DEFAULT_NEGOEX_AUTH_SCHEME).unwrap(); let mut mech_token = Vec::new(); @@ -453,24 +455,22 @@ impl SspiImpl for Pku2u { self.negoex_messages.extend_from_slice(&buffer); - let mut reader: Box = Box::new(buffer.as_slice()); + let acceptor_nego = Nego::decode(&buffer)?; - let acceptor_nego = Nego::decode(&mut reader, &buffer)?; - - check_conversation_id!(acceptor_nego.header.conversation_id.0, self.conversation_id); + check_conversation_id!(acceptor_nego.header.conversation_id, self.conversation_id); check_sequence_number!(acceptor_nego.header.sequence_num, self.next_seq_number()); // We support only one auth scheme. So the server must choose it otherwise it's an invalid behaviour if let Some(auth_scheme) = acceptor_nego.auth_schemes.get(0) { - if auth_scheme.0 == Uuid::from_str(AUTH_SCHEME).unwrap() { - self.auth_scheme = Some(auth_scheme.0); + if *auth_scheme == Uuid::from_str(DEFAULT_NEGOEX_AUTH_SCHEME).unwrap() { + self.auth_scheme = Some(*auth_scheme); } else { return Err(Error::new( ErrorKind::InvalidToken, format!( "The server selected unsupported auth scheme {:?}. The only one supported auth scheme: {}", - auth_scheme.0, AUTH_SCHEME) + auth_scheme, DEFAULT_NEGOEX_AUTH_SCHEME) )); } } else { @@ -480,13 +480,16 @@ impl SspiImpl for Pku2u { )); } + if buffer.len() < acceptor_nego.header.header_len as usize { + return Err(Error::new(ErrorKind::InvalidToken, "NEGOEX buffer is too short".into())); + } + let acceptor_exchange_data = &buffer[(acceptor_nego.header.message_len as usize)..]; - let mut reader: Box = Box::new(acceptor_exchange_data); - let acceptor_exchange = Exchange::decode(&mut reader, acceptor_exchange_data)?; + let acceptor_exchange = Exchange::decode(acceptor_exchange_data)?; - check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); + check_conversation_id!(acceptor_exchange.header.conversation_id, self.conversation_id); check_sequence_number!(acceptor_exchange.header.sequence_num, self.next_seq_number()); - check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); + check_auth_scheme!(acceptor_exchange.auth_scheme, self.auth_scheme); let mut mech_token = Vec::new(); @@ -506,7 +509,7 @@ impl SspiImpl for Pku2u { &self.config.p2p_certificate, &kdc_req_body, &self.dh_parameters, - &self.config.device_private_key, + &self.config.private_key, )?; let exchange_data = @@ -553,11 +556,11 @@ impl SspiImpl for Pku2u { self.negoex_messages.extend_from_slice(&buffer); - let acceptor_exchange = Exchange::decode(buffer.as_slice(), &buffer)?; + let acceptor_exchange = Exchange::decode(&buffer)?; - check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); + check_conversation_id!(acceptor_exchange.header.conversation_id, self.conversation_id); check_sequence_number!(acceptor_exchange.header.sequence_num, self.next_seq_number()); - check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); + check_auth_scheme!(acceptor_exchange.auth_scheme, self.auth_scheme); self.gss_api_messages.extend_from_slice(&acceptor_exchange.exchange); @@ -617,12 +620,13 @@ impl SspiImpl for Pku2u { let exchange_seq_number = self.next_seq_number(); let verify_seq_number = self.next_seq_number(); - let authenticator_seb_key = OsRng::default().gen::<[u8; 32]>().to_vec(); + let enc_type = self.encryption_params.encryption_type.as_ref().unwrap_or(&DEFAULT_ENCRYPTION_TYPE); + let authenticator_seb_key = generate_random_key(enc_type, &mut OsRng::default()); let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, seq_num: Some(exchange_seq_number), - sub_key: Some(authenticator_seb_key.clone()), + sub_key: Some((enc_type.clone(), authenticator_seb_key.clone())), checksum: Some(ChecksumOptions { checksum_type: AUTHENTICATOR_CHECKSUM_TYPE.to_vec(), checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), @@ -698,22 +702,25 @@ impl SspiImpl for Pku2u { .0 .0; - let mut reader: Box = Box::new(buffer.as_slice()); - let acceptor_exchange = Exchange::decode(&mut reader, &buffer)?; + let acceptor_exchange = Exchange::decode(&buffer)?; - check_conversation_id!(acceptor_exchange.header.conversation_id.0, self.conversation_id); + check_conversation_id!(acceptor_exchange.header.conversation_id, self.conversation_id); check_sequence_number!(acceptor_exchange.header.sequence_num, self.next_seq_number()); - check_auth_scheme!(acceptor_exchange.auth_scheme.0, self.auth_scheme); + check_auth_scheme!(acceptor_exchange.auth_scheme, self.auth_scheme); + + if buffer.len() < acceptor_exchange.header.header_len as usize { + return Err(Error::new(ErrorKind::InvalidToken, "NEGOEX buffer is too short".into())); + } self.negoex_messages .extend_from_slice(&buffer[0..(acceptor_exchange.header.message_len as usize)]); let acceptor_verify_data = &buffer[(acceptor_exchange.header.message_len as usize)..]; - let acceptor_verify = Verify::decode(acceptor_verify_data, acceptor_verify_data)?; + let acceptor_verify = Verify::decode(acceptor_verify_data)?; - check_conversation_id!(acceptor_verify.header.conversation_id.0, self.conversation_id); + check_conversation_id!(acceptor_verify.header.conversation_id, self.conversation_id); check_sequence_number!(acceptor_verify.header.sequence_num, self.next_seq_number()); - check_auth_scheme!(acceptor_verify.auth_scheme.0, self.auth_scheme); + check_auth_scheme!(acceptor_verify.auth_scheme, self.auth_scheme); let (ap_rep, _): (ApRep, _) = extract_krb_rep(&acceptor_exchange.exchange)?; diff --git a/src/sspi/pku2u/cert_utils.rs b/src/sspi/pku2u/cert_utils.rs index 577ea06e..2b297e21 100644 --- a/src/sspi/pku2u/cert_utils.rs +++ b/src/sspi/pku2u/cert_utils.rs @@ -118,6 +118,10 @@ fn validate_client_p2p_certificate(certificate: &Certificate) -> bool { } } + if !cn { + return false; + } + let mut client_auth = false; for extension in &certificate.tbs_certificate.extensions.0 .0 { @@ -130,7 +134,7 @@ fn validate_client_p2p_certificate(certificate: &Certificate) -> bool { } } - cn && client_auth + client_auth } unsafe fn export_certificate_private_key(cert: *const CERT_CONTEXT) -> Result { diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index 73aec4a0..bf2abd2f 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -7,16 +7,24 @@ use crate::Result; #[derive(Debug, Clone)] pub struct Pku2uConfig { pub p2p_certificate: Certificate, - pub device_private_key: RsaPrivateKey, + pub private_key: RsaPrivateKey, } impl Pku2uConfig { + pub fn new(p2p_certificate: Certificate, private_key: RsaPrivateKey) -> Self { + Self { + p2p_certificate, + private_key, + } + } + + #[cfg(target_os = "windows")] pub fn default_client_config() -> Result { - let (p2p_certificate, device_private_key) = extract_client_p2p_cert_and_key()?; + let (p2p_certificate, private_key) = extract_client_p2p_cert_and_key()?; Ok(Self { p2p_certificate, - device_private_key, + private_key, }) } } diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index 45c78bd4..fa78c83b 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -26,7 +26,7 @@ use picky_krb::constants::gss_api::{ACCEPT_INCOMPLETE, AUTHENTICATOR_CHECKSUM_TY use picky_krb::constants::key_usages::KEY_USAGE_FINISHED; use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REQ}; use picky_krb::crypto::diffie_hellman::{compute_public_key, generate_private_key}; -use picky_krb::crypto::{ChecksumSuite, CipherSuite}; +use picky_krb::crypto::ChecksumSuite; use picky_krb::data_types::{ Authenticator, AuthenticatorInner, AuthorizationData, AuthorizationDataInner, Checksum, EncryptionKey, KerbAdRestrictionEntry, KerberosStringAsn1, KerberosTime, LsapTokenInfoIntegrity, PaData, PrincipalName, Realm, @@ -442,9 +442,9 @@ pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result Option { } } +pub fn generate_random_key(cipher: &CipherSuite, rnd: &mut OsRng) -> Vec { + let key_size = cipher.cipher().key_size(); + let mut key = Vec::with_capacity(key_size); + + for _ in 0..key_size { + key.push(rnd.gen()); + } + + key +} + #[cfg(feature = "network_client")] #[cfg(test)] mod tests { From f1a9a16f409e72a42499a5c8bb095c9104a1aa9f Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Fri, 28 Oct 2022 10:56:42 +0300 Subject: [PATCH 20/36] sspi: pku2u: replace hardcoded as req username with generated one from the certificate; remove hardcoded authenticator checksum --- src/sspi/kerberos.rs | 14 +++++++-- src/sspi/pku2u.rs | 16 +++++++++-- src/sspi/pku2u/generators.rs | 55 +++++++++++++++++++++++++++++++++--- src/utils.rs | 3 +- 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 44d2fbe4..3f8eee6c 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -42,7 +42,7 @@ use crate::sspi::kerberos::server::extractors::{ use crate::sspi::kerberos::utils::{generate_initiator_raw, validate_mic_token}; use crate::sspi::ntlm::AuthIdentityBuffers; use crate::sspi::{self, Error, ErrorKind, Result, Sspi, SspiEx, SspiImpl, PACKAGE_ID_NONE}; -use crate::utils::{utf16_bytes_to_utf8_string, generate_random_key}; +use crate::utils::{generate_random_key, utf16_bytes_to_utf8_string}; use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, InitializeSecurityContextResult, PackageCapabilities, PackageInfo, @@ -383,7 +383,11 @@ impl Sspi for Kerberos { let seq_num = self.next_seq_number(); - let enc_type = self.encryption_params.encryption_type.as_ref().unwrap_or(&DEFAULT_ENCRYPTION_TYPE); + let enc_type = self + .encryption_params + .encryption_type + .as_ref() + .unwrap_or(&DEFAULT_ENCRYPTION_TYPE); let authenticator_seb_key = generate_random_key(enc_type, &mut OsRng::default()); let authenticator = generate_authenticator(GenerateAuthenticatorOptions { @@ -589,7 +593,11 @@ impl SspiImpl for Kerberos { let seq_num = self.next_seq_number(); - let enc_type = self.encryption_params.encryption_type.as_ref().unwrap_or(&DEFAULT_ENCRYPTION_TYPE); + let enc_type = self + .encryption_params + .encryption_type + .as_ref() + .unwrap_or(&DEFAULT_ENCRYPTION_TYPE); let authenticator_seb_key = generate_random_key(enc_type, &mut OsRng::default()); let authenticator = generate_authenticator(GenerateAuthenticatorOptions { diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 69ce85cf..9179339d 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -36,10 +36,11 @@ use crate::builders::ChangePassword; use crate::internal::SspiImpl; use crate::kerberos::client::generators::{ generate_ap_req, generate_as_req, generate_as_req_kdc_body, ChecksumOptions, GenerateAsReqOptions, - GenerateAuthenticatorOptions, AUTHENTICATOR_DEFAULT_CHECKSUM, + GenerateAuthenticatorOptions, }; use crate::kerberos::server::extractors::extract_sub_session_key_from_ap_rep; use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE, MAX_SIGNATURE, RRC, SECURITY_TRAILER}; +use crate::pku2u::generators::generate_as_req_username_from_certificate; use crate::sspi::pku2u::cert_utils::validate_server_p2p_certificate; use crate::sspi::pku2u::extractors::{ extract_krb_rep, extract_pa_pk_as_rep, extract_server_dh_public_key, extract_server_nonce, @@ -60,6 +61,11 @@ pub const PKG_NAME: &str = "Pku2u"; pub const AZURE_AD_DOMAIN: &str = "AzureAD"; +/// [Authenticator Checksum](https://datatracker.ietf.org/doc/html/rfc4121#section-4.1.1) +const AUTHENTICATOR_DEFAULT_CHECKSUM: [u8; 24] = [ + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 64, 0, 0, +]; + /// Default NEGOEX authentication scheme pub const DEFAULT_NEGOEX_AUTH_SCHEME: &str = "0d53335c-f9ea-4d0d-b2ec-4ae3786ec308"; @@ -499,7 +505,7 @@ impl SspiImpl for Pku2u { let kdc_req_body = generate_as_req_kdc_body(&GenerateAsReqOptions { realm: WELLKNOWN_REALM, - username: "AzureAD\\MS-Organization-P2P-Access [2022]\\S-1-12-1-3653211022-1339006422-2627573900-1560734919", + username: &generate_as_req_username_from_certificate(&self.config.p2p_certificate)?, cname_type: 0x80, snames: &snames, // we don't need the nonce in Pku2u @@ -620,7 +626,11 @@ impl SspiImpl for Pku2u { let exchange_seq_number = self.next_seq_number(); let verify_seq_number = self.next_seq_number(); - let enc_type = self.encryption_params.encryption_type.as_ref().unwrap_or(&DEFAULT_ENCRYPTION_TYPE); + let enc_type = self + .encryption_params + .encryption_type + .as_ref() + .unwrap_or(&DEFAULT_ENCRYPTION_TYPE); let authenticator_seb_key = generate_random_key(enc_type, &mut OsRng::default()); let authenticator = generate_authenticator(GenerateAuthenticatorOptions { diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index fa78c83b..9882530f 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -21,7 +21,9 @@ use picky_asn1_x509::signer_info::{ Attributes, CertificateSerialNumber, DigestAlgorithmIdentifier, IssuerAndSerialNumber, SignatureAlgorithmIdentifier, SignatureValue, SignerIdentifier, SignerInfo, UnsignedAttributes, }; -use picky_asn1_x509::{oids, AlgorithmIdentifier, Attribute, AttributeValues, Certificate, ShaVariant}; +use picky_asn1_x509::{ + oids, AlgorithmIdentifier, Attribute, AttributeTypeAndValueParameters, AttributeValues, Certificate, ShaVariant, +}; use picky_krb::constants::gss_api::{ACCEPT_INCOMPLETE, AUTHENTICATOR_CHECKSUM_TYPE}; use picky_krb::constants::key_usages::KEY_USAGE_FINISHED; use picky_krb::constants::types::{NT_SRV_INST, PA_PK_AS_REQ}; @@ -417,9 +419,6 @@ pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result Result Result { + let mut username = "AzureAD\\".to_owned(); + + // extract issuer + let mut issuer = false; + for attr_type_and_value in certificate.tbs_certificate.issuer.0 .0.iter() { + for v in attr_type_and_value.0.iter() { + if v.ty.0 == oids::at_common_name() { + if let AttributeTypeAndValueParameters::CommonName(name) = &v.value { + issuer = true; + username.push_str(&name.to_utf8_lossy()); + } + } + } + } + + if !issuer { + return Err(Error::new( + ErrorKind::InternalError, + "Bad client certificate: cannot find common name of the issuer".into(), + )); + } + + username.push('\\'); + + // extract long S-id + let mut subject = false; + for attr_type_and_value in certificate.tbs_certificate.subject.0 .0.iter() { + for v in attr_type_and_value.0.iter() { + if v.ty.0 == oids::at_common_name() { + if let AttributeTypeAndValueParameters::CommonName(name) = &v.value { + subject = true; + username.push_str(&name.to_utf8_lossy()); + } + } + } + } + + if !subject { + return Err(Error::new( + ErrorKind::InternalError, + "Bad client certificate: cannot find appropriate common name of the subject".into(), + )); + } + + Ok(username) +} diff --git a/src/utils.rs b/src/utils.rs index f19eaceb..ccd88493 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,7 @@ use byteorder::{LittleEndian, ReadBytesExt}; use picky_krb::crypto::CipherSuite; -use rand::{rngs::OsRng, Rng}; +use rand::rngs::OsRng; +use rand::Rng; use crate::sspi::pku2u::AZURE_AD_DOMAIN; From cdc2c417b0a283e447f26519a571391fa257929a Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Fri, 28 Oct 2022 12:02:31 +0300 Subject: [PATCH 21/36] sspi: small refactoring --- src/sspi/kerberos.rs | 14 ++++++++++---- src/sspi/kerberos/client/generators.rs | 13 +++++++++---- src/sspi/negotiate.rs | 4 ++-- src/sspi/pku2u.rs | 13 ++++++++----- src/sspi/pku2u/config.rs | 3 ++- src/sspi/pku2u/generators.rs | 10 ++++------ 6 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 3f8eee6c..aff50b1e 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -25,7 +25,7 @@ use self::client::extractors::{ use self::client::generators::{ generate_ap_req, generate_as_req, generate_as_req_kdc_body, generate_authenticator, generate_krb_priv_request, generate_neg_ap_req, generate_neg_token_init, generate_pa_datas_for_as_req, generate_tgs_req, - get_client_principal_name_type, get_client_principal_realm, ChecksumOptions, GenerateAsPaDataOptions, + get_client_principal_name_type, get_client_principal_realm, ChecksumOptions, EncKey, GenerateAsPaDataOptions, GenerateAsReqOptions, GenerateAuthenticatorOptions, AUTHENTICATOR_DEFAULT_CHECKSUM, DEFAULT_AP_REQ_OPTIONS, }; use self::config::{KdcType, KerberosConfig}; @@ -393,7 +393,10 @@ impl Sspi for Kerberos { let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, seq_num: Some(seq_num), - sub_key: Some((enc_type.clone(), authenticator_seb_key.clone())), + sub_key: Some(EncKey { + key_type: enc_type.clone(), + key_value: authenticator_seb_key, + }), checksum: None, channel_bindings: self.channel_bindings.as_ref(), extensions: Vec::new(), @@ -598,12 +601,15 @@ impl SspiImpl for Kerberos { .encryption_type .as_ref() .unwrap_or(&DEFAULT_ENCRYPTION_TYPE); - let authenticator_seb_key = generate_random_key(enc_type, &mut OsRng::default()); + let authenticator_sub_key = generate_random_key(enc_type, &mut OsRng::default()); let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &tgs_rep.0, seq_num: Some(seq_num), - sub_key: Some((enc_type.clone(), authenticator_seb_key)), + sub_key: Some(EncKey { + key_type: enc_type.clone(), + key_value: authenticator_sub_key, + }), checksum: Some(ChecksumOptions { checksum_type: AUTHENTICATOR_CHECKSUM_TYPE.to_vec(), checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), diff --git a/src/sspi/kerberos/client/generators.rs b/src/sspi/kerberos/client/generators.rs index fd563e16..74593abe 100644 --- a/src/sspi/kerberos/client/generators.rs +++ b/src/sspi/kerberos/client/generators.rs @@ -322,10 +322,15 @@ pub struct AuthenticatorChecksumExtension { pub extension_value: Vec, } +pub struct EncKey { + pub key_type: CipherSuite, + pub key_value: Vec, +} + pub struct GenerateAuthenticatorOptions<'a> { pub kdc_rep: &'a KdcRep, pub seq_num: Option, - pub sub_key: Option<(CipherSuite, Vec)>, + pub sub_key: Option, pub checksum: Option, pub channel_bindings: Option<&'a ChannelBindings>, pub extensions: Vec, @@ -389,10 +394,10 @@ pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result { if let Some(pku2u) = Pku2uConfig::default_client_config() .ok() - .map(|config| Pku2u::new_client_from_config(config).ok()) - .flatten() + .and_then(|config| Pku2u::new_client_from_config(config).ok()) { NegotiatedProtocol::Pku2u(pku2u) } else { diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 9179339d..cd9edf0d 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -35,7 +35,7 @@ use self::generators::{ use crate::builders::ChangePassword; use crate::internal::SspiImpl; use crate::kerberos::client::generators::{ - generate_ap_req, generate_as_req, generate_as_req_kdc_body, ChecksumOptions, GenerateAsReqOptions, + generate_ap_req, generate_as_req, generate_as_req_kdc_body, ChecksumOptions, EncKey, GenerateAsReqOptions, GenerateAuthenticatorOptions, }; use crate::kerberos::server::extractors::extract_sub_session_key_from_ap_rep; @@ -631,19 +631,22 @@ impl SspiImpl for Pku2u { .encryption_type .as_ref() .unwrap_or(&DEFAULT_ENCRYPTION_TYPE); - let authenticator_seb_key = generate_random_key(enc_type, &mut OsRng::default()); + let authenticator_sub_key = generate_random_key(enc_type, &mut OsRng::default()); let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, seq_num: Some(exchange_seq_number), - sub_key: Some((enc_type.clone(), authenticator_seb_key.clone())), + sub_key: Some(EncKey { + key_type: enc_type.clone(), + key_value: authenticator_sub_key.clone(), + }), checksum: Some(ChecksumOptions { checksum_type: AUTHENTICATOR_CHECKSUM_TYPE.to_vec(), checksum_value: AUTHENTICATOR_DEFAULT_CHECKSUM.to_vec(), }), channel_bindings: None, extensions: vec![generate_authenticator_extension( - &authenticator_seb_key, + &authenticator_sub_key, &self.gss_api_messages, )?], })?; @@ -675,7 +678,7 @@ impl SspiImpl for Pku2u { check_if_empty!(self.auth_scheme, "auth_scheme is not set"), ChecksumSuite::HmacSha196Aes256.into(), ChecksumSuite::HmacSha196Aes256.hasher().checksum( - &authenticator_seb_key, + &authenticator_sub_key, INITIATOR_SIGN, &self.negoex_messages, )?, diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index bf2abd2f..cfae8f7e 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -1,7 +1,6 @@ use picky_asn1_x509::Certificate; use rsa::RsaPrivateKey; -use super::cert_utils::extract_client_p2p_cert_and_key; use crate::Result; #[derive(Debug, Clone)] @@ -20,6 +19,8 @@ impl Pku2uConfig { #[cfg(target_os = "windows")] pub fn default_client_config() -> Result { + use super::cert_utils::extract_client_p2p_cert_and_key; + let (p2p_certificate, private_key) = extract_client_p2p_cert_and_key()?; Ok(Self { diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index 9882530f..00f5ed07 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -50,7 +50,7 @@ use sha1::{Digest, Sha1}; use super::{DhParameters, Pku2uConfig}; use crate::crypto::compute_md5_channel_bindings_hash; use crate::kerberos::client::generators::{ - AuthenticatorChecksumExtension, ChecksumOptions, GenerateAuthenticatorOptions, MAX_MICROSECONDS_IN_SECOND, + AuthenticatorChecksumExtension, ChecksumOptions, EncKey, GenerateAuthenticatorOptions, MAX_MICROSECONDS_IN_SECOND, }; use crate::{Error, ErrorKind, Result, KERBEROS_VERSION}; @@ -441,10 +441,10 @@ pub fn generate_authenticator(options: GenerateAuthenticatorOptions) -> Result Result Result { let mut username = "AzureAD\\".to_owned(); - // extract issuer let mut issuer = false; for attr_type_and_value in certificate.tbs_certificate.issuer.0 .0.iter() { for v in attr_type_and_value.0.iter() { @@ -479,7 +478,6 @@ pub fn generate_as_req_username_from_certificate(certificate: &Certificate) -> R username.push('\\'); - // extract long S-id let mut subject = false; for attr_type_and_value in certificate.tbs_certificate.subject.0 .0.iter() { for v in attr_type_and_value.0.iter() { From 0e29e8d4ce5b80c762e033bdd7fdf624aa405cdf Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Fri, 28 Oct 2022 15:44:11 +0300 Subject: [PATCH 22/36] sspi: negotiate: improve negotiate config and module refactoring --- ffi/src/sec_handle.rs | 4 +- src/sspi/internal/credssp.rs | 1 + src/sspi/kerberos.rs | 6 +-- src/sspi/kerberos/config.rs | 14 +++++++ src/sspi/negotiate.rs | 78 ++++++++++++++++++------------------ src/sspi/ntlm.rs | 18 ++++++++- src/sspi/pku2u.rs | 4 +- src/sspi/pku2u/config.rs | 15 ++++++- src/utils.rs | 2 +- 9 files changed, 93 insertions(+), 49 deletions(-) diff --git a/ffi/src/sec_handle.rs b/ffi/src/sec_handle.rs index 7e19f35a..f1c8d040 100644 --- a/ffi/src/sec_handle.rs +++ b/ffi/src/sec_handle.rs @@ -77,9 +77,9 @@ pub(crate) unsafe fn p_ctxt_handle_to_sspi_context( let sspi_context = match name { negotiate::PKG_NAME => { if let Some(settings) = &attributes.kdc_proxy_settings { - SspiContext::Negotiate(Negotiate::new(NegotiateConfig::new_with_kerberos( + SspiContext::Negotiate(Negotiate::new(NegotiateConfig::new(Box::new( KerberosConfig::from_kdc_url(&settings.proxy_server, Box::new(ReqwestNetworkClient::new())), - ))?) + )))?) } else { SspiContext::Negotiate(Negotiate::new(NegotiateConfig::default())?) } diff --git a/src/sspi/internal/credssp.rs b/src/sspi/internal/credssp.rs index 7e4e5cf0..297d20f9 100644 --- a/src/sspi/internal/credssp.rs +++ b/src/sspi/internal/credssp.rs @@ -154,6 +154,7 @@ enum EndpointType { } #[derive(Debug, Clone)] +#[allow(clippy::large_enum_variant)] pub enum ClientMode { Negotiate(NegotiateConfig), Kerberos(KerberosConfig), diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index aff50b1e..2c851157 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -42,7 +42,7 @@ use crate::sspi::kerberos::server::extractors::{ use crate::sspi::kerberos::utils::{generate_initiator_raw, validate_mic_token}; use crate::sspi::ntlm::AuthIdentityBuffers; use crate::sspi::{self, Error, ErrorKind, Result, Sspi, SspiEx, SspiImpl, PACKAGE_ID_NONE}; -use crate::utils::{generate_random_key, utf16_bytes_to_utf8_string}; +use crate::utils::{generate_random_symmetric_key, utf16_bytes_to_utf8_string}; use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, InitializeSecurityContextResult, PackageCapabilities, PackageInfo, @@ -388,7 +388,7 @@ impl Sspi for Kerberos { .encryption_type .as_ref() .unwrap_or(&DEFAULT_ENCRYPTION_TYPE); - let authenticator_seb_key = generate_random_key(enc_type, &mut OsRng::default()); + let authenticator_seb_key = generate_random_symmetric_key(enc_type, &mut OsRng::default()); let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, @@ -601,7 +601,7 @@ impl SspiImpl for Kerberos { .encryption_type .as_ref() .unwrap_or(&DEFAULT_ENCRYPTION_TYPE); - let authenticator_sub_key = generate_random_key(enc_type, &mut OsRng::default()); + let authenticator_sub_key = generate_random_symmetric_key(enc_type, &mut OsRng::default()); let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &tgs_rep.0, diff --git a/src/sspi/kerberos/config.rs b/src/sspi/kerberos/config.rs index 43c68a5a..491306b5 100644 --- a/src/sspi/kerberos/config.rs +++ b/src/sspi/kerberos/config.rs @@ -8,6 +8,8 @@ use url::Url; use super::network_client::reqwest_network_client::ReqwestNetworkClient; use super::network_client::NetworkClient; use super::SSPI_KDC_URL_ENV; +use crate::negotiate::{NegotiatedProtocol, PoolConfig}; +use crate::{Kerberos, Result}; #[derive(Debug, Clone)] pub enum KdcType { @@ -30,6 +32,18 @@ impl Debug for KerberosConfig { } } +impl PoolConfig for KerberosConfig { + fn new_client(&self) -> Result { + Ok(NegotiatedProtocol::Kerberos(Kerberos::new_client_from_config( + Clone::clone(self), + )?)) + } + + fn clone(&self) -> Box { + Box::new(Clone::clone(self)) + } +} + pub fn parse_kdc_url(mut kdc: String) -> (Url, KdcType) { if !kdc.contains("://") { kdc = format!("tcp://{}", kdc); diff --git a/src/sspi/negotiate.rs b/src/sspi/negotiate.rs index 1dad81c1..96a4b184 100644 --- a/src/sspi/negotiate.rs +++ b/src/sspi/negotiate.rs @@ -15,6 +15,7 @@ use crate::kerberos::config::KdcType; use crate::kerberos::network_client::reqwest_network_client::ReqwestNetworkClient; #[cfg(feature = "network_client")] use crate::kerberos::SSPI_KDC_URL_ENV; +use crate::ntlm::NtlmConfig; use crate::sspi::{Result, PACKAGE_ID_NONE}; #[cfg(feature = "network_client")] use crate::utils::get_domain_from_fqdn; @@ -24,8 +25,8 @@ use crate::utils::resolve_kdc_host; use crate::{ builders, AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, AuthIdentityBuffers, CertTrustStatus, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, Error, ErrorKind, - InitializeSecurityContextResult, Kerberos, KerberosConfig, Ntlm, PackageCapabilities, PackageInfo, Pku2u, - SecurityBuffer, SecurityPackageType, SecurityStatus, Sspi, SspiEx, + InitializeSecurityContextResult, Kerberos, Ntlm, PackageCapabilities, PackageInfo, Pku2u, SecurityBuffer, + SecurityPackageType, SecurityStatus, Sspi, SspiEx, }; pub const PKG_NAME: &str = "Negotiate"; @@ -40,13 +41,33 @@ lazy_static! { }; } -#[derive(Debug, Clone)] +use std::fmt::Debug; + +pub trait PoolConfig: Debug { + fn new_client(&self) -> Result; + fn clone(&self) -> Box; +} + +#[derive(Debug)] #[allow(clippy::large_enum_variant)] -pub enum NegotiateConfig { - Pku2u(Pku2uConfig), - Kerberos(KerberosConfig), - Ntlm, - Empty, +pub struct NegotiateConfig(Box); + +impl NegotiateConfig { + pub fn new(config: Box) -> Self { + Self(config) + } +} + +impl Default for NegotiateConfig { + fn default() -> Self { + Self(Box::new(NtlmConfig)) + } +} + +impl Clone for NegotiateConfig { + fn clone(&self) -> Self { + Self(self.0.clone()) + } } #[allow(clippy::large_enum_variant)] @@ -65,37 +86,8 @@ pub struct Negotiate { impl Negotiate { pub fn new(config: NegotiateConfig) -> Result { - let protocol = match config { - NegotiateConfig::Pku2u(config) => Pku2u::new_client_from_config(config) - .map(NegotiatedProtocol::Pku2u) - .unwrap_or_else(|_| NegotiatedProtocol::Ntlm(Ntlm::new())), - NegotiateConfig::Kerberos(config) => Kerberos::new_client_from_config(config) - .map(NegotiatedProtocol::Kerberos) - .unwrap_or_else(|_| NegotiatedProtocol::Ntlm(Ntlm::new())), - NegotiateConfig::Ntlm => NegotiatedProtocol::Ntlm(Ntlm::new()), - NegotiateConfig::Empty => { - if let Some(pku2u) = Pku2uConfig::default_client_config() - .ok() - .and_then(|config| Pku2u::new_client_from_config(config).ok()) - { - NegotiatedProtocol::Pku2u(pku2u) - } else { - #[cfg(feature = "network_client")] - if env::var(SSPI_KDC_URL_ENV).is_ok() { - Kerberos::new_client_from_config(KerberosConfig::from_env()) - .map(NegotiatedProtocol::Kerberos) - .unwrap_or_else(|_| NegotiatedProtocol::Ntlm(Ntlm::new())) - } else { - NegotiatedProtocol::Ntlm(Ntlm::new()) - } - #[cfg(not(feature = "network_client"))] - NegotiatedProtocol::Ntlm(Ntlm::new()) - } - } - }; - Ok(Negotiate { - protocol, + protocol: config.0.new_client()?, auth_identity: None, }) } @@ -116,9 +108,17 @@ impl Negotiate { .map_err(|err| Error::new(ErrorKind::InternalError, format!("{:?}", err)))?, kdc_type: KdcType::Kdc, network_client: Box::new(ReqwestNetworkClient::new()), - })?) + })?); + + return Ok(()); } } + + #[cfg(feature = "network_client")] + if env::var(SSPI_KDC_URL_ENV).is_ok() { + self.protocol = + Kerberos::new_client_from_config(KerberosConfig::from_env()).map(NegotiatedProtocol::Kerberos)?; + } } Ok(()) diff --git a/src/sspi/ntlm.rs b/src/sspi/ntlm.rs index 3806072b..2a2f5a0c 100644 --- a/src/sspi/ntlm.rs +++ b/src/sspi/ntlm.rs @@ -12,6 +12,7 @@ use serde_derive::{Deserialize, Serialize}; use super::channel_bindings::ChannelBindings; use crate::crypto::{compute_hmac_md5, Rc4, HASH_SIZE}; +use crate::negotiate::{NegotiatedProtocol, PoolConfig}; use crate::sspi::internal::SspiImpl; use crate::sspi::{ self, CertTrustStatus, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, @@ -19,7 +20,9 @@ use crate::sspi::{ PackageCapabilities, PackageInfo, SecurityBuffer, SecurityBufferType, SecurityPackageType, SecurityStatus, ServerResponseFlags, Sspi, SspiEx, PACKAGE_ID_NONE, }; -use crate::{utils, AcceptSecurityContextResult, AcquireCredentialsHandleResult, InitializeSecurityContextResult}; +use crate::{ + utils, AcceptSecurityContextResult, AcquireCredentialsHandleResult, InitializeSecurityContextResult, Result, +}; pub const PKG_NAME: &str = "NTLM"; pub const NTLM_VERSION_SIZE: usize = 8; @@ -48,6 +51,19 @@ lazy_static! { }; } +#[derive(Debug, Clone)] +pub struct NtlmConfig; + +impl PoolConfig for NtlmConfig { + fn new_client(&self) -> Result { + Ok(NegotiatedProtocol::Ntlm(Ntlm::new())) + } + + fn clone(&self) -> Box { + Box::new(Clone::clone(self)) + } +} + #[derive(Debug, Copy, Clone, Eq, PartialEq)] enum NtlmState { Initial, diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index cd9edf0d..1e8370cf 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -49,7 +49,7 @@ use crate::sspi::pku2u::extractors::{ use crate::sspi::pku2u::generators::{generate_authenticator, generate_authenticator_extension}; use crate::sspi::pku2u::validate::validate_signed_data; use crate::sspi::{self, PACKAGE_ID_NONE}; -use crate::utils::generate_random_key; +use crate::utils::generate_random_symmetric_key; use crate::{ AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, AuthIdentityBuffers, CertTrustStatus, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, EncryptionFlags, Error, ErrorKind, @@ -631,7 +631,7 @@ impl SspiImpl for Pku2u { .encryption_type .as_ref() .unwrap_or(&DEFAULT_ENCRYPTION_TYPE); - let authenticator_sub_key = generate_random_key(enc_type, &mut OsRng::default()); + let authenticator_sub_key = generate_random_symmetric_key(enc_type, &mut OsRng::default()); let authenticator = generate_authenticator(GenerateAuthenticatorOptions { kdc_rep: &as_rep.0, diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index cfae8f7e..3699d4d9 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -1,7 +1,8 @@ use picky_asn1_x509::Certificate; use rsa::RsaPrivateKey; -use crate::Result; +use crate::negotiate::{NegotiatedProtocol, PoolConfig}; +use crate::{Pku2u, Result}; #[derive(Debug, Clone)] pub struct Pku2uConfig { @@ -29,3 +30,15 @@ impl Pku2uConfig { }) } } + +impl PoolConfig for Pku2uConfig { + fn new_client(&self) -> Result { + Ok(NegotiatedProtocol::Pku2u(Pku2u::new_client_from_config(Clone::clone( + self, + ))?)) + } + + fn clone(&self) -> Box { + Box::new(Clone::clone(self)) + } +} diff --git a/src/utils.rs b/src/utils.rs index ccd88493..6910e9b5 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -65,7 +65,7 @@ pub fn resolve_kdc_host(domain: &str) -> Option { } } -pub fn generate_random_key(cipher: &CipherSuite, rnd: &mut OsRng) -> Vec { +pub fn generate_random_symmetric_key(cipher: &CipherSuite, rnd: &mut OsRng) -> Vec { let key_size = cipher.cipher().key_size(); let mut key = Vec::with_capacity(key_size); From 7748f460a6f5006c031ec5897f2ad0e4ca8730b1 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Fri, 28 Oct 2022 15:58:58 +0300 Subject: [PATCH 23/36] sspi: negotiate: add comment about negotiation algorithm; fixed compilation with the feature --- src/sspi/negotiate.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/sspi/negotiate.rs b/src/sspi/negotiate.rs index 96a4b184..c842fdbe 100644 --- a/src/sspi/negotiate.rs +++ b/src/sspi/negotiate.rs @@ -92,6 +92,13 @@ impl Negotiate { }) } + // negotiates the authorization protocol based on the username and the domain + // Decision rules: + // 1) if `self.protocol` is not NTLM then we've already negotiated a suitable protocol. Nothing to do. + // 2) if the provided domain is Azure AD domain then it'll use Pku2u + // 3) if the provided username is FQDN and we can resolve KDC then it'll use Kerberos + // 4) if SSPI_KDC_URL_ENV is set then it'll also use Kerberos + // 5) in any other cases, it'll use NTLM fn negotiate_protocol(&mut self, username: &[u8], domain: &[u8]) -> Result<()> { if let NegotiatedProtocol::Ntlm(_) = &self.protocol { if is_azure_ad_domain(domain) { @@ -103,7 +110,7 @@ impl Negotiate { #[cfg(feature = "network_client")] if let Some(domain) = get_domain_from_fqdn(username) { if let Some(host) = resolve_kdc_host(&domain) { - self.protocol = NegotiatedProtocol::Kerberos(Kerberos::new_client_from_config(KerberosConfig { + self.protocol = NegotiatedProtocol::Kerberos(Kerberos::new_client_from_config(crate::KerberosConfig { url: Url::from_str(&host) .map_err(|err| Error::new(ErrorKind::InternalError, format!("{:?}", err)))?, kdc_type: KdcType::Kdc, @@ -117,7 +124,7 @@ impl Negotiate { #[cfg(feature = "network_client")] if env::var(SSPI_KDC_URL_ENV).is_ok() { self.protocol = - Kerberos::new_client_from_config(KerberosConfig::from_env()).map(NegotiatedProtocol::Kerberos)?; + Kerberos::new_client_from_config(crate::KerberosConfig::from_env()).map(NegotiatedProtocol::Kerberos)?; } } From d2c989b50ae763ca3f7dc18c30aaa8e0762a26b8 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Fri, 28 Oct 2022 16:19:05 +0300 Subject: [PATCH 24/36] sspi: negotiate: rename config trait --- src/sspi/kerberos/config.rs | 6 +++--- src/sspi/negotiate.rs | 25 +++++++++++++------------ src/sspi/ntlm.rs | 6 +++--- src/sspi/pku2u/config.rs | 6 +++--- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/sspi/kerberos/config.rs b/src/sspi/kerberos/config.rs index 491306b5..5606748b 100644 --- a/src/sspi/kerberos/config.rs +++ b/src/sspi/kerberos/config.rs @@ -8,7 +8,7 @@ use url::Url; use super::network_client::reqwest_network_client::ReqwestNetworkClient; use super::network_client::NetworkClient; use super::SSPI_KDC_URL_ENV; -use crate::negotiate::{NegotiatedProtocol, PoolConfig}; +use crate::negotiate::{NegotiatedProtocol, ProtocolConfig}; use crate::{Kerberos, Result}; #[derive(Debug, Clone)] @@ -32,14 +32,14 @@ impl Debug for KerberosConfig { } } -impl PoolConfig for KerberosConfig { +impl ProtocolConfig for KerberosConfig { fn new_client(&self) -> Result { Ok(NegotiatedProtocol::Kerberos(Kerberos::new_client_from_config( Clone::clone(self), )?)) } - fn clone(&self) -> Box { + fn clone(&self) -> Box { Box::new(Clone::clone(self)) } } diff --git a/src/sspi/negotiate.rs b/src/sspi/negotiate.rs index c842fdbe..7601654b 100644 --- a/src/sspi/negotiate.rs +++ b/src/sspi/negotiate.rs @@ -43,17 +43,17 @@ lazy_static! { use std::fmt::Debug; -pub trait PoolConfig: Debug { +pub trait ProtocolConfig: Debug { fn new_client(&self) -> Result; - fn clone(&self) -> Box; + fn clone(&self) -> Box; } #[derive(Debug)] #[allow(clippy::large_enum_variant)] -pub struct NegotiateConfig(Box); +pub struct NegotiateConfig(Box); impl NegotiateConfig { - pub fn new(config: Box) -> Self { + pub fn new(config: Box) -> Self { Self(config) } } @@ -110,12 +110,13 @@ impl Negotiate { #[cfg(feature = "network_client")] if let Some(domain) = get_domain_from_fqdn(username) { if let Some(host) = resolve_kdc_host(&domain) { - self.protocol = NegotiatedProtocol::Kerberos(Kerberos::new_client_from_config(crate::KerberosConfig { - url: Url::from_str(&host) - .map_err(|err| Error::new(ErrorKind::InternalError, format!("{:?}", err)))?, - kdc_type: KdcType::Kdc, - network_client: Box::new(ReqwestNetworkClient::new()), - })?); + self.protocol = + NegotiatedProtocol::Kerberos(Kerberos::new_client_from_config(crate::KerberosConfig { + url: Url::from_str(&host) + .map_err(|err| Error::new(ErrorKind::InternalError, format!("{:?}", err)))?, + kdc_type: KdcType::Kdc, + network_client: Box::new(ReqwestNetworkClient::new()), + })?); return Ok(()); } @@ -123,8 +124,8 @@ impl Negotiate { #[cfg(feature = "network_client")] if env::var(SSPI_KDC_URL_ENV).is_ok() { - self.protocol = - Kerberos::new_client_from_config(crate::KerberosConfig::from_env()).map(NegotiatedProtocol::Kerberos)?; + self.protocol = Kerberos::new_client_from_config(crate::KerberosConfig::from_env()) + .map(NegotiatedProtocol::Kerberos)?; } } diff --git a/src/sspi/ntlm.rs b/src/sspi/ntlm.rs index 2a2f5a0c..27c8c5e5 100644 --- a/src/sspi/ntlm.rs +++ b/src/sspi/ntlm.rs @@ -12,7 +12,7 @@ use serde_derive::{Deserialize, Serialize}; use super::channel_bindings::ChannelBindings; use crate::crypto::{compute_hmac_md5, Rc4, HASH_SIZE}; -use crate::negotiate::{NegotiatedProtocol, PoolConfig}; +use crate::negotiate::{NegotiatedProtocol, ProtocolConfig}; use crate::sspi::internal::SspiImpl; use crate::sspi::{ self, CertTrustStatus, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, @@ -54,12 +54,12 @@ lazy_static! { #[derive(Debug, Clone)] pub struct NtlmConfig; -impl PoolConfig for NtlmConfig { +impl ProtocolConfig for NtlmConfig { fn new_client(&self) -> Result { Ok(NegotiatedProtocol::Ntlm(Ntlm::new())) } - fn clone(&self) -> Box { + fn clone(&self) -> Box { Box::new(Clone::clone(self)) } } diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index 3699d4d9..12c71880 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -1,7 +1,7 @@ use picky_asn1_x509::Certificate; use rsa::RsaPrivateKey; -use crate::negotiate::{NegotiatedProtocol, PoolConfig}; +use crate::negotiate::{NegotiatedProtocol, ProtocolConfig}; use crate::{Pku2u, Result}; #[derive(Debug, Clone)] @@ -31,14 +31,14 @@ impl Pku2uConfig { } } -impl PoolConfig for Pku2uConfig { +impl ProtocolConfig for Pku2uConfig { fn new_client(&self) -> Result { Ok(NegotiatedProtocol::Pku2u(Pku2u::new_client_from_config(Clone::clone( self, ))?)) } - fn clone(&self) -> Box { + fn clone(&self) -> Box { Box::new(Clone::clone(self)) } } From b7db9d56868ef1dc04f2b8c4ad610a9fcf48a9e8 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Fri, 28 Oct 2022 17:19:20 +0300 Subject: [PATCH 25/36] sspi: negotiate: remove useless clippy macro --- src/sspi/negotiate.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sspi/negotiate.rs b/src/sspi/negotiate.rs index 7601654b..db89debd 100644 --- a/src/sspi/negotiate.rs +++ b/src/sspi/negotiate.rs @@ -49,7 +49,6 @@ pub trait ProtocolConfig: Debug { } #[derive(Debug)] -#[allow(clippy::large_enum_variant)] pub struct NegotiateConfig(Box); impl NegotiateConfig { From dac8f0f47295c2b4aa140140fb16aacbd283d72b Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 31 Oct 2022 13:33:45 +0200 Subject: [PATCH 26/36] sspi: pku2u: certi_utils fixes --- src/sspi/pku2u/cert_utils.rs | 122 +++++++++++++++++++++++++---------- 1 file changed, 88 insertions(+), 34 deletions(-) diff --git a/src/sspi/pku2u/cert_utils.rs b/src/sspi/pku2u/cert_utils.rs index 2b297e21..ad3ff24b 100644 --- a/src/sspi/pku2u/cert_utils.rs +++ b/src/sspi/pku2u/cert_utils.rs @@ -8,12 +8,14 @@ use byteorder::{LittleEndian, ReadBytesExt}; use picky_asn1_x509::signed_data::{CertificateChoices, SignedData}; use picky_asn1_x509::{oids, AttributeTypeAndValueParameters, Certificate, ExtensionView, PublicKey}; use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; -use winapi::shared::bcrypt::{BCRYPT_RSAFULLPRIVATE_BLOB, BCRYPT_RSAPUBLIC_MAGIC}; +use winapi::shared::bcrypt::{BCRYPT_RSAFULLPRIVATE_BLOB, BCRYPT_RSAPRIVATE_BLOB, BCRYPT_RSAPUBLIC_MAGIC}; use winapi::um::ncrypt::NCryptFreeObject; use winapi::um::wincrypt::{ - CertEnumCertificatesInStore, CertOpenStore, CryptAcquireCertificatePrivateKey, CERT_CONTEXT, - CERT_STORE_PROV_SYSTEM_W, CERT_SYSTEM_STORE_LOCAL_MACHINE_ID, CERT_SYSTEM_STORE_LOCATION_SHIFT, - CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE, + CertCloseStore, CertEnumCertificatesInStore, CertFreeCertificateContext, CertOpenStore, + CryptAcquireCertificatePrivateKey, CryptExportKey, CryptReleaseContext, CERT_CONTEXT, CERT_NCRYPT_KEY_SPEC, + CERT_STORE_PROV_SYSTEM_W, CERT_SYSTEM_STORE_CURRENT_USER, CERT_SYSTEM_STORE_CURRENT_USER_ID, + CERT_SYSTEM_STORE_LOCAL_MACHINE_ID, CERT_SYSTEM_STORE_LOCATION_SHIFT, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, + CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE, PRIVATEKEYBLOB, }; use windows_sys::Win32::Foundation; use windows_sys::Win32::Security::Cryptography::{NCryptExportKey, CERT_KEY_SPEC}; @@ -101,7 +103,7 @@ fn decode_private_key(mut buffer: impl Read) -> Result { /// Validates the device certificate /// Requirements for the device certificate: -/// 1. Subject CN starts with 'MS-Organization-P2P-Access' +/// 1. Issuer CN starts with 'MS-Organization-P2P-Access' /// 2. ClientAuth extended key usage present fn validate_client_p2p_certificate(certificate: &Certificate) -> bool { let mut cn = false; @@ -144,7 +146,7 @@ unsafe fn export_certificate_private_key(cert: *const CERT_CONTEXT) -> Result Result Result<(Certificate, RsaPrivateKey)> { let mut certificate = CertEnumCertificatesInStore(cert_store, null_mut()); + let mut i = 1; + while !certificate.is_null() { + println!("i: {}", i); + let cert_der = from_raw_parts((*certificate).pbCertEncoded, (*certificate).cbCertEncoded as usize); let cert: Certificate = picky_asn1_der::from_bytes(cert_der)?; if !validate_client_p2p_certificate(&cert) { - certificate = CertEnumCertificatesInStore(cert_store, certificate); + let next_certificate = CertEnumCertificatesInStore(cert_store, certificate); + + // CertFreeCertificateContext(certificate); + + certificate = next_certificate; + + i += 1; continue; } - let private_key = export_certificate_private_key(certificate)?; + println!("cert der: {:?}", cert_der); + + let private_key = export_certificate_private_key(certificate); - return Ok((cert, private_key)); + CertFreeCertificateContext(certificate); + + return Ok((cert, private_key?)); } Err(Error::new( @@ -214,14 +258,14 @@ unsafe fn extract_client_p2p_certificate(cert_store: *mut c_void) -> Result<(Cer pub fn extract_client_p2p_cert_and_key() -> Result<(Certificate, RsaPrivateKey)> { unsafe { - let which = "My"; - let data = OsStr::new(which).encode_wide().chain(Some(0)).collect::>(); + let my: [u16; 3] = [77, 121, 0]; let cert_store = CertOpenStore( CERT_STORE_PROV_SYSTEM_W, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT, - data.as_ptr() as *mut _, + // CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT, + my.as_ptr() as *const _, ); if cert_store.is_null() { @@ -231,7 +275,11 @@ pub fn extract_client_p2p_cert_and_key() -> Result<(Certificate, RsaPrivateKey)> )); } - extract_client_p2p_certificate(cert_store) + let cert_and_key = extract_client_p2p_certificate(cert_store); + + CertCloseStore(cert_store, 0); + + cert_and_key } } @@ -284,8 +332,14 @@ pub fn validate_server_p2p_certificate(signed_data: &SignedData) -> Result Date: Tue, 1 Nov 2022 01:05:45 +0200 Subject: [PATCH 27/36] sspi: pku2u: fix certificates extraction; sspi: credssp: fix negotokens on pub key auth stage; --- src/sspi/internal/credssp.rs | 6 ++ src/sspi/pku2u/cert_utils.rs | 128 +++++++++++++++-------------------- 2 files changed, 62 insertions(+), 72 deletions(-) diff --git a/src/sspi/internal/credssp.rs b/src/sspi/internal/credssp.rs index 297d20f9..8d2909b7 100644 --- a/src/sspi/internal/credssp.rs +++ b/src/sspi/internal/credssp.rs @@ -293,6 +293,12 @@ impl CredSspClient { )?); ts_request.client_nonce = Some(self.client_nonce); + if let Some(nego_tokens) = &ts_request.nego_tokens { + if nego_tokens.is_empty() { + ts_request.nego_tokens = None; + } + } + self.state = CredSspState::AuthInfo; } diff --git a/src/sspi/pku2u/cert_utils.rs b/src/sspi/pku2u/cert_utils.rs index ad3ff24b..651c9ca5 100644 --- a/src/sspi/pku2u/cert_utils.rs +++ b/src/sspi/pku2u/cert_utils.rs @@ -1,6 +1,5 @@ -use std::ffi::{c_void, OsStr}; +use std::ffi::c_void; use std::io::Read; -use std::os::windows::prelude::OsStrExt; use std::ptr::{null, null_mut}; use std::slice::from_raw_parts; @@ -8,14 +7,12 @@ use byteorder::{LittleEndian, ReadBytesExt}; use picky_asn1_x509::signed_data::{CertificateChoices, SignedData}; use picky_asn1_x509::{oids, AttributeTypeAndValueParameters, Certificate, ExtensionView, PublicKey}; use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; -use winapi::shared::bcrypt::{BCRYPT_RSAFULLPRIVATE_BLOB, BCRYPT_RSAPRIVATE_BLOB, BCRYPT_RSAPUBLIC_MAGIC}; +use winapi::shared::bcrypt::{BCRYPT_RSAFULLPRIVATE_BLOB, BCRYPT_RSAPUBLIC_MAGIC}; use winapi::um::ncrypt::NCryptFreeObject; use winapi::um::wincrypt::{ CertCloseStore, CertEnumCertificatesInStore, CertFreeCertificateContext, CertOpenStore, - CryptAcquireCertificatePrivateKey, CryptExportKey, CryptReleaseContext, CERT_CONTEXT, CERT_NCRYPT_KEY_SPEC, - CERT_STORE_PROV_SYSTEM_W, CERT_SYSTEM_STORE_CURRENT_USER, CERT_SYSTEM_STORE_CURRENT_USER_ID, - CERT_SYSTEM_STORE_LOCAL_MACHINE_ID, CERT_SYSTEM_STORE_LOCATION_SHIFT, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, - CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE, PRIVATEKEYBLOB, + CryptAcquireCertificatePrivateKey, CERT_CONTEXT, CERT_STORE_PROV_SYSTEM_W, CERT_SYSTEM_STORE_CURRENT_USER_ID, + CERT_SYSTEM_STORE_LOCATION_SHIFT, CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE, }; use windows_sys::Win32::Foundation; use windows_sys::Win32::Security::Cryptography::{NCryptExportKey, CERT_KEY_SPEC}; @@ -146,7 +143,7 @@ unsafe fn export_certificate_private_key(cert: *const CERT_CONTEXT) -> Result Result() as *mut _, + 0, + &mut private_key_buffer_len, + 0, + ); + if status != 0 { NCryptFreeObject(private_key_handle); - if status != 0 { - return Err(Error::new( - ErrorKind::InternalError, - format!( - "Cannot extract certificate private key: unsuccessful extraction n: {:x?}", - status - ), - )); - } - } else { - println!("IN CRYPT"); + return Err(Error::new( + ErrorKind::InternalError, + format!( + "Cannot extract certificate private key: unsuccessful extraction n: {:x?}", + status + ), + )); + } - let status = CryptExportKey( - private_key_handle as _, - 0, - PRIVATEKEYBLOB, - 0, - key_blob.as_mut_ptr(), - &mut result_len, - ); + let mut private_key_blob = vec![0; private_key_buffer_len as usize]; + + let status = NCryptExportKey( + private_key_handle as _, + 0, + blob_type_wide.as_ptr() as *const _, + null(), + private_key_blob.as_mut_ptr(), + private_key_blob.len() as _, + &mut private_key_buffer_len, + 0, + ); - CryptReleaseContext(private_key_handle, 0); + NCryptFreeObject(private_key_handle); - if status != 0 { - return Err(Error::new( - ErrorKind::InternalError, - format!( - "Cannot extract certificate private key: unsuccessful extraction c: {:x?}", - status - ), - )); - } + if status != 0 { + return Err(Error::new( + ErrorKind::InternalError, + format!( + "Cannot extract certificate private key: unsuccessful extraction n: {:x?}", + status + ), + )); } - let private_key = decode_private_key(&key_blob[0..result_len as usize])?; + let private_key = decode_private_key(&private_key_blob[0..private_key_buffer_len as usize])?; Ok(private_key) } @@ -221,28 +220,18 @@ unsafe fn export_certificate_private_key(cert: *const CERT_CONTEXT) -> Result Result<(Certificate, RsaPrivateKey)> { let mut certificate = CertEnumCertificatesInStore(cert_store, null_mut()); - let mut i = 1; - while !certificate.is_null() { - println!("i: {}", i); - let cert_der = from_raw_parts((*certificate).pbCertEncoded, (*certificate).cbCertEncoded as usize); let cert: Certificate = picky_asn1_der::from_bytes(cert_der)?; if !validate_client_p2p_certificate(&cert) { let next_certificate = CertEnumCertificatesInStore(cert_store, certificate); - // CertFreeCertificateContext(certificate); - certificate = next_certificate; - i += 1; - continue; } - println!("cert der: {:?}", cert_der); - let private_key = export_certificate_private_key(certificate); CertFreeCertificateContext(certificate); @@ -258,13 +247,14 @@ unsafe fn extract_client_p2p_certificate(cert_store: *mut c_void) -> Result<(Cer pub fn extract_client_p2p_cert_and_key() -> Result<(Certificate, RsaPrivateKey)> { unsafe { + // "My\0" encoded as a wide string. + // More info: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certopenstore#remarks let my: [u16; 3] = [77, 121, 0]; let cert_store = CertOpenStore( CERT_STORE_PROV_SYSTEM_W, 0, 0, - CERT_SYSTEM_STORE_LOCAL_MACHINE_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT, - // CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT, + CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT, my.as_ptr() as *const _, ); @@ -332,14 +322,8 @@ pub fn validate_server_p2p_certificate(signed_data: &SignedData) -> Result Date: Tue, 1 Nov 2022 01:43:29 +0200 Subject: [PATCH 28/36] sspi: pku2u: split cert_utils into two separat submodules; fix compilation on Linus OS; ffi: fix compilation on Linux OS; --- ffi/src/sec_handle.rs | 6 +++ src/sspi/negotiate.rs | 4 +- src/sspi/pku2u.rs | 2 +- src/sspi/pku2u/cert_utils/mod.rs | 6 +++ src/sspi/pku2u/cert_utils/validation.rs | 50 ++++++++++++++++++ .../win_extraction.rs} | 52 ++----------------- src/sspi/pku2u/config.rs | 2 +- 7 files changed, 70 insertions(+), 52 deletions(-) create mode 100644 src/sspi/pku2u/cert_utils/mod.rs create mode 100644 src/sspi/pku2u/cert_utils/validation.rs rename src/sspi/pku2u/{cert_utils.rs => cert_utils/win_extraction.rs} (88%) diff --git a/ffi/src/sec_handle.rs b/ffi/src/sec_handle.rs index f1c8d040..04173989 100644 --- a/ffi/src/sec_handle.rs +++ b/ffi/src/sec_handle.rs @@ -85,6 +85,12 @@ pub(crate) unsafe fn p_ctxt_handle_to_sspi_context( } } pku2u::PKG_NAME => { + #[cfg(not(target_os = "windows"))] + return Err(Error::new( + ErrorKind::InvalidParameter, + "PKU2U is not supported on non-Windows OS yet".into(), + )); + #[cfg(target_os = "windows")] SspiContext::Pku2u(Pku2u::new_client_from_config(Pku2uConfig::default_client_config()?)?) } kerberos::PKG_NAME => { diff --git a/src/sspi/negotiate.rs b/src/sspi/negotiate.rs index db89debd..51e70a98 100644 --- a/src/sspi/negotiate.rs +++ b/src/sspi/negotiate.rs @@ -7,7 +7,6 @@ use lazy_static::lazy_static; #[cfg(feature = "network_client")] use url::Url; -use super::pku2u::Pku2uConfig; use crate::internal::SspiImpl; #[cfg(feature = "network_client")] use crate::kerberos::config::KdcType; @@ -100,7 +99,10 @@ impl Negotiate { // 5) in any other cases, it'll use NTLM fn negotiate_protocol(&mut self, username: &[u8], domain: &[u8]) -> Result<()> { if let NegotiatedProtocol::Ntlm(_) = &self.protocol { + #[cfg(target_os = "windows")] if is_azure_ad_domain(domain) { + use super::pku2u::Pku2uConfig; + self.protocol = NegotiatedProtocol::Pku2u(Pku2u::new_client_from_config(Pku2uConfig::default_client_config()?)?); return Ok(()); diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 1e8370cf..523c7b17 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -41,7 +41,7 @@ use crate::kerberos::client::generators::{ use crate::kerberos::server::extractors::extract_sub_session_key_from_ap_rep; use crate::kerberos::{EncryptionParams, DEFAULT_ENCRYPTION_TYPE, MAX_SIGNATURE, RRC, SECURITY_TRAILER}; use crate::pku2u::generators::generate_as_req_username_from_certificate; -use crate::sspi::pku2u::cert_utils::validate_server_p2p_certificate; +use crate::sspi::pku2u::cert_utils::validation::validate_server_p2p_certificate; use crate::sspi::pku2u::extractors::{ extract_krb_rep, extract_pa_pk_as_rep, extract_server_dh_public_key, extract_server_nonce, extract_session_key_from_as_rep, diff --git a/src/sspi/pku2u/cert_utils/mod.rs b/src/sspi/pku2u/cert_utils/mod.rs new file mode 100644 index 00000000..41ee50b9 --- /dev/null +++ b/src/sspi/pku2u/cert_utils/mod.rs @@ -0,0 +1,6 @@ +pub mod validation; +#[cfg(target_os = "windows")] +pub mod win_extraction; + +#[cfg(target_os = "windows")] +pub use win_extraction as extraction; diff --git a/src/sspi/pku2u/cert_utils/validation.rs b/src/sspi/pku2u/cert_utils/validation.rs new file mode 100644 index 00000000..32d90af8 --- /dev/null +++ b/src/sspi/pku2u/cert_utils/validation.rs @@ -0,0 +1,50 @@ +use picky_asn1_x509::signed_data::{CertificateChoices, SignedData}; +use picky_asn1_x509::{Certificate, PublicKey}; +use rsa::{BigUint, RsaPublicKey}; + +use crate::{Error, ErrorKind, Result}; + +/// validates server's p2p certificate. +/// If certificate is valid then return its public key. +pub fn validate_server_p2p_certificate(signed_data: &SignedData) -> Result { + let certificates = &signed_data.certificates.0 .0; + + if let Some(certificate) = certificates.iter().next() { + let cert: Certificate = match certificate { + CertificateChoices::Certificate(cert) => picky_asn1_der::from_bytes(&cert.0)?, + _ => { + return Err(Error::new( + ErrorKind::CertificateUnknown, + "Received unknown certificate format".into(), + )) + } + }; + + let public_key = match cert.tbs_certificate.subject_public_key_info.subject_public_key { + PublicKey::Rsa(rsa) => rsa, + _ => { + return Err(Error::new( + ErrorKind::CertificateUnknown, + "Received certificate has unsupported public key type. Only RSA is supported.".into(), + )) + } + } + .0; + + return RsaPublicKey::new( + BigUint::from_bytes_be(&public_key.modulus.0), + BigUint::from_bytes_be(&public_key.public_exponent.0), + ) + .map_err(|err| { + Error::new( + ErrorKind::InvalidToken, + format!("Invalid certificate public key: {:?}", err), + ) + }); + } + + Err(Error::new( + ErrorKind::CertificateUnknown, + "Received invalid server certificates".into(), + )) +} diff --git a/src/sspi/pku2u/cert_utils.rs b/src/sspi/pku2u/cert_utils/win_extraction.rs similarity index 88% rename from src/sspi/pku2u/cert_utils.rs rename to src/sspi/pku2u/cert_utils/win_extraction.rs index 651c9ca5..62eb03f1 100644 --- a/src/sspi/pku2u/cert_utils.rs +++ b/src/sspi/pku2u/cert_utils/win_extraction.rs @@ -4,9 +4,8 @@ use std::ptr::{null, null_mut}; use std::slice::from_raw_parts; use byteorder::{LittleEndian, ReadBytesExt}; -use picky_asn1_x509::signed_data::{CertificateChoices, SignedData}; -use picky_asn1_x509::{oids, AttributeTypeAndValueParameters, Certificate, ExtensionView, PublicKey}; -use rsa::{BigUint, RsaPrivateKey, RsaPublicKey}; +use picky_asn1_x509::{oids, AttributeTypeAndValueParameters, Certificate, ExtensionView}; +use rsa::{BigUint, RsaPrivateKey}; use winapi::shared::bcrypt::{BCRYPT_RSAFULLPRIVATE_BLOB, BCRYPT_RSAPUBLIC_MAGIC}; use winapi::um::ncrypt::NCryptFreeObject; use winapi::um::wincrypt::{ @@ -273,56 +272,11 @@ pub fn extract_client_p2p_cert_and_key() -> Result<(Certificate, RsaPrivateKey)> } } -/// validates server's p2p certificate. -/// If certificate is valid then return its public key. -pub fn validate_server_p2p_certificate(signed_data: &SignedData) -> Result { - let certificates = &signed_data.certificates.0 .0; - - if let Some(certificate) = certificates.iter().next() { - let cert: Certificate = match certificate { - CertificateChoices::Certificate(cert) => picky_asn1_der::from_bytes(&cert.0)?, - _ => { - return Err(Error::new( - ErrorKind::CertificateUnknown, - "Received unknown certificate format".into(), - )) - } - }; - - let public_key = match cert.tbs_certificate.subject_public_key_info.subject_public_key { - PublicKey::Rsa(rsa) => rsa, - _ => { - return Err(Error::new( - ErrorKind::CertificateUnknown, - "Received certificate has unsupported public key type. Only RSA is supported.".into(), - )) - } - } - .0; - - return RsaPublicKey::new( - BigUint::from_bytes_be(&public_key.modulus.0), - BigUint::from_bytes_be(&public_key.public_exponent.0), - ) - .map_err(|err| { - Error::new( - ErrorKind::InvalidToken, - format!("Invalid certificate public key: {:?}", err), - ) - }); - } - - Err(Error::new( - ErrorKind::CertificateUnknown, - "Received invalid server certificates".into(), - )) -} - #[cfg(test)] mod tests { use picky_asn1_x509::Certificate; - use crate::pku2u::cert_utils::validate_client_p2p_certificate; + use super::validate_client_p2p_certificate; #[test] fn test_client_p2p_certificate_validation() { diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index 12c71880..d679dc49 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -20,7 +20,7 @@ impl Pku2uConfig { #[cfg(target_os = "windows")] pub fn default_client_config() -> Result { - use super::cert_utils::extract_client_p2p_cert_and_key; + use super::cert_utils::extraction::extract_client_p2p_cert_and_key; let (p2p_certificate, private_key) = extract_client_p2p_cert_and_key()?; From df85de4694f6d5fc3467c20a53d4baa4b9da4d27 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Tue, 1 Nov 2022 12:04:25 +0200 Subject: [PATCH 29/36] sspi: pku2u: cert_utils: extraction: improve error messages --- src/sspi/pku2u/cert_utils/win_extraction.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sspi/pku2u/cert_utils/win_extraction.rs b/src/sspi/pku2u/cert_utils/win_extraction.rs index 62eb03f1..302430b5 100644 --- a/src/sspi/pku2u/cert_utils/win_extraction.rs +++ b/src/sspi/pku2u/cert_utils/win_extraction.rs @@ -180,7 +180,7 @@ unsafe fn export_certificate_private_key(cert: *const CERT_CONTEXT) -> Result Result Date: Tue, 1 Nov 2022 18:14:38 +0200 Subject: [PATCH 30/36] sspi: fix cargo clippy warnings --- src/dns.rs | 22 +++++++++++----------- src/kdc.rs | 10 ++++------ src/sspi/kerberos.rs | 11 +++++------ src/sspi/kerberos/config.rs | 6 ++---- src/sspi/negotiate.rs | 11 +++++------ 5 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/dns.rs b/src/dns.rs index 44cd166c..9c976cc4 100644 --- a/src/dns.rs +++ b/src/dns.rs @@ -50,9 +50,9 @@ cfg_if::cfg_if! { if let (Some(namespace), Some(name_server_list)) = (namespace, name_server_list) { let name_servers: Vec = name_server_list.split(';').map(|x| x.to_string()).collect(); rules.push(DnsClientNrptRule { - rule_name: rule_name, - namespace: namespace, - name_servers: name_servers + rule_name, + namespace, + name_servers, }); } } @@ -90,7 +90,7 @@ cfg_if::cfg_if! { } pub fn get_name_servers_for_domain(domain: &str) -> Vec { - let domain_namespace = if domain.starts_with(".") { + let domain_namespace = if domain.starts_with('.') { domain.to_string() } else { format!(".{}", &domain) @@ -102,7 +102,7 @@ cfg_if::cfg_if! { } } - return get_default_name_servers(); + get_default_name_servers() } pub fn detect_kdc_hosts_from_dns_windows(domain: &str) -> Vec { @@ -110,14 +110,14 @@ cfg_if::cfg_if! { let krb_tcp_srv = dns_query_srv_records(krb_tcp_name); if !krb_tcp_srv.is_empty() { - return krb_tcp_srv.iter().map(|x| format!("tcp://{}:88", x).to_owned()).collect() + return krb_tcp_srv.iter().map(|x| format!("tcp://{}:88", x)).collect() } let krb_udp_name = &format!("_kerberos._udp.{}", domain); let krb_udp_srv = dns_query_srv_records(krb_udp_name); if !krb_udp_srv.is_empty() { - return krb_udp_srv.iter().map(|x| format!("udp://{}:88", x).to_owned()).collect() + return krb_udp_srv.iter().map(|x| format!("udp://{}:88", x)).collect() } Vec::new() @@ -231,7 +231,7 @@ cfg_if::cfg_if! { use url::Url; fn get_trust_dns_name_server_from_url_str(url: &str) -> Option { - let url = if !url.contains("://") && url.len() > 0 { + let url = if !url.contains("://") && url.is_empty() { format!("udp://{}", url) } else { url.to_string() @@ -240,7 +240,7 @@ cfg_if::cfg_if! { if let Ok(url) = Url::parse(&url) { if let Some(url_host) = url.host_str() { let url_port = url.port().unwrap_or(53); - let url_protocol = match url.scheme().to_lowercase().as_str() { + let protocol = match url.scheme().to_lowercase().as_str() { "tcp" => Protocol::Tcp, "udp" => Protocol::Udp, _ => Protocol::Udp, @@ -248,8 +248,8 @@ cfg_if::cfg_if! { if let Ok(ip_addr) = IpAddr::from_str(url_host) { let socket_addr = SocketAddr::new(ip_addr, url_port); return Some(NameServerConfig { - socket_addr: socket_addr, - protocol: url_protocol, + socket_addr, + protocol, tls_dns_name: None, trust_nx_responses: false, bind_addr: None diff --git a/src/kdc.rs b/src/kdc.rs index 495c4090..b68a2605 100644 --- a/src/kdc.rs +++ b/src/kdc.rs @@ -19,8 +19,8 @@ pub fn detect_kdc_hosts_from_system(domain: &str) -> Vec { let domains_key_path = "SYSTEM\\CurrentControlSet\\Control\\Lsa\\Kerberos\\Domains"; let domain_key_path = format!("{}\\{}", domains_key_path, &domain_upper); if let Ok(domain_key) = hklm.open_subkey(domain_key_path) { - let kdc_names: Vec = domain_key.get_value("KdcNames").unwrap_or(Vec::new()); - kdc_names.iter().map(|x| format!("tcp://{}:88", x).to_owned()).collect() + let kdc_names: Vec = domain_key.get_value("KdcNames").unwrap_or_default(); + kdc_names.iter().map(|x| format!("tcp://{}:88", x)).collect() } else { Vec::new() } @@ -40,15 +40,13 @@ pub fn detect_kdc_hosts(domain: &str) -> Vec { return vec![kdc_url]; } - let mut kdc_hosts = detect_kdc_hosts_from_system(domain); + let kdc_hosts = detect_kdc_hosts_from_system(domain); if !kdc_hosts.is_empty() { return kdc_hosts; } - kdc_hosts = detect_kdc_hosts_from_dns(domain); - - return kdc_hosts; + detect_kdc_hosts_from_dns(domain) } pub fn detect_kdc_host(domain: &str) -> Option { diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index 415b8e74..bfcde8ff 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -106,6 +106,7 @@ pub struct Kerberos { impl Kerberos { pub fn new_client_from_config(config: KerberosConfig) -> Result { let kdc_url = config.url.clone(); + Ok(Self { state: KerberosState::Negotiate, config, @@ -113,13 +114,14 @@ impl Kerberos { encryption_params: EncryptionParams::default_for_client(), seq_number: OsRng::default().gen::(), realm: None, - kdc_url: kdc_url, + kdc_url, channel_bindings: None, }) } pub fn new_server_from_config(config: KerberosConfig) -> Result { let kdc_url = config.url.clone(); + Ok(Self { state: KerberosState::Negotiate, config, @@ -127,7 +129,7 @@ impl Kerberos { encryption_params: EncryptionParams::default_for_server(), seq_number: OsRng::default().gen::(), realm: None, - kdc_url: kdc_url, + kdc_url, channel_bindings: None, }) } @@ -151,10 +153,7 @@ impl Kerberos { if let Some((realm, kdc_url)) = self.get_kdc() { return match kdc_url.scheme() { "udp" | "tcp" => self.config.network_client.send(&kdc_url, data), - "http" | "https" => self - .config - .network_client - .send_http(&kdc_url, data, Some(realm.to_string())), + "http" | "https" => self.config.network_client.send_http(&kdc_url, data, Some(realm)), _ => Err(Error { error_type: ErrorKind::InternalError, description: "Invalid KDC server URL protocol scheme".to_owned(), diff --git a/src/sspi/kerberos/config.rs b/src/sspi/kerberos/config.rs index 08bac5e5..54f13c17 100644 --- a/src/sspi/kerberos/config.rs +++ b/src/sspi/kerberos/config.rs @@ -45,11 +45,9 @@ pub fn parse_kdc_url(mut kdc: String) -> Option { impl KerberosConfig { pub fn get_kdc_url(self, domain: &str) -> Option { if let Some(kdc_url) = self.url { - Some(kdc_url).clone() - } else if let Some(kdc_url) = detect_kdc_url(&domain) { - Some(kdc_url).clone() + Some(kdc_url) } else { - None + detect_kdc_url(domain) } } diff --git a/src/sspi/negotiate.rs b/src/sspi/negotiate.rs index 4c0163e1..ab8502ba 100644 --- a/src/sspi/negotiate.rs +++ b/src/sspi/negotiate.rs @@ -98,7 +98,7 @@ impl Negotiate { Ok(Negotiate { protocol, - package_list: config.package_list.clone(), + package_list: config.package_list, auth_identity: None, }) } @@ -143,10 +143,9 @@ impl Negotiate { let mut pku2u_package: bool = true; if let Some(package_list) = &package_list { - for package in package_list.split(",") { - let (package_name, enabled) = if package.starts_with("!") { - let package_name = package[1..].to_lowercase(); - (package_name, false) + for package in package_list.split(',') { + let (package_name, enabled) = if let Some(package_name) = package.strip_prefix('!') { + (package_name.to_lowercase(), false) } else { let package_name = package.to_lowercase(); (package_name, true) @@ -328,7 +327,7 @@ impl SspiImpl for Negotiate { let auth_identity: AuthIdentity = identity.clone().into(); if let Some(domain) = &auth_identity.domain { - self.negotiate_protocol(&auth_identity.username, &domain)?; + self.negotiate_protocol(&auth_identity.username, domain)?; } else { self.negotiate_protocol(&auth_identity.username, "")?; } From 96763d02e10529831334b0301b172b55c1667b51 Mon Sep 17 00:00:00 2001 From: Alexandr Yusuk Date: Tue, 1 Nov 2022 19:11:20 +0200 Subject: [PATCH 31/36] build: update picky-rs crate family revisions --- Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 67c5059b..cd47e015 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,10 +37,10 @@ serde = "1.0" serde_derive = "1.0" url = "2.2.2" reqwest = { version = "0.11", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], optional = true, default-features = false } -picky-krb = { path = "../picky-rs/picky-krb" } -picky-asn1 = { path = "../picky-rs/picky-asn1", features = ["chrono_conversion"] } -picky-asn1-der = { path = "../picky-rs/picky-asn1-der" } -picky-asn1-x509 = { path = "../picky-rs/picky-asn1-x509", features = ["pkcs7"] } +picky-krb = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40" } +picky-asn1 = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40", features = ["chrono_conversion"] } +picky-asn1-der = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40" } +picky-asn1-x509 = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40", features = ["pkcs7"] } oid = "0.2.1" uuid = { version = "1.1", features = ["v4"] } whoami = "0.5" From 921fffc57bc4cabefc38e366787f568452832e29 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 7 Nov 2022 12:43:06 +0200 Subject: [PATCH 32/36] sspi: remove rsa dependency and use picky instead; small refactoring in the negotiate module --- Cargo.toml | 3 +- src/crypto/rc4.rs | 2 +- src/kdc.rs | 7 +-- src/krb.rs | 58 +++++++++++++-------- src/sspi/kerberos.rs | 3 +- src/sspi/negotiate.rs | 40 ++++++++------ src/sspi/pku2u.rs | 3 +- src/sspi/pku2u/cert_utils/validation.rs | 17 +++--- src/sspi/pku2u/cert_utils/win_extraction.rs | 29 +++++++---- src/sspi/pku2u/config.rs | 6 +-- src/sspi/pku2u/generators.rs | 19 +++---- src/sspi/pku2u/validate.rs | 12 ++--- 12 files changed, 110 insertions(+), 89 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cd47e015..48a4f0ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ serde = "1.0" serde_derive = "1.0" url = "2.2.2" reqwest = { version = "0.11", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], optional = true, default-features = false } +picky = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40" } picky-krb = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40" } picky-asn1 = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40", features = ["chrono_conversion"] } picky-asn1-der = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40" } @@ -46,7 +47,7 @@ uuid = { version = "1.1", features = ["v4"] } whoami = "0.5" trust-dns-resolver = { version = "0.21.2", optional = true } portpicker = { version = "0.1.1", optional = true } -rsa = "0.6.1" +num-bigint-dig = "0.8.1" [target.'cfg(windows)'.dependencies] winreg = "0.10" diff --git a/src/crypto/rc4.rs b/src/crypto/rc4.rs index 70848f07..cf75ae14 100644 --- a/src/crypto/rc4.rs +++ b/src/crypto/rc4.rs @@ -109,7 +109,7 @@ mod test { fn empty_message() { let key = "key".to_string(); let message = "".to_string(); - let expected = []; + let expected: [u8; 0] = []; assert_eq!(Rc4::new(key.as_bytes()).process(message.as_bytes())[..], expected); } diff --git a/src/kdc.rs b/src/kdc.rs index d5748834..5f4a9be2 100644 --- a/src/kdc.rs +++ b/src/kdc.rs @@ -5,15 +5,16 @@ cfg_if::cfg_if! { } } -use crate::krb::Krb5Conf; - use std::env; +#[cfg(not(target_os = "windows"))] use std::path::Path; use std::str::FromStr; use url::Url; use crate::dns::detect_kdc_hosts_from_dns; +#[cfg(not(target_os = "windows"))] +use crate::krb::Krb5Conf; #[cfg(target_os = "windows")] pub fn detect_kdc_hosts_from_system(domain: &str) -> Vec { @@ -38,7 +39,7 @@ pub fn detect_kdc_hosts_from_system(domain: &str) -> Vec { for krb5_conf_path in krb5_conf_paths { if krb5_conf_path.exists() { - if let Some(krb5_conf) = Krb5Conf::new_from_file(krb5_conf_path) { + if let Some(krb5_conf) = Krb5Conf::new_from_file(krb5_conf_path) { if let Some(kdc) = krb5_conf.get_value(vec!["realms", domain, "kdc"]) { let kdc_url = format!("tcp://{}", kdc.as_str()); return vec![kdc_url]; diff --git a/src/krb.rs b/src/krb.rs index 6e544ca2..d180f0aa 100644 --- a/src/krb.rs +++ b/src/krb.rs @@ -1,15 +1,15 @@ #![allow(dead_code)] -use std::path::Path; -use std::io::{BufRead,BufReader}; use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::path::Path; fn can_skip_line(line: &str) -> bool { if let Some(first_char) = line.chars().nth(0) { match first_char { - '#' => { true } // comment line - ';' => { true } // comment line - _ => { false } + '#' => true, // comment line + ';' => true, // comment line + _ => false, } } else { true // empty line @@ -49,7 +49,7 @@ fn try_read_line(reader: &mut impl BufRead, line: &mut String) -> bool { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Krb5Conf { - pub values: Vec<(String,String)>, + pub values: Vec<(String, String)>, path: Vec, } @@ -57,7 +57,7 @@ impl Krb5Conf { fn new() -> Self { Self { values: Vec::new(), - path: Vec::new() + path: Vec::new(), } } @@ -109,7 +109,7 @@ impl Krb5Conf { if can_skip_line(&line) { continue; } - + while is_section_line(&line) { self.read_section(reader, &mut line); } @@ -124,21 +124,21 @@ impl Krb5Conf { fn read_values(&mut self, reader: &mut impl BufRead, line: &mut String) { if let Some((lhs, _)) = line.split_once("=") { self.enter_group(lhs.trim()); - + while try_read_line(reader, line) { if can_skip_line(&line) { continue; } - + if line.ends_with("}") { break; } - + self.read_value(reader, line); } } } - + fn read_value(&mut self, reader: &mut impl BufRead, line: &mut String) { if line.contains("{") { self.read_values(reader, line); @@ -150,20 +150,20 @@ impl Krb5Conf { } } } - + fn read_section(&mut self, reader: &mut impl BufRead, line: &mut String) { let name = get_section_name(line).unwrap(); self.enter_section(&name); - + while try_read_line(reader, line) { if can_skip_line(&line) { continue; } - + if line.chars().nth(0).unwrap() == '[' { break; } - + self.read_value(reader, line); } } @@ -174,7 +174,7 @@ mod tests { use super::Krb5Conf; #[test] fn test_parse_krb5_conf() { - let krb5_conf_data = r#" + let krb5_conf_data = r#" [libdefaults] default_realm = AD.IT-HELP.NINJA udp_preference_limit = 1 @@ -191,11 +191,23 @@ mod tests { default_domain = ad.it-help.ninja } "#; - let krb5_conf = Krb5Conf::new_from_data(&krb5_conf_data).unwrap(); - - assert_eq!(krb5_conf.get_value(vec!["libdefaults","default_realm"]), Some("AD.IT-HELP.NINJA".to_string())); - assert_eq!(krb5_conf.get_value(vec!["realms","ad.it-help.ninja","kdc"]), Some("IT-HELP-DC.ad.it-help.ninja:88".to_string())); - assert_eq!(krb5_conf.get_value(vec!["realms","ad.it-help.ninja","admin_server"]), Some("IT-HELP-DC.ad.it-help.ninja:88".to_string())); - assert_eq!(krb5_conf.get_value(vec!["realms","ad.it-help.ninja","default_domain"]), Some("ad.it-help.ninja".to_string())); + let krb5_conf = Krb5Conf::new_from_data(&krb5_conf_data).unwrap(); + + assert_eq!( + krb5_conf.get_value(vec!["libdefaults", "default_realm"]), + Some("AD.IT-HELP.NINJA".to_string()) + ); + assert_eq!( + krb5_conf.get_value(vec!["realms", "ad.it-help.ninja", "kdc"]), + Some("IT-HELP-DC.ad.it-help.ninja:88".to_string()) + ); + assert_eq!( + krb5_conf.get_value(vec!["realms", "ad.it-help.ninja", "admin_server"]), + Some("IT-HELP-DC.ad.it-help.ninja:88".to_string()) + ); + assert_eq!( + krb5_conf.get_value(vec!["realms", "ad.it-help.ninja", "default_domain"]), + Some("ad.it-help.ninja".to_string()) + ); } } diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index bfcde8ff..c6b5fd6a 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -220,7 +220,8 @@ impl Sspi for Kerberos { message: &mut [SecurityBuffer], _sequence_number: u32, ) -> Result { - SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Token)?; + // checks if the Token buffer present + let _ = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Token)?; let data = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Data)?; let cipher = self diff --git a/src/sspi/negotiate.rs b/src/sspi/negotiate.rs index ab8502ba..fa9484cd 100644 --- a/src/sspi/negotiate.rs +++ b/src/sspi/negotiate.rs @@ -3,18 +3,22 @@ use std::fmt::Debug; use lazy_static::lazy_static; use crate::internal::SspiImpl; +#[cfg(feature = "network_client")] use crate::kdc::detect_kdc_url; +#[cfg(feature = "network_client")] use crate::kerberos::client::generators::get_client_principal_realm; #[cfg(feature = "network_client")] use crate::kerberos::network_client::reqwest_network_client::ReqwestNetworkClient; use crate::ntlm::NtlmConfig; use crate::sspi::{Result, PACKAGE_ID_NONE}; use crate::utils::is_azure_ad_domain; +#[cfg(feature = "network_client")] +use crate::KerberosConfig; use crate::{ builders, AcceptSecurityContextResult, AcquireCredentialsHandleResult, AuthIdentity, AuthIdentityBuffers, CertTrustStatus, ContextNames, ContextSizes, CredentialUse, DecryptionFlags, Error, ErrorKind, - InitializeSecurityContextResult, Kerberos, KerberosConfig, Ntlm, PackageCapabilities, PackageInfo, Pku2u, - SecurityBuffer, SecurityPackageType, SecurityStatus, Sspi, SspiEx, + InitializeSecurityContextResult, Kerberos, Ntlm, PackageCapabilities, PackageInfo, Pku2u, SecurityBuffer, + SecurityPackageType, SecurityStatus, Sspi, SspiEx, }; pub const PKG_NAME: &str = "Negotiate"; @@ -89,6 +93,12 @@ pub struct Negotiate { auth_identity: Option, } +struct PackageListConfig { + ntlm: bool, + kerberos: bool, + pku2u: bool, +} + impl Negotiate { pub fn new(config: NegotiateConfig) -> Result { let mut protocol = config.protocol_config.new_client()?; @@ -137,10 +147,10 @@ impl Negotiate { Ok(()) } - fn get_package_list_config(package_list: &Option) -> (bool, bool, bool) { - let mut ntlm_package: bool = true; - let mut kerberos_package: bool = true; - let mut pku2u_package: bool = true; + fn parse_package_list_config(package_list: &Option) -> PackageListConfig { + let mut ntlm: bool = true; + let mut kerberos: bool = true; + let mut pku2u: bool = true; if let Some(package_list) = &package_list { for package in package_list.split(',') { @@ -152,15 +162,15 @@ impl Negotiate { }; match package_name.as_str() { - "ntlm" => ntlm_package = enabled, - "kerberos" => kerberos_package = enabled, - "pku2u" => pku2u_package = enabled, + "ntlm" => ntlm = enabled, + "kerberos" => kerberos = enabled, + "pku2u" => pku2u = enabled, _ => eprintln!("unexpected package name: {}", &package_name), } } } - (ntlm_package, kerberos_package, pku2u_package) + PackageListConfig { ntlm, kerberos, pku2u } } fn filter_protocol( @@ -168,29 +178,29 @@ impl Negotiate { package_list: &Option, ) -> Result> { let mut filtered_protocol = None; - let (ntlm_package, kerberos_package, pku2u_package) = Self::get_package_list_config(package_list); + let PackageListConfig { ntlm, kerberos, pku2u } = Self::parse_package_list_config(package_list); match &negotiated_protocol { NegotiatedProtocol::Pku2u(_) => { - if !pku2u_package { + if !pku2u { filtered_protocol = Some(NegotiatedProtocol::Ntlm(Ntlm::new())); } } NegotiatedProtocol::Kerberos(_) => { - if !kerberos_package { + if !kerberos { filtered_protocol = Some(NegotiatedProtocol::Ntlm(Ntlm::new())); } } NegotiatedProtocol::Ntlm(_) => { #[cfg(not(feature = "network_client"))] - if !ntlm_package { + if !ntlm { return Err(Error::new( ErrorKind::InternalError, "Can not initialize Kerberos: network client is not provided".into(), )); } #[cfg(feature = "network_client")] - if !ntlm_package { + if !ntlm { let kerberos_client = Kerberos::new_client_from_config(KerberosConfig::from_env())?; filtered_protocol = Some(NegotiatedProtocol::Kerberos(kerberos_client)); } diff --git a/src/sspi/pku2u.rs b/src/sspi/pku2u.rs index 523c7b17..bb2a81f4 100644 --- a/src/sspi/pku2u.rs +++ b/src/sspi/pku2u.rs @@ -212,7 +212,8 @@ impl Sspi for Pku2u { message: &mut [SecurityBuffer], sequence_number: u32, ) -> Result { - SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Token)?; + // checks if the Token buffer present + let _ = SecurityBuffer::find_buffer(message, SecurityBufferType::Token)?; let data = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Data)?; let cipher = self diff --git a/src/sspi/pku2u/cert_utils/validation.rs b/src/sspi/pku2u/cert_utils/validation.rs index 32d90af8..31321376 100644 --- a/src/sspi/pku2u/cert_utils/validation.rs +++ b/src/sspi/pku2u/cert_utils/validation.rs @@ -1,6 +1,7 @@ +use num_bigint_dig::BigUint; +use picky::key::PublicKey as RsaPublicKey; use picky_asn1_x509::signed_data::{CertificateChoices, SignedData}; use picky_asn1_x509::{Certificate, PublicKey}; -use rsa::{BigUint, RsaPublicKey}; use crate::{Error, ErrorKind, Result}; @@ -31,16 +32,10 @@ pub fn validate_server_p2p_certificate(signed_data: &SignedData) -> Result Result { +fn decode_private_key(mut buffer: impl Read) -> Result { let rsa_key_blob = BcryptRsaKeyBlob::from_read(&mut buffer)?; if rsa_key_blob.magic == BCRYPT_RSAPUBLIC_MAGIC { @@ -87,12 +88,18 @@ fn decode_private_key(mut buffer: impl Read) -> Result { let mut private_exp = vec![0; (rsa_key_blob.bit_len / 8) as usize]; buffer.read_exact(&mut private_exp)?; - let rsa_private_key = RsaPrivateKey::from_components( - BigUint::from_bytes_be(&modulus), - BigUint::from_bytes_be(&public_exp), - BigUint::from_bytes_be(&private_exp), - vec![BigUint::from_bytes_be(&prime1), BigUint::from_bytes_be(&prime2)], - ); + let rsa_private_key = PrivateKey::from_rsa_components( + &BigUint::from_bytes_be(&modulus), + &BigUint::from_bytes_be(&public_exp), + &BigUint::from_bytes_be(&private_exp), + &vec![BigUint::from_bytes_be(&prime1), BigUint::from_bytes_be(&prime2)], + ) + .map_err(|err| { + Error::new( + ErrorKind::InternalError, + format!("Can not create a private from components: {:?}", err), + ) + })?; Ok(rsa_private_key) } @@ -135,7 +142,7 @@ fn validate_client_p2p_certificate(certificate: &Certificate) -> bool { client_auth } -unsafe fn export_certificate_private_key(cert: *const CERT_CONTEXT) -> Result { +unsafe fn export_certificate_private_key(cert: *const CERT_CONTEXT) -> Result { let mut private_key_handle = HCRYPTPROV_OR_NCRYPT_KEY_HANDLE::default(); let mut spec = CERT_KEY_SPEC::default(); let mut free = Foundation::BOOL::default(); @@ -216,7 +223,7 @@ unsafe fn export_certificate_private_key(cert: *const CERT_CONTEXT) -> Result Result<(Certificate, RsaPrivateKey)> { +unsafe fn extract_client_p2p_certificate(cert_store: *mut c_void) -> Result<(Certificate, PrivateKey)> { let mut certificate = CertEnumCertificatesInStore(cert_store, null_mut()); while !certificate.is_null() { @@ -244,7 +251,7 @@ unsafe fn extract_client_p2p_certificate(cert_store: *mut c_void) -> Result<(Cer )) } -pub fn extract_client_p2p_cert_and_key() -> Result<(Certificate, RsaPrivateKey)> { +pub fn extract_client_p2p_cert_and_key() -> Result<(Certificate, PrivateKey)> { unsafe { // "My\0" encoded as a wide string. // More info: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certopenstore#remarks diff --git a/src/sspi/pku2u/config.rs b/src/sspi/pku2u/config.rs index d679dc49..d6d2fb83 100644 --- a/src/sspi/pku2u/config.rs +++ b/src/sspi/pku2u/config.rs @@ -1,5 +1,5 @@ +use picky::key::PrivateKey; use picky_asn1_x509::Certificate; -use rsa::RsaPrivateKey; use crate::negotiate::{NegotiatedProtocol, ProtocolConfig}; use crate::{Pku2u, Result}; @@ -7,11 +7,11 @@ use crate::{Pku2u, Result}; #[derive(Debug, Clone)] pub struct Pku2uConfig { pub p2p_certificate: Certificate, - pub private_key: RsaPrivateKey, + pub private_key: PrivateKey, } impl Pku2uConfig { - pub fn new(p2p_certificate: Certificate, private_key: RsaPrivateKey) -> Self { + pub fn new(p2p_certificate: Certificate, private_key: PrivateKey) -> Self { Self { p2p_certificate, private_key, diff --git a/src/sspi/pku2u/generators.rs b/src/sspi/pku2u/generators.rs index 00f5ed07..67a832e4 100644 --- a/src/sspi/pku2u/generators.rs +++ b/src/sspi/pku2u/generators.rs @@ -2,6 +2,9 @@ use std::fmt::Debug; use std::str::FromStr; use chrono::Utc; +use picky::hash::HashAlgorithm; +use picky::key::PrivateKey; +use picky::signature::SignatureAlgorithm; use picky_asn1::bit_string::BitString; use picky_asn1::date::GeneralizedTime; use picky_asn1::restricted_string::IA5String; @@ -44,7 +47,6 @@ use picky_krb::pkinit::{ }; use rand::rngs::OsRng; use rand::Rng; -use rsa::{Hash, PaddingScheme, RsaPrivateKey}; use sha1::{Digest, Sha1}; use super::{DhParameters, Pku2uConfig}; @@ -131,11 +133,7 @@ pub fn generate_neg_token_targ(token: Vec) -> Result, - private_key: &RsaPrivateKey, -) -> Result { +pub fn generate_signer_info(p2p_cert: &Certificate, digest: Vec, private_key: &PrivateKey) -> Result { let signed_attributes = Asn1SetOf::from(vec![ Attribute { ty: ObjectIdentifierAsn1::from(oids::content_type()), @@ -156,11 +154,8 @@ pub fn generate_signer_info( let hashed_signed_attributes = sha1.finalize().to_vec(); - let signature = private_key - .sign( - PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA1)), - &hashed_signed_attributes, - ) + let signature = SignatureAlgorithm::RsaPkcs1v15(HashAlgorithm::SHA1) + .sign(&hashed_signed_attributes, private_key) .map_err(|err| { Error::new( ErrorKind::InternalError, @@ -237,7 +232,7 @@ pub fn generate_pa_datas_for_as_req( p2p_cert: &Certificate, kdc_req_body: &KdcReqBody, dh_parameters: &DhParameters, - private_key: &RsaPrivateKey, + private_key: &PrivateKey, ) -> Result> { let current_date = Utc::now(); let mut microseconds = current_date.timestamp_subsec_micros(); diff --git a/src/sspi/pku2u/validate.rs b/src/sspi/pku2u/validate.rs index e3b95c8a..a9f2a878 100644 --- a/src/sspi/pku2u/validate.rs +++ b/src/sspi/pku2u/validate.rs @@ -1,6 +1,8 @@ +use picky::hash::HashAlgorithm; +use picky::key::PublicKey as RsaPublicKey; +use picky::signature::SignatureAlgorithm; use picky_asn1::wrapper::Asn1SetOf; use picky_asn1_x509::signed_data::SignedData; -use rsa::{Hash, PaddingScheme, PublicKey, RsaPublicKey}; use sha1::{Digest, Sha1}; use crate::{Error, ErrorKind, Result}; @@ -19,11 +21,7 @@ pub fn validate_signed_data(signed_data: &SignedData, rsa_public_key: &RsaPublic sha1.update(&picky_asn1_der::to_vec(&signed_attributes)?); let hashed_signed_attributes = sha1.finalize().to_vec(); - rsa_public_key - .verify( - PaddingScheme::PKCS1v15Sign { hash: Some(Hash::SHA1) }, - &hashed_signed_attributes, - &signer_info.signature.0 .0, - ) + SignatureAlgorithm::RsaPkcs1v15(HashAlgorithm::SHA1) + .verify(rsa_public_key, &hashed_signed_attributes, &signer_info.signature.0 .0) .map_err(|_| Error::new(ErrorKind::InvalidToken, "Invalid signed data signature".into())) } From b6179acc6e4ec99730df8bec39de9ba34fd717c0 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 7 Nov 2022 14:10:36 +0200 Subject: [PATCH 33/36] sspi: kerberos: small refactoring in encrypt_message function --- src/sspi/kerberos.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sspi/kerberos.rs b/src/sspi/kerberos.rs index c6b5fd6a..e2a78833 100644 --- a/src/sspi/kerberos.rs +++ b/src/sspi/kerberos.rs @@ -221,7 +221,7 @@ impl Sspi for Kerberos { _sequence_number: u32, ) -> Result { // checks if the Token buffer present - let _ = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Token)?; + let _ = SecurityBuffer::find_buffer(message, SecurityBufferType::Token)?; let data = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Data)?; let cipher = self From 45ada9f75359e9a64c0c5570c3741fad6eaf2525 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Mon, 7 Nov 2022 21:22:02 +0200 Subject: [PATCH 34/36] sspi: pku2u: add comment about why 'My' certificates store is used --- src/sspi/pku2u/cert_utils/win_extraction.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sspi/pku2u/cert_utils/win_extraction.rs b/src/sspi/pku2u/cert_utils/win_extraction.rs index 85eb4349..73c9e1bb 100644 --- a/src/sspi/pku2u/cert_utils/win_extraction.rs +++ b/src/sspi/pku2u/cert_utils/win_extraction.rs @@ -251,6 +251,8 @@ unsafe fn extract_client_p2p_certificate(cert_store: *mut c_void) -> Result<(Cer )) } +// The P2P certificates always are placed in the Personal folder. +// It uses the "My" certificates store that has access to the Personal folder in order to extract those certificates. pub fn extract_client_p2p_cert_and_key() -> Result<(Certificate, PrivateKey)> { unsafe { // "My\0" encoded as a wide string. From 04a37950c286f614598fac5863051c33e96e29b9 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Tue, 8 Nov 2022 11:26:39 +0200 Subject: [PATCH 35/36] sspi: pku2u: improve comment about certificates extraction --- src/sspi/pku2u/cert_utils/win_extraction.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sspi/pku2u/cert_utils/win_extraction.rs b/src/sspi/pku2u/cert_utils/win_extraction.rs index 73c9e1bb..93063630 100644 --- a/src/sspi/pku2u/cert_utils/win_extraction.rs +++ b/src/sspi/pku2u/cert_utils/win_extraction.rs @@ -251,7 +251,9 @@ unsafe fn extract_client_p2p_certificate(cert_store: *mut c_void) -> Result<(Cer )) } -// The P2P certificates always are placed in the Personal folder. +// There is no specification/documentation that said where the P2P certificates should be installed. +// During dev testing, we notice that they always are in the Personal folder. +// So we assume that the needed certificates are placed in this folder // It uses the "My" certificates store that has access to the Personal folder in order to extract those certificates. pub fn extract_client_p2p_cert_and_key() -> Result<(Certificate, PrivateKey)> { unsafe { From e4d13a9b47bd14f37d30a04ae3de3464821ef821 Mon Sep 17 00:00:00 2001 From: Alex Yusuk Date: Tue, 8 Nov 2022 16:27:24 +0200 Subject: [PATCH 36/36] update picky-* dependencies versions --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d5c915f4..7ed589ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,11 +37,11 @@ serde = "1.0" serde_derive = "1.0" url = "2.2.2" reqwest = { version = "0.11", features = ["blocking", "rustls-tls", "rustls-tls-native-roots"], optional = true, default-features = false } -picky = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40" } -picky-krb = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40" } -picky-asn1 = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40", features = ["chrono_conversion"] } -picky-asn1-der = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40" } -picky-asn1-x509 = { git = "https://github.com/Devolutions/picky-rs.git", rev = "50dfc40", features = ["pkcs7"] } +picky = { version = "7.0.0-rc.3" } +picky-krb = { version = "0.5.0" } +picky-asn1 = { version = "0.7.0", features = ["chrono_conversion"] } +picky-asn1-der = { version = "0.4.0" } +picky-asn1-x509 = { version = "0.9.0", features = ["pkcs7"] } oid = "0.2.1" uuid = { version = "1.1", features = ["v4"] } whoami = "0.5"