forked from osmocom/wireshark
packet-kerberos: add support for decrypting KRB5 FAST messages
Currently this is only available for MIT Kerberos, but it should be possible to implement the same using krb5_crypto_fx_cf2() from Heimdal. Change-Id: Ic3327dfde770f9345485bf97e2ac6045b909b64e Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-on: https://code.wireshark.org/review/36472 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>osmith/wip
parent
a97956fa20
commit
738e73a50e
|
@ -86,8 +86,12 @@ if(KERBEROS_FOUND)
|
|||
include(CheckSymbolExists)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${KERBEROS_INCLUDE_DIRS})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${KERBEROS_LIBRARIES})
|
||||
#see also HAVE_HEIMDAL_KERBEROS in cmakeconfig.h.in
|
||||
check_symbol_exists("heimdal_version" "krb5.h" HAVE_HEIMDAL_KERBEROS)
|
||||
# see also HAVE_KRB5_PAC_VERIFY cmakeconfig.h.in
|
||||
check_symbol_exists("krb5_pac_verify" "krb5.h" HAVE_KRB5_PAC_VERIFY)
|
||||
# see also HAVE_KRB5_C_FX_CF2_SIMPLE in cmakeconfig.h.in
|
||||
check_symbol_exists("krb5_c_fx_cf2_simple" "krb5.h" HAVE_KRB5_C_FX_CF2_SIMPLE)
|
||||
set(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
if(NOT HAVE_HEIMDAL_KERBEROS)
|
||||
|
|
|
@ -88,6 +88,9 @@
|
|||
/* Define to 1 if you have the `krb5_pac_verify' function. */
|
||||
#cmakedefine HAVE_KRB5_PAC_VERIFY 1
|
||||
|
||||
/* Define to 1 if you have the `krb5_c_fx_cf2_simple' function. */
|
||||
#cmakedefine HAVE_KRB5_C_FX_CF2_SIMPLE 1
|
||||
|
||||
/* Define to 1 if you have the `inflatePrime' function. */
|
||||
#cmakedefine HAVE_INFLATEPRIME 1
|
||||
|
||||
|
|
|
@ -17,15 +17,20 @@ IMPORTS
|
|||
PA-AUTHENTICATION-SET ::= SEQUENCE OF PA-AUTHENTICATION-SET-ELEM
|
||||
|
||||
PA-AUTHENTICATION-SET-ELEM ::= SEQUENCE {
|
||||
pa-type [0] Int32,
|
||||
pa-type [0] PADATA-TYPE, -- use k5.asn Int32,
|
||||
-- same as padata-type.
|
||||
pa-hint [1] OCTET STRING OPTIONAL,
|
||||
pa-value [2] OCTET STRING OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
KrbFastArmorTypes ::= INTEGER {
|
||||
fX-FAST-reserved(0),
|
||||
fX-FAST-ARMOR-AP-REQUEST(1) -- [RFC6113]
|
||||
}
|
||||
|
||||
KrbFastArmor ::= SEQUENCE {
|
||||
armor-type [0] Int32,
|
||||
armor-type [0] KrbFastArmorTypes,
|
||||
-- Type of the armor.
|
||||
armor-value [1] OCTET STRING,
|
||||
-- Value of the armor.
|
||||
|
@ -37,6 +42,12 @@ PA-FX-FAST-REQUEST ::= CHOICE {
|
|||
...
|
||||
}
|
||||
|
||||
EncryptedKrbFastReq ::= SEQUENCE {
|
||||
etype [0] ENCTYPE -- EncryptionType --,
|
||||
kvno [1] UInt32 OPTIONAL,
|
||||
cipher [2] OCTET STRING -- ciphertext
|
||||
}
|
||||
|
||||
KrbFastArmoredReq ::= SEQUENCE {
|
||||
armor [0] KrbFastArmor OPTIONAL,
|
||||
-- Contains the armor that identifies the armor key.
|
||||
|
@ -51,7 +62,7 @@ KrbFastArmoredReq ::= SEQUENCE {
|
|||
-- type is the required checksum type for the enctype of
|
||||
-- the armor key, and the key usage number is
|
||||
-- KEY_USAGE_FAST_REQ_CHKSUM.
|
||||
enc-fast-req [2] EncryptedData, -- KrbFastReq --
|
||||
enc-fast-req [2] EncryptedKrbFastReq, -- KrbFastReq --
|
||||
-- The encryption key is the armor key, and the key usage
|
||||
-- number is KEY_USAGE_FAST_ENC.
|
||||
...
|
||||
|
@ -70,18 +81,25 @@ KrbFastReq ::= SEQUENCE {
|
|||
...
|
||||
}
|
||||
|
||||
FastOptions ::= KerberosFlags
|
||||
-- reserved(0),
|
||||
-- hide-client-names(1),
|
||||
-- kdc-follow-referrals(16)
|
||||
FastOptions ::= BIT STRING {
|
||||
reserved(0),
|
||||
hide-client-names(1),
|
||||
kdc-follow-referrals(16)
|
||||
} (SIZE (32..MAX)) -- KerberosFlags
|
||||
|
||||
PA-FX-FAST-REPLY ::= CHOICE {
|
||||
armored-data [0] KrbFastArmoredRep,
|
||||
...
|
||||
}
|
||||
|
||||
EncryptedKrbFastResponse ::= SEQUENCE {
|
||||
etype [0] ENCTYPE -- EncryptionType --,
|
||||
kvno [1] UInt32 OPTIONAL,
|
||||
cipher [2] OCTET STRING -- ciphertext
|
||||
}
|
||||
|
||||
KrbFastArmoredRep ::= SEQUENCE {
|
||||
enc-fast-rep [0] EncryptedData, -- KrbFastResponse --
|
||||
enc-fast-rep [0] EncryptedKrbFastResponse, -- KrbFastResponse --
|
||||
-- The encryption key is the armor key in the request, and
|
||||
-- the key usage number is KEY_USAGE_FAST_REP.
|
||||
...
|
||||
|
@ -117,8 +135,13 @@ KrbFastFinished ::= SEQUENCE {
|
|||
...
|
||||
}
|
||||
|
||||
EncryptedChallenge ::= EncryptedData
|
||||
EncryptedChallenge ::= SEQUENCE {
|
||||
etype [0] ENCTYPE -- EncryptionType --,
|
||||
kvno [1] UInt32 OPTIONAL,
|
||||
cipher [2] OCTET STRING -- ciphertext
|
||||
}
|
||||
-- Encrypted PA-ENC-TS-ENC, encrypted in the challenge key
|
||||
-- using key usage KEY_USAGE_ENC_CHALLENGE_CLIENT for the
|
||||
-- client and KEY_USAGE_ENC_CHALLENGE_KDC for the KDC.
|
||||
|
||||
END
|
||||
|
|
|
@ -19,6 +19,9 @@ PA-ENC-TIMESTAMP/cipher pA-ENC-TIMESTAMP_cipher
|
|||
EncryptedAPREPData/cipher encryptedAPREPData_cipher
|
||||
EncryptedKrbPrivData/cipher encryptedKrbPrivData_cipher
|
||||
EncryptedKrbCredData/cipher encryptedKrbCredData_cipher
|
||||
EncryptedKrbFastReq/cipher encryptedKrbFastReq_cipher
|
||||
EncryptedKrbFastResponse/cipher encryptedKrbFastResponse_cipher
|
||||
EncryptedChallenge/cipher encryptedChallenge_cipher
|
||||
EncAPRepPart/_untag/subkey encAPRepPart_subkey
|
||||
EncTicketPart/_untag/key encTicketPart_key
|
||||
EncKDCRepPart/key encKDCRepPart_key
|
||||
|
@ -31,6 +34,8 @@ Ticket/_untag/enc-part ticket_enc_part
|
|||
ETYPE-INFO-ENTRY/salt info_salt
|
||||
ETYPE-INFO2-ENTRY/salt info2_salt
|
||||
AP-REQ/_untag/authenticator authenticator_enc_part
|
||||
PA-FX-FAST-REQUEST/armored-data armored_data_request
|
||||
PA-FX-FAST-REPLY/armored-data armored_data_reply
|
||||
|
||||
#.OMIT_ASSIGNMENT
|
||||
AD-AND-OR
|
||||
|
@ -38,12 +43,15 @@ AD-KDCIssued
|
|||
AD-LoginAlias
|
||||
AD-MANDATORY-FOR-KDC
|
||||
ChangePasswdDataMS
|
||||
EncryptedData
|
||||
EtypeList
|
||||
KerberosFlags
|
||||
KRB5SignedPath
|
||||
KRB5SignedPathData
|
||||
KRB5SignedPathPrincipals
|
||||
Krb5int32
|
||||
Krb5uint32
|
||||
PA-AUTHENTICATION-SET
|
||||
PA-ClientCanonicalized
|
||||
PA-ClientCanonicalizedNames
|
||||
PA-ENC-TS-ENC
|
||||
|
@ -60,11 +68,6 @@ Principal
|
|||
PROV-SRV-LOCATION
|
||||
SAMFlags
|
||||
TYPED-DATA
|
||||
KrbFastReq
|
||||
KrbFastResponse
|
||||
KrbFastFinished
|
||||
FastOptions
|
||||
KerberosFlags
|
||||
|
||||
#.NO_EMIT ONLY_VALS
|
||||
Applications
|
||||
|
@ -78,6 +81,7 @@ Applications TYPE_PREFIX
|
|||
#.MAKE_ENUM
|
||||
PADATA-TYPE PROT_PREFIX UPPER_CASE
|
||||
AUTHDATA-TYPE PROT_PREFIX UPPER_CASE
|
||||
KrbFastArmorTypes PROT_PREFIX UPPER_CASE
|
||||
|
||||
#.FN_BODY MESSAGE-TYPE VAL_PTR = &msgtype
|
||||
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
|
||||
|
@ -137,10 +141,10 @@ AUTHDATA-TYPE PROT_PREFIX UPPER_CASE
|
|||
case KRB5_ET_KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET:
|
||||
case KRB5_ET_KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS:
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_kerberos_e_data, dissect_kerberos_SEQUENCE_OF_PA_DATA);
|
||||
|
||||
break;
|
||||
default:
|
||||
offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_kerberos_e_data, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
@ -164,7 +168,9 @@ AUTHDATA-TYPE PROT_PREFIX UPPER_CASE
|
|||
|
||||
switch(private_data->padata_type){
|
||||
case KERBEROS_PA_TGS_REQ:
|
||||
private_data->within_PA_TGS_REQ++;
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_index, dissect_kerberos_Applications);
|
||||
private_data->within_PA_TGS_REQ--;
|
||||
break;
|
||||
case KERBEROS_PA_PK_AS_REP_19:
|
||||
private_data->is_win2k_pkinit = TRUE;
|
||||
|
@ -210,16 +216,19 @@ AUTHDATA-TYPE PROT_PREFIX UPPER_CASE
|
|||
case KERBEROS_PA_PW_SALT:
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_index, dissect_krb5_PW_SALT);
|
||||
break;
|
||||
case KERBEROS_PA_AUTHENTICATION_SET:
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_index, dissect_kerberos_PA_AUTHENTICATION_SET);
|
||||
case KERBEROS_PA_AUTH_SET_SELECTED:
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_index, dissect_kerberos_PA_AUTHENTICATION_SET_ELEM);
|
||||
break;
|
||||
case KERBEROS_PA_FX_FAST:
|
||||
if(private_data->msg_type == KRB5_MSG_AS_REQ || private_data->msg_type == KRB5_MSG_TGS_REQ){
|
||||
if (kerberos_private_is_kdc_req(private_data)) {
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_index, dissect_kerberos_PA_FX_FAST_REQUEST);
|
||||
}else{
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_index, dissect_kerberos_PA_FX_FAST_REPLY);
|
||||
}
|
||||
break;
|
||||
case KERBEROS_PA_FX_ERROR:
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_index, dissect_kerberos_Applications);
|
||||
break;
|
||||
case KERBEROS_PA_ENCRYPTED_CHALLENGE:
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_index, dissect_kerberos_EncryptedChallenge);
|
||||
break;
|
||||
|
@ -234,6 +243,7 @@ AUTHDATA-TYPE PROT_PREFIX UPPER_CASE
|
|||
break;
|
||||
default:
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, sub_tree, tvb, offset,hf_index, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
#.FN_BODY HostAddress/address
|
||||
|
@ -272,6 +282,7 @@ AUTHDATA-TYPE PROT_PREFIX UPPER_CASE
|
|||
default:
|
||||
proto_tree_add_expert(tree, actx->pinfo, &ei_kerberos_address, tvb, offset, len);
|
||||
address_str = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* push it up two levels in the decode pane */
|
||||
|
@ -361,6 +372,7 @@ AUTHDATA-TYPE PROT_PREFIX UPPER_CASE
|
|||
break;
|
||||
default:
|
||||
offset=dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_index, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
#.FN_BODY EncryptionKey/keytype VAL_PTR=&gbl_keytype
|
||||
|
@ -463,6 +475,16 @@ AUTHDATA-TYPE PROT_PREFIX UPPER_CASE
|
|||
private_data->save_encryption_key_parent_hf_index = save_encryption_key_parent_hf_index;
|
||||
private_data->save_encryption_key_fn = saved_encryption_key_fn;
|
||||
|
||||
#.FN_BODY KrbFastResponse/strengthen-key
|
||||
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
|
||||
gint save_encryption_key_parent_hf_index = private_data->save_encryption_key_parent_hf_index;
|
||||
kerberos_key_save_fn saved_encryption_key_fn = private_data->save_encryption_key_fn;
|
||||
private_data->save_encryption_key_parent_hf_index = hf_kerberos_KrbFastResponse;
|
||||
private_data->save_encryption_key_fn = save_KrbFastResponse_strengthen_key;
|
||||
%(DEFAULT_BODY)s
|
||||
private_data->save_encryption_key_parent_hf_index = save_encryption_key_parent_hf_index;
|
||||
private_data->save_encryption_key_fn = saved_encryption_key_fn;
|
||||
|
||||
#.FN_BODY AUTHDATA-TYPE VAL_PTR=&(private_data->ad_type)
|
||||
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
|
||||
%(DEFAULT_BODY)s
|
||||
|
@ -477,6 +499,9 @@ AUTHDATA-TYPE PROT_PREFIX UPPER_CASE
|
|||
case KERBEROS_AD_IF_RELEVANT:
|
||||
offset=dissect_ber_octet_string_wcb(implicit_tag, actx, tree, tvb, offset, hf_index, dissect_kerberos_AD_IF_RELEVANT);
|
||||
break;
|
||||
case KERBEROS_AD_AUTHENTICATION_STRENGTH:
|
||||
offset=dissect_ber_octet_string_wcb(implicit_tag, actx, tree, tvb, offset, hf_index, dissect_kerberos_PA_AUTHENTICATION_SET_ELEM);
|
||||
break;
|
||||
case KERBEROS_AD_GSS_API_ETYPE_NEGOTIATION:
|
||||
offset=dissect_ber_octet_string_wcb(implicit_tag, actx, tree, tvb, offset, hf_index, dissect_kerberos_SEQUENCE_OF_ENCTYPE);
|
||||
break;
|
||||
|
@ -491,6 +516,7 @@ AUTHDATA-TYPE PROT_PREFIX UPPER_CASE
|
|||
break;
|
||||
default:
|
||||
offset=dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
#.FN_BODY S4UUserID/subject-certificate
|
||||
|
@ -546,3 +572,44 @@ AUTHDATA-TYPE PROT_PREFIX UPPER_CASE
|
|||
#.FN_FTR EncKDCRepPart/encrypted-pa-data
|
||||
private_data->is_enc_padata = FALSE;
|
||||
|
||||
#.FN_BODY EncryptedKrbFastReq/cipher
|
||||
##ifdef HAVE_KERBEROS
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_index, dissect_krb5_decrypt_KrbFastReq);
|
||||
##else
|
||||
%(DEFAULT_BODY)s
|
||||
##endif
|
||||
return offset;
|
||||
|
||||
#.FN_BODY EncryptedKrbFastResponse/cipher
|
||||
##ifdef HAVE_KERBEROS
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_index, dissect_krb5_decrypt_KrbFastResponse);
|
||||
##else
|
||||
%(DEFAULT_BODY)s
|
||||
##endif
|
||||
return offset;
|
||||
|
||||
#.FN_BODY EncryptedChallenge/cipher
|
||||
##ifdef HAVE_KERBEROS
|
||||
offset=dissect_ber_octet_string_wcb(FALSE, actx, tree, tvb, offset, hf_index, dissect_krb5_decrypt_EncryptedChallenge);
|
||||
##else
|
||||
%(DEFAULT_BODY)s
|
||||
##endif
|
||||
return offset;
|
||||
|
||||
#.FN_BODY KrbFastArmorTypes VAL_PTR=&(private_data->fast_type)
|
||||
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
|
||||
%(DEFAULT_BODY)s
|
||||
|
||||
#.FN_BODY KrbFastArmor/armor-value
|
||||
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
|
||||
|
||||
switch(private_data->fast_type){
|
||||
case KERBEROS_FX_FAST_ARMOR_AP_REQUEST:
|
||||
private_data->fast_armor_within_armor_value++;
|
||||
offset=dissect_ber_octet_string_wcb(implicit_tag, actx, tree, tvb, offset, hf_index, dissect_kerberos_Applications);
|
||||
private_data->fast_armor_within_armor_value--;
|
||||
break;
|
||||
default:
|
||||
offset=dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, NULL);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -71,6 +71,13 @@
|
|||
#include "packet-gssapi.h"
|
||||
#include "packet-x509af.h"
|
||||
|
||||
#define KEY_USAGE_FAST_REQ_CHKSUM 50
|
||||
#define KEY_USAGE_FAST_ENC 51
|
||||
#define KEY_USAGE_FAST_REP 52
|
||||
#define KEY_USAGE_FAST_FINISHED 53
|
||||
#define KEY_USAGE_ENC_CHALLENGE_CLIENT 54
|
||||
#define KEY_USAGE_ENC_CHALLENGE_KDC 55
|
||||
|
||||
void proto_register_kerberos(void);
|
||||
void proto_reg_handoff_kerberos(void);
|
||||
|
||||
|
@ -114,6 +121,15 @@ typedef struct {
|
|||
guint learnt_key_ids;
|
||||
wmem_list_t *decryption_keys;
|
||||
wmem_list_t *learnt_keys;
|
||||
guint32 within_PA_TGS_REQ;
|
||||
enc_key_t *PA_TGS_REQ_key;
|
||||
enc_key_t *PA_TGS_REQ_subkey;
|
||||
guint32 fast_type;
|
||||
guint32 fast_armor_within_armor_value;
|
||||
enc_key_t *PA_FAST_ARMOR_AP_key;
|
||||
enc_key_t *PA_FAST_ARMOR_AP_subkey;
|
||||
enc_key_t *fast_armor_key;
|
||||
enc_key_t *fast_strengthen_key;
|
||||
} kerberos_private_data_t;
|
||||
|
||||
static dissector_handle_t kerberos_handle_udp;
|
||||
|
@ -131,13 +147,15 @@ static int dissect_kerberos_PA_S4U_X509_USER(gboolean implicit_tag _U_, tvbuff_t
|
|||
static int dissect_kerberos_ETYPE_INFO(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_ETYPE_INFO2(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_AD_IF_RELEVANT(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_PA_AUTHENTICATION_SET(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_PA_AUTHENTICATION_SET_ELEM(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_PA_FX_FAST_REQUEST(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_EncryptedChallenge(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_PA_FX_FAST_REPLY(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_PA_PAC_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_KERB_AD_RESTRICTION_ENTRY(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_SEQUENCE_OF_ENCTYPE(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_KrbFastReq(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_kerberos_KrbFastResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
|
||||
/* Desegment Kerberos over TCP messages */
|
||||
static gboolean krb_desegment = TRUE;
|
||||
|
@ -213,6 +231,7 @@ static gint hf_krb_ad_ap_options = -1;
|
|||
static gint hf_krb_ad_ap_options_cbt = -1;
|
||||
static gint hf_krb_ad_target_principal = -1;
|
||||
static gint hf_krb_key_hidden_item = -1;
|
||||
static gint hf_kerberos_KrbFastResponse = -1;
|
||||
#ifdef HAVE_KERBEROS
|
||||
static gint hf_krb_patimestamp = -1;
|
||||
static gint hf_krb_pausec = -1;
|
||||
|
@ -571,14 +590,22 @@ add_encryption_key(packet_info *pinfo,
|
|||
proto_item *key_hidden_item,
|
||||
tvbuff_t *key_tvb,
|
||||
int keytype, int keylength, const char *keyvalue,
|
||||
const char *origin)
|
||||
const char *origin,
|
||||
enc_key_t *src1, enc_key_t *src2)
|
||||
{
|
||||
wmem_allocator_t *key_scope = NULL;
|
||||
enc_key_t *new_key = NULL;
|
||||
const char *methodl = "learnt";
|
||||
const char *methodu = "Learnt";
|
||||
proto_item *item = NULL;
|
||||
|
||||
private_data->last_added_key = NULL;
|
||||
|
||||
if (src1 != NULL && src2 != NULL) {
|
||||
methodl = "derived";
|
||||
methodu = "Derived";
|
||||
}
|
||||
|
||||
if(pinfo->fd->visited){
|
||||
/*
|
||||
* We already processed this,
|
||||
|
@ -596,7 +623,8 @@ add_encryption_key(packet_info *pinfo,
|
|||
}
|
||||
|
||||
new_key = wmem_new0(key_scope, enc_key_t);
|
||||
g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt in frame %u",origin,pinfo->num);
|
||||
g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s %s in frame %u",
|
||||
methodl, origin, pinfo->num);
|
||||
new_key->fd_num = pinfo->num;
|
||||
new_key->id = ++private_data->learnt_key_ids;
|
||||
g_snprintf(new_key->id_str, KRB_MAX_ID_STR_LEN, "%d.%u",
|
||||
|
@ -604,6 +632,8 @@ add_encryption_key(packet_info *pinfo,
|
|||
new_key->keytype=keytype;
|
||||
new_key->keylength=keylength;
|
||||
memcpy(new_key->keyvalue, keyvalue, MIN(keylength, KRB_MAX_KEY_LENGTH));
|
||||
new_key->src1 = src1;
|
||||
new_key->src2 = src2;
|
||||
|
||||
if(!pinfo->fd->visited){
|
||||
/*
|
||||
|
@ -617,13 +647,31 @@ add_encryption_key(packet_info *pinfo,
|
|||
|
||||
item = proto_tree_add_expert_format(key_tree, pinfo, &ei_kerberos_learnt_keytype,
|
||||
key_tvb, 0, keylength,
|
||||
"Learnt %s keytype %d (id=%d.%u) (%02x%02x%02x%02x...)",
|
||||
origin, keytype, pinfo->num, new_key->id,
|
||||
"%s %s keytype %d (id=%d.%u) (%02x%02x%02x%02x...)",
|
||||
methodu, origin, keytype, pinfo->num, new_key->id,
|
||||
keyvalue[0] & 0xFF, keyvalue[1] & 0xFF,
|
||||
keyvalue[2] & 0xFF, keyvalue[3] & 0xFF);
|
||||
if (item != NULL && key_hidden_item != NULL) {
|
||||
proto_tree_move_item(key_tree, key_hidden_item, item);
|
||||
}
|
||||
if (src1 != NULL) {
|
||||
enc_key_t *sek = src1;
|
||||
expert_add_info_format(pinfo, item, &ei_kerberos_learnt_keytype,
|
||||
"SRC1 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
|
||||
sek->key_origin, sek->keytype,
|
||||
sek->id_str, sek->num_same,
|
||||
sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF,
|
||||
sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF);
|
||||
}
|
||||
if (src2 != NULL) {
|
||||
enc_key_t *sek = src2;
|
||||
expert_add_info_format(pinfo, item, &ei_kerberos_learnt_keytype,
|
||||
"SRC2 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
|
||||
sek->key_origin, sek->keytype,
|
||||
sek->id_str, sek->num_same,
|
||||
sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF,
|
||||
sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF);
|
||||
}
|
||||
|
||||
kerberos_key_list_append(private_data->learnt_keys, new_key);
|
||||
private_data->last_added_key = new_key;
|
||||
|
@ -650,7 +698,9 @@ save_encryption_key(tvbuff_t *tvb _U_, int offset _U_, int length _U_,
|
|||
private_data->key.keytype,
|
||||
private_data->key.keylength,
|
||||
private_data->key.keyvalue,
|
||||
origin);
|
||||
origin,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -659,7 +709,25 @@ save_Authenticator_subkey(tvbuff_t *tvb, int offset, int length,
|
|||
int parent_hf_index,
|
||||
int hf_index)
|
||||
{
|
||||
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
|
||||
|
||||
save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index);
|
||||
|
||||
if (private_data->last_decryption_key == NULL) {
|
||||
return;
|
||||
}
|
||||
if (private_data->last_added_key == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (private_data->within_PA_TGS_REQ != 0) {
|
||||
private_data->PA_TGS_REQ_key = private_data->last_decryption_key;
|
||||
private_data->PA_TGS_REQ_subkey = private_data->last_added_key;
|
||||
}
|
||||
if (private_data->fast_armor_within_armor_value != 0) {
|
||||
private_data->PA_FAST_ARMOR_AP_key = private_data->last_decryption_key;
|
||||
private_data->PA_FAST_ARMOR_AP_subkey = private_data->last_added_key;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -698,6 +766,19 @@ save_KrbCredInfo_key(tvbuff_t *tvb, int offset, int length,
|
|||
save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index);
|
||||
}
|
||||
|
||||
static void
|
||||
save_KrbFastResponse_strengthen_key(tvbuff_t *tvb, int offset, int length,
|
||||
asn1_ctx_t *actx, proto_tree *tree,
|
||||
int parent_hf_index,
|
||||
int hf_index)
|
||||
{
|
||||
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
|
||||
|
||||
save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index);
|
||||
|
||||
private_data->fast_strengthen_key = private_data->last_added_key;
|
||||
}
|
||||
|
||||
static void used_encryption_key(proto_tree *tree, packet_info *pinfo,
|
||||
kerberos_private_data_t *private_data,
|
||||
enc_key_t *ek, int usage, tvbuff_t *cryptotvb)
|
||||
|
@ -712,6 +793,24 @@ static void used_encryption_key(proto_tree *tree, packet_info *pinfo,
|
|||
ek->keytype, usage, ek->key_origin, ek->id_str, ek->num_same,
|
||||
ek->keyvalue[0] & 0xFF, ek->keyvalue[1] & 0xFF,
|
||||
ek->keyvalue[2] & 0xFF, ek->keyvalue[3] & 0xFF);
|
||||
if (ek->src1 != NULL) {
|
||||
sek = ek->src1;
|
||||
expert_add_info_format(pinfo, item, &ei_kerberos_decrypted_keytype,
|
||||
"SRC1 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
|
||||
sek->key_origin, sek->keytype,
|
||||
sek->id_str, sek->num_same,
|
||||
sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF,
|
||||
sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF);
|
||||
}
|
||||
if (ek->src2 != NULL) {
|
||||
sek = ek->src2;
|
||||
expert_add_info_format(pinfo, item, &ei_kerberos_decrypted_keytype,
|
||||
"SRC2 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
|
||||
sek->key_origin, sek->keytype,
|
||||
sek->id_str, sek->num_same,
|
||||
sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF,
|
||||
sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF);
|
||||
}
|
||||
sek = ek->same_list;
|
||||
while (sek != NULL) {
|
||||
expert_add_info_format(pinfo, item, &ei_kerberos_decrypted_keytype,
|
||||
|
@ -765,6 +864,58 @@ static void used_signing_key(proto_tree *tree, packet_info *pinfo,
|
|||
|
||||
static krb5_context krb5_ctx;
|
||||
|
||||
static void
|
||||
krb5_fast_key(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb,
|
||||
enc_key_t *ek1 _U_, const char *p1 _U_,
|
||||
enc_key_t *ek2 _U_, const char *p2 _U_,
|
||||
const char *origin _U_)
|
||||
{
|
||||
#ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
|
||||
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
|
||||
krb5_error_code ret;
|
||||
krb5_keyblock k1;
|
||||
krb5_keyblock k2;
|
||||
krb5_keyblock *k = NULL;
|
||||
|
||||
if (!krb_decrypt) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ek1 == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ek2 == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
k1.magic = KV5M_KEYBLOCK;
|
||||
k1.enctype = ek1->keytype;
|
||||
k1.length = ek1->keylength;
|
||||
k1.contents = (guint8 *)ek1->keyvalue;
|
||||
|
||||
k2.magic = KV5M_KEYBLOCK;
|
||||
k2.enctype = ek2->keytype;
|
||||
k2.length = ek2->keylength;
|
||||
k2.contents = (guint8 *)ek2->keyvalue;
|
||||
|
||||
ret = krb5_c_fx_cf2_simple(krb5_ctx, &k1, p1, &k2, p2, &k);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_encryption_key(actx->pinfo,
|
||||
private_data,
|
||||
tree, NULL, tvb,
|
||||
k->enctype, k->length,
|
||||
(const char *)k->contents,
|
||||
origin,
|
||||
ek1, ek2);
|
||||
|
||||
krb5_free_keyblock(krb5_ctx, k);
|
||||
#endif
|
||||
}
|
||||
|
||||
USES_APPLE_DEPRECATED_API
|
||||
void
|
||||
read_keytab_file(const char *filename)
|
||||
|
@ -874,6 +1025,12 @@ decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userda
|
|||
enc_key_t *ek = (enc_key_t *)value;
|
||||
krb5_error_code ret;
|
||||
krb5_keytab_entry key;
|
||||
#ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
|
||||
enc_key_t *ak = state->private_data->fast_armor_key;
|
||||
enc_key_t *sk = state->private_data->fast_strengthen_key;
|
||||
gboolean try_with_armor_key = FALSE;
|
||||
gboolean try_with_strengthen_key = FALSE;
|
||||
#endif
|
||||
|
||||
if (state->ek != NULL) {
|
||||
/*
|
||||
|
@ -882,6 +1039,173 @@ decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userda
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
|
||||
if (ak != NULL && ak != ek && ak->keytype == state->keytype && ek->fd_num == -1) {
|
||||
switch (state->usage) {
|
||||
case KEY_USAGE_ENC_CHALLENGE_CLIENT:
|
||||
case KEY_USAGE_ENC_CHALLENGE_KDC:
|
||||
if (ek->fd_num == -1) {
|
||||
/* Challenges are based on a long term key */
|
||||
try_with_armor_key = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we already have a strengthen_key
|
||||
* we don't need to try with the armor key
|
||||
* again
|
||||
*/
|
||||
if (sk != NULL) {
|
||||
try_with_armor_key = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (sk != NULL && sk != ek && sk->keytype == state->keytype && sk->keytype == ek->keytype) {
|
||||
switch (state->usage) {
|
||||
case 3:
|
||||
if (ek->fd_num == -1) {
|
||||
/* AS-REP is based on a long term key */
|
||||
try_with_strengthen_key = TRUE;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
case 9:
|
||||
if (ek->fd_num != -1) {
|
||||
/* TGS-REP is not based on a long term key */
|
||||
try_with_strengthen_key = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (try_with_armor_key) {
|
||||
krb5_keyblock k1;
|
||||
krb5_keyblock k2;
|
||||
krb5_keyblock *k = NULL;
|
||||
const char *p1 = NULL;
|
||||
|
||||
k1.magic = KV5M_KEYBLOCK;
|
||||
k1.enctype = ak->keytype;
|
||||
k1.length = ak->keylength;
|
||||
k1.contents = (guint8 *)ak->keyvalue;
|
||||
|
||||
k2.magic = KV5M_KEYBLOCK;
|
||||
k2.enctype = ek->keytype;
|
||||
k2.length = ek->keylength;
|
||||
k2.contents = (guint8 *)ek->keyvalue;
|
||||
|
||||
switch (state->usage) {
|
||||
case KEY_USAGE_ENC_CHALLENGE_CLIENT:
|
||||
p1 = "clientchallengearmor";
|
||||
break;
|
||||
case KEY_USAGE_ENC_CHALLENGE_KDC:
|
||||
p1 = "kdcchallengearmor";
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Should never be called!
|
||||
*/
|
||||
/*
|
||||
* try the next one...
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
ret = krb5_c_fx_cf2_simple(krb5_ctx,
|
||||
&k1, p1,
|
||||
&k2, "challengelongterm",
|
||||
&k);
|
||||
if (ret != 0) {
|
||||
/*
|
||||
* try the next one...
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
ret = state->decrypt_cb_fn(k,
|
||||
state->usage,
|
||||
state->decrypt_cb_data);
|
||||
if (ret == 0) {
|
||||
add_encryption_key(state->pinfo,
|
||||
state->private_data,
|
||||
state->tree,
|
||||
NULL,
|
||||
state->cryptotvb,
|
||||
k->enctype, k->length,
|
||||
(const char *)k->contents,
|
||||
p1,
|
||||
ak, ek);
|
||||
krb5_free_keyblock(krb5_ctx, k);
|
||||
/*
|
||||
* remember the key and stop traversing
|
||||
*/
|
||||
state->ek = state->private_data->last_added_key;
|
||||
return;
|
||||
}
|
||||
krb5_free_keyblock(krb5_ctx, k);
|
||||
/*
|
||||
* don't stop traversing...
|
||||
* try the next one...
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (try_with_strengthen_key) {
|
||||
krb5_keyblock k1;
|
||||
krb5_keyblock k2;
|
||||
krb5_keyblock *k = NULL;
|
||||
|
||||
k1.magic = KV5M_KEYBLOCK;
|
||||
k1.enctype = sk->keytype;
|
||||
k1.length = sk->keylength;
|
||||
k1.contents = (guint8 *)sk->keyvalue;
|
||||
|
||||
k2.magic = KV5M_KEYBLOCK;
|
||||
k2.enctype = ek->keytype;
|
||||
k2.length = ek->keylength;
|
||||
k2.contents = (guint8 *)ek->keyvalue;
|
||||
|
||||
ret = krb5_c_fx_cf2_simple(krb5_ctx,
|
||||
&k1, "strengthenkey",
|
||||
&k2, "replykey",
|
||||
&k);
|
||||
if (ret != 0) {
|
||||
/*
|
||||
* try the next one...
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
ret = state->decrypt_cb_fn(k,
|
||||
state->usage,
|
||||
state->decrypt_cb_data);
|
||||
if (ret == 0) {
|
||||
add_encryption_key(state->pinfo,
|
||||
state->private_data,
|
||||
state->tree,
|
||||
NULL,
|
||||
state->cryptotvb,
|
||||
k->enctype, k->length,
|
||||
(const char *)k->contents,
|
||||
"strengthen-reply-key",
|
||||
sk, ek);
|
||||
krb5_free_keyblock(krb5_ctx, k);
|
||||
/*
|
||||
* remember the key and stop traversing
|
||||
*/
|
||||
state->ek = state->private_data->last_added_key;
|
||||
return;
|
||||
}
|
||||
krb5_free_keyblock(krb5_ctx, k);
|
||||
/*
|
||||
* don't stop traversing...
|
||||
* try the next one...
|
||||
*/
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* shortcircuit and bail out if enctypes are not matching */
|
||||
if ((state->keytype != -1) && (ek->keytype != state->keytype)) {
|
||||
/*
|
||||
|
@ -1407,6 +1731,15 @@ verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
|
|||
static krb5_context krb5_ctx;
|
||||
|
||||
USES_APPLE_DEPRECATED_API
|
||||
|
||||
static void
|
||||
krb5_fast_key(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb,
|
||||
enc_key_t *ek1 _U_, const char *p1 _U_,
|
||||
enc_key_t *ek2 _U_, const char *p2 _U_,
|
||||
const char *origin _U_)
|
||||
{
|
||||
/* TODO: use krb5_crypto_fx_cf2() from Heimdal */
|
||||
}
|
||||
void
|
||||
read_keytab_file(const char *filename)
|
||||
{
|
||||
|
@ -1669,6 +2002,13 @@ save_KrbCredInfo_key(tvbuff_t *tvb, int offset, int length,
|
|||
save_encryption_key(tvb, offset, length, actx, tree, parent_hf_index, hf_index);
|
||||
}
|
||||
|
||||
static void
|
||||
save_KrbFastResponse_strengthen_key(tvbuff_t *tvb _U_, int offset _U_, int length _U_,
|
||||
asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)
|
||||
{
|
||||
save_encryption_key(tvb, offset, length, actx, tree, hf_index);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_keytab(void) {
|
||||
GSList *ske;
|
||||
|
@ -2425,6 +2765,141 @@ dissect_krb5_decrypt_CRED_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset,
|
|||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_krb5_decrypt_KrbFastReq(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
|
||||
proto_tree *tree, int hf_index _U_)
|
||||
{
|
||||
guint8 *plaintext;
|
||||
int length;
|
||||
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
|
||||
tvbuff_t *next_tvb;
|
||||
|
||||
next_tvb=tvb_new_subset_remaining(tvb, offset);
|
||||
length=tvb_captured_length_remaining(tvb, offset);
|
||||
|
||||
private_data->fast_armor_key = NULL;
|
||||
if (private_data->PA_FAST_ARMOR_AP_subkey != NULL) {
|
||||
krb5_fast_key(actx, tree, tvb,
|
||||
private_data->PA_FAST_ARMOR_AP_subkey,
|
||||
"subkeyarmor",
|
||||
private_data->PA_FAST_ARMOR_AP_key,
|
||||
"ticketarmor",
|
||||
"KrbFastReq_FAST_armorKey");
|
||||
if (private_data->PA_TGS_REQ_subkey != NULL) {
|
||||
enc_key_t *explicit_armor_key = private_data->last_added_key;
|
||||
|
||||
/*
|
||||
* See [MS-KILE] 3.3.5.7.4 Compound Identity
|
||||
*/
|
||||
krb5_fast_key(actx, tree, tvb,
|
||||
explicit_armor_key,
|
||||
"explicitarmor",
|
||||
private_data->PA_TGS_REQ_subkey,
|
||||
"tgsarmor",
|
||||
"KrbFastReq_explicitArmorKey");
|
||||
}
|
||||
private_data->fast_armor_key = private_data->last_added_key;
|
||||
} else if (private_data->PA_TGS_REQ_subkey != NULL) {
|
||||
krb5_fast_key(actx, tree, tvb,
|
||||
private_data->PA_TGS_REQ_subkey,
|
||||
"subkeyarmor",
|
||||
private_data->PA_TGS_REQ_key,
|
||||
"ticketarmor",
|
||||
"KrbFastReq_TGS_armorKey");
|
||||
private_data->fast_armor_key = private_data->last_added_key;
|
||||
}
|
||||
|
||||
/* RFC6113 :
|
||||
* KrbFastResponse encrypted with usage
|
||||
* KEY_USAGE_FAST_ENC 51
|
||||
*/
|
||||
plaintext=decrypt_krb5_data_asn1(tree, actx, KEY_USAGE_FAST_ENC,
|
||||
next_tvb, NULL);
|
||||
|
||||
if(plaintext){
|
||||
tvbuff_t *child_tvb;
|
||||
child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
|
||||
|
||||
/* Add the decrypted data to the data source list. */
|
||||
add_new_data_source(actx->pinfo, child_tvb, "Krb5 FastReq");
|
||||
|
||||
offset=dissect_kerberos_KrbFastReq(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_krb5_decrypt_KrbFastResponse(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
|
||||
proto_tree *tree, int hf_index _U_)
|
||||
{
|
||||
guint8 *plaintext;
|
||||
int length;
|
||||
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
|
||||
tvbuff_t *next_tvb;
|
||||
|
||||
next_tvb=tvb_new_subset_remaining(tvb, offset);
|
||||
length=tvb_captured_length_remaining(tvb, offset);
|
||||
|
||||
/*
|
||||
* RFC6113 :
|
||||
* KrbFastResponse encrypted with usage
|
||||
* KEY_USAGE_FAST_REP 52
|
||||
*/
|
||||
plaintext=decrypt_krb5_data_asn1(tree, actx, KEY_USAGE_FAST_REP,
|
||||
next_tvb, NULL);
|
||||
|
||||
if(plaintext){
|
||||
tvbuff_t *child_tvb;
|
||||
child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
|
||||
|
||||
/* Add the decrypted data to the data source list. */
|
||||
add_new_data_source(actx->pinfo, child_tvb, "Krb5 FastRep");
|
||||
|
||||
private_data->fast_armor_key = private_data->last_decryption_key;
|
||||
offset=dissect_kerberos_KrbFastResponse(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_krb5_decrypt_EncryptedChallenge(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
|
||||
proto_tree *tree, int hf_index _U_)
|
||||
{
|
||||
guint8 *plaintext;
|
||||
int length;
|
||||
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
|
||||
tvbuff_t *next_tvb;
|
||||
int usage = 0;
|
||||
const char *name = NULL;
|
||||
|
||||
next_tvb=tvb_new_subset_remaining(tvb, offset);
|
||||
length=tvb_captured_length_remaining(tvb, offset);
|
||||
|
||||
/* RFC6113 :
|
||||
* KEY_USAGE_ENC_CHALLENGE_CLIENT 54
|
||||
* KEY_USAGE_ENC_CHALLENGE_KDC 55
|
||||
*/
|
||||
if (kerberos_private_is_kdc_req(private_data)) {
|
||||
usage = KEY_USAGE_ENC_CHALLENGE_CLIENT;
|
||||
name = "Krb5 CHALLENGE_CLIENT";
|
||||
} else {
|
||||
usage = KEY_USAGE_ENC_CHALLENGE_KDC;
|
||||
name = "Krb5 CHALLENGE_KDC";
|
||||
}
|
||||
plaintext=decrypt_krb5_data_asn1(tree, actx, usage, next_tvb, NULL);
|
||||
|
||||
if(plaintext){
|
||||
tvbuff_t *child_tvb;
|
||||
child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
|
||||
|
||||
/* Add the decrypted data to the data source list. */
|
||||
add_new_data_source(actx->pinfo, child_tvb, name);
|
||||
|
||||
offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const int *hf_krb_pa_supported_enctypes_fields[] = {
|
||||
|
@ -3136,6 +3611,28 @@ kerberos_display_key(gpointer data, gpointer userdata)
|
|||
ek->id_str, ek->num_same,
|
||||
ek->keyvalue[0] & 0xFF, ek->keyvalue[1] & 0xFF,
|
||||
ek->keyvalue[2] & 0xFF, ek->keyvalue[3] & 0xFF);
|
||||
if (ek->src1 != NULL) {
|
||||
sek = ek->src1;
|
||||
expert_add_info_format(state->pinfo,
|
||||
item,
|
||||
state->expindex,
|
||||
"SRC1 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
|
||||
sek->key_origin, sek->keytype,
|
||||
sek->id_str, sek->num_same,
|
||||
sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF,
|
||||
sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF);
|
||||
}
|
||||
if (ek->src2 != NULL) {
|
||||
sek = ek->src2;
|
||||
expert_add_info_format(state->pinfo,
|
||||
item,
|
||||
state->expindex,
|
||||
"SRC2 %s keytype %d (id=%s same=%u) (%02x%02x%02x%02x...)",
|
||||
sek->key_origin, sek->keytype,
|
||||
sek->id_str, sek->num_same,
|
||||
sek->keyvalue[0] & 0xFF, sek->keyvalue[1] & 0xFF,
|
||||
sek->keyvalue[2] & 0xFF, sek->keyvalue[3] & 0xFF);
|
||||
}
|
||||
sek = ek->same_list;
|
||||
while (sek != NULL) {
|
||||
expert_add_info_format(state->pinfo,
|
||||
|
@ -3599,6 +4096,9 @@ void proto_register_kerberos(void) {
|
|||
{ &hf_krb_key_hidden_item,
|
||||
{ "KeyHiddenItem", "krb5.key_hidden_item",
|
||||
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
||||
{ &hf_kerberos_KrbFastResponse,
|
||||
{ "KrbFastResponse", "kerberos.KrbFastResponse_element",
|
||||
FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
|
||||
#ifdef HAVE_KERBEROS
|
||||
{ &hf_krb_patimestamp,
|
||||
{ "patimestamp", "kerberos.patimestamp",
|
||||
|
|
|
@ -80,6 +80,8 @@ typedef struct _enc_key_t {
|
|||
char id_str[KRB_MAX_ID_STR_LEN+1];
|
||||
struct _enc_key_t *same_list;
|
||||
guint num_same;
|
||||
struct _enc_key_t *src1;
|
||||
struct _enc_key_t *src2;
|
||||
} enc_key_t;
|
||||
extern enc_key_t *enc_key_list;
|
||||
extern wmem_map_t *kerberos_longterm_keys;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -88,6 +88,8 @@ typedef struct _enc_key_t {
|
|||
char id_str[KRB_MAX_ID_STR_LEN+1];
|
||||
struct _enc_key_t *same_list;
|
||||
guint num_same;
|
||||
struct _enc_key_t *src1;
|
||||
struct _enc_key_t *src2;
|
||||
} enc_key_t;
|
||||
extern enc_key_t *enc_key_list;
|
||||
extern wmem_map_t *kerberos_longterm_keys;
|
||||
|
@ -141,7 +143,7 @@ extern gboolean krb_decrypt;
|
|||
int dissect_kerberos_ChangePasswdData(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
|
||||
/*--- End of included file: packet-kerberos-exp.h ---*/
|
||||
#line 111 "./asn1/kerberos/packet-kerberos-template.h"
|
||||
#line 113 "./asn1/kerberos/packet-kerberos-template.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue