use crate::ike::ipsec_parser::*;
use super::ipsec_parser::IkeV2Transform;
-use crate::ike::ike::{IKEState, IkeEvent};
+use crate::ike::ike::{IKEState, IKETransaction, IkeEvent};
use crate::ike::parser::IsakmpHeader;
use ipsec_parser::{IkeExchangeType, IkePayloadType, IkeV2Header};
/// The transforms proposed by the initiator
pub client_transforms: Vec<Vec<IkeV2Transform>>,
- /// The transforms selected by the responder
- pub server_transforms: Vec<Vec<IkeV2Transform>>,
-
/// The encryption algorithm selected by the responder
pub alg_enc: IkeTransformEncType,
/// The authentication algorithm selected by the responder
connection_state: IKEV2ConnectionState::Init,
dh_group: IkeTransformDHType::None,
client_transforms: Vec::new(),
- server_transforms: Vec::new(),
alg_enc: IkeTransformEncType::ENCR_NULL,
alg_auth: IkeTransformAuthType::NONE,
alg_prf: IkeTransformPRFType::PRF_NULL,
tx.hdr.min_ver = isakmp_header.min_ver;
tx.hdr.msg_id = isakmp_header.msg_id;
tx.hdr.flags = isakmp_header.flags;
- state.transactions.push(tx);
let mut payload_types = Vec::new();
let mut errors = 0;
let mut notify_types = Vec::new();
IkeV2PayloadContent::Dummy => (),
IkeV2PayloadContent::SA(ref prop) => {
// if hdr.flags & IKEV2_FLAG_INITIATOR != 0 {
- add_proposals(state, prop, direction);
+ add_proposals(state, &mut tx, prop, direction);
// }
}
IkeV2PayloadContent::KE(ref kex) => {
}
state.ikev2_container.connection_state =
state.ikev2_container.connection_state.advance(payload);
- if let Some(tx) = state.transactions.last_mut() {
- // borrow back tx to update it
- tx.payload_types
- .ikev2_payload_types
- .append(&mut payload_types);
- tx.errors = errors;
- tx.notify_types.append(&mut notify_types);
-
- if direction == STREAM_TOCLIENT
- && state.ikev2_container.server_transforms.len() > 0
- {
- tx.hdr.ikev2_transforms.clear();
- for transforms in &state.ikev2_container.server_transforms {
- let mut proposal = Vec::new();
- transforms.iter().for_each(|t| match *t {
- IkeV2Transform::Encryption(ref e) => {
- proposal.push(IkeV2Transform::Encryption(*e))
- }
- IkeV2Transform::Auth(ref e) => {
- proposal.push(IkeV2Transform::Auth(*e))
- }
- IkeV2Transform::PRF(ref e) => {
- proposal.push(IkeV2Transform::PRF(*e))
- }
- IkeV2Transform::DH(ref e) => proposal.push(IkeV2Transform::DH(*e)),
- IkeV2Transform::ESN(ref e) => {
- proposal.push(IkeV2Transform::ESN(*e))
- }
- _ => (),
- });
- tx.hdr.ikev2_transforms.push(proposal);
- }
- }
- }
+ tx.payload_types
+ .ikev2_payload_types
+ .append(&mut payload_types);
+ tx.errors = errors;
+ tx.notify_types.append(&mut notify_types);
}
}
_e => {
SCLogDebug!("parse_ikev2_payload_with_type: {:?}", _e);
}
}
+ state.transactions.push(tx);
return AppLayerResult::ok();
}
-fn add_proposals(state: &mut IKEState, prop: &Vec<IkeV2Proposal>, direction: u8) {
+fn add_proposals(state: &mut IKEState, tx: &mut IKETransaction, prop: &Vec<IkeV2Proposal>, direction: u8) {
for p in prop {
let transforms: Vec<IkeV2Transform> = p.transforms.iter().map(|x| x.into()).collect();
// Rule 1: warn on weak or unknown transforms
| IkeTransformEncType::ENCR_NULL => {
SCLogDebug!("Weak Encryption: {:?}", enc);
// XXX send event only if direction == STREAM_TOCLIENT ?
- state.set_event(IkeEvent::WeakCryptoEnc);
+ tx.set_event(IkeEvent::WeakCryptoEnc);
}
_ => (),
}
IkeV2Transform::PRF(ref prf) => match *prf {
IkeTransformPRFType::PRF_NULL => {
SCLogDebug!("'Null' PRF transform proposed");
- state.set_event(IkeEvent::InvalidProposal);
+ tx.set_event(IkeEvent::InvalidProposal);
}
IkeTransformPRFType::PRF_HMAC_MD5 | IkeTransformPRFType::PRF_HMAC_SHA1 => {
SCLogDebug!("Weak PRF: {:?}", prf);
- state.set_event(IkeEvent::WeakCryptoPrf);
+ tx.set_event(IkeEvent::WeakCryptoPrf);
}
_ => (),
},
| IkeTransformAuthType::AUTH_HMAC_MD5_128
| IkeTransformAuthType::AUTH_HMAC_SHA1_160 => {
SCLogDebug!("Weak auth: {:?}", auth);
- state.set_event(IkeEvent::WeakCryptoAuth);
+ tx.set_event(IkeEvent::WeakCryptoAuth);
}
_ => (),
}
IkeV2Transform::DH(ref dh) => match *dh {
IkeTransformDHType::None => {
SCLogDebug!("'None' DH transform proposed");
- state.set_event(IkeEvent::InvalidProposal);
+ tx.set_event(IkeEvent::InvalidProposal);
}
IkeTransformDHType::Modp768
| IkeTransformDHType::Modp1024
| IkeTransformDHType::Modp1024s160
| IkeTransformDHType::Modp1536 => {
SCLogDebug!("Weak DH: {:?}", dh);
- state.set_event(IkeEvent::WeakCryptoDh);
+ tx.set_event(IkeEvent::WeakCryptoDh);
}
_ => (),
},
IkeV2Transform::Unknown(_tx_type, _tx_id) => {
SCLogDebug!("Unknown proposal: type={:?}, id={}", _tx_type, _tx_id);
- state.set_event(IkeEvent::UnknownProposal);
+ tx.set_event(IkeEvent::UnknownProposal);
}
_ => (),
}
_ => false,
}) {
SCLogDebug!("No DH transform found");
- state.set_event(IkeEvent::WeakCryptoNoDh);
+ tx.set_event(IkeEvent::WeakCryptoNoDh);
}
// Rule 3: check if proposing AH ([RFC7296] section 3.3.1)
if p.protocol_id == ProtocolID::AH {
SCLogDebug!("Proposal uses protocol AH - no confidentiality");
- state.set_event(IkeEvent::NoEncryption);
+ tx.set_event(IkeEvent::NoEncryption);
}
// Rule 4: lack of integrity is accepted only if using an AEAD proposal
// Look if no auth was proposed, including if proposal is Auth::None
_ => false,
}) {
SCLogDebug!("No integrity transform found");
- state.set_event(IkeEvent::WeakCryptoNoAuth);
+ tx.set_event(IkeEvent::WeakCryptoNoAuth);
}
}
// Finally
if direction == STREAM_TOCLIENT {
transforms.iter().for_each(|t| match *t {
- IkeV2Transform::Encryption(ref e) => state.ikev2_container.alg_enc = *e,
- IkeV2Transform::Auth(ref a) => state.ikev2_container.alg_auth = *a,
- IkeV2Transform::PRF(ref p) => state.ikev2_container.alg_prf = *p,
- IkeV2Transform::DH(ref dh) => state.ikev2_container.alg_dh = *dh,
- IkeV2Transform::ESN(ref e) => state.ikev2_container.alg_esn = *e,
- _ => (),
+ IkeV2Transform::Encryption(ref e) => {
+ state.ikev2_container.alg_enc = *e;
+ tx.hdr.ikev2_transforms.push(IkeV2Transform::Encryption(*e));
+ }
+ IkeV2Transform::Auth(ref a) => {
+ state.ikev2_container.alg_auth = *a;
+ tx.hdr.ikev2_transforms.push(IkeV2Transform::Auth(*a));
+ }
+ IkeV2Transform::PRF(ref p) => {
+ state.ikev2_container.alg_prf = *p;
+ tx.hdr.ikev2_transforms.push(IkeV2Transform::PRF(*p));
+ }
+ IkeV2Transform::DH(ref dh) => {
+ state.ikev2_container.alg_dh = *dh;
+ tx.hdr.ikev2_transforms.push(IkeV2Transform::DH(*dh));
+ }
+ IkeV2Transform::ESN(ref e) => {
+ state.ikev2_container.alg_esn = *e;
+ tx.hdr.ikev2_transforms.push(IkeV2Transform::ESN(*e));
+ }
+ _ => {},
});
SCLogDebug!("Selected transforms: {:?}", transforms);
- state.ikev2_container.server_transforms.push(transforms);
} else {
SCLogDebug!("Proposed transforms: {:?}", transforms);
state.ikev2_container.client_transforms.push(transforms);