authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-22 20:23:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-02 16:57:15-07:00
logc71c562486c5b3e92a1ea936f3c7b848853b2d5c
treebe90f9b5d8a04f786380c08737e5ac707220fd4c
parent642a8b05c3687d5c084ed164c773bd4d0a4faaef

remove std.crypto.der

Only a little bit of generalized logic for DER encoding is needed and so it can live inside the Certificate namespace. This commit removes the generic "parse object id" function which is no longer used in favor of more specific, smaller sets of object ids used with ComptimeStringMap.

4 files changed, 84 insertions(+), 169 deletions(-)

lib/std/crypto.zig-2
...@@ -177,7 +177,6 @@ const std = @import("std.zig");...@@ -177,7 +177,6 @@ const std = @import("std.zig");
177pub const errors = @import("crypto/errors.zig");177pub const errors = @import("crypto/errors.zig");
178178
179pub const tls = @import("crypto/tls.zig");179pub const tls = @import("crypto/tls.zig");
180pub const der = @import("crypto/der.zig");
181pub const Certificate = @import("crypto/Certificate.zig");180pub const Certificate = @import("crypto/Certificate.zig");
182181
183test {182test {
...@@ -269,7 +268,6 @@ test {...@@ -269,7 +268,6 @@ test {
269 _ = random;268 _ = random;
270 _ = errors;269 _ = errors;
271 _ = tls;270 _ = tls;
272 _ = der;
273 _ = Certificate;271 _ = Certificate;
274}272}
275273
lib/std/crypto/Certificate.zig+83-1
...@@ -499,9 +499,91 @@ pub fn checkVersion(bytes: []const u8, version: der.Element) !void {...@@ -499,9 +499,91 @@ pub fn checkVersion(bytes: []const u8, version: der.Element) !void {
499const std = @import("../std.zig");499const std = @import("../std.zig");
500const crypto = std.crypto;500const crypto = std.crypto;
501const mem = std.mem;501const mem = std.mem;
502const der = std.crypto.der;
503const Certificate = @This();502const Certificate = @This();
504503
504pub const der = struct {
505 pub const Class = enum(u2) {
506 universal,
507 application,
508 context_specific,
509 private,
510 };
511
512 pub const PC = enum(u1) {
513 primitive,
514 constructed,
515 };
516
517 pub const Identifier = packed struct(u8) {
518 tag: Tag,
519 pc: PC,
520 class: Class,
521 };
522
523 pub const Tag = enum(u5) {
524 boolean = 1,
525 integer = 2,
526 bitstring = 3,
527 null = 5,
528 object_identifier = 6,
529 sequence = 16,
530 sequence_of = 17,
531 utc_time = 23,
532 generalized_time = 24,
533 _,
534 };
535
536 pub const Element = struct {
537 identifier: Identifier,
538 slice: Slice,
539
540 pub const Slice = struct {
541 start: u32,
542 end: u32,
543
544 pub const empty: Slice = .{ .start = 0, .end = 0 };
545 };
546 };
547
548 pub const ParseElementError = error{CertificateFieldHasInvalidLength};
549
550 pub fn parseElement(bytes: []const u8, index: u32) ParseElementError!Element {
551 var i = index;
552 const identifier = @bitCast(Identifier, bytes[i]);
553 i += 1;
554 const size_byte = bytes[i];
555 i += 1;
556 if ((size_byte >> 7) == 0) {
557 return .{
558 .identifier = identifier,
559 .slice = .{
560 .start = i,
561 .end = i + size_byte,
562 },
563 };
564 }
565
566 const len_size = @truncate(u7, size_byte);
567 if (len_size > @sizeOf(u32)) {
568 return error.CertificateFieldHasInvalidLength;
569 }
570
571 const end_i = i + len_size;
572 var long_form_size: u32 = 0;
573 while (i < end_i) : (i += 1) {
574 long_form_size = (long_form_size << 8) | bytes[i];
575 }
576
577 return .{
578 .identifier = identifier,
579 .slice = .{
580 .start = i,
581 .end = i + long_form_size,
582 },
583 };
584 }
585};
586
505test {587test {
506 _ = Bundle;588 _ = Bundle;
507}589}
lib/std/crypto/Certificate/Bundle.zig+1-1
...@@ -154,8 +154,8 @@ const fs = std.fs;...@@ -154,8 +154,8 @@ const fs = std.fs;
154const mem = std.mem;154const mem = std.mem;
155const crypto = std.crypto;155const crypto = std.crypto;
156const Allocator = std.mem.Allocator;156const Allocator = std.mem.Allocator;
157const der = std.crypto.der;
158const Certificate = std.crypto.Certificate;157const Certificate = std.crypto.Certificate;
158const der = Certificate.der;
159const Bundle = @This();159const Bundle = @This();
160160
161const base64 = std.base64.standard.decoderWithIgnore(" \t\r\n");161const base64 = std.base64.standard.decoderWithIgnore(" \t\r\n");
lib/std/crypto/der.zig deleted-165
...@@ -1,165 +0,0 @@
1pub const Class = enum(u2) {
2 universal,
3 application,
4 context_specific,
5 private,
6};
7
8pub const PC = enum(u1) {
9 primitive,
10 constructed,
11};
12
13pub const Identifier = packed struct(u8) {
14 tag: Tag,
15 pc: PC,
16 class: Class,
17};
18
19pub const Tag = enum(u5) {
20 boolean = 1,
21 integer = 2,
22 bitstring = 3,
23 null = 5,
24 object_identifier = 6,
25 sequence = 16,
26 sequence_of = 17,
27 utc_time = 23,
28 generalized_time = 24,
29 _,
30};
31
32pub const Oid = enum {
33 rsadsi,
34 pkcs,
35 rsaEncryption,
36 md2WithRSAEncryption,
37 md5WithRSAEncryption,
38 sha1WithRSAEncryption,
39 sha256WithRSAEncryption,
40 sha384WithRSAEncryption,
41 sha512WithRSAEncryption,
42 sha224WithRSAEncryption,
43 pbeWithMD2AndDES_CBC,
44 pbeWithMD5AndDES_CBC,
45 pkcs9_emailAddress,
46 md2,
47 md5,
48 rc4,
49 ecdsa_with_Recommended,
50 ecdsa_with_Specified,
51 ecdsa_with_SHA224,
52 ecdsa_with_SHA256,
53 ecdsa_with_SHA384,
54 ecdsa_with_SHA512,
55 X500,
56 X509,
57 commonName,
58 serialNumber,
59 countryName,
60 localityName,
61 stateOrProvinceName,
62 organizationName,
63 organizationalUnitName,
64 organizationIdentifier,
65
66 pub const map = std.ComptimeStringMap(Oid, .{
67 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D }, .rsadsi },
68 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01 }, .pkcs },
69 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }, .rsaEncryption },
70 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x02 }, .md2WithRSAEncryption },
71 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04 }, .md5WithRSAEncryption },
72 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05 }, .sha1WithRSAEncryption },
73 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B }, .sha256WithRSAEncryption },
74 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C }, .sha384WithRSAEncryption },
75 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0D }, .sha512WithRSAEncryption },
76 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E }, .sha224WithRSAEncryption },
77 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x01 }, .pbeWithMD2AndDES_CBC },
78 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x03 }, .pbeWithMD5AndDES_CBC },
79 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01 }, .pkcs9_emailAddress },
80 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02 }, .md2 },
81 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 }, .md5 },
82 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x04 }, .rc4 },
83 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x02 }, .ecdsa_with_Recommended },
84 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03 }, .ecdsa_with_Specified },
85 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01 }, .ecdsa_with_SHA224 },
86 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02 }, .ecdsa_with_SHA256 },
87 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03 }, .ecdsa_with_SHA384 },
88 .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04 }, .ecdsa_with_SHA512 },
89 .{ &[_]u8{0x55}, .X500 },
90 .{ &[_]u8{ 0x55, 0x04 }, .X509 },
91 .{ &[_]u8{ 0x55, 0x04, 0x03 }, .commonName },
92 .{ &[_]u8{ 0x55, 0x04, 0x05 }, .serialNumber },
93 .{ &[_]u8{ 0x55, 0x04, 0x06 }, .countryName },
94 .{ &[_]u8{ 0x55, 0x04, 0x07 }, .localityName },
95 .{ &[_]u8{ 0x55, 0x04, 0x08 }, .stateOrProvinceName },
96 .{ &[_]u8{ 0x55, 0x04, 0x0A }, .organizationName },
97 .{ &[_]u8{ 0x55, 0x04, 0x0B }, .organizationalUnitName },
98 .{ &[_]u8{ 0x55, 0x04, 0x61 }, .organizationIdentifier },
99 });
100};
101
102pub const Element = struct {
103 identifier: Identifier,
104 slice: Slice,
105
106 pub const Slice = struct {
107 start: u32,
108 end: u32,
109
110 pub const empty: Slice = .{ .start = 0, .end = 0 };
111 };
112};
113
114pub const ParseElementError = error{CertificateFieldHasInvalidLength};
115
116pub fn parseElement(bytes: []const u8, index: u32) ParseElementError!Element {
117 var i = index;
118 const identifier = @bitCast(Identifier, bytes[i]);
119 i += 1;
120 const size_byte = bytes[i];
121 i += 1;
122 if ((size_byte >> 7) == 0) {
123 return .{
124 .identifier = identifier,
125 .slice = .{
126 .start = i,
127 .end = i + size_byte,
128 },
129 };
130 }
131
132 const len_size = @truncate(u7, size_byte);
133 if (len_size > @sizeOf(u32)) {
134 return error.CertificateFieldHasInvalidLength;
135 }
136
137 const end_i = i + len_size;
138 var long_form_size: u32 = 0;
139 while (i < end_i) : (i += 1) {
140 long_form_size = (long_form_size << 8) | bytes[i];
141 }
142
143 return .{
144 .identifier = identifier,
145 .slice = .{
146 .start = i,
147 .end = i + long_form_size,
148 },
149 };
150}
151
152pub const ParseObjectIdError = error{
153 CertificateHasUnrecognizedObjectId,
154 CertificateFieldHasWrongDataType,
155} || ParseElementError;
156
157pub fn parseObjectId(bytes: []const u8, element: Element) ParseObjectIdError!Oid {
158 if (element.identifier.tag != .object_identifier)
159 return error.CertificateFieldHasWrongDataType;
160 return Oid.map.get(bytes[element.slice.start..element.slice.end]) orelse
161 return error.CertificateHasUnrecognizedObjectId;
162}
163
164const std = @import("../std.zig");
165const der = @This();