master
 1//! Distinguised Encoding Rules as defined in X.690 and X.691.
 2//!
 3//! Subset of Basic Encoding Rules (BER) which eliminates flexibility in
 4//! an effort to acheive normality. Used in PKI.
 5const std = @import("std");
 6const asn1 = @import("../asn1.zig");
 7
 8pub const Decoder = @import("der/Decoder.zig");
 9pub const Encoder = @import("der/Encoder.zig");
10
11pub fn decode(comptime T: type, encoded: []const u8) !T {
12    var decoder = Decoder{ .bytes = encoded };
13    const res = try decoder.any(T);
14    std.debug.assert(decoder.index == encoded.len);
15    return res;
16}
17
18/// Caller owns returned memory.
19pub fn encode(allocator: std.mem.Allocator, value: anytype) ![]u8 {
20    var encoder = Encoder.init(allocator);
21    defer encoder.deinit();
22    try encoder.any(value);
23    return try encoder.buffer.toOwnedSlice();
24}
25
26test encode {
27    // https://lapo.it/asn1js/#MAgGAyoDBAIBBA
28    const Value = struct { a: asn1.Oid, b: i32 };
29    const test_case = .{
30        .value = Value{ .a = asn1.Oid.fromDotComptime("1.2.3.4"), .b = 4 },
31        .encoded = &[_]u8{ 0x30, 0x08, 0x06, 0x03, 0x2A, 0x03, 0x04, 0x02, 0x01, 0x04 },
32    };
33    const allocator = std.testing.allocator;
34    const actual = try encode(allocator, test_case.value);
35    defer allocator.free(actual);
36
37    try std.testing.expectEqualSlices(u8, test_case.encoded, actual);
38}
39
40test decode {
41    // https://lapo.it/asn1js/#MAgGAyoDBAIBBA
42    const Value = struct { a: asn1.Oid, b: i32 };
43    const test_case = .{
44        .value = Value{ .a = asn1.Oid.fromDotComptime("1.2.3.4"), .b = 4 },
45        .encoded = &[_]u8{ 0x30, 0x08, 0x06, 0x03, 0x2A, 0x03, 0x04, 0x02, 0x01, 0x04 },
46    };
47    const decoded = try decode(Value, test_case.encoded);
48
49    try std.testing.expectEqualDeep(test_case.value, decoded);
50}
51
52test {
53    _ = Decoder;
54    _ = Encoder;
55}