* @brief Decrypts a cyphertext binary encrypted with this class with the set key */
| 259 | * @brief Decrypts a cyphertext binary encrypted with this class with the set key |
| 260 | */ |
| 261 | QByteArray Licensing::SimpleCrypt::decryptToByteArray(const QByteArray& cypher) |
| 262 | { |
| 263 | if (m_keyParts.isEmpty()) { |
| 264 | qWarning() << "No key set."; |
| 265 | m_lastError = ErrorNoKeySet; |
| 266 | return QByteArray(); |
| 267 | } |
| 268 | |
| 269 | QByteArray ba = cypher; |
| 270 | if (cypher.size() < 3) |
| 271 | return QByteArray(); |
| 272 | |
| 273 | char version = ba.at(0); |
| 274 | if (version != 3) { |
| 275 | m_lastError = ErrorUnknownVersion; |
| 276 | return QByteArray(); |
| 277 | } |
| 278 | |
| 279 | CryptoFlags flags = CryptoFlags(ba.at(1)); |
| 280 | ba = ba.mid(2); |
| 281 | int pos(0); |
| 282 | int cnt(ba.size()); |
| 283 | char lastChar = 0; |
| 284 | while (pos < cnt) { |
| 285 | char currentChar = ba[pos]; |
| 286 | ba[pos] = ba.at(pos) ^ lastChar ^ m_keyParts.at(pos % 8); |
| 287 | lastChar = currentChar; |
| 288 | ++pos; |
| 289 | } |
| 290 | |
| 291 | ba = ba.mid(1); |
| 292 | |
| 293 | bool integrityOk(true); |
| 294 | if (flags.testFlag(CryptoFlagChecksum)) { |
| 295 | if (ba.length() < 2) { |
| 296 | m_lastError = ErrorIntegrityFailed; |
| 297 | return QByteArray(); |
| 298 | } |
| 299 | quint16 storedChecksum; |
| 300 | { |
| 301 | QDataStream s(&ba, QIODevice::ReadOnly); |
| 302 | s >> storedChecksum; |
| 303 | } |
| 304 | |
| 305 | ba = ba.mid(2); |
| 306 | quint16 checksum = qChecksum(ba, Qt::ChecksumIso3309); |
| 307 | integrityOk = (checksum == storedChecksum); |
| 308 | } |
| 309 | |
| 310 | else if (flags.testFlag(CryptoFlagHash)) { |
| 311 | if (ba.length() < 20) { |
| 312 | m_lastError = ErrorIntegrityFailed; |
| 313 | return QByteArray(); |
| 314 | } |
| 315 | |
| 316 | QByteArray storedHash = ba.left(20); |
| 317 | ba = ba.mid(20); |
| 318 | QCryptographicHash hash(QCryptographicHash::Sha1); |
no test coverage detected