Support ENUMERATED in client DER library
This commit is contained in:
@@ -6,6 +6,7 @@ namespace StudySystemClient.Der {
|
||||
}
|
||||
|
||||
private const uint BASE_HEADER_SIZE = 2;
|
||||
private const uint8 MAX_INT64_BYTES = 8;
|
||||
|
||||
public static Datum decode(uint8[] bytes, out uint? size = null)
|
||||
throws DecodeError {
|
||||
@@ -61,6 +62,8 @@ namespace StudySystemClient.Der {
|
||||
return new Sequence.from_content(content);
|
||||
case Null.TYPE:
|
||||
return new Null.from_content(content);
|
||||
case Enumerated.TYPE:
|
||||
return new Enumerated.from_content(content);
|
||||
default:
|
||||
throw new DecodeError.UNKNOWN_TYPE("Unsupported type: %02x",
|
||||
type);
|
||||
@@ -135,7 +138,6 @@ namespace StudySystemClient.Der {
|
||||
|
||||
public class Integer : Datum {
|
||||
internal const uint8 TYPE = 0x02;
|
||||
private const uint8 MAX_BYTES = 8;
|
||||
|
||||
public int64 value { get; private set; }
|
||||
|
||||
@@ -150,59 +152,6 @@ namespace StudySystemClient.Der {
|
||||
content = bytes;
|
||||
value = decode_int64(content);
|
||||
}
|
||||
|
||||
private static uint64 twos_complement(uint64 x) {
|
||||
return ~x + 1;
|
||||
}
|
||||
|
||||
private static int min_bits(bool negative, uint64 x) {
|
||||
int n = 0;
|
||||
if (negative) {
|
||||
while ((x >> (n + 8) & 0xff) != 0xff)
|
||||
n += 8;
|
||||
} else {
|
||||
while (x >> (n + 8) > 0)
|
||||
n += 8;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
private static uint8[] encode_int64(int64 val) {
|
||||
var negative = val < 0;
|
||||
var uval = negative ? twos_complement(val.abs()) : val;
|
||||
var shift = min_bits(negative, uval);
|
||||
|
||||
var buffer = new ByteArray();
|
||||
for (; shift >= 0; shift -= 8)
|
||||
buffer.append({(uint8)(uval >> shift)});
|
||||
|
||||
if (!negative && (buffer.data[0] & 0x80) != 0)
|
||||
buffer.prepend({0x00});
|
||||
|
||||
return buffer.data;
|
||||
}
|
||||
|
||||
private static int64 decode_int64(uint8[] bytes) throws DecodeError {
|
||||
if (bytes.length > MAX_BYTES) {
|
||||
throw new DecodeError.INVALID_CONTENT(
|
||||
"int64 too small for %u bytes", bytes.length);
|
||||
}
|
||||
var negative = (bytes[0] & 0x80) != 0;
|
||||
var val = decode_start_val(negative, bytes.length);
|
||||
foreach (var byte in bytes)
|
||||
val = val << 8 | byte;
|
||||
return negative ? -(int64)twos_complement(val) : (int64)val;
|
||||
}
|
||||
|
||||
private static uint64 decode_start_val(bool negative, uint length)
|
||||
{
|
||||
if (!negative)
|
||||
return 0;
|
||||
var val = 0;
|
||||
for (uint i = 0; i < MAX_BYTES - length; ++i)
|
||||
val = val << 8 | 0xff;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
public class Utf8String : Datum {
|
||||
@@ -307,4 +256,75 @@ namespace StudySystemClient.Der {
|
||||
content = bytes;
|
||||
}
|
||||
}
|
||||
|
||||
public class Enumerated : Datum {
|
||||
internal const uint8 TYPE = 0x0a;
|
||||
|
||||
public int64 value { get; private set; }
|
||||
|
||||
public Enumerated(int64 val) {
|
||||
type = TYPE;
|
||||
content = encode_int64(val);
|
||||
value = val;
|
||||
}
|
||||
|
||||
internal Enumerated.from_content(uint8[] bytes) throws DecodeError {
|
||||
type = TYPE;
|
||||
content = bytes;
|
||||
value = decode_int64(content);
|
||||
}
|
||||
}
|
||||
|
||||
private static uint64 twos_complement(uint64 x) {
|
||||
return ~x + 1;
|
||||
}
|
||||
|
||||
private static int min_bits(bool negative, uint64 x) {
|
||||
int n = 0;
|
||||
if (negative) {
|
||||
while ((x >> (n + 8) & 0xff) != 0xff)
|
||||
n += 8;
|
||||
} else {
|
||||
while (x >> (n + 8) > 0)
|
||||
n += 8;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
private static uint8[] encode_int64(int64 val) {
|
||||
var negative = val < 0;
|
||||
var uval = negative ? twos_complement(val.abs()) : val;
|
||||
var shift = min_bits(negative, uval);
|
||||
|
||||
var buffer = new ByteArray();
|
||||
for (; shift >= 0; shift -= 8)
|
||||
buffer.append({(uint8)(uval >> shift)});
|
||||
|
||||
if (!negative && (buffer.data[0] & 0x80) != 0)
|
||||
buffer.prepend({0x00});
|
||||
|
||||
return buffer.data;
|
||||
}
|
||||
|
||||
private static int64 decode_int64(uint8[] bytes) throws DecodeError {
|
||||
if (bytes.length > MAX_INT64_BYTES) {
|
||||
throw new DecodeError.INVALID_CONTENT(
|
||||
"int64 too small for %u bytes", bytes.length);
|
||||
}
|
||||
var negative = (bytes[0] & 0x80) != 0;
|
||||
var val = decode_start_val(negative, bytes.length);
|
||||
foreach (var byte in bytes)
|
||||
val = val << 8 | byte;
|
||||
return negative ? -(int64)twos_complement(val) : (int64)val;
|
||||
}
|
||||
|
||||
private static uint64 decode_start_val(bool negative, uint length)
|
||||
{
|
||||
if (!negative)
|
||||
return 0;
|
||||
var val = 0;
|
||||
for (uint i = 0; i < MAX_INT64_BYTES - length; ++i)
|
||||
val = val << 8 | 0xff;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,9 @@ namespace StudySystemClient {
|
||||
css_provider,
|
||||
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
new MainWindow(this, new Connection(Config.CERT_DIR));
|
||||
var connection = new Connection(Config.CERT_DIR);
|
||||
var main_window = new MainWindow(this, connection);
|
||||
main_window.present();
|
||||
} catch (Error e) {
|
||||
stderr.printf("Failed to initialize: %s\n", e.message);
|
||||
return;
|
||||
|
||||
@@ -18,8 +18,6 @@ namespace StudySystemClient {
|
||||
|
||||
var activities_view = new ActivitiesView();
|
||||
set_child(activities_view);
|
||||
|
||||
present();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user