/ src / BerParser.cpp
BerParser.cpp
  1  /**
  2   * @file BerParser.cpp
  3   * @author Rene Ceska xceska06 (xceska06@stud.fit.vutbr.cz)
  4   * @date 2023-11-19
  5   */
  6  #include "inc/BerParser.h"
  7  
  8  /**
  9   * @brief Parses BER encoded message and converts it to BerObject, it works recursively
 10   *
 11   * @param start  start of the BER
 12   * @param err  1 if error, 0 if success
 13   * @param end  end of the array
 14   * @return BerObject*
 15   */
 16  BerObject *ParseBerObject(std::vector<unsigned char>::iterator start,
 17                            int *err, std::vector<unsigned char>::iterator end) {
 18    BerObject *berObject;
 19  
 20    unsigned char tag = start[0];
 21      // main switch for all types
 22    switch (tag) {
 23      {
 24      case BER_SEQUENCE_C:
 25        BerSequenceObject *berSequenceObject = new BerSequenceObject();
 26        int length = GetLength(start + 1, err, end);
 27        GoIntoTag(start, err, end);
 28        GetLengthOfLength(start +1, err, end);
 29        int i = 0;
 30        while (i < length) {
 31          BerObject *parsedBerObject = ParseBerObject(start, err, end);
 32          berSequenceObject->objects.push_back(parsedBerObject);
 33            i += BER_TAG_LENGTH + GetLengthOfLength(start +1, err, end) +
 34               GetLength(start + 1, err, end);
 35          SkipTags(start, 1, err, end);
 36        }
 37        berObject = berSequenceObject;
 38        break;
 39      }
 40      {
 41      case BER_BIND_REQUEST_C:
 42        BerSequenceObject *berSequenceObject =
 43            new BerSequenceObject(BER_BIND_REQUEST_C);
 44        int length = GetLength(start + 1, err, end);
 45        GoIntoTag(start, err, end);
 46  
 47        GetLengthOfLength(start +1, err, end);
 48        int i = 0;
 49        while (i < length) {
 50          BerObject *parsedBerObject = ParseBerObject(start, err, end);
 51          berSequenceObject->objects.push_back(parsedBerObject);
 52            i += BER_TAG_LENGTH + GetLengthOfLength(start +1, err, end) +
 53               GetLength(start + 1, err, end);
 54          SkipTags(start, 1, err, end);
 55        }
 56        berObject = berSequenceObject;
 57        break;
 58      }
 59      {
 60      case BER_SEARCH_REQUEST_C:
 61        BerSequenceObject *berSequenceObject =
 62            new BerSequenceObject(BER_SEARCH_REQUEST_C);
 63        int length = GetLength(start + 1, err, end);
 64        GoIntoTag(start, err, end);
 65  
 66        GetLengthOfLength(start +1, err, end);
 67        int i = 0;
 68        while (i < length) {
 69          BerObject *parsedBerObject = ParseBerObject(start, err, end);
 70          berSequenceObject->objects.push_back(parsedBerObject);
 71          i += BER_TAG_LENGTH + GetLengthOfLength(start +1, err, end) +
 72               GetLength(start + 1, err, end);
 73          SkipTags(start, 1, err, end);
 74        }
 75        berObject = berSequenceObject;
 76        break;
 77      }
 78    case BER_INT_C: {
 79      BerIntObject *berIntObject = new BerIntObject();
 80      int value = ParseINT(start, err, end);
 81      berIntObject->setValue(value);
 82      berObject = berIntObject;
 83      break;
 84    }
 85  
 86    case BER_ENUM_C: {
 87      int lenghtOfLenght = GetLengthOfLength(start +1 , err, end);
 88  
 89      char value = start[lenghtOfLenght + BER_TAG_LENGTH];
 90  
 91      berObject = new BerEnumObject(value);
 92      break;
 93    }
 94    case BER_SET_C: {
 95      BerSetObject *berSetObject = new BerSetObject();
 96      int length = GetLength(start + 1, err, end);
 97      GoIntoTag(start, err,end);
 98  
 99      int i = 0;
100      while (i < length) {
101  
102        BerObject *parsedBerObject = ParseBerObject(start, err, end);
103        berSetObject->objects.push_back(parsedBerObject);
104        i += BER_TAG_LENGTH + GetLengthOfLength(start +1, err, end) +
105               GetLength(start + 1, err, end);
106        SkipTags(start, 1, err, end);
107      }
108      berObject = berSetObject;
109      break;
110    }
111    case BER_OCTET_STRING_C: {
112  
113      int lenghtOfLenght = GetLengthOfLength(start +1, err, end);
114      int length = GetLength(start + 1, err, end);
115      BerStringObject *berStringObject = new BerStringObject();
116      if (length == 0) {
117        berStringObject->value = std::vector<unsigned char>();
118        berObject = berStringObject;
119        break;
120      }
121      berStringObject->value = std::vector<unsigned char>(
122          start + lenghtOfLenght + BER_TAG_LENGTH,
123          start + lenghtOfLenght + BER_TAG_LENGTH + length);
124      berObject = berStringObject;
125      break;
126    }
127    case BER_BOOL_C: {
128      int lenghtOfLenght = GetLengthOfLength(start +1, err, end);
129      GetLength(start + 1, err, end);
130      berObject = new BerBoolObject(start[lenghtOfLenght + BER_TAG_LENGTH]);
131      break;
132    }
133    default: // filters and other types
134      std::vector<unsigned char> berVector = std::vector<unsigned char>(
135          start, start + GetLengthOfLength(start+1, err, end) + BER_TAG_LENGTH +
136                     GetLength(start + 1, err, end));
137      berObject = new BerUndefinedObject(berVector);
138  
139      break;
140    }
141    return berObject;
142  }