master
1const std = @import("std");
2const asn1 = @import("../asn1.zig");
3
4const der = asn1.der;
5const Tag = asn1.Tag;
6const FieldTag = asn1.FieldTag;
7
8/// An example that uses all ASN1 types and available implementation features.
9const AllTypes = struct {
10 a: u8 = 0,
11 b: asn1.BitString,
12 c: C,
13 d: asn1.Opaque(Tag.universal(.string_utf8, false)),
14 e: asn1.Opaque(Tag.universal(.octetstring, false)),
15 f: ?u16,
16 g: ?Nested,
17 h: asn1.Any,
18
19 pub const asn1_tags = .{
20 .a = FieldTag.initExplicit(0, .context_specific),
21 .b = FieldTag.initExplicit(1, .context_specific),
22 .c = FieldTag.initImplicit(2, .context_specific),
23 .g = FieldTag.initImplicit(3, .context_specific),
24 };
25
26 const C = enum {
27 a,
28 b,
29
30 pub const oids = asn1.Oid.StaticMap(@This()).initComptime(.{
31 .a = "1.2.3.4",
32 .b = "1.2.3.5",
33 });
34 };
35
36 const Nested = struct {
37 inner: Asn1T,
38 sum: i16,
39
40 const Asn1T = struct { a: u8, b: i16 };
41
42 pub fn decodeDer(decoder: *der.Decoder) !Nested {
43 const inner = try decoder.any(Asn1T);
44 return Nested{ .inner = inner, .sum = inner.a + inner.b };
45 }
46
47 pub fn encodeDer(self: Nested, encoder: *der.Encoder) !void {
48 try encoder.any(self.inner);
49 }
50 };
51};
52
53test AllTypes {
54 const expected = AllTypes{
55 .a = 2,
56 .b = asn1.BitString{ .bytes = &[_]u8{ 0x04, 0xa0 } },
57 .c = .a,
58 .d = .{ .bytes = "asdf" },
59 .e = .{ .bytes = "fdsa" },
60 .f = (1 << 8) + 1,
61 .g = .{ .inner = .{ .a = 4, .b = 5 }, .sum = 9 },
62 .h = .{ .tag = Tag.init(.string_ia5, false, .universal), .bytes = "asdf" },
63 };
64 // https://lapo.it/asn1js/#MC-gAwIBAqEFAwMABKCCAyoDBAwEYXNkZgQEZmRzYQICAQGjBgIBBAIBBRYEYXNkZg
65 const path = "./der/testdata/all_types.der";
66 const encoded = @embedFile(path);
67 const actual = try asn1.der.decode(AllTypes, encoded);
68 try std.testing.expectEqualDeep(expected, actual);
69
70 const allocator = std.testing.allocator;
71 const buf = try asn1.der.encode(allocator, expected);
72 defer allocator.free(buf);
73 try std.testing.expectEqualSlices(u8, encoded, buf);
74
75 // Use this to update test file.
76 // const dir = try std.fs.cwd().openDir("lib/std/crypto/asn1", .{});
77 // var file = try dir.createFile(path, .{});
78 // defer file.close();
79 // try file.writeAll(buf);
80}