Skip to content

Commit

Permalink
cryptorHeader for new cryptoModule
Browse files Browse the repository at this point in the history
  • Loading branch information
mohitpubnub committed Sep 27, 2023
1 parent 639bb30 commit 6378d0c
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
84 changes: 84 additions & 0 deletions pubnub/lib/src/crypto/crypto.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,90 @@ import 'dart:typed_data' show Uint8List;
import 'package:pubnub/core.dart';
import 'encryption_mode.dart';

class CryptorHeader {
static const SENTINEL = 'PNED';
static const LEGACY_IDENTIFIER = '';
static const IDENTIFIER_LENGTH = 4;
static const MAX_VERSION = 1;

static CryptorHeaderV1? from(String id, List<int> metadata) {
if (id == LEGACY_IDENTIFIER) return null;
return CryptorHeaderV1(id, metadata.length);
}

static CryptorHeaderV1? tryParse(List<int> encryptedData) {
List<int> sentinel;
var version;
if (encryptedData.length >= 4) {
sentinel = encryptedData.sublist(0,4).toList();
if (utf8.decode(sentinel) != SENTINEL) return null;
}

if (encryptedData.length >= 5) {
version = encryptedData[4];
} else {
throw PubNubException('decryption error');
}
if (version > MAX_VERSION) throw PubNubException('unknown cryptor');

var identifier;
var pos = 5 + IDENTIFIER_LENGTH;
if (encryptedData.length >= pos) {
identifier = encryptedData.sublist(5, pos).toList();
} else {
throw PubNubException('decryption error');
}
var metadataLength;
if (encryptedData.length > pos + 1) {
metadataLength = encryptedData[pos];
}
pos += 1;
if (metadataLength == 255 && encryptedData.length >= pos + 2) {
metadataLength = encryptedData
.sublist(pos, pos + 2)
.fold<int>(0, (acc, el) => (acc << 8) + el);
}
return CryptorHeaderV1(utf8.decode(identifier), metadataLength);
}
}

class CryptorHeaderV1 {
static const VERSION = 1;
final String _identifier;
final int _metadataLength;

CryptorHeaderV1(this._identifier, this._metadataLength);

String get identifier => _identifier;
int get metadataLength => _metadataLength;

int get length {
return (CryptorHeader.SENTINEL.length +
1 +
CryptorHeader.IDENTIFIER_LENGTH +
(_metadataLength < 225 ? 1 : 3) +
_metadataLength);
}

List<int> get data {
var pos = 0;
var header = List<int>.filled(length, 0);
header.setAll(pos, CryptorHeader.SENTINEL.codeUnits);
pos += CryptorHeader.SENTINEL.length;
header[pos] = VERSION;
pos++;
header.setAll(pos, _identifier.codeUnits);
pos+=CryptorHeader.IDENTIFIER_LENGTH;
var metadataLength = this.metadataLength;
if (metadataLength < 255){
header[pos] = metadataLength;
} else {
header.setAll(pos, [255, metadataLength >> 8, metadataLength & 0xff]);
}
return header;
}
}

/// Configuration used in cryptography.
class CryptoConfiguration {
/// Encryption mode used.
Expand Down
9 changes: 9 additions & 0 deletions pubnub/test/unit/crypto/crypto_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,14 @@ void main() {

expect(result, equals(plaintext));
});

test('cryptoHeader tryParse/data from encrypted text', () async {
var encryptedDataWithHeader = 'PNEDACRH�_�ƿ';
var headerData = [80, 78, 69, 68, 1, 65, 67, 82, 72, 16];
var expectedBytes = [...headerData, ...List<int>.filled(16, 0)];

CryptorHeaderV1? header = CryptorHeader.tryParse(encryptedDataWithHeader.codeUnits);
expect(header!.data, equals(expectedBytes));
});
});
}

0 comments on commit 6378d0c

Please sign in to comment.