00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "pana_sha1.h"
00035 #include "pana_security_assoc.h"
00036 #include "pana_exceptions.h"
00037 #include "pana_memory_manager.h"
00038
00039 #define PANA_SA_DEBUG 0
00040
00041 diameter_octetstring_t &PANA_MacKey::MacKey(diameter_octetstring_t &msk,
00042 ACE_UINT32 ISN_pac,
00043 ACE_UINT32 ISN_paa)
00044 {
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 PANA_Sha1 sha1;
00059 sha1.Update((unsigned char*)msk.data(), msk.size());
00060 sha1.Update((unsigned char*)&ISN_pac, sizeof(ISN_pac));
00061 sha1.Update((unsigned char*)&ISN_paa, sizeof(ISN_paa));
00062 sha1.Final();
00063
00064 char sbuf[PANA_MACGEN_HMACSIZE];
00065 ACE_OS::memset(sbuf, 0x0, sizeof(sbuf));
00066 sha1.GetHash((unsigned char*)sbuf);
00067
00068 m_MacKey.assign((char*)(sbuf), sizeof(sbuf));
00069
00070 #if PANA_SA_DEBUG
00071 printf("EAP key: %d\n", msk.size());
00072 for (int i=0; i<msk.size(); i++) {
00073 printf("%02X ", ((char*)msk.data())[i]);
00074 }
00075 printf("\n");
00076 #endif
00077
00078 return (m_MacKey);
00079 }
00080
00081 void PANA_SecurityAssociation::GenerateMacValue(AAAMessageBlock *panaPDU,
00082 diameter_octetstring_t &macValue)
00083 {
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 PANA_Sha1 sha1;
00098 sha1.Update((unsigned char*)m_MacKey.data(), m_MacKey.size());
00099 sha1.Update((unsigned char*)panaPDU->base(), panaPDU->length());
00100 sha1.Final();
00101
00102 char sbuf[PANA_MACGEN_HMACSIZE];
00103 ACE_OS::memset(sbuf, 0x0, sizeof(sbuf));
00104 sha1.GetHash((unsigned char*)sbuf);
00105 macValue.assign((char*)sbuf, sizeof(sbuf));
00106
00107 #if PANA_SA_DEBUG
00108 printf("Master key: %d\n", m_MacKey.size());
00109 for (int i=0; i<m_MacKey.size(); i++) {
00110 printf("%02X ", ((char*)m_MacKey.data())[i]);
00111 }
00112 printf("\n");
00113
00114 printf("PDU: %d\n", panaPDU->length());
00115 for (int i=0; i<panaPDU->length(); i++) {
00116 printf("%02X ", ((char*)panaPDU->base())[i]);
00117 }
00118 printf("\n");
00119
00120 printf("MAC Value: %d\n", macValue.size());
00121 for (int i=0; i<macValue.size(); i++) {
00122 printf("%02X ", ((char*)macValue.data())[i]);
00123 }
00124 printf("\n");
00125 #endif
00126 }
00127
00128 bool PANA_SecurityAssociation::AddMacValue(PANA_Message &msg)
00129 {
00130 AAAAvpContainerManager cm;
00131 AAAAvpContainerEntryManager em;
00132
00133 AAAAvpContainer *c_macAvp = cm.acquire("Mac-Avp");
00134 AAAAvpContainerEntry *e = em.acquire(AAA_AVPDataType(AAA_AVP_MAC_TYPE));
00135 PANA_TVData_t &macAvp = e->dataRef(Type2Type<PANA_TVData_t>());
00136 c_macAvp->add(e);
00137
00138 msg.avpList().add(c_macAvp);
00139
00140
00141 char sbuf[PANA_MACGEN_HMACSIZE];
00142 ACE_OS::memset(sbuf, 0x0, sizeof(sbuf));
00143 macAvp.value.assign(sbuf, sizeof(sbuf));
00144 macAvp.type = PANA_MACGEN_HMACSHA1;
00145
00146 PANA_MessageBuffer *rawBuf = PANA_MESSAGE_POOL()->malloc();
00147
00148 PANA_HeaderParser hp;
00149 AAADictionaryOption opt(PARSE_STRICT, PANA_DICT_PROTOCOL_ID);
00150 hp.setRawData(reinterpret_cast<AAAMessageBlock*>(rawBuf));
00151 hp.setAppData(static_cast<PANA_MsgHeader*>(&msg));
00152 hp.setDictData(&opt);
00153
00154 hp.parseAppToRaw();
00155
00156
00157 PANA_PayloadParser pp;
00158 pp.setRawData(reinterpret_cast<AAAMessageBlock*>(rawBuf));
00159 pp.setAppData(&(msg.avpList()));
00160 pp.setDictData(msg.getDictHandle());
00161
00162 pp.parseAppToRaw();
00163
00164
00165 msg.length(rawBuf->wr_ptr() - rawBuf->base());
00166 hp.parseAppToRaw();
00167
00168
00169 GenerateMacValue((AAAMessageBlock*)rawBuf, macAvp.value);
00170 PANA_MESSAGE_POOL()->free(rawBuf);
00171 msg.avpList().reset();
00172 return (true);
00173 }
00174
00175 bool PANA_SecurityAssociation::ValidateMacValue(PANA_Message &msg)
00176 {
00177 try {
00178 if (m_MSK.size() == 0) {
00179 throw (PANA_Exception(PANA_Exception::FAILED,
00180 "Warning: No MSK installed"));
00181 }
00182
00183 AAAAvpContainer* c_macAvp = msg.avpList().search("Mac-Avp");
00184 if (c_macAvp == 0) {
00185 throw (PANA_Exception(PANA_Exception::FAILED,
00186 "No MAC value found in the message"));
00187 }
00188 PANA_TVData_t &macAvp = (*c_macAvp)[0]->dataRef(Type2Type<PANA_TVData_t>());
00189
00190
00191 if (macAvp.type != PANA_MACGEN_HMACSHA1) {
00192 throw (PANA_Exception(PANA_Exception::FAILED,
00193 "Warning: MAC algorithm not supported"));
00194 }
00195
00196
00197 diameter_octetstring_t mvalue;
00198 mvalue.assign(macAvp.value.data(), macAvp.value.size());
00199
00200 #if PANA_SA_DEBUG
00201 printf("AVP Value: %d\n", mvalue.size());
00202 for (int i=0; i<mvalue.size(); i++) {
00203 printf("%02X ", ((char*)mvalue.data())[i]);
00204 }
00205 printf("\n");
00206 #endif
00207
00208
00209 char sbuf[PANA_MACGEN_HMACSIZE];
00210 ACE_OS::memset(sbuf, 0x0, sizeof(sbuf));
00211 macAvp.value.assign(sbuf, sizeof(sbuf));
00212 macAvp.type = PANA_MACGEN_HMACSHA1;
00213
00214 PANA_MessageBuffer *aBuffer = PANA_MESSAGE_POOL()->malloc();
00215 msg.avpList().reset();
00216
00217
00218 PANA_HeaderParser hp;
00219 AAADictionaryOption opt(PARSE_STRICT, PANA_DICT_PROTOCOL_ID);
00220 hp.setRawData(reinterpret_cast<AAAMessageBlock*>(aBuffer));
00221 hp.setAppData(static_cast<PANA_MsgHeader*>(&msg));
00222 hp.setDictData(&opt);
00223
00224 hp.parseAppToRaw();
00225
00226
00227 PANA_PayloadParser pp;
00228 pp.setRawData(reinterpret_cast<AAAMessageBlock*>(aBuffer));
00229 pp.setAppData(&(msg.avpList()));
00230 pp.setDictData(msg.getDictHandle());
00231
00232 pp.parseAppToRaw();
00233
00234
00235 msg.length(aBuffer->wr_ptr() - aBuffer->base());
00236 hp.parseAppToRaw();
00237
00238 GenerateMacValue((AAAMessageBlock*)aBuffer, macAvp.value);
00239
00240
00241 if (! (macAvp.value == mvalue)) {
00242 ACE_DEBUG((LM_ERROR, "(%P|%t) MAC value is invalid\n"));
00243 }
00244
00245 PANA_MESSAGE_POOL()->free(aBuffer);
00246 return (true);
00247 }
00248 catch (AAAErrorStatus st) {
00249 ACE_DEBUG((LM_ERROR, "(%P|%t) Parsing error is session transmitter\n"));
00250 }
00251 catch (PANA_Exception &e) {
00252 ACE_DEBUG((LM_ERROR, "(%P|%t) %s\n", e.description().data()));
00253 }
00254
00255 return (false);
00256 }