- MMS: fixed problem in handling of indefinite length encoded BER elements

pull/246/head
Michael Zillgith 5 years ago
parent cf7dbcc612
commit de6886c6f3

@ -24,6 +24,40 @@
#include "libiec61850_platform_includes.h"
#include "ber_decode.h"
static int
getIndefiniteLength(uint8_t* buffer, int bufPos, int maxBufPos)
{
int length = 0;
while (bufPos < maxBufPos) {
if ((buffer[bufPos] == 0) && (buffer[bufPos+1] == 0)) {
return length + 2;
}
else {
length++;
if ((buffer[bufPos++] & 0x1f) == 0x1f) {
/* handle extended tags */
bufPos++;
length++;
}
int subLength = -1;
int newBufPos = BerDecoder_decodeLength(buffer, &subLength, bufPos, maxBufPos);
if (newBufPos == -1)
return -1;
length += subLength + newBufPos - bufPos;
bufPos = newBufPos + subLength;
}
}
return -1;
}
int
BerDecoder_decodeLength(uint8_t* buffer, int* length, int bufPos, int maxBufPos)
{
@ -36,7 +70,7 @@ BerDecoder_decodeLength(uint8_t* buffer, int* length, int bufPos, int maxBufPos)
int lenLength = len1 & 0x7f;
if (lenLength == 0) { /* indefinite length form */
*length = -1;
*length = getIndefiniteLength(buffer, bufPos, maxBufPos);
}
else {
*length = 0;

@ -230,6 +230,9 @@ parseAarePdu(AcseConnection* self, uint8_t* buffer, int bufPos, int maxBufPos)
}
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default: /* ignore unknown tag */
if (DEBUG_ACSE)
printf("ACSE: parseAarePdu: unknown tag %02x\n", tag);
@ -363,6 +366,9 @@ parseAarqPdu(AcseConnection* self, uint8_t* buffer, int bufPos, int maxBufPos)
}
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default: /* ignore unknown tag */
if (DEBUG_ACSE)
printf("ACSE: parseAarqPdu: unknown tag %02x\n", tag);
@ -454,6 +460,8 @@ AcseConnection_parseMessage(AcseConnection* self, ByteBuffer* message)
case 0x64: /* A_ABORT */
indication = ACSE_ABORT;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
if (DEBUG_ACSE)
printf("ACSE: Unknown ACSE message\n");

@ -553,6 +553,8 @@ parseServiceError(uint8_t* buffer, int bufPos, int maxLength, MmsServiceError* e
case 0xa3: /* serviceSpecificInfo */
bufPos += length; /* ignore */
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
bufPos += length; /* ignore */
break;
@ -605,6 +607,8 @@ mmsMsg_parseConfirmedErrorPDU(uint8_t* buffer, int bufPos, int maxBufPos, uint32
if (bufPos < 0)
goto exit_error;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
bufPos += length; /* ignore */
break;
@ -673,7 +677,7 @@ exit_error:
return -1;
}
static void
void
handleAsyncResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, MmsOutstandingCall outstandingCall, MmsError err)
{

@ -114,6 +114,9 @@ mmsClient_handleFileOpenRequest(
bufPos += length;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default: /* unrecognized parameter */
bufPos += length;
goto exit_reject_invalid_pdu;
@ -470,6 +473,8 @@ parseFileAttributes(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* fileSi
}
}
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
return false;
}
@ -523,6 +528,8 @@ parseDirectoryEntry(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t invokeI
return false;
bufPos += length;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
bufPos += length;
if (DEBUG_MMS_CLIENT)
@ -568,6 +575,8 @@ parseListOfDirectoryEntries(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t
parseDirectoryEntry(buffer, bufPos, bufPos + length, invokeId, handler, parameter);
bufPos += length;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
bufPos += length;
if (DEBUG_MMS_CLIENT)
@ -626,6 +635,8 @@ mmsClient_parseFileDirectoryResponse(ByteBuffer* response, int bufPos, uint32_t
moreFollows = BerDecoder_decodeBoolean(buffer, bufPos);
bufPos += length;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
bufPos += length;
if (DEBUG_MMS_CLIENT)
@ -684,6 +695,8 @@ mmsMsg_parseFileOpenResponse(uint8_t* buffer, int bufPos, int maxBufPos, int32_t
return false;
bufPos += length;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
bufPos += length;
if (DEBUG_MMS_CLIENT)
@ -748,6 +761,9 @@ mmsMsg_parseFileReadResponse(uint8_t* buffer, int bufPos, int maxBufPos, uint32_
bufPos += length;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
bufPos += length;
if (DEBUG_MMS_CLIENT)

@ -96,6 +96,8 @@ mmsClient_parseIdentifyResponse(MmsConnection self, ByteBuffer* response, uint32
case 0x83: /* list of abstract syntaxes */
bufPos += length;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default: /* ignore unknown tags */
bufPos += length;
break;

@ -149,6 +149,9 @@ parseInitResponseDetail(MmsConnection self, uint8_t* buffer, int bufPos, int max
}
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
break;
}
@ -221,6 +224,9 @@ mmsClient_parseInitiateResponse(MmsConnection self, ByteBuffer* response)
}
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
break; /* Ignore unknown tags */
}

@ -72,6 +72,9 @@ parseJournalVariable(uint8_t* buffer, int bufPos, int maxLength, MmsJournalVaria
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
break;
@ -115,6 +118,9 @@ parseJournalVariables(uint8_t* buffer, int bufPos, int maxLength, MmsJournalEntr
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
break;
}
@ -152,6 +158,9 @@ parseData(uint8_t* buffer, int bufPos, int maxLength, MmsJournalEntry journalEnt
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
break;
@ -200,6 +209,9 @@ parseEntryContent(uint8_t* buffer, int bufPos, int maxLength, MmsJournalEntry jo
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: parseReadJournalResponse: ignore unknown tag %02x\n", tag);
@ -250,6 +262,9 @@ parseJournalEntry(uint8_t* buffer, int bufPos, int maxLength, LinkedList journal
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: parseReadJournalResponse: unknown tag %02x\n", tag);
@ -288,6 +303,9 @@ parseListOfJournalEntries(uint8_t* buffer, int bufPos, int maxLength, LinkedList
return false;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: parseReadJournalResponse: unknown tag %02x\n", tag);
@ -353,6 +371,9 @@ mmsClient_parseReadJournalResponse(MmsConnection self, ByteBuffer* response, int
*moreFollows = BerDecoder_decodeBoolean(buffer, bufPos);
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: mmsClient_parseReadJournalResponse: message contains unknown tag %02x!\n", tag);

@ -95,6 +95,8 @@ mmsClient_parseStatusResponse(MmsConnection self, ByteBuffer* response, int bufP
case 0x82: /* localDetail */
bufPos += length;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
return false;
}

@ -135,6 +135,8 @@ getNumberOfElements(uint8_t* buffer, int bufPos, int elementLength)
break;
case 0x91: /* Utctime */
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
goto exit_with_error;
}
@ -304,6 +306,9 @@ MmsValue_decodeMmsData(uint8_t* buffer, int bufPos, int bufferLength, int* endBu
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default: /* unknown tag -> decoding error */
goto exit_with_error;
}

@ -308,6 +308,9 @@ parseInitiateRequestPdu(MmsServerConnection self, uint8_t* buffer, int bufPos, i
/* we ignore this */
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
break; /* Ignore unknown tags */
}

@ -333,6 +333,9 @@ mmsServer_handleFileOpenRequest(
bufPos += length;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default: /* unrecognized parameter */
bufPos += length;
goto exit_reject_invalid_pdu;
@ -672,6 +675,9 @@ mmsServer_handleObtainFileRequest(
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default: /* unrecognized parameter */
bufPos += length;
goto exit_reject_invalid_pdu;
@ -1095,6 +1101,8 @@ mmsServer_handleFileRenameRequest(
if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: newFileName: (%s)\n", newFileName);
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default: /* ignore unknown tag */
if (DEBUG_MMS_SERVER)
@ -1181,6 +1189,9 @@ mmsServer_handleFileDirectoryRequest(
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default: /* unrecognized parameter */
if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: handleFileDirectoryRequest: unrecognized parameter\n");

@ -486,6 +486,8 @@ mmsServer_handleGetNameListRequest(
case 0x82: /* association-specific */
objectScope = OBJECT_SCOPE_ASSOCIATION;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_MODIFIER, response);
return;
@ -497,6 +499,10 @@ mmsServer_handleGetNameListRequest(
continueAfter = (char*) (buffer + bufPos);
continueAfterLength = length;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
/* ignore unknown tag */
break;

@ -387,6 +387,9 @@ handleConfirmedRequestPdu(
break;
#endif /* (MMS_GET_DATA_SET_ATTRIBUTES == 1) */
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response);
return;
@ -682,6 +685,9 @@ MmsServerConnection_parseMessage(MmsServerConnection self, ByteBuffer* message,
printf("MMS_SERVER: received reject PDU!\n");
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
mmsMsg_createMmsRejectPdu(NULL, MMS_ERROR_REJECT_UNKNOWN_PDU_TYPE, response);
break;

@ -245,6 +245,10 @@ parseFullyEncodedData(IsoPresentation* self, uint8_t* buffer, int len, int bufPo
bufPos += length;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
if (DEBUG_PRES)
printf("PRES: fed: unknown tag %02x\n", tag);
@ -289,6 +293,7 @@ parsePCDLEntry(IsoPresentation* self, uint8_t* buffer, int totalLength, int bufP
contextId = BerDecoder_decodeUint32(buffer, len, bufPos);
bufPos += len;
break;
case 0x06: /* abstract-syntax-name */
if (DEBUG_PRES)
printf("PRES: abstract-syntax-name with len %i\n", len);
@ -305,12 +310,17 @@ parsePCDLEntry(IsoPresentation* self, uint8_t* buffer, int totalLength, int bufP
bufPos += len;
break;
case 0x30: /* transfer-syntax-name */
if (DEBUG_PRES)
printf("PRES: ignore transfer-syntax-name\n");
bufPos += len;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
if (DEBUG_PRES)
printf("PRES: unknown tag in presentation-context-definition-list-entry\n");
@ -367,6 +377,8 @@ parsePresentationContextDefinitionList(IsoPresentation* self, uint8_t* buffer, i
if (bufPos < 0)
return -1;
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
if (DEBUG_PRES)
printf("PRES: unknown tag in presentation-context-definition-list\n");
@ -436,6 +448,7 @@ parseNormalModeParameters(IsoPresentation* self, uint8_t* buffer, int totalLengt
printf("PRES: pcd list\n");
bufPos = parsePresentationContextDefinitionList(self, buffer, len, bufPos);
break;
case 0x61: /* user data */
if (DEBUG_PRES)
printf("PRES: user-data\n");
@ -447,6 +460,9 @@ parseNormalModeParameters(IsoPresentation* self, uint8_t* buffer, int totalLengt
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
if (DEBUG_PRES)
printf("PRES: unknown tag in normal-mode\n");
@ -508,6 +524,8 @@ IsoPresentation_parseAcceptMessage(IsoPresentation* self, ByteBuffer* byteBuffer
return 0;
}
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default:
if (DEBUG_PRES)
@ -634,6 +652,8 @@ IsoPresentation_parseUserData(IsoPresentation* self, ByteBuffer* readBuffer)
int userDataLength;
uint8_t lengthByte = buffer[bufPos];
bufPos = BerDecoder_decodeLength(buffer, &userDataLength, bufPos, length);
if (bufPos < 0) {
@ -642,6 +662,11 @@ IsoPresentation_parseUserData(IsoPresentation* self, ByteBuffer* readBuffer)
return 0;
}
if (lengthByte == 0x80) {
/* remove end element from user data length when indefinite length encoded */
userDataLength = userDataLength - 2;
}
ByteBuffer_wrap(&(self->nextPayload), buffer + bufPos, userDataLength, userDataLength);
return 1;
@ -721,6 +746,8 @@ IsoPresentation_parseConnect(IsoPresentation* self, ByteBuffer* byteBuffer)
return 0;
}
break;
case 0x00: /* indefinite length end tag -> ignore */
break;
default: /* unsupported element */
if (DEBUG_PRES)

Loading…
Cancel
Save