-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
331 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import 'dart:async'; | ||
import 'dart:convert'; | ||
import 'dart:io'; | ||
import 'dart:math' as math; | ||
|
||
import 'package:collection/collection.dart'; | ||
import 'package:dage/src/armor_parser.dart'; | ||
|
||
const _label = 'AGE ENCRYPTED FILE'; | ||
const _armorStart = '-----BEGIN $_label-----'; | ||
const _armorEnd = '-----END $_label-----'; | ||
|
||
final _codec = AgeArmorCodec(); | ||
|
||
class AgeArmorCodec extends Codec<List<int>, String> { | ||
@override | ||
Converter<String, List<int>> get decoder => AgeArmorDecoder(); | ||
|
||
@override | ||
Converter<List<int>, String> get encoder => AgeArmorEncoder(); | ||
} | ||
|
||
class AgeArmorDecoder extends Converter<String, List<int>> { | ||
@override | ||
List<int> convert(String input) { | ||
final result = decode(input); | ||
if (result.isEmpty) { | ||
throw NoArmorBlockFoundException._(input); | ||
} | ||
return result.first; | ||
} | ||
|
||
List<List<int>> decode(String armoredString) { | ||
final trimmed = armoredString.trim(); | ||
if (!trimmed.startsWith(_armorStart)) { | ||
throw Exception('Armored file not valid'); | ||
} | ||
if (!trimmed.endsWith(_armorEnd)) { | ||
throw Exception('Armored file not valid'); | ||
} | ||
final result = <List<int>>[]; | ||
for (final matches in armorParserMatches('$trimmed\n')) { | ||
final preLabel = matches[0]; | ||
final data = matches[1]; | ||
final postLabel = matches[2]; | ||
|
||
if (preLabel != postLabel || _label != preLabel) { | ||
print('WHAT'); | ||
This comment has been minimized.
Sorry, something went wrong. |
||
continue; | ||
} | ||
|
||
result.add(base64.decode(data)); | ||
} | ||
return result; | ||
} | ||
} | ||
|
||
class AgeArmorEncoder extends Converter<List<int>, String> { | ||
@override | ||
String convert(List<int> input) { | ||
final s = StringBuffer(); | ||
s.writeln(_armorStart); | ||
final lines = base64.encode(input); | ||
for (var i = 0; i < lines.length; i += 64) { | ||
s.writeln(lines.substring(i, math.min(lines.length, i + 64))); | ||
} | ||
s.writeln(_armorEnd); | ||
return s.toString(); | ||
} | ||
} | ||
|
||
Future<bool> isArmored(File file) async { | ||
final header = await file.openRead(0, _armorStart.length).toList(); | ||
final eq = const ListEquality().equals; | ||
return eq(header.flattened.toList(), _armorStart.codeUnits); | ||
} | ||
|
||
Converter<List<int>, List<int>> get armorDecoder => | ||
utf8.decoder.fuse(_codec.decoder); | ||
|
||
Converter<List<int>, List<int>> get armorEncoder => | ||
_codec.encoder.fuse(utf8.encoder); | ||
|
||
class NoArmorBlockFoundException implements Exception { | ||
final String data; | ||
|
||
NoArmorBlockFoundException._(this.data); | ||
|
||
@override | ||
String toString() => 'No valid armor blocks were found in the data:\n$data'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright 2019 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
import 'package:petitparser/petitparser.dart'; | ||
|
||
final _cr = char('\x0d'); | ||
final _lf = char('\x0a'); | ||
final _eol = ignore((_cr & _lf) | _cr | _lf); | ||
|
||
final _preeb = | ||
(string('-----BEGIN ') & string('AGE ENCRYPTED FILE') & string('-----')) | ||
.pick(1); | ||
final _posteb = | ||
(string('-----END ') & string('AGE ENCRYPTED FILE') & string('-----')) | ||
.pick(1); | ||
final _base64char = pattern('a-zA-Z0-9+/'); | ||
final _base64pad = char('='); | ||
|
||
final _base64line = _base64char.times(64) & _eol; | ||
|
||
final _base64singlePadSuffix = (_base64char.repeat(3) & _base64pad & _eol); | ||
final _base64doublePadSuffix = | ||
(_base64char.repeat(2) & _base64pad.repeat(2) & _eol); | ||
|
||
final _base64finl = _base64char.repeat(4).repeat(1, 15) & | ||
(_base64singlePadSuffix | _base64doublePadSuffix | _eol) | | ||
_base64singlePadSuffix | | ||
_base64doublePadSuffix; | ||
|
||
final _base64text = flatten( | ||
(_base64line.plus() & _base64finl) | _base64line.star() | _base64finl); | ||
final armorParser = | ||
(_preeb & _eol & _base64text & _posteb & _eol).permute([0, 2, 3]); | ||
|
||
Iterable<List> armorParserMatches(String armoredString) { | ||
return armorParser.allMatches(armoredString, overlapping: false); | ||
} | ||
|
||
void _flattenString(dynamic value, StringBuffer target) { | ||
if (value == null) { | ||
return; | ||
} | ||
if (value is String) { | ||
target.write(value); | ||
return; | ||
} | ||
if (value is List) { | ||
for (final v in value) { | ||
_flattenString(v, target); | ||
} | ||
return; | ||
} | ||
throw ArgumentError('Unsupported type ${value.runtimeType}'); | ||
} | ||
|
||
/// Create a [Parser] that ignores output from [p] and return `null`. | ||
Parser<String?> ignore<T>(Parser<T> p) => p.map((_) => null); | ||
|
||
/// Create a [Parser] that flattens all strings in the result from [p]. | ||
Parser<String> flatten(Parser<dynamic> p) => p.map((value) { | ||
final s = StringBuffer(); | ||
_flattenString(value, s); | ||
return s.toString(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
-----BEGIN AGE ENCRYPTED FILE----- | ||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBURWlGMHlwcXIrYnB2Y3FY | ||
TnlDVkpwTDdPdXdQZFZ3UEw3S1FFYkZET0NjCkVtRUNBRWNLTituL1ZzOVNiV2lW | ||
K0h1MHIrRThSNzdEZFdZeWQ4M253N1UKLS0tIFZuKzU0anFpaVVDRStXWmNFVlkz | ||
ZjFzcUhqbHUvejFMQ1EvVDdYbTdxSTAK7s9ix86RtDMnTmjU8vkTTLdMW/73vqpS | ||
yPC8DpksHoMx+2Y= | ||
-----END AGE ENCRYPTED FILE----- |
Empty file.
Oops, something went wrong.
@v3rm0n 🤣