⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eap_archie_fsm.cxx

📁 Diameter协议栈
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/* BEGIN_COPYRIGHT                                                        *//*                                                                        *//* Open Diameter: Open-source software for the Diameter and               *//*                Diameter related protocols                              *//*                                                                        *//* Copyright (C) 2002-2004 Open Diameter Project                          *//*                                                                        *//* This library is free software; you can redistribute it and/or modify   *//* it under the terms of the GNU Lesser General Public License as         *//* published by the Free Software Foundation; either version 2.1 of the   *//* License, or (at your option) any later version.                        *//*                                                                        *//* This library is distributed in the hope that it will be useful,        *//* but WITHOUT ANY WARRANTY; without even the implied warranty of         *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *//* Lesser General Public License for more details.                        *//*                                                                        *//* You should have received a copy of the GNU Lesser General Public       *//* License along with this library; if not, write to the Free Software    *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307    *//* USA.                                                                   *//*                                                                        *//* In addition, when you copy and redistribute some or the entire part of *//* the source code of this software with or without modification, you     *//* MUST include this copyright notice in each copy.                       *//*                                                                        *//* If you make any changes that are appeared to be useful, please send    *//* sources that include the changed part to                               *//* diameter-developers@lists.sourceforge.net so that we can reflect your  *//* changes to one unified version of this software.                       *//*                                                                        *//* END_COPYRIGHT                                                          */// $Id: eap_archie_fsm.cxx,v 1.15 2004/06/17 21:13:34 yohba Exp $// EAP-Archie state machines.// Written by Yoshihiro Ohba (yohba@tari.toshiba.com)#include "eap_archie_fsm.hxx"#include "eap_archie_parser.hxx"#include "eap_archie_crypto.hxx"#include <openssl/rand.h>/// Action class.class EapPeerArchieAction : public AAA_Action<EapPeerArchieStateMachine>{ public:  virtual void operator()(EapPeerArchieStateMachine&) {} protected:  EapPeerArchieAction() {}  virtual ~EapPeerArchieAction() {}};/// Action class.class EapAuthArchieAction : public AAA_Action<EapAuthArchieStateMachine>{ public:  virtual void operator()(EapAuthArchieStateMachine&) {} protected:  EapAuthArchieAction() {}  virtual ~EapAuthArchieAction() {}};/// State table used by EapPeerArchieStateMachine.class EAP_ARCHIE_EXPORTS EapPeerArchieStateTable_S :   public AAA_StateTable<EapPeerArchieStateMachine>{  friend class ACE_Singleton<EapPeerArchieStateTable_S, 			     ACE_Recursive_Thread_Mutex>;private:  /// defined as a leaf class  class AcDoIntegrityCheckForRequestMsg : public EapPeerArchieAction  {    void operator()(EapPeerArchieStateMachine &msm)    {      EapPeerSwitchStateMachine &ssm = msm.PeerSwitchStateMachine();      AAAMessageBlock *msg = ssm.GetRxMessage();      EAP_LOG(LM_DEBUG, "PeerArchie: Integrity check on request message.\n");      // Check the Arhice-Request.      EapRequestArchieRequest request;      EapRequestArchieRequestParser parser;      parser.setAppData(&request);      parser.setRawData(msg);      try { parser.parseRawToApp(); }      catch (...) {	    EAP_LOG(LM_ERROR, "PeerArchie: Parse error.\n");	    msm.Event(EvSgInvalid);	    return;	  }      // Input shared secret.      std::string& sharedSecret = msm.SharedSecret() = msm.InputSharedSecret();      // Check if the shared secret validity.      if (sharedSecret.size() != 64)	{	  EAP_LOG(LM_ERROR, "PeerArchie: Invalid shared secret length.\n");	  msm.Event(EvSgInvalid);	  return;	}      msm.AuthID()  = request.AuthID();      msm.SessionID()  = request.SessionID();      // Retain the message.      msm.History().append(msg->base() + 4, 4 + 256);  // exclude SessionID      msm.Event(EvSgValid);    }  };  class AcBuildResponse : public EapPeerArchieAction  {    void operator()(EapPeerArchieStateMachine &msm)    {      EapPeerSwitchStateMachine &ssm = msm.PeerSwitchStateMachine();      EAP_LOG(LM_DEBUG, "PeerArchie: Building a response message.\n");      AAAMessageBlock *msg = 	    AAAMessageBlock::Acquire(8 + 32 + 256 + 40 + 516 + 12);      ACE_OS::memset(msg->base(), 0, 8 + 32 + 256 + 40 + 516 + 12);      EapResponseArchieResponse response;      response.SessionID() = msm.SessionID();      response.PeerID() = msm.PeerID() = msm.InputIdentity();      // Compute nonceP.      unsigned char nonceP[40];      if (RAND_bytes(nonceP, 40) == 0)	  {	    EAP_LOG(LM_ERROR, 		  "AuthArchieStateTable: Failed to generate NonceP.\n");	    return;	  }      response.NonceP() = msm.NonceP() 	    = std::string((char*)nonceP, sizeof(nonceP));      // Calculate Binding.  At this time, binding field is just a      // place holder and never used.      response.Binding() = msm.Binding();      EapResponseArchieResponseParser parser;      parser.setAppData(&response);      parser.setRawData(msg);      try { parser.parseAppToRaw(); }      catch (...) {	    EAP_LOG(LM_ERROR, "PeerArchie: Parse error.\n");	    msm.Event(EvSgInvalid);	    return;	  }      // Update the history.      msm.History().append(msg->base() + 4, 4+32+256+40+516);      // Obtain shared secret from the application.      std::string& sharedSecret = msm.SharedSecret();      EapCryptoAES_CBC_MAC macCalculator;      // Obtain Key Confirmation Key from the shared secret.      std::string KCK(sharedSecret.data(), 16);      // Calculate MAC1.      macCalculator(msm.History(), response.Mac1(), KCK, 		    EapCryptoAES_CBC_MAC::MAC_Length96);            // Rewind the pointer.      msg->wr_ptr(msg->base() + 4);      // Parse the message again to write the calculated MAC.      try { parser.parseAppToRaw(); }      catch (...) {	    EAP_LOG(LM_ERROR, "PeerArchie: Parse error.\n");	    msm.Event(EvSgInvalid);	    return;	  }      // Set the message to the session.      ssm.SetTxMessage(msg);            // Update external method state.      ssm.MethodState() = EapPeerSwitchStateMachine::CONT;      // Send a "valid" signal to the switch state machine.      ssm.Event(EapPeerSwitchStateMachine::EvSgValidReq);    }  };  class AcDoIntegrityCheckForConfirmMsg : public EapPeerArchieAction  {    void operator()(EapPeerArchieStateMachine &msm)    {      EapPeerSwitchStateMachine &ssm = msm.PeerSwitchStateMachine();      AAAMessageBlock *msg = ssm.GetRxMessage();      EAP_LOG(LM_DEBUG, "PeerArchie: Identity checking on confirm message.\n");      // Check the Arhice-Confirm.      EapRequestArchieConfirm confirm;      EapRequestArchieConfirmParser parser;      parser.setAppData(&confirm);      parser.setRawData(msg);      try { parser.parseRawToApp(); }      catch (...) {	    EAP_LOG(LM_ERROR, "PeerArchie: Parse error.\n");	    msm.Event(EvSgInvalid);	    return;	  }      // Check session id.      if (confirm.SessionID() != msm.SessionID())	  {	    EAP_LOG(LM_ERROR, "PeerArchie: Session ID mismatch.");	    msm.Event(EvSgInvalid);	    return;	  }      // Obtain shared secret from the application.      std::string& sharedSecret = msm.SharedSecret();      // Obtain Key Confirmation Key from the shared secret.      std::string KCK(sharedSecret.data(), 16);      // Obtain history of received message and construct MAC input.      std::string input = msm.History();      input.append(msg->base() + 4, 4+32+40+516);      std::string mac2;      // Compute MAC2 and do validity check.      EapCryptoAES_CBC_MAC macCalculator;      macCalculator(input, mac2, KCK, EapCryptoAES_CBC_MAC::MAC_Length96);      if (mac2 != confirm.Mac2())	{	  EAP_LOG(LM_ERROR, "PeerArchie: Invalid MAC2.\n");	  msm.Event(EvSgInvalid);	  return;	}      // If validity check is successful, store the received fields      // and update the history data.      msm.NonceA()  = confirm.NonceA();      msm.Binding()  = confirm.Binding();      msm.History() = input;      // Continue to the next step.      msm.Event(EvSgValid);    }  };  class AcNotifySuccess : public EapPeerArchieAction  {    void operator()(EapPeerArchieStateMachine &msm)    {      // prepare the Response/Archie-Finish      EapPeerSwitchStateMachine &ssm = msm.PeerSwitchStateMachine();      EapResponseArchieFinish finish;      finish.SessionID() = msm.SessionID();      finish.Mac3() = std::string(12, ' ');      AAAMessageBlock *msg = AAAMessageBlock::Acquire(8 + 32 + 12);          ACE_OS::memset(msg->base(), 0, 8 + 32 + 12);      EapResponseArchieFinishParser parser;      parser.setAppData(&finish);      parser.setRawData(msg);      try { parser.parseAppToRaw(); }      catch (...) {	    EAP_LOG(LM_ERROR, "PeerArchie: Parse error.\n");	    msm.Event(EvSgInvalid);	    return;	  }      // Calculate MAC3.      // Obtain shared secret from the application.      std::string& sharedSecret = msm.SharedSecret();      EapCryptoAES_CBC_MAC macCalculator;      // Obtain Key Confirmation Key from the shared secret.      std::string KCK(sharedSecret.data(), 16);      std::string input(msg->base()+4, 4+32);      macCalculator(input, finish.Mac3(), KCK, 		    EapCryptoAES_CBC_MAC::MAC_Length96);            // Rewind the pointer.      msg->wr_ptr(msg->base() + 4);      // Write the message again.      try { parser.parseAppToRaw(); }	  catch (...) {	    EAP_LOG(LM_ERROR, "PeerArchie: Parse error.\n");	    msm.Event(EvSgInvalid);	    return;	  }      // Set the message to the session.      ssm.SetTxMessage(msg);          ssm.Decision() = EapPeerSwitchStateMachine::UNCOND_SUCC;      EAP_LOG(LM_DEBUG, "PeerArchie: Archie-Finish prepared.\n");      // Update external method state.      ssm.MethodState() = EapPeerSwitchStateMachine::DONE;      msm.KeyData() = msm.MK();      ssm.Event(EapPeerSwitchStateMachine::EvSgValidReq);    }  };  class AcNotifyInvalid : public EapPeerArchieAction  {    void operator()(EapPeerArchieStateMachine &msm)    {      EapPeerSwitchStateMachine &ssm = msm.PeerSwitchStateMachine();      ssm.Event(EapPeerSwitchStateMachine::EvSgInvalidReq);    }  };  enum {    EvSgValid,    EvSgInvalid,  };  enum state {    StInitialize,     StProcessRequest,     StResponseSent,     StProcessConfirm,     StSuccess  };  AcDoIntegrityCheckForRequestMsg acDoIntegrityCheckForRequestMsg;  AcDoIntegrityCheckForConfirmMsg acDoIntegrityCheckForConfirmMsg;  AcBuildResponse acBuildResponse;  AcNotifySuccess acNotifySuccess;  AcNotifyInvalid acNotifyInvalid;  EapPeerArchieStateTable_S()   {    AddStateTableEntry(StInitialize, 		       EapMethodStateMachine::EvSgIntegrityCheck, 		       StProcessRequest, acDoIntegrityCheckForRequestMsg);    AddWildcardStateTableEntry(StInitialize, StInitialize);    AddStateTableEntry(StProcessRequest, EvSgInvalid,		       StInitialize, acNotifyInvalid);    AddStateTableEntry(StProcessRequest, EvSgValid, 		       StResponseSent, acBuildResponse);    AddStateTableEntry(StResponseSent, 		       EapMethodStateMachine::EvSgIntegrityCheck, 		       StProcessConfirm, acDoIntegrityCheckForConfirmMsg);    AddWildcardStateTableEntry(StResponseSent, StResponseSent);    AddStateTableEntry(StProcessConfirm, EvSgInvalid,		       StResponseSent, acNotifyInvalid);    AddStateTableEntry(StProcessConfirm, EvSgValid, 		       StSuccess, acNotifySuccess);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -