[SEBA-805] Using the Request Authenticator value saved in State Machine to check Message Authentication for each Radius response as per rfc 2869

Change-Id: I4e4083b93d1be4b84021dfd1d0a14cc4cde574db
diff --git a/app/src/main/java/org/opencord/aaa/impl/AaaManager.java b/app/src/main/java/org/opencord/aaa/impl/AaaManager.java
index d3ba6fc..35f880d 100755
--- a/app/src/main/java/org/opencord/aaa/impl/AaaManager.java
+++ b/app/src/main/java/org/opencord/aaa/impl/AaaManager.java
@@ -24,6 +24,7 @@
 import java.util.Map;
 import java.util.Dictionary;
 import java.util.HashSet;
+import java.util.Arrays;
 
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.felix.scr.annotations.Component;
@@ -85,6 +86,9 @@
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
 /**
  * AAA application for ONOS.
  */
@@ -321,11 +325,33 @@
         }
     }
 
-    private void checkReceivedPacketForValidValidator(RADIUS radiusPacket) {
-        if (!radiusPacket.checkMessageAuthenticator(radiusSecret)) {
+    private void checkReceivedPacketForValidValidator(RADIUS radiusPacket, byte[] requestAuthenticator) {
+        if (!checkResponseMessageAuthenticator(radiusSecret, radiusPacket, requestAuthenticator)) {
             aaaStatisticsManager.getAaaStats().increaseInvalidValidatorsRx();
         }
     }
+
+    private boolean checkResponseMessageAuthenticator(String key, RADIUS radiusPacket, byte[] requestAuthenticator) {
+        byte[] newHash = new byte[16];
+        Arrays.fill(newHash, (byte) 0);
+        byte[] messageAuthenticator = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH).getValue();
+        byte[] authenticator = radiusPacket.getAuthenticator();
+        radiusPacket.updateAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, newHash);
+        radiusPacket.setAuthenticator(requestAuthenticator);
+        // Calculate the MD5 HMAC based on the message
+        try {
+            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacMD5");
+            Mac mac = Mac.getInstance("HmacMD5");
+            mac.init(keySpec);
+            newHash = mac.doFinal(radiusPacket.serialize());
+        } catch (Exception e) {
+            log.error("Failed to generate message authenticator: {}", e.getMessage());
+        }
+        radiusPacket.updateAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, messageAuthenticator);
+        radiusPacket.setAuthenticator(authenticator);
+        // Compare the calculated Message-Authenticator with the one in the message
+        return Arrays.equals(newHash, messageAuthenticator);
+    }
     public void checkForPacketFromUnknownServer(String hostAddress) {
             if (!hostAddress.equals(configuredAaaServerAddress)) {
                  getConfiguredAaaServerAddress();
@@ -370,7 +396,7 @@
         }
         EAP eapPayload;
         Ethernet eth;
-        checkReceivedPacketForValidValidator(radiusPacket);
+        checkReceivedPacketForValidValidator(radiusPacket, stateMachine.requestAuthenticator());
         if (outPacketSet.contains(radiusPacket.getIdentifier())) {
             aaaStatisticsManager.getAaaStats().increaseOrDecreasePendingRequests(false);
             outPacketSet.remove(new Byte(radiusPacket.getIdentifier()));