Exemple #1
0
void gseDecodePDU(unsigned char *buf) {
	unsigned char	tag = 0;
	CTYPE_INT16U	lengthFieldSize = 0;
	CTYPE_INT16U	lengthValue = 0;
	CTYPE_INT16U	offsetForSequence = 0;
	CTYPE_INT16U	offsetForNonSequence = 0;
	unsigned char	*gocbRef = NULL;
	CTYPE_INT16U	gocbRefLength = 0;
	CTYPE_INT32U	timeAllowedToLive = 0;
	CTYPE_TIMESTAMP	T = 0;
	CTYPE_INT32U	sqNum = 0;
	CTYPE_INT32U	stNum = 0;

	while (1) {
		tag = (unsigned char) buf[0];	// assumes only one byte is used
		lengthFieldSize = getLengthFieldSize((unsigned char) buf[1]);
		lengthValue = decodeLength((unsigned char *) &buf[1]);
		offsetForSequence = 1 + lengthFieldSize;
		offsetForNonSequence = 1 + lengthFieldSize + lengthValue;

		switch (tag) {
		case GSE_TAG_GOCBREF:
			// save pointer to gocbRef name
			gocbRef = &buf[offsetForSequence];
			gocbRefLength = lengthValue;

			buf = &buf[offsetForNonSequence];
			break;
		case GSE_TAG_TIME_ALLOWED_TO_LIVE:
			ber_decode_integer(&buf[offsetForSequence], lengthValue, &timeAllowedToLive, SV_GET_LENGTH_INT32U);
			buf = &buf[offsetForNonSequence];
			break;
		case ASN1_TAG_SEQUENCE:
			buf = &buf[offsetForSequence];
			break;
		case GSE_TAG_DATSET:
			buf = &buf[offsetForNonSequence];
			break;
		case GSE_TAG_T:
			memcpy(&T, &buf[offsetForSequence], BER_GET_LENGTH_CTYPE_TIMESTAMP(&T));
			buf = &buf[offsetForNonSequence];
			break;
		case GSE_TAG_STNUM:
			ber_decode_integer(&buf[offsetForSequence], lengthValue, &stNum, SV_GET_LENGTH_INT32U);
			buf = &buf[offsetForNonSequence];
			break;
		case GSE_TAG_SQNUM:
			ber_decode_integer(&buf[offsetForSequence], lengthValue, &sqNum, SV_GET_LENGTH_INT32U);
			buf = &buf[offsetForNonSequence];
			break;
		case GSE_TAG_ALLDATA:
			gseDecodeDataset(&buf[offsetForSequence], lengthValue, gocbRef, gocbRefLength, timeAllowedToLive, T, stNum, sqNum);
			return;
		default:
			buf = &buf[offsetForNonSequence];
			break;
		}
	}
}
Exemple #2
0
int BER_DECODE_CTYPE_TIMESTAMP(unsigned char *buf, CTYPE_TIMESTAMP *value) {
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset++] == 0x89) {
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

		netmemcpy(value, &buf[offset], len);
	}

	return offset + len;
}
Exemple #3
0
int BER_DECODE_CTYPE_BOOLEAN(unsigned char *buf, CTYPE_BOOLEAN *value) {
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset++] == ASN1_TAG_BOOLEAN) {
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

		netmemcpy(value, &buf[offset], len);
	}

	return offset + len;
}
Exemple #4
0
int BER_DECODE_CTYPE_INT32U(unsigned char *buf, CTYPE_INT32U *value) {
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset++] == ASN1_TAG_UNSIGNED) {
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

		ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U);
	}

	return offset + len;
}
Exemple #5
0
int BER_DECODE_CTYPE_QUALITY(unsigned char *buf, CTYPE_QUALITY *value) {
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset] == ASN1_TAG_BIT_STRING) {
		offset++;
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

		netmemcpy(value, &buf[offset + 1], len - 1);	// skip over one byte (which contains number of unused bits)
	}

	return offset + len;
}
Exemple #6
0
int BER_DECODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) {	// assuming enum is an int - allows any enum type to be used
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset++] == ASN1_TAG_UNSIGNED) {
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

#if GOOSE_FIXED_SIZE == 1
		ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT8);
#else
		ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U);
#endif
	}

	return offset + len;
}
Exemple #7
0
int BER_DECODE_CTYPE_FLOAT64(unsigned char *buf, CTYPE_FLOAT64 *value) {
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset++] == 0x87) {
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

		// check for fixed-length GOOSE. If not, check for 11 bits for exponent
		if (len == 9 && buf[offset] == 0x0B) {
			netmemcpy(value, &buf[offset + 1], len - 1);
		}
		else if (len == 8) {
			netmemcpy(value, &buf[offset], len);
		}
	}

	return offset + len - 1;
}
Exemple #8
0
int stats3_decompress_bits(range_coder *c,unsigned char m[1025],int *len_out)
{
  int i;
  *len_out=0;

  /* Check if message is encoded naturally */
  int notRawASCII=range_decode_equiprobable(c,2);
  if (notRawASCII==0) {
    /* raw bytes -- copy from input to output */
    // printf("decoding raw bytes: bits_used=%d\n",c->bits_used);
    for(i=0;c->bit_stream[i]&&i<1024&&i<(c->bit_stream_length>>3);i++) {
      m[i]=c->bit_stream[i];
      // printf("%d 0x%02x\n",i,c->bit_stream[i]);
    }
    // printf("%d 0x%02x\n",i,c->bit_stream[i]);
    m[i]=0;
    *len_out=i;
    return 0;
  }
  
  int notPackedASCII=range_decode_symbol(c,&probPackedASCII,2);

  int encodedLength=decodeLength(c);
  for(i=0;i<encodedLength;i++) m[i]='?'; m[i]=0;
  *len_out=encodedLength;

  if (notPackedASCII==0) {
    /* packed ASCII -- copy from input to output */
    // printf("decoding packed ASCII\n");
    decodePackedASCII(c,(char *)m,encodedLength);
    return 0;
  }

  unsigned char nonAlphaValues[1024];
  int nonAlphaPositions[1024];
  int nonAlphaCount=0;

  decodeNonAlpha(c,nonAlphaPositions,nonAlphaValues,&nonAlphaCount,encodedLength);

  int alphaCount=(*len_out)-nonAlphaCount;

  // printf("message contains %d non-alpha characters, %d alpha chars.\n",nonAlphaCount,alphaCount);

  unsigned char lowerCaseAlphaChars[1025];

  decodeLCAlphaSpace(c,lowerCaseAlphaChars,alphaCount);
  lowerCaseAlphaChars[alphaCount]=0;

  decodeCaseModel1(c,lowerCaseAlphaChars);
  mungeCase((char *)lowerCaseAlphaChars);
  
  /* reintegrate alpha and non-alpha characters */
  int nonAlphaPointer=0;
  int alphaPointer=0;
  for(i=0;i<(*len_out);i++)
    {
      if (nonAlphaPointer<nonAlphaCount
	  &&nonAlphaPositions[nonAlphaPointer]==i) {
	m[i]=nonAlphaValues[nonAlphaPointer++];
      } else {
	m[i]=lowerCaseAlphaChars[alphaPointer++];
      }
    }
  m[i]=0;

  return 0;
}
Exemple #9
0
bool SRUP_MSG_OBS_BASE::DeSerialize(const uint8_t *serial_data)
{
    uint16_t x;
    uint32_t p=0;
    uint8_t bytes[2];

    // We need to unmarshall the data to reconstruct the object...
    // We can start with the two bytes for the header.
    // One for the version - and one for the message type.

    std::memcpy(m_version, (uint8_t*) serial_data, 1);
    p+=1;
    std::memcpy(m_msgtype, (uint8_t*) serial_data + p, 1);
    p+=1;

    // Now we have to unmarshall the sequence ID...
    uint8_t sid_bytes[8];
    for (int i=0;i<8;i++)
    {
        std::memcpy(&sid_bytes[i], (uint8_t*) serial_data + p, 1);
        ++p;
    }

    // ... then we copy them into m_sequence_ID
    if (m_sequence_ID != nullptr)
        delete(m_sequence_ID);
    m_sequence_ID = new uint64_t;
    std::memcpy(m_sequence_ID, sid_bytes, 8);

    // Next we have to unmarshall the sender ID...
    uint8_t snd_bytes[8];
    for (int i=0;i<8;i++)
    {
        std::memcpy(&snd_bytes[i], (uint8_t*) serial_data + p, 1);
        ++p;
    }

    // ... then we copy them into the sender ID
    if (m_sender_ID != nullptr)
        delete(m_sender_ID);
    m_sender_ID = new uint64_t;
    std::memcpy(m_sender_ID, snd_bytes, 8);

    // Now we have two-bytes for the size of the token ... and x bytes for the token
    std::memcpy(bytes, serial_data + p, 2);
    x = decodeLength(bytes);
    p+=2;
    if(m_token != nullptr)
        delete(m_token);
    m_token = new uint8_t[x+1];
    std::memcpy(m_token, (uint8_t *) serial_data + p, x);
    m_token_len = x;
    p+=x;

    // The next two bytes are the size of the signature...
    std::memcpy(bytes, serial_data + p, 2);
    x = decodeLength(bytes);
    p+=2;

    m_sig_len = x;

    // The next x bytes are the value of the signature.
    if(m_signature != nullptr)
        delete(m_signature);
    m_signature = new uint8_t[x];
    std::memcpy(m_signature, serial_data + p, x);

    p+=x;

    // Lastly we have the encrypted data.
    std::memcpy(bytes, serial_data + p, 2);
    x = decodeLength(bytes);
    p+=2;

    auto* encrypted_data = new uint8_t[x];

    std::memcpy(encrypted_data, (uint8_t *) serial_data + p, x);
    m_crypto->crypt(encrypted_data, x);

    delete[] encrypted_data;

    return true;
}