00001 /* BEGIN_COPYRIGHT */ 00002 /* */ 00003 /* Open Diameter: Open-source software for the Diameter and */ 00004 /* Diameter related protocols */ 00005 /* */ 00006 /* Copyright (C) 2002-2004 Open Diameter Project */ 00007 /* */ 00008 /* This library is free software; you can redistribute it and/or modify */ 00009 /* it under the terms of the GNU Lesser General Public License as */ 00010 /* published by the Free Software Foundation; either version 2.1 of the */ 00011 /* License, or (at your option) any later version. */ 00012 /* */ 00013 /* This library is distributed in the hope that it will be useful, */ 00014 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 00015 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ 00016 /* Lesser General Public License for more details. */ 00017 /* */ 00018 /* You should have received a copy of the GNU Lesser General Public */ 00019 /* License along with this library; if not, write to the Free Software */ 00020 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ 00021 /* USA. */ 00022 /* */ 00023 /* In addition, when you copy and redistribute some or the entire part of */ 00024 /* the source code of this software with or without modification, you */ 00025 /* MUST include this copyright notice in each copy. */ 00026 /* */ 00027 /* If you make any changes that are appeared to be useful, please send */ 00028 /* sources that include the changed part to */ 00029 /* diameter-developers@lists.sourceforge.net so that we can reflect your */ 00030 /* changes to one unified version of this software. */ 00031 /* */ 00032 /* END_COPYRIGHT */ 00033 // $Id: eap_md5.hxx,v 1.13 2004/06/17 21:13:36 yohba Exp $ 00034 00035 // eap_identity.hxx: Identity method state machine 00036 // Written by Yoshihiro Ohba 00037 00038 #ifndef __EAP_MD5_HXX__ 00039 #define __EAP_MD5_HXX__ 00040 00041 #include <ace/Basic_Types.h> 00042 #include <openssl/md5.h> 00043 #include "eap.hxx" 00044 #include "eap_fsm.hxx" 00045 #include "eap_authfsm.hxx" 00046 #include "eap_peerfsm.hxx" 00047 00048 /* MD5-Challenge Request/Response description. 00049 00050 In section 5.4 of RFC2284bis: 00051 00052 "5.4 MD5-Challenge 00053 Description 00054 00055 The MD5-Challenge Type is analogous to the PPP CHAP protocol 00056 [RFC1994] (with MD5 as the specified algorithm). The Request 00057 contains a "challenge" message to the peer. A Response MUST be 00058 sent in reply to the Request. The Response MAY be either of Type 00059 4 (MD5-Challenge), Nak (Type 3) or Expanded Nak (Type 254). The 00060 Nak reply indicates the peer's desired authentication Type(s). 00061 EAP peer and EAP server implementations MUST support the 00062 MD5-Challenge mechanism. An authenticator that supports only 00063 pass-through MUST allow communication with a backend 00064 authentication server that is capable of supporting MD5-Challenge, 00065 although the EAP authenticator implementation need not support 00066 MD5-Challenge itself. However, if the EAP authenticator can be 00067 configured to authenticate peers locally (e.g., not operate in 00068 pass-through), then the requirement for support of the 00069 MD5-Challenge mechanism applies. 00070 00071 Note that the use of the Identifier field in the MD5-Challenge 00072 Type is different from that described in [RFC1994]. EAP allows 00073 for retransmission of MD5-Challenge Request packets while 00074 [RFC1994] states that both the Identifier and Challenge fields 00075 MUST change each time a Challenge (the CHAP equivalent of the 00076 MD5-Challenge Request packet) is sent. 00077 00078 Note: [RFC1994] treats the shared secret as an octet string, and 00079 does not specify how it is entered into the system (or if it is 00080 handled by the user at all). EAP MD5-Challenge implementations MAY 00081 support entering passphrases with non-ASCII characters. See 00082 Section 5 for instructions how the input should be processed and 00083 encoded into octets. 00084 00085 00086 Type 00087 00088 4 00089 00090 Type-Data 00091 00092 The contents of the Type-Data field is summarized below. For 00093 reference on the use of these fields see the PPP Challenge 00094 Handshake Authentication Protocol [RFC1994]. 00095 00096 0 1 2 3 00097 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 00098 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 00099 | Value-Size | Value ... 00100 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 00101 | Name ... 00102 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 00103 " 00104 00105 00106 In section 5 of RFC2284bis: 00107 00108 "EAP methods MAY support authentication based on shared secrets. If 00109 the shared secret is a passphrase entered by the user, 00110 implementations MAY support entering passphrases with non-ASCII 00111 characters. In this case, the input should be processed using an 00112 appropriate stringprep [RFC3454] profile, and encoded in octets using 00113 UTF-8 encoding [RFC2279]. A preliminary version of a possible 00114 stringprep profile is described in [SASLPREP]." 00115 00116 In section 2.3 of RFC1994: 00117 00118 "2.3. Design Requirements 00119 00120 The CHAP algorithm requires that the length of the secret MUST be at 00121 least 1 octet. The secret SHOULD be at least as large and 00122 unguessable as a well-chosen password. It is preferred that the 00123 secret be at least the length of the hash value for the hashing 00124 algorithm chosen (16 octets for MD5). This is to ensure a 00125 sufficiently large range for the secret to provide protection against 00126 exhaustive search attacks. 00127 00128 The one-way hash algorithm is chosen such that it is computationally 00129 infeasible to determine the secret from the known challenge and 00130 response values. 00131 00132 Each challenge value SHOULD be unique, since repetition of a 00133 challenge value in conjunction with the same secret would permit an 00134 attacker to reply with a previously intercepted response. Since it 00135 is expected that the same secret MAY be used to authenticate with 00136 servers in disparate geographic regions, the challenge SHOULD exhibit 00137 global and temporal uniqueness. 00138 00139 Each challenge value SHOULD also be unpredictable, least an attacker 00140 trick a peer into responding to a predicted future challenge, and 00141 then use the response to masquerade as that peer to an authenticator. 00142 00143 Although protocols such as CHAP are incapable of protecting against 00144 realtime active wiretapping attacks, generation of unique 00145 unpredictable challenges can protect against a wide range of active 00146 attacks. 00147 00148 A discussion of sources of uniqueness and probability of divergence 00149 is included in the Magic-Number Configuration Option [1]." 00150 00151 00152 In section 4 of RFC1994: 00153 00154 "4. Packet Format 00155 00156 Exactly one Challenge-Handshake Authentication Protocol packet is 00157 encapsulated in the Information field of a PPP Data Link Layer frame 00158 where the protocol field indicates type hex c223 (Challenge-Handshake 00159 Authentication Protocol). A summary of the CHAP packet format is 00160 shown below. The fields are transmitted from left to right. 00161 00162 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 00163 | Code | Identifier | Length | 00164 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 00165 | Data ... 00166 +-+-+-+-+ 00167 00168 Code 00169 00170 The Code field is one octet and identifies the type of CHAP 00171 packet. CHAP Codes are assigned as follows: 00172 00173 1 Challenge 00174 2 Response 00175 3 Success 00176 4 Failure 00177 00178 Identifier 00179 00180 The Identifier field is one octet and aids in matching challenges, 00181 responses and replies. 00182 00183 Length 00184 00185 The Length field is two octets and indicates the length of the 00186 CHAP packet including the Code, Identifier, Length and Data 00187 fields. Octets outside the range of the Length field should be 00188 treated as Data Link Layer padding and should be ignored on 00189 reception. 00190 00191 Data 00192 00193 The Data field is zero or more octets. The format of the Data 00194 field is determined by the Code field. 00195 00196 00197 4.1. Challenge and Response 00198 00199 Description 00200 00201 The Challenge packet is used to begin the Challenge-Handshake 00202 Authentication Protocol. The authenticator MUST transmit a CHAP 00203 packet with the Code field set to 1 (Challenge). Additional 00204 Challenge packets MUST be sent until a valid Response packet is 00205 received, or an optional retry counter expires. 00206 00207 A Challenge packet MAY also be transmitted at any time during the 00208 Network-Layer Protocol phase to ensure that the connection has not 00209 been altered. 00210 00211 The peer SHOULD expect Challenge packets during the Authentication 00212 phase and the Network-Layer Protocol phase. Whenever a Challenge 00213 packet is received, the peer MUST transmit a CHAP packet with the 00214 Code field set to 2 (Response). 00215 00216 Whenever a Response packet is received, the authenticator compares 00217 the Response Value with its own calculation of the expected value. 00218 Based on this comparison, the authenticator MUST send a Success or 00219 Failure packet (described below). 00220 00221 Implementation Notes: Because the Success might be lost, the 00222 authenticator MUST allow repeated Response packets during the 00223 Network-Layer Protocol phase after completing the 00224 Authentication phase. To prevent discovery of alternative 00225 Names and Secrets, any Response packets received having the 00226 current Challenge Identifier MUST return the same reply Code 00227 previously returned for that specific Challenge (the message 00228 portion MAY be different). Any Response packets received 00229 during any other phase MUST be silently discarded. 00230 00231 When the Failure is lost, and the authenticator terminates the 00232 link, the LCP Terminate-Request and Terminate-Ack provide an 00233 alternative indication that authentication failed. 00234 00235 00236 A summary of the Challenge and Response packet format is shown below. 00237 The fields are transmitted from left to right. 00238 00239 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 00240 | Code | Identifier | Length | 00241 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 00242 | Value-Size | Value ... 00243 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 00244 | Name ... 00245 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 00246 00247 Code 00248 00249 1 for Challenge; 00250 00251 2 for Response. 00252 00253 Identifier 00254 00255 The Identifier field is one octet. The Identifier field MUST be 00256 changed each time a Challenge is sent. 00257 00258 The Response Identifier MUST be copied from the Identifier field 00259 of the Challenge which caused the Response. 00260 00261 Value-Size 00262 00263 This field is one octet and indicates the length of the Value 00264 field. 00265 00266 Value 00267 00268 The Value field is one or more octets. The most significant octet 00269 is transmitted first. 00270 00271 The Challenge Value is a variable stream of octets. The 00272 importance of the uniqueness of the Challenge Value and its 00273 relationship to the secret is described above. The Challenge 00274 Value MUST be changed each time a Challenge is sent. The length 00275 of the Challenge Value depends upon the method used to generate 00276 the octets, and is independent of the hash algorithm used. 00277 00278 The Response Value is the one-way hash calculated over a stream of 00279 octets consisting of the Identifier, followed by (concatenated 00280 with) the "secret", followed by (concatenated with) the Challenge 00281 Value. The length of the Response Value depends upon the hash 00282 algorithm used (16 octets for MD5). 00283 00284 00285 Name 00286 00287 The Name field is one or more octets representing the 00288 identification of the system transmitting the packet. There are 00289 no limitations on the content of this field. For example, it MAY 00290 contain ASCII character strings or globally unique identifiers in 00291 ASN.1 syntax. The Name should not be NUL or CR/LF terminated. 00292 The size is determined from the Length field." 00293 00294 */ 00295 00297 class EAP_EXPORTS EapPeerMD5ChallengeStateMachine 00298 : public EapMethodStateMachine, 00299 public EapStateMachine<EapPeerMD5ChallengeStateMachine> 00300 { 00301 friend class EapMethodStateMachineCreator<EapPeerMD5ChallengeStateMachine>; 00302 friend class EapPeerMD5ChallengeStateTable_S; 00303 public: 00304 00306 void Start() throw(AAA_Error) 00307 { 00308 isDone = false; 00309 EapStateMachine<EapPeerMD5ChallengeStateMachine>::Start(); 00310 } 00311 00313 inline void Notify(AAA_Event ev) 00314 { 00315 EapStateMachine<EapPeerMD5ChallengeStateMachine>::Notify(ev); 00316 } 00317 00320 virtual void InputPassphrase()=0; 00321 00323 std::string& Passphrase() { return passphrase; } 00324 00326 std::string& Value() { return value; } 00327 00329 std::string& MyName() { return myName; } 00330 00332 std::string& PeerName() { return peerName; } 00333 00334 protected: 00335 EapPeerMD5ChallengeStateMachine(EapSwitchStateMachine &s); 00336 ~EapPeerMD5ChallengeStateMachine() {} 00337 00338 private: 00340 std::string passphrase; 00341 00343 std::string myName, peerName; 00344 00346 std::string value; 00347 }; 00348 00350 class EAP_EXPORTS EapAuthMD5ChallengeStateMachine 00351 : public EapMethodStateMachine, 00352 public EapStateMachine<EapAuthMD5ChallengeStateMachine> 00353 { 00354 friend class EapMethodStateMachineCreator<EapAuthMD5ChallengeStateMachine>; 00355 friend class EapAuthMD5ChallengeStateTable_S; 00356 public: 00357 00359 void Start() throw(AAA_Error) 00360 { 00361 EapStateMachine<EapAuthMD5ChallengeStateMachine>::Start(); 00362 } 00363 00365 inline void Notify(AAA_Event ev) 00366 { 00367 EapStateMachine<EapAuthMD5ChallengeStateMachine>::Notify(ev); 00368 } 00369 00370 void Receive(AAAMessageBlock *b) {} 00371 00374 virtual void InputPassphrase()=0; 00375 00377 std::string& Passphrase() { return passphrase; } 00378 00380 std::string& Value() { return value; } 00381 00383 // void Value(std::string& str) { value=str; } 00384 00386 std::string& MyName() { return myName; } 00387 00389 std::string& PeerName() { return peerName; } 00390 00391 protected: 00392 EapAuthMD5ChallengeStateMachine(EapSwitchStateMachine &s); 00393 ~EapAuthMD5ChallengeStateMachine() {} 00394 00395 private: 00397 std::string passphrase; 00398 00400 std::string myName, peerName; 00401 00403 std::string value; 00404 }; 00405 00406 #endif // __EAP_MD5_HXX__