Skip to content

Commit

Permalink
Quick Patch for CVE-2024-3596 to include Message-Authenticator in all…
Browse files Browse the repository at this point in the history
… responses
  • Loading branch information
pendula95 committed Oct 10, 2024
1 parent c5d4463 commit 309ea5b
Showing 1 changed file with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions src/main/java/org/tinyradius/packet/RadiusPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
Expand All @@ -28,6 +29,9 @@
import org.tinyradius.util.RadiusException;
import org.tinyradius.util.RadiusUtil;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

/**
* This class represents a Radius packet. Subclasses provide convenience methods
* for special packet types.
Expand Down Expand Up @@ -848,6 +852,21 @@ protected void encodePacket(OutputStream out, String sharedSecret, RadiusPacket
// (User-Password attribute needs the authenticator)
authenticator = createRequestAuthenticator(sharedSecret);
encodeRequestAttributes(sharedSecret);
} else {
//To mitigate CVE-2024-3596 we MUST add Message-Authenticator attribute to all responses
boolean exists = false;
for (Iterator i = this.attributes.iterator(); i.hasNext(); ) {
RadiusAttribute a = (RadiusAttribute) i.next();
//If already present in the packet we need to set it to sixteen octets of zero
if (a.getVendorId() == -1 && a.getAttributeType() == MESSAGE_AUTHENTICATOR) {
a.setAttributeData(new byte[16]);
exists = true;
break;
}
}
if (!exists) {
this.attributes.add(new RadiusAttribute(MESSAGE_AUTHENTICATOR, new byte[16]));
}
}

byte[] attributes = getAttributeBytes();
Expand All @@ -857,6 +876,18 @@ protected void encodePacket(OutputStream out, String sharedSecret, RadiusPacket

// response packet authenticator
if (request != null) {
try {
//calculate Message-Authenticator according to RFC2869
byte[] messageAuthenticator = createResponseMessageAuthenticator(sharedSecret, packetLength, attributes, request.getAuthenticator());
for (Iterator i = this.attributes.iterator(); i.hasNext();) {
RadiusAttribute a = (RadiusAttribute) i.next();
if (a.getVendorId() == -1 && a.getAttributeType() == MESSAGE_AUTHENTICATOR) {
a.setAttributeData(messageAuthenticator);
}
}
} catch (InvalidKeyException ex) {
new RuntimeException("failed to create message authenticator", ex);
}
// after encoding attributes, create authenticator
authenticator = createResponseAuthenticator(sharedSecret, packetLength, attributes, request.getAuthenticator());
}
Expand Down Expand Up @@ -948,6 +979,19 @@ protected byte[] createResponseAuthenticator(String sharedSecret, int packetLeng
return md5.digest();
}

protected byte[] createResponseMessageAuthenticator(String sharedSecret, int packetLength, byte[] attributes, byte[] requestAuthenticator) throws InvalidKeyException {
Mac hmacMd5 = getHmacMd5();
hmacMd5.reset();
hmacMd5.init(new SecretKeySpec(sharedSecret.getBytes(), hmacMd5.getAlgorithm()));
hmacMd5.update((byte) getPacketType());
hmacMd5.update((byte) getPacketIdentifier());
hmacMd5.update((byte) (packetLength >> 8));
hmacMd5.update((byte) (packetLength & 0x0ff));
hmacMd5.update(requestAuthenticator, 0, requestAuthenticator.length);
hmacMd5.update(attributes, 0, attributes.length);
return hmacMd5.doFinal();
}

/**
* Reads a Radius packet from the given input stream and
* creates an appropiate RadiusPacket descendant object.
Expand Down Expand Up @@ -1116,6 +1160,22 @@ protected MessageDigest getMd5Digest() {
return md5Digest;
}

/**
* Returns a MD5 digest.
*
* @return MessageDigest object
*/
protected Mac getHmacMd5() {
if (hmacMd5 == null)
try {
hmacMd5 = Mac.getInstance("HmacMD5");
}
catch (NoSuchAlgorithmException nsae) {
throw new RuntimeException("Hmac is not available", nsae);
}
return hmacMd5;
}

/**
* Encodes the attributes of this Radius packet to a byte array.
*
Expand Down Expand Up @@ -1153,6 +1213,11 @@ protected byte[] getAttributeBytes() throws IOException {
*/
private MessageDigest md5Digest = null;

/**
* hmacMd5 mac.
*/
private Mac hmacMd5 = null;

/**
* Authenticator for this Radius packet.
*/
Expand All @@ -1173,4 +1238,13 @@ protected byte[] getAttributeBytes() throws IOException {
*/
private static SecureRandom random = new SecureRandom();

/**
* Radius attribute type for MS-CHAP-Challenge attribute.
*/

/**
* Radius attribute type for Message-Authenticator attribute.
*/
private static final int MESSAGE_AUTHENTICATOR = 80;

}

0 comments on commit 309ea5b

Please sign in to comment.