From c71c562486c5b3e92a1ea936f3c7b848853b2d5c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 22 Dec 2022 20:23:50 -0700 Subject: [PATCH] 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. --- lib/std/crypto.zig | 2 - lib/std/crypto/Certificate.zig | 84 ++++++++++++- lib/std/crypto/Certificate/Bundle.zig | 2 +- lib/std/crypto/der.zig | 165 -------------------------- 4 files changed, 84 insertions(+), 169 deletions(-) delete mode 100644 lib/std/crypto/der.zig diff --git a/lib/std/crypto.zig b/lib/std/crypto.zig index 6387eb48ae711e5a04f74e256e17e56f1b720f25..20522c175d892d77a1766fe2eb60f7947384ea09 100644 --- a/lib/std/crypto.zig +++ b/lib/std/crypto.zig @@ -177,7 +177,6 @@ const std = @import("std.zig"); pub const errors = @import("crypto/errors.zig"); pub const tls = @import("crypto/tls.zig"); -pub const der = @import("crypto/der.zig"); pub const Certificate = @import("crypto/Certificate.zig"); test { @@ -269,7 +268,6 @@ test { _ = random; _ = errors; _ = tls; - _ = der; _ = Certificate; } diff --git a/lib/std/crypto/Certificate.zig b/lib/std/crypto/Certificate.zig index 330c380e5d089546b5616bdd5135f59f7764ff51..6c51ccb1333d025668de0d494a436b8616818db9 100644 --- a/lib/std/crypto/Certificate.zig +++ b/lib/std/crypto/Certificate.zig @@ -499,9 +499,91 @@ pub fn checkVersion(bytes: []const u8, version: der.Element) !void { const std = @import("../std.zig"); const crypto = std.crypto; const mem = std.mem; -const der = std.crypto.der; const Certificate = @This(); +pub const der = struct { + pub const Class = enum(u2) { + universal, + application, + context_specific, + private, + }; + + pub const PC = enum(u1) { + primitive, + constructed, + }; + + pub const Identifier = packed struct(u8) { + tag: Tag, + pc: PC, + class: Class, + }; + + pub const Tag = enum(u5) { + boolean = 1, + integer = 2, + bitstring = 3, + null = 5, + object_identifier = 6, + sequence = 16, + sequence_of = 17, + utc_time = 23, + generalized_time = 24, + _, + }; + + pub const Element = struct { + identifier: Identifier, + slice: Slice, + + pub const Slice = struct { + start: u32, + end: u32, + + pub const empty: Slice = .{ .start = 0, .end = 0 }; + }; + }; + + pub const ParseElementError = error{CertificateFieldHasInvalidLength}; + + pub fn parseElement(bytes: []const u8, index: u32) ParseElementError!Element { + var i = index; + const identifier = @bitCast(Identifier, bytes[i]); + i += 1; + const size_byte = bytes[i]; + i += 1; + if ((size_byte >> 7) == 0) { + return .{ + .identifier = identifier, + .slice = .{ + .start = i, + .end = i + size_byte, + }, + }; + } + + const len_size = @truncate(u7, size_byte); + if (len_size > @sizeOf(u32)) { + return error.CertificateFieldHasInvalidLength; + } + + const end_i = i + len_size; + var long_form_size: u32 = 0; + while (i < end_i) : (i += 1) { + long_form_size = (long_form_size << 8) | bytes[i]; + } + + return .{ + .identifier = identifier, + .slice = .{ + .start = i, + .end = i + long_form_size, + }, + }; + } +}; + test { _ = Bundle; } diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index ea2831bcd9db86727c3b2b4ee37b4cf1c92fe1d4..8c1a63cd468a941072a7f2568b03d99fc3479ff9 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -154,8 +154,8 @@ const fs = std.fs; const mem = std.mem; const crypto = std.crypto; const Allocator = std.mem.Allocator; -const der = std.crypto.der; const Certificate = std.crypto.Certificate; +const der = Certificate.der; const Bundle = @This(); const base64 = std.base64.standard.decoderWithIgnore(" \t\r\n"); diff --git a/lib/std/crypto/der.zig b/lib/std/crypto/der.zig deleted file mode 100644 index 9f4065eeb760df70b9ba9461f56607b2c5b5cc06..0000000000000000000000000000000000000000 --- a/lib/std/crypto/der.zig +++ /dev/null @@ -1,165 +0,0 @@ -pub const Class = enum(u2) { - universal, - application, - context_specific, - private, -}; - -pub const PC = enum(u1) { - primitive, - constructed, -}; - -pub const Identifier = packed struct(u8) { - tag: Tag, - pc: PC, - class: Class, -}; - -pub const Tag = enum(u5) { - boolean = 1, - integer = 2, - bitstring = 3, - null = 5, - object_identifier = 6, - sequence = 16, - sequence_of = 17, - utc_time = 23, - generalized_time = 24, - _, -}; - -pub const Oid = enum { - rsadsi, - pkcs, - rsaEncryption, - md2WithRSAEncryption, - md5WithRSAEncryption, - sha1WithRSAEncryption, - sha256WithRSAEncryption, - sha384WithRSAEncryption, - sha512WithRSAEncryption, - sha224WithRSAEncryption, - pbeWithMD2AndDES_CBC, - pbeWithMD5AndDES_CBC, - pkcs9_emailAddress, - md2, - md5, - rc4, - ecdsa_with_Recommended, - ecdsa_with_Specified, - ecdsa_with_SHA224, - ecdsa_with_SHA256, - ecdsa_with_SHA384, - ecdsa_with_SHA512, - X500, - X509, - commonName, - serialNumber, - countryName, - localityName, - stateOrProvinceName, - organizationName, - organizationalUnitName, - organizationIdentifier, - - pub const map = std.ComptimeStringMap(Oid, .{ - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D }, .rsadsi }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01 }, .pkcs }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }, .rsaEncryption }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x02 }, .md2WithRSAEncryption }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04 }, .md5WithRSAEncryption }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05 }, .sha1WithRSAEncryption }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B }, .sha256WithRSAEncryption }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C }, .sha384WithRSAEncryption }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0D }, .sha512WithRSAEncryption }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E }, .sha224WithRSAEncryption }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x01 }, .pbeWithMD2AndDES_CBC }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x03 }, .pbeWithMD5AndDES_CBC }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01 }, .pkcs9_emailAddress }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02 }, .md2 }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 }, .md5 }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x04 }, .rc4 }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x02 }, .ecdsa_with_Recommended }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03 }, .ecdsa_with_Specified }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01 }, .ecdsa_with_SHA224 }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02 }, .ecdsa_with_SHA256 }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03 }, .ecdsa_with_SHA384 }, - .{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04 }, .ecdsa_with_SHA512 }, - .{ &[_]u8{0x55}, .X500 }, - .{ &[_]u8{ 0x55, 0x04 }, .X509 }, - .{ &[_]u8{ 0x55, 0x04, 0x03 }, .commonName }, - .{ &[_]u8{ 0x55, 0x04, 0x05 }, .serialNumber }, - .{ &[_]u8{ 0x55, 0x04, 0x06 }, .countryName }, - .{ &[_]u8{ 0x55, 0x04, 0x07 }, .localityName }, - .{ &[_]u8{ 0x55, 0x04, 0x08 }, .stateOrProvinceName }, - .{ &[_]u8{ 0x55, 0x04, 0x0A }, .organizationName }, - .{ &[_]u8{ 0x55, 0x04, 0x0B }, .organizationalUnitName }, - .{ &[_]u8{ 0x55, 0x04, 0x61 }, .organizationIdentifier }, - }); -}; - -pub const Element = struct { - identifier: Identifier, - slice: Slice, - - pub const Slice = struct { - start: u32, - end: u32, - - pub const empty: Slice = .{ .start = 0, .end = 0 }; - }; -}; - -pub const ParseElementError = error{CertificateFieldHasInvalidLength}; - -pub fn parseElement(bytes: []const u8, index: u32) ParseElementError!Element { - var i = index; - const identifier = @bitCast(Identifier, bytes[i]); - i += 1; - const size_byte = bytes[i]; - i += 1; - if ((size_byte >> 7) == 0) { - return .{ - .identifier = identifier, - .slice = .{ - .start = i, - .end = i + size_byte, - }, - }; - } - - const len_size = @truncate(u7, size_byte); - if (len_size > @sizeOf(u32)) { - return error.CertificateFieldHasInvalidLength; - } - - const end_i = i + len_size; - var long_form_size: u32 = 0; - while (i < end_i) : (i += 1) { - long_form_size = (long_form_size << 8) | bytes[i]; - } - - return .{ - .identifier = identifier, - .slice = .{ - .start = i, - .end = i + long_form_size, - }, - }; -} - -pub const ParseObjectIdError = error{ - CertificateHasUnrecognizedObjectId, - CertificateFieldHasWrongDataType, -} || ParseElementError; - -pub fn parseObjectId(bytes: []const u8, element: Element) ParseObjectIdError!Oid { - if (element.identifier.tag != .object_identifier) - return error.CertificateFieldHasWrongDataType; - return Oid.map.get(bytes[element.slice.start..element.slice.end]) orelse - return error.CertificateHasUnrecognizedObjectId; -} - -const std = @import("../std.zig"); -const der = @This(); -- 2.54.0