Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(all): Use Uint8Lists #90

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/lib/import_pass/import_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class PkPassImportSource {

final String? contentResolverPath;
final String? filePath;
final List<int>? bytes;
final Uint8List? bytes;

Future<PkPass> getPass() async {
if (contentResolverPath != null) {
Expand Down
6 changes: 3 additions & 3 deletions passkit/lib/src/apple_wwdr_certificate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ X509 get wwdrG4 =>
/// More info at:
/// https://developer.apple.com/help/account/reference/wwdr-intermediate-certificates/
/// https://www.apple.com/certificateauthority/
// ignore: constant_identifier_names
const worldwide_Developer_Relations_G4 = [
// ignore: constant_identifier_names, non_constant_identifier_names
final worldwide_Developer_Relations_G4 = Uint8List.fromList([
48,
130,
4,
Expand Down Expand Up @@ -1127,4 +1127,4 @@ const worldwide_Developer_Relations_G4 = [
207,
242,
159,
];
]);
21 changes: 8 additions & 13 deletions passkit/lib/src/archive_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:typed_data';

import 'package:archive/archive.dart';
import 'package:crypto/crypto.dart';
import 'package:passkit/src/archive_file_extension.dart';
import 'package:passkit/src/pkpass/exceptions.dart';
import 'package:passkit/src/pkpass/pk_pass_image.dart';
import 'package:passkit/src/strings_parser/naive_strings_file_parser.dart';
Expand All @@ -15,13 +16,8 @@ import 'package:passkit/src/strings_parser/naive_strings_file_parser.dart';
final _utf8JsonDecoder = const Utf8Decoder().fuse(const JsonDecoder());

extension ArchiveX on Archive {
List<int>? findBytesForFile(String fileName) =>
findFile(fileName)?.content as List<int>?;

Uint8List? findUint8ListForFile(String fileName) {
final data = findBytesForFile(fileName);
return data == null ? null : Uint8List.fromList(data);
}
Uint8List? findBytesForFile(String fileName) =>
findFile(fileName)?.binaryContent;

Map<String, dynamic>? findFileAndReadAsJson(String fileName) {
final bytes = findBytesForFile(fileName);
Expand All @@ -33,9 +29,9 @@ extension ArchiveX on Archive {

PkImage? loadImage(String name) {
return PkImage.fromImages(
image1: findUint8ListForFile('$name.png'),
image2: findUint8ListForFile('[email protected]'),
image3: findUint8ListForFile('[email protected]'),
image1: findBytesForFile('$name.png'),
image2: findBytesForFile('[email protected]'),
image3: findBytesForFile('[email protected]'),
);
}

Expand All @@ -52,8 +48,7 @@ extension ArchiveX on Archive {
for (final languageFile in translationFiles) {
final language = languageFile.name.split('.').first;

languageData[language] =
parseStringsFile(languageFile.content as List<int>);
languageData[language] = parseStringsFile(languageFile.binaryContent);
}
return languageData;
}
Expand Down Expand Up @@ -88,7 +83,7 @@ extension ArchiveX on Archive {

for (final file in filesWithoutSignatureAndManifest) {
final checksumInManifest = manifest[file.name] as String?;
final digest = sha1.convert(file.content as List<int>);
final digest = sha1.convert(file.binaryContent);
if (checksumInManifest != digest.toString()) {
throw ChecksumMismatchException(file.name);
}
Expand Down
7 changes: 7 additions & 0 deletions passkit/lib/src/archive_file_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'dart:typed_data';

import 'package:archive/archive.dart';

extension ArchiveFileX on ArchiveFile {
Uint8List get binaryContent => Uint8List.fromList(content as List<int>);
}
11 changes: 5 additions & 6 deletions passkit/lib/src/order/pk_order.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:typed_data';

import 'package:archive/archive.dart';
import 'package:passkit/src/archive_extensions.dart';
import 'package:passkit/src/archive_file_extension.dart';
import 'package:passkit/src/pkpass/exceptions.dart';
import 'package:passkit/src/signature_verification.dart';

Expand All @@ -20,7 +21,7 @@ class PkOrder {
/// verification and validation.
// TODO(ueman): Provide an async method for this.
static PkOrder fromBytes(
final List<int> bytes, {
final Uint8List bytes, {
bool skipChecksumVerification = false,
bool skipSignatureVerification = false,
}) {
Expand All @@ -38,10 +39,8 @@ class PkOrder {

if (skipSignatureVerification) {
final manifestContent =
archive.findFile('manifest.json')!.content as List<int>;
final signatureContent = Uint8List.fromList(
archive.findFile('signature')!.content as List<int>,
);
archive.findFile('manifest.json')!.binaryContent;
final signatureContent = archive.findFile('signature')!.binaryContent;

verifySignature(
signatureBytes: signatureContent,
Expand Down Expand Up @@ -77,7 +76,7 @@ class PkOrder {
final Map<String, Map<String, dynamic>>? languageData;

/// The bytes of this PkPass
final List<int> sourceData;
final Uint8List sourceData;

/// Indicates whether a webservices is available.
bool get isWebServiceAvailable => order.webServiceURL != null;
Expand Down
45 changes: 19 additions & 26 deletions passkit/lib/src/pkpass/pkpass.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:archive/archive.dart';
import 'package:crypto/crypto.dart';
import 'package:meta/meta.dart';
import 'package:passkit/src/apple_wwdr_certificate.dart';
import 'package:passkit/src/archive_file_extension.dart';
import 'package:passkit/src/pkpass/exceptions.dart';
import 'package:passkit/src/pkpass/pass_data.dart';
import 'package:passkit/src/pkpass/pass_type.dart';
Expand All @@ -27,7 +28,7 @@ import 'package:passkit/src/strings_parser/naive_strings_file_parser.dart';
/// a PR: https://github.com/ueman/passkit/issues/74
typedef SignatureBuilder = Uint8List Function(
String manifest,
List<int> wwdrCertificate,
Uint8List wwdrCertificate,
);

/// Dart uses a special fast decoder when using a fused [Utf8Decoder] and [JsonDecoder].
Expand Down Expand Up @@ -82,7 +83,7 @@ class PkPass {
/// certificate.
// TODO(any): Provide an async method for this.
static PkPass fromBytes(
final List<int> bytes, {
final Uint8List bytes, {
bool skipChecksumVerification = false,
bool skipSignatureVerification = false,
}) {
Expand All @@ -99,10 +100,8 @@ class PkPass {
archive.checkSha1Checksums(manifest);
if (!skipSignatureVerification) {
final manifestContent =
archive.findFile('manifest.json')!.content as List<int>;
final signatureContent = Uint8List.fromList(
archive.findFile('signature')!.content as List<int>,
);
archive.findFile('manifest.json')!.binaryContent;
final signatureContent = archive.findFile('signature')!.binaryContent;

verifySignature(
signatureBytes: signatureContent,
Expand Down Expand Up @@ -148,7 +147,7 @@ class PkPass {
// gracefully fall back to just parsing the PkPass file.
// TODO(ueman): Provide an async method for this.
static List<PkPass> passesFromBytes(
final List<int> bytes, {
final Uint8List bytes, {
bool skipChecksumVerification = false,
bool skipSignatureVerification = false,
}) {
Expand All @@ -162,7 +161,7 @@ class PkPass {
return pkPasses
.map(
(file) => fromBytes(
file.content as List<int>,
file.binaryContent,
skipChecksumVerification: skipChecksumVerification,
skipSignatureVerification: skipSignatureVerification,
),
Expand Down Expand Up @@ -243,7 +242,7 @@ class PkPass {
final Map<String, Map<String, dynamic>>? languageData;

/// The bytes of this PkPass
final List<int> sourceData;
final Uint8List sourceData;

/// Indicates whether a webservices is available.
bool get isWebServiceAvailable => pass.webServiceURL != null;
Expand Down Expand Up @@ -301,7 +300,7 @@ class PkPass {

final manifest = <String, String>{};
for (final file in archive.files) {
manifest[file.name] = sha1.convert(file.content as List<int>).toString();
manifest[file.name] = sha1.convert(file.binaryContent).toString();
}

final manifestContent = encoder.convert(manifest);
Expand Down Expand Up @@ -332,13 +331,8 @@ class PkPass {
// This is intentionally not exposed to keep this an implementation detail.
// Tests should be written against the PkPass class directly.
extension on Archive {
List<int>? findBytesForFile(String fileName) =>
findFile(fileName)?.content as List<int>?;

Uint8List? findUint8ListForFile(String fileName) {
final data = findBytesForFile(fileName);
return data == null ? null : Uint8List.fromList(data);
}
Uint8List? findBytesForFile(String fileName) =>
findFile(fileName)?.binaryContent;

/// Returns a map of locale to a map of resolution to image bytes.
/// Returns null, if no image is localized
Expand Down Expand Up @@ -367,11 +361,11 @@ extension on Archive {
}

if (fileName.endsWith('@2x.png')) {
map[language]![2] = Uint8List.fromList(file.content as List<int>);
map[language]![2] = file.binaryContent;
} else if (fileName.endsWith('@3x.png')) {
map[language]![3] = Uint8List.fromList(file.content as List<int>);
map[language]![3] = file.binaryContent;
} else {
map[language]![1] = Uint8List.fromList(file.content as List<int>);
map[language]![1] = file.binaryContent;
}
}

Expand All @@ -395,9 +389,9 @@ extension on Archive {

PkImage? loadImage(String name) {
return PkImage.fromImages(
image1: findUint8ListForFile('$name.png'),
image2: findUint8ListForFile('[email protected]'),
image3: findUint8ListForFile('[email protected]'),
image1: findBytesForFile('$name.png'),
image2: findBytesForFile('[email protected]'),
image3: findBytesForFile('[email protected]'),
localizedImages: loadLocalizedImage(name),
);
}
Expand All @@ -415,8 +409,7 @@ extension on Archive {
for (final languageFile in translationFiles) {
final language = languageFile.name.split('.').first;

languageData[language] =
parseStringsFile(languageFile.content as List<int>);
languageData[language] = parseStringsFile(languageFile.binaryContent);
}
return languageData;
}
Expand Down Expand Up @@ -468,7 +461,7 @@ extension on Archive {

for (final file in filesWithoutSignatureAndManifest) {
final checksumInManifest = manifest[file.name] as String?;
final digest = sha1.convert(file.content as List<int>);
final digest = sha1.convert(file.binaryContent);
if (checksumInManifest != digest.toString()) {
throw ChecksumMismatchException(file.name);
}
Expand Down
5 changes: 3 additions & 2 deletions passkit/lib/src/signature_verification.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import 'dart:typed_data';

import 'package:collection/collection.dart';
import 'package:crypto/crypto.dart';
import 'package:passkit/src/apple_wwdr_certificate.dart';
import 'package:passkit/src/pkpass/exceptions.dart';
import 'package:pkcs7/pkcs7.dart';
import 'package:collection/collection.dart';

/// [identifier] corresponds to the `passTypeIdentifier` in PkPasses or the
/// `orderTypeIdentifier` for PkOrders.
Expand All @@ -17,7 +18,7 @@ import 'package:collection/collection.dart';
// as long as the contents match?
bool verifySignature({
required Uint8List signatureBytes,
required List<int> manifestBytes,
required Uint8List manifestBytes,
required String identifier,
required String teamIdentifier,
DateTime? now,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import 'dart:convert';
import 'dart:typed_data';

/// Parses [content] to a [Map<String, String>] which contains the
/// key-value-pairs for translations.
Map<String, String> parseStringsFile(List<int> content) {
Map<String, String> parseStringsFile(Uint8List content) {
final string = _stringsFileDecoder.convert(content);
return naiveStringsFileParser(string);
}
Expand Down