0

I am implementing a radius proxy with a help of TinyRadius lib. PAP & CHAP proxying without any problems but EAP messages not. So, i am recalculate Request Authenticator for radius packet after adding a proxy attribute, then i recalculate Message-Authenticator according to RFC3579.

And there is two question:

According to RFC3579: Message-Authenticator = HMAC-MD5 (Type, Identifier, Length, Request Authenticator, Attributes)

1) Length=? Is it a length of radius packet or EAP-message?

2) Request Authenticator - this is authenticator for radius packet, am i right? So, if i add it to the Message-Authenticator attribute into the radius packet - radius packet will be changed and i must to recalculate Request Authenticator but if i recalculate Request Authenticator - Message-Authenticator will be invalid because it depends on Request Authenticator.

Shared secrets for clients and endpoint radius server is the same (checked many times).

All i need - is to teach proxy to proxying EAP messages, but always get:

Received Access-Request Id 191 from 192.168.200.250:1814 to 192.168.200.250:10000 length 171
Dropping packet without response because of error: Received packet from 192.168.200.250 with invalid Message-Authenticator!  (Shared secret is incorrect.)

UPDATE:

Request-Authentificator generating:

protected byte[] createRequestAuthenticator(String sharedSecret){
        MessageDigest md5=getMd5Digest();
        md5.reset();
        byte[] requestAuthenticator=new byte[16];
        Random r=new Random();
        for(int i=0;i<16;i++){
            requestAuthenticator[i]=(byte)r.nextInt();
        }
        md5.update(sharedSecret.getBytes(),0,sharedSecret.length());
        md5.update(requestAuthenticator,0,requestAuthenticator.length);
        return md5.digest();         
    }

Message-Authenticator generating:

protected byte[] createRFC3579MessageAuthenticator(String sharedSecret,int packetLength,byte[] requestAuthenticator,byte[] attributes){        
        try{
            Mac mac=Mac.getInstance("HmacMD5");
            mac.init(new SecretKeySpec(sharedSecret.getBytes(),"HmacMD5"));
            mac.update((byte)getPacketType());
            mac.update((byte)getPacketIdentifier());
            mac.update((byte)(packetLength>>8));
            mac.update((byte)(packetLength&0x0ff));
            mac.update(requestAuthenticator,0,requestAuthenticator.length);
            mac.update(attributes,0,attributes.length);
            return mac.doFinal();
        }catch(NoSuchAlgorithmException|InvalidKeyException ex){
            Logger.getLogger(RadiusPacket.class.getName()).log(Level.SEVERE,null,ex);
            return null;
        }
    }
user124
  • 13
  • 5

1 Answers1

0

1) Length is the length of the RADIUS packet which contains one or more EAP-Message attributes if you're performing EAP.

2) No - The request authenticator is a random 16 bit challenge in the RADIUS packet header that's used for duplicate detection and as part of a hashing scheme for attributes like CHAP. It should only change if you're generating a new packet, not when you're retransmitting an existing one.

Message-Authenticator is an attribute in the Access-Request itself. The Message-Authenticator contains a HMAC of the RADIUS packet keyed off the shared secret.

Causes of the Message-Authenticator being incorrect are:

  • Shared secret mismatch.
  • Bad implementation of the Message-Authenticator HMAC.
  • Packet being modified in flight between RADIUS client and server.

And then FreeRADIUS specific issues:

  • Wrong client entry being used due to incorrect IP scoping.
  • Shared secret being incorrect due to bad home server configuration.

Note: If you're using FreeRADIUS then you shouldn't generate the Message-Authenticator yourself. You just need to set Message-Authenticator = 0x00 in the upstream request and FreeRADIUS will fill in the value automatically.

If you want to generate you own Message-Authenticator values, that's described by RFC 2869 section #5.14.

For Access-Requests:

Message-Authenticator = HMAC-MD5 (Type, 
                                  Identifier,
                                  Length,
                                  Request Authenticator,
                                  Attributes)

Where attributes includes a placeholder Message-Authenticator attribute of all zeros .i.e 0x4f1200000000000000000000000000000000. This may be what you forgot to include if you're seeing Message-Authenticator validation issues.

The key of the HMAC is the shared secret.

You'll need to generate your random Request-Authenticator value first before calculating the HMAC.

For response packets (Access-Accept, Access-Reject, Access-Challenge) the Message-Authenticator is calculated using the Request Authenticator from the Access-Request.

The Response-Authenticator is calculated after the Message-Authenticator has been generated and written to the placeholder bytes in the outgoing packet. So the Response-Authenticator is over the entire packet, including the Message-Authenticator.

Arran Cudbard-Bell
  • 5,912
  • 2
  • 26
  • 48
  • Yes, i am generating a new packet because i add a proxy attribute to a packet, so, i generate a new packet, packaging all attributes from client's packet+proxy attribute and recalculate request authentificator. Then i need to recalculate message-authenticator and place it into Message-Authenticator attribute, am i right? But Message-Authenticator depends on request-authenticator, this is the separate request-authenticator or request-authenticator of the radius packet? And how can i calculate request-authenticator if after that i change the packet by placing a Message-Authenticator into it? – user124 Oct 04 '19 at 15:38
  • You don't calculate the Request-Authenticator, it's a random value. FreeRADIUS will generate a new Message-Authenticator attribute value automatically when you proxy. – Arran Cudbard-Bell Oct 05 '19 at 01:28
  • RFC 2865 section 3 "In Access-Request Packets, the Authenticator value is a 16 octet random number, called the Request Authenticator." You don't calculate it, you generate it, it's a random value. – Arran Cudbard-Bell Oct 05 '19 at 01:31
  • freeRADIUS works as endpoint radius server, proxy - it's my application created with a help of TinyRadius API. Calculated - i mean do md5 of shared_secret+random_bytes. But, if client send yo my proxy an EAP request, i must calculate message-authenticator also and there, were a questions about it. – user124 Oct 05 '19 at 01:38
  • Add to question how i generate authenticators. Any suggestions? – user124 Oct 05 '19 at 12:45
  • Added text to the answer – Arran Cudbard-Bell Oct 05 '19 at 18:34
  • To tell the truth, don't understand what does a placeholder mean? I must add to attribute Message-Authenticator (from received packet) 16 zeros before calculating an new Message-Authenticator? – user124 Oct 05 '19 at 19:37
  • I got a packet from client--> decode it --> add proxy state attribute --> generate new Request-Authenticator --> calculate new Message-Authenticator --> add it to Message-Authenticator attribute -->make new radius packet --> send. Am i right? – user124 Oct 05 '19 at 19:45
  • Yes pretty much. If the request you're forwarding contains a Message-Authenticator attribute, after validating the Message-Authenticator, set the Message-Authenticator value to zeros and calculate a new one. If the request you're forwarding does not contain a Message-Authenticator attribute, add one to the forwarded request in the format I gave in the answer, the calculate the new HMAC and write it to the Message-Authenticator attribute. – Arran Cudbard-Bell Oct 05 '19 at 19:50
  • Can i connect you, maybe through an e-mail? – user124 Oct 05 '19 at 19:50
  • Placeholder in this context means put something in the packet where the calculated hmac will be. – Arran Cudbard-Bell Oct 05 '19 at 19:50
  • Sure, my email is pretty easy to find on the internet :) – Arran Cudbard-Bell Oct 05 '19 at 19:51
  • For the code you've posted above, there's no reason to call the MD5 function in "createRequestAuthenticator" in fact you may leak information about the shared secret. It really is 16 random octets, not 16 random octets hashed with something. – Arran Cudbard-Bell Oct 05 '19 at 19:54
  • createRFC3579MessageAuthenticator looks fine, provided the attribute list is correct and contains a zeroed out Message-Authenticator attribute. – Arran Cudbard-Bell Oct 05 '19 at 19:56