/ src / ber_helper_functions.cpp
ber_helper_functions.cpp
  1  /**
  2   * @file ber_helper_functions.cpp
  3   * @author Rene Ceska xceska06 (xceska06@stud.fit.vutbr.cz)
  4   * @date 2023-11-19
  5   */
  6  #include "inc/ber_helper_functions.h"
  7  
  8  filterTypes getFilterType(std::vector<unsigned char>::iterator start) {
  9    if (start[0] == 0xA0) {
 10      return AND;
 11    } else if (start[0] == 0xA1) {
 12      return OR;
 13    } else if (start[0] == 0xA2) {
 14      return NOT;
 15    } else if (start[0] == 0xA3) {
 16      return equalityMatch;
 17    } else if (start[0] == 0xA4) {
 18      return substrings;
 19    }
 20    return undefined;
 21  }
 22  
 23  unsigned int ParseINT(std::vector<unsigned char>::iterator s, int *err,
 24                        std::vector<unsigned char>::iterator end) {
 25    unsigned int value = 0;
 26    int length = GetLength(s + 1, err, end);
 27    int lengthLength = GetLengthOfLength(s + 1, err, end);
 28    if (length > 4) {
 29      return 0;
 30      *err = 2;
 31    }
 32  
 33    switch (length) {
 34    case 0:
 35      value = 0;
 36      *err = 1;
 37      break;
 38    case 1:
 39      value = s[1 + lengthLength];
 40      err = 0;
 41      break;
 42    case 2:
 43      value = s[1 + lengthLength] << 8 | s[2 + lengthLength];
 44      err = 0;
 45      break;
 46    case 3:
 47      value = s[1 + lengthLength] << 16 | s[2 + lengthLength] << 8 |
 48              s[3 + lengthLength];
 49      err = 0;
 50      break;
 51    case 4:
 52      value = s[1 + lengthLength] << 24 | s[2 + lengthLength] << 16 |
 53              s[3 + lengthLength] << 8 | s[4 + lengthLength];
 54      err = 0;
 55      break;
 56  
 57    default:
 58      break;
 59    }
 60    return value;
 61  }
 62  
 63  int GetLengthOfLength(std::vector<unsigned char>::iterator start, int *err,
 64                        std::vector<unsigned char>::iterator end) {
 65  
 66    if (std::distance(start, end) < 1) {
 67      *err = 1;
 68      return 0;
 69    }
 70  
 71    int length = 0;
 72    if ((start[0] >> 7) != 1) { // if first bit is 0 -> shortform
 73      length = 1;
 74      *err = 0;
 75    } else {
 76      length = start[0] & 0x7F;
 77      length += 1;
 78    }
 79    return length;
 80  }
 81  
 82  std::vector<unsigned char> ToLowerCase(std::vector<unsigned char> input) {
 83    std::vector<unsigned char> result;
 84    for (unsigned long int i = 0; i < input.size(); i++) {
 85      result.push_back(std::tolower(input[i]));
 86    }
 87    return result;
 88  }
 89  
 90  int GetLength(std::vector<unsigned char>::iterator start, int *err,
 91                std::vector<unsigned char>::iterator end) {
 92    if (std::distance(start, end) < 1) {
 93      *err = 1;
 94      return 0;
 95    }
 96  
 97    int length = 0;
 98    if ((start[0] >> 7) != 1) { // if first bit is 0 -> shortform
 99      length = start[0];
100      *err = 0;
101    } else {
102      int lengthOfLength = start[0] & 0x7F; // remove bit indicating longform
103  
104      if (lengthOfLength > std::distance(start, end)) { // array is too short
105        *err = 1;
106        return 0;
107      }
108      if (lengthOfLength > 4 &&
109          start[lengthOfLength - 4] > 0x00) { // only support up to 4 bytes, more
110                                              // is not necessary for this project
111        *err = 1;
112        return 0;
113      }
114      int startOfLength = lengthOfLength - 3;
115      if (startOfLength < 0) {
116        startOfLength = 1;
117      }
118      for (int i = startOfLength; i <= lengthOfLength; i++) {
119        length = length << 8 | start[i];
120      }
121      *err = 0;
122    }
123    return length;
124  }
125  
126  void SkipTags(std::vector<unsigned char>::iterator &start, int n, int *err,
127                std::vector<unsigned char>::iterator end) {
128  
129    int i = 0;
130    int jumpLength = 1;
131    while (i < n) {
132      if (std::distance(start, end) < jumpLength) {
133        *err = 1;
134        return;
135      }
136      int length =
137          GetLength(start + jumpLength, err, end) +
138          GetLengthOfLength(start + jumpLength, err, end);
139      if (*err != 0) {
140        *err = 1;
141        return;
142      }
143  
144      jumpLength += length + 1; // +1 for tag
145      i++;
146    }
147    start = start + jumpLength - 1; // -1 to get index of tag instead of length
148  }
149  
150  void IncreaseLength4Bytes(std::vector<unsigned char>::iterator &start, int n,
151                            int *err, std::vector<unsigned char>::iterator end) {
152  
153    int length = GetLength(start, err, end) + n;
154  
155    start[1] = length >> 24;
156    start[2] = length >> 16;
157    start[3] = length >> 8;
158    start[4] = length;
159  }
160  
161  void AppendLenght4Bytes(std::vector<unsigned char> &start, int value) {
162    start.push_back(0x84); // size
163    start.push_back(value >> 24);
164    start.push_back(value >> 16);
165    start.push_back(value >> 8);
166    start.push_back(value);
167  }
168  
169  int WriteIntAppend(std::vector<unsigned char> &s, int value) {
170    if (value < 0) {
171      return -1;
172    }
173    int overflow = 0;
174    s.push_back(BER_INT_C);
175    if (value < 0x100) {
176      s.push_back(0x01); // length
177      if ((value) == 0xFF) {
178        s.push_back(0x00);
179        overflow = 1;
180      }
181      s.push_back(value);
182      return 3 + overflow;
183    } else if (value < 0x10000) {
184      s.push_back(0x02); // length
185      if ((value >> 8) == 0xFF) {
186        s.push_back(0x00);
187        overflow = 1;
188      }
189      s.push_back(value >> 8);
190      s.push_back(value);
191      return 4 + overflow;
192    } else if (value < 0x1000000) {
193      s.push_back(0x03); // length
194      if ((value >> 16) == 0xFF) {
195        s.push_back(0x00);
196        overflow = 1;
197      }
198      s.push_back(value >> 16);
199      s.push_back(value >> 8);
200      s.push_back(value);
201      return 5 + overflow;
202    } else if (value < 0x100000000) {
203      s.push_back(0x04); // length
204      if ((value >> 24) == 0xFF) {
205        s.push_back(0x00);
206        overflow = 1;
207      }
208      s.push_back(value >> 24);
209      s.push_back(value >> 16);
210      s.push_back(value >> 8);
211      s.push_back(value);
212      return 6 + overflow;
213    } else {
214      return -1;
215    }
216    return -1;
217  }
218  
219  int HowManyBytesWillIntUse(int value) {
220    if (value < 0) {
221      return -1;
222    }
223    if (value < 0x100) {
224      if ((value) == 0xFF) {
225        return 4;
226      } else {
227        return 3;
228      }
229  
230    } else if (value < 0x10000) {
231      if ((value >> 8) == 0xFF) {
232        return 5;
233      } else {
234        return 4;
235      }
236    } else if (value < 0x1000000) {
237      if ((value >> 16) == 0xFF) {
238        return 6;
239      } else {
240        return 5;
241      }
242    } else if (value < 0x100000000) {
243      if ((value >> 24) == 0xFF) {
244        return 7;
245      } else {
246        return 6;
247      }
248    } else {
249      return -1;
250    }
251    return -1;
252  }
253  
254  void GoIntoTag(std::vector<unsigned char>::iterator &start, int *err,
255                 std::vector<unsigned char>::iterator end) {
256  
257    int length = GetLengthOfLength(start + 1, err, end) + 1; // +1 for tag
258    if (*err != 0) {
259      *err = 1;
260      return;
261    }
262  
263    start += length; // return pointer to next tag
264  }