|
@@ -60,7 +60,7 @@ namespace Binman {
|
|
|
return new BinaryData.from_byte_array(signed_checksum).equals(new BinaryData.from_byte_array(checksum_bytes));
|
|
|
}
|
|
|
|
|
|
- private InputStream get_stream() throws Error {
|
|
|
+ internal InputStream get_stream() throws Error {
|
|
|
var decompressor = new ZlibDecompressor(ZlibCompressorFormat.GZIP);
|
|
|
return new ConverterInputStream(file.read(), decompressor);
|
|
|
}
|
|
@@ -86,7 +86,7 @@ namespace Binman {
|
|
|
public string name { get; set; }
|
|
|
public string description { get; set; }
|
|
|
public int serial { get; set; }
|
|
|
- public string post_exec { get; set; }
|
|
|
+ public string? post_exec { get; set; }
|
|
|
public BinaryData key { get; set; }
|
|
|
public Vector<string> remotes { get; set; }
|
|
|
|
|
@@ -95,7 +95,9 @@ namespace Binman {
|
|
|
cfg.map<string>("name", o => o.name, (o, v) => o.name = v);
|
|
|
cfg.map<string>("desc", o => o.description, (o, v) => o.description = v);
|
|
|
cfg.map<int>("serial", o => o.serial, (o, v) => o.serial = v);
|
|
|
- cfg.map<string>("post-exec", o => o.post_exec, (o, v) => o.post_exec = v);
|
|
|
+ cfg.map<string>("post-exec", o => o.post_exec, (o, v) => o.post_exec = v)
|
|
|
+ .undefined_when(o => o.post_exec == null)
|
|
|
+ .when_undefined(o => o.post_exec = null);
|
|
|
cfg.map<string>("key", o => o.key.to_base64(), (o, v) => o.key = new BinaryData.from_base64(v));
|
|
|
cfg.map_many<string>("remotes", o => o.remotes, (o, v) => o.remotes = v.to_vector());
|
|
|
cfg.set_constructor(() => new ManifestHeader());
|
|
@@ -105,8 +107,8 @@ namespace Binman {
|
|
|
|
|
|
public class ManifestEntry {
|
|
|
public string path { get; set; }
|
|
|
- public int user { get; set; }
|
|
|
- public int group { get; set; }
|
|
|
+ public Posix.uid_t user { get; set; }
|
|
|
+ public Posix.gid_t group { get; set; }
|
|
|
public Posix.mode_t mode { get; set; }
|
|
|
public string? target { get; set; }
|
|
|
public string? licence { get; set; }
|
|
@@ -116,13 +118,21 @@ namespace Binman {
|
|
|
public static PropertyMapper<ManifestEntry> get_mapper() {
|
|
|
return PropertyMapper.build_for<ManifestEntry>(cfg => cfg
|
|
|
.map<string>("path", o => o.path, (o, v) => o.path = v)
|
|
|
- .map<int>("uid", o => o.user, (o, v) => o.user = v)
|
|
|
- .map<int>("gid", o => o.group, (o, v) => o.group = v)
|
|
|
- .map<int>("mod", o => (int)o.mode, (o, v) => o.mode = v)
|
|
|
- .map<string?>("target", o => o.target, (o, v) => o.target = v, false)
|
|
|
- .map<string?>("licence", o => o.licence, (o, v) => o.licence = v, false)
|
|
|
- .map_properties_with<ManifestFileDescriptor?>("bin", o => o.binary, (o, v) => o.binary = v, ManifestFileDescriptor.get_mapper(), false)
|
|
|
- .map_properties_with<ManifestFileDescriptor?>("ccs", o => o.source, (o, v) => o.source = v, ManifestFileDescriptor.get_mapper(), false)
|
|
|
+ .map<uint>("uid", o => (uint)o.user, (o, v) => o.user = v)
|
|
|
+ .map<uint>("gid", o => (uint)o.group, (o, v) => o.group = v)
|
|
|
+ .map<uint>("mod", o => (uint)o.mode, (o, v) => o.mode = v)
|
|
|
+ .map<string?>("target", o => o.target, (o, v) => o.target = v)
|
|
|
+ .undefined_when(o => o.target == null)
|
|
|
+ .when_undefined(o => o.target = null)
|
|
|
+ .map<string?>("licence", o => o.licence, (o, v) => o.licence = v)
|
|
|
+ .undefined_when(o => o.licence == null)
|
|
|
+ .when_undefined(o => o.licence = null)
|
|
|
+ .map_properties_with<ManifestFileDescriptor?>("bin", o => o.binary, (o, v) => o.binary = v, ManifestFileDescriptor.get_mapper())
|
|
|
+ .undefined_when(o => o.binary == null)
|
|
|
+ .when_undefined(o => o.binary = null)
|
|
|
+ .map_properties_with<ManifestFileDescriptor?>("ccs", o => o.source, (o, v) => o.source = v, ManifestFileDescriptor.get_mapper())
|
|
|
+ .undefined_when(o => o.source == null)
|
|
|
+ .when_undefined(o => o.source = null)
|
|
|
.set_constructor(() => new ManifestEntry())
|
|
|
);
|
|
|
}
|
|
@@ -152,5 +162,36 @@ namespace Binman {
|
|
|
.set_constructor(() => new ManifestSignature())
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ public ManifestSignature.generate(File file, uint8[] signing_key) throws Error {
|
|
|
+ var manifest_file = new ManifestFile(file);
|
|
|
+ var stream = new DataInputStream(manifest_file.get_stream());
|
|
|
+ var checksum = new Checksum(ChecksumType.SHA512);
|
|
|
+
|
|
|
+ string? line;
|
|
|
+ try {
|
|
|
+ while ((line = stream.read_line()) != null && line.chomp().length > 0) {
|
|
|
+ var obj = new JsonElement.from_string(line).as<JsonObject>();
|
|
|
+
|
|
|
+ // Don't include signature object in checksum
|
|
|
+ if(obj.has("signature")) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ checksum.update(line.data, line.data.length);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch(Error e) {
|
|
|
+ // Ignore
|
|
|
+ }
|
|
|
+
|
|
|
+ // Calculate checksum
|
|
|
+ var checksum_bytes = new uint8[ChecksumType.SHA512.get_length()];
|
|
|
+ size_t size = checksum_bytes.length;
|
|
|
+ checksum.get_digest(checksum_bytes, ref size);
|
|
|
+
|
|
|
+ // Sign checksum
|
|
|
+ this.signature = new BinaryData.from_byte_array(Sodium.Asymmetric.Signing.sign(checksum_bytes, signing_key));
|
|
|
+ }
|
|
|
}
|
|
|
}
|