@@ -873,9 +873,9 @@ static rlm_rcode_t CC_HINT(nonnull) process_reply(eap_handler_t *eap_session,
873873 rlm_rcode_t rcode = RLM_MODULE_REJECT ;
874874 VALUE_PAIR * vp ;
875875 vp_cursor_t cursor ;
876- uint8_t msk [2 * CHAP_VALUE_LENGTH ] = {0 }, emsk [2 * EAPTLS_MPPE_KEY_LEN ] = {0 };
876+ uint8_t msk [2 * EAPTLS_MPPE_KEY_LEN ] = {0 }, emsk [2 * EAPTLS_MPPE_KEY_LEN ] = {0 };
877877 size_t msklen = 0 , emsklen = 0 ;
878- bool doing_eap ;
878+ bool doing_eap , msk1 , msk2 ;
879879
880880 teap_tunnel_t * t = tls_session -> opaque ;
881881
@@ -893,52 +893,73 @@ static rlm_rcode_t CC_HINT(nonnull) process_reply(eap_handler_t *eap_session,
893893 switch (reply -> code ) {
894894 case PW_CODE_ACCESS_ACCEPT :
895895 RDEBUG ("Phase 2: Got tunneled Access-Accept" );
896+ msk1 = msk2 = false;
896897
897898 for (vp = fr_cursor_init (& cursor , & reply -> vps ); vp ; vp = fr_cursor_next (& cursor )) {
898- if (vp -> da -> attr == PW_EAP_EMSK ) {
899- // FIXME check if we should be generating an emsk from MPPE keys below
900- emsklen = MIN (vp -> vp_length , sizeof (emsk ));
901- memcpy (emsk , vp -> vp_octets , emsklen );
902- break ;
899+ debug_pair (vp );
900+
901+ if (vp -> da -> vendor == 0 ) {
902+ if (vp -> da -> attr == PW_EAP_EMSK ) {
903+ emsklen = MIN (vp -> vp_length , sizeof (emsk ));
904+ memcpy (emsk , vp -> vp_octets , emsklen );
905+ continue ;
906+ }
907+
908+ if (vp -> da -> attr == PW_EAP_MSK ) {
909+ msk1 = msk2 = true;
910+ msklen = MIN (vp -> vp_length , sizeof (msk ));
911+ memcpy (msk , vp -> vp_octets , msklen );
912+ continue ;
913+ }
903914 }
904915
916+ if (msk1 && msk2 && emsklen ) break ;
917+
905918 if (vp -> da -> vendor != VENDORPEC_MICROSOFT ) continue ;
906919
907- /* like for EAP-FAST, the keying material is used reversed */
908920 switch (vp -> da -> attr ) {
909921 case PW_MSCHAP_MPPE_SEND_KEY :
910922 if (vp -> vp_length == EAPTLS_MPPE_KEY_LEN ) {
911- /* do not set emsklen here so not to blat EAP-EMSK */
912- // emsklen = sizeof(emsk);
913- memcpy (emsk , vp -> vp_octets , EAPTLS_MPPE_KEY_LEN );
914- } else if (vp -> vp_length == CHAP_VALUE_LENGTH ) {
915- msklen = sizeof (msk );
923+ if (msk2 ) {
924+ fr_assert (memcmp (& msk [EAPTLS_MPPE_KEY_LEN ], vp -> vp_octets , EAPTLS_MPPE_KEY_LEN ) == 0 );
925+ } else {
926+ memcpy (& msk [EAPTLS_MPPE_KEY_LEN ], vp -> vp_octets , EAPTLS_MPPE_KEY_LEN );
927+ msk2 = true;
928+ }
929+
930+ } else if (vp -> vp_length == CHAP_VALUE_LENGTH ) { /* reversed, like EAP-FAST */
931+ msk2 = true;
916932 memcpy (msk , vp -> vp_octets , CHAP_VALUE_LENGTH );
933+
917934 } else {
918935 wrong_length :
919936 REDEBUG ("Phase 2: Found %s with incorrect length. Expected %u or %u, got %zu" ,
920937 vp -> da -> name , CHAP_VALUE_LENGTH , EAPTLS_MPPE_KEY_LEN , vp -> vp_length );
921938 return RLM_MODULE_INVALID ;
922939 }
923940
924- RDEBUGHEX ("Phase 2: MSCHAP-MPPE-SEND-KEY [low MSK]" , vp -> vp_octets , vp -> length );
941+ RDEBUGHEX ("Phase 2: MSCHAP-MPPE-Send-Key" , vp -> vp_octets , vp -> length );
942+ msklen += vp -> length ;
925943 break ;
926944
927945 case PW_MSCHAP_MPPE_RECV_KEY :
928- /* only do this if there is no EAP-EMSK */
929- if (vp -> vp_length == EAPTLS_MPPE_KEY_LEN && emsklen == 0 ) {
930- msklen = sizeof (msk );
931- memcpy (msk , vp -> vp_octets , EAPTLS_MPPE_KEY_LEN );
932- emsklen = sizeof (emsk );
933- memcpy (& emsk [EAPTLS_MPPE_KEY_LEN ], vp -> vp_octets , EAPTLS_MPPE_KEY_LEN );
946+ if (vp -> vp_length == EAPTLS_MPPE_KEY_LEN ) {
947+ if (msk1 ) {
948+ fr_assert (memcmp (msk , vp -> vp_octets , EAPTLS_MPPE_KEY_LEN ) == 0 );
949+ } else {
950+ memcpy (msk , vp -> vp_octets , EAPTLS_MPPE_KEY_LEN );
951+ msk1 = true;
952+ }
953+
934954 } else if (vp -> vp_length == CHAP_VALUE_LENGTH ) {
935- msklen = sizeof ( msk ) ;
955+ msk1 = true ;
936956 memcpy (& msk [CHAP_VALUE_LENGTH ], vp -> vp_octets , CHAP_VALUE_LENGTH );
937957 } else {
938958 goto wrong_length ;
939959 }
940960
941- RDEBUGHEX ("Phase 2: MSCHAP-MPPE-RECV-KEY [high MSK]" , vp -> vp_octets , vp -> vp_length );
961+ RDEBUGHEX ("Phase 2: MSCHAP-MPPE-Recv-Key" , vp -> vp_octets , vp -> vp_length );
962+ msklen += vp -> length ;
942963 break ;
943964
944965 case PW_MSCHAP2_SUCCESS :
@@ -977,6 +998,7 @@ static rlm_rcode_t CC_HINT(nonnull) process_reply(eap_handler_t *eap_session,
977998 * Clean up the tunneled reply.
978999 */
9791000 fr_pair_delete_by_num (& reply -> vps , PW_EAP_EMSK , 0 , TAG_ANY );
1001+ fr_pair_delete_by_num (& reply -> vps , PW_EAP_MSK , 0 , TAG_ANY );
9801002 fr_pair_delete_by_num (& reply -> vps , PW_EAP_SESSION_ID , 0 , TAG_ANY );
9811003 }
9821004
0 commit comments