Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleans up unneceesary bytes from x.encoding.asn module #22932

Merged
merged 2 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion vlib/x/encoding/asn1/bitstring.v
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ mut:
pad u8 // numbers of unused bits
}

// data returns underlying BitString data.
pub fn (bs BitString) data() []u8 {
return bs.data
}

// pad returns underlying BitString pad byte.
pub fn (bs BitString) pad() u8 {
return bs.pad
}

// check performs check internal validity of the BitString data.
fn (bs BitString) check() ! {
// to align with octet size, ie, 8 in length, pad bits only need maximum 7 bits
Expand Down Expand Up @@ -147,7 +157,7 @@ fn (bs BitString) bytes_len() int {
// Utility function

// maximum allowed binary bits string length
const max_bitstring_len = 8192
const max_bitstring_len = 65536

// valid_bitstring checks whether this s string is a valid of arrays of binary string `0` and `1`.
fn valid_bitstring(s string) bool {
Expand Down
6 changes: 1 addition & 5 deletions vlib/x/encoding/asn1/boolean.v
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,8 @@ fn (b Boolean) payload_with_rule(rule EncodingRule) ![]u8 {
return [b.value]
}

fn parse_boolean(mut p Parser) !Boolean {
return Boolean.parse(mut p)!
}

// parse tries to read a Boolean type from parser or return error on fails
fn Boolean.parse(mut p Parser) !Boolean {
pub fn Boolean.parse(mut p Parser) !Boolean {
tag := p.read_tag()!
if !tag.equal(default_boolean_tag) {
return error('Get unexpected non boolean tag')
Expand Down
4 changes: 0 additions & 4 deletions vlib/x/encoding/asn1/boolean_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ fn test_parse_boolean_with_parser() ! {
// out := p.read_element[Boolean]()!
// assert out.str() == 'Boolean (TRUE)'

// this is OK
out_2nd := parse[Boolean](data, parse_boolean)!
assert out_2nd.str() == 'Boolean (TRUE)'

// THis is ok
mut p2 := Parser.new(data)
out_3th := Boolean.parse(mut p2)!
Expand Down
23 changes: 0 additions & 23 deletions vlib/x/encoding/asn1/core.v
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,6 @@ fn (t Tag) str() string {
return '${cls}-${form}-${number}'
}

// uniqid_with_id the id of this tag for special purposes identifying in decode
fn (t Tag) uniqid_with_id(id string) string {
return '${t.str()}-${id}'
}

// bytes_len tells amount of bytes needed to store tag in base 128
fn (t Tag) bytes_len() int {
if t.number == 0 {
Expand Down Expand Up @@ -525,24 +520,6 @@ fn universal_tag_from_int(v int) !Tag {
}
}

// Params is optional params passed to encode or decodeing
// of tag, length or ASN.1 element to drive how encoding works.
@[params]
struct Params {
mut:
rule EncodingRule = .der
}

fn default_params() &Params {
return &Params{}
}

fn params_with_rule(rule EncodingRule) &Params {
return &Params{
rule: .der
}
}

// EncodingRule is standard of rule thats drives how some ASN.1
// element was encoded or deserialized.
pub enum EncodingRule {
Expand Down
24 changes: 0 additions & 24 deletions vlib/x/encoding/asn1/element.v
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,6 @@ fn (el Element) equal_payload(other Element) bool {
return constant_time_compare(x, y) == 1
}

fn Element.parse(mut p Parser) !Element {
el := p.read_tlv()!
return el
}

fn Element.decode(src []u8) !(Element, int) {
el, pos := Element.decode_with_rule(src, 0, .der)!
return el, pos
Expand Down Expand Up @@ -305,22 +300,3 @@ pub fn ElementList.from_bytes(src []u8) ![]Element {
}
return els
}

// Utility function
//
// is_element check whethers T is fullfills Element
fn is_element[T]() bool {
s := $if T is Element { true } $else { false }
return s
}

fn has_tag_method[T]() bool {
$for method in T.methods {
$if method.name == 'tag' {
$if method.return_type is Tag {
return true
}
}
}
return false
}
21 changes: 1 addition & 20 deletions vlib/x/encoding/asn1/element_decode.v
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ pub fn (el Element) unwrap_with_field_options(fo FieldOptions) !Element {
// checks inner tag from payload
tag, _ := Tag.decode_with_rule(el.payload()!, 0, .der)!
if !tag.equal(inner_tag) {
asn1_error(.unexpected_tag_value, 'Get unexpected inner tag from payload')!
return error('Get unexpected inner tag from payload')
}
}
inner_form := inner_tag.constructed
Expand All @@ -177,25 +177,6 @@ pub fn (el Element) unwrap_with_field_options(fo FieldOptions) !Element {

// unwrap the provided element, turn into inner element.
fn unwrap(el Element, mode TaggedMode, inner_tag Tag) !Element {
if el.tag().class == .universal {
return error('you cant unwrap universal element')
}
if mode == .explicit {
if !el.tag().constructed {
return error('explicit mode should have constructed tag')
}
// checks inner tag within payload
tag, _ := Tag.decode_with_rule(el.payload()!, 0, .der)!
if !tag.equal(inner_tag) {
asn1_error(.unexpected_tag_value, 'Get unexpected inner tag from payload')!
}
}
if mode == .implicit {
// the form should derived from inner element
if el.tag().constructed != inner_tag.constructed {
return error('Different form between element and provided inner_tag')
}
}
match mode {
.explicit {
// el.payload is serialized of inner element
Expand Down
3 changes: 2 additions & 1 deletion vlib/x/encoding/asn1/element_encode.v
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ module asn1
// assert out == [u8(0x0C), 0x02, 0x68, 0x69]
// ```
pub fn encode(el Element) ![]u8 {
return encode_with_options(el, '')!
// without options, we call `.encode_with_rule` directly on element.
return encode_with_rule(el, .der)!
}

// `encode_with_options` serializes element into bytes array with options string passed to drive the result.
Expand Down
50 changes: 0 additions & 50 deletions vlib/x/encoding/asn1/errors.v

This file was deleted.

41 changes: 10 additions & 31 deletions vlib/x/encoding/asn1/examples/examples0.v
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,16 @@ module main

import x.encoding.asn1

// defined type KerberosString = asn1.GeneralString directly
// produces x00000000: at ???: RUNTIME ERROR: invalid memory access
// /tmp/v_0/examples_0.01JBJNNT0EJVN2FRKJ3ZM83EC9.tmp.c:22858: by asn1__Element_encode_with_options
// /tmp/v_0/examples_0.01JBJNNT0EJVN2FRKJ3ZM83EC9.tmp.c:22838: by asn1__encode_with_options
// /tmp/v_0/examples_0.01JBJNNT0EJVN2FRKJ3ZM83EC9.tmp.c:22825: by asn1__encode
// /tmp/v_0/examples_0.01JBJNNT0EJVN2FRKJ3ZM83EC9.tmp.c:28683: by main__KerberosStringList_payload
// /tmp/v_0/examples_0.01JBJNNT0EJVN2FRKJ3ZM83EC9.tmp.c:4319: by main__KerberosStringList_payload_Interface_asn1__Element_method_wrapper
struct KerberosString {
val asn1.GeneralString
}

fn (k KerberosString) tag() asn1.Tag {
return asn1.default_generalstring_tag
}
// Previously, defined type KerberosString = asn1.GeneralString directly
// without reduplicating required Element methods, would produces
// RUNTIME ERROR: invalid memory access.
// **Updates**
// Its has been resolved in [22901](https://github.com/vlang/v/issues/22901)
// Thanks to @felipensp
type KerberosString = asn1.GeneralString

fn KerberosString.new(s string) !KerberosString {
return KerberosString{
val: asn1.GeneralString.new(s)!
}
}

fn KerberosString.from_bytes(b []u8) !KerberosString {
return KerberosString{
val: asn1.GeneralString.new(b.bytestr())!
}
}

fn (k KerberosString) payload() ![]u8 {
return k.val.payload()!
return KerberosString(asn1.GeneralString.new(s)!)
}

type KerberosStringList = []KerberosString
Expand Down Expand Up @@ -70,9 +51,7 @@ fn (pn PrincipalName) tag() asn1.Tag {
}

fn (pn PrincipalName) payload() ![]u8 {
kd := asn1.KeyDefault(map[string]asn1.Element{})
// there are some issues with make_payload when your structure contains generic.
// see https://github.com/vlang/v/issues/22721
kd := asn1.new_key_default()
payload := asn1.make_payload[PrincipalName](pn, kd)!
return payload
}
Expand Down Expand Up @@ -100,7 +79,7 @@ fn PrincipalName.decode(bytes []u8) !PrincipalName {
mut a := []KerberosString{}
for item in el_seq.fields() {
gst := item.into_object[asn1.GeneralString]()!
obj := KerberosString{gst}
obj := KerberosString(gst)
a << obj
}

Expand Down
31 changes: 1 addition & 30 deletions vlib/x/encoding/asn1/examples/examples2.v
Original file line number Diff line number Diff line change
Expand Up @@ -166,33 +166,13 @@ fn EmployeeNumber.new(val asn1.Integer) !asn1.ApplicationElement {
return asn1.ApplicationElement.from_element(val, 2, .implicit)!
}

// Issues: without defines this required tag and payload, this leads into panic RUNTIME ERROR
// 0x00000000: at ???: RUNTIME ERROR: invalid memory access
fn (e EmployeeNumber) tag() asn1.Tag {
return e.RawElement.tag()
}

fn (e EmployeeNumber) payload() ![]u8 {
return e.RawElement.payload()!
}

// // Date ::= [APPLICATION 3] IMPLICIT VisibleString -- YYYYMMDD
// Date ::= [APPLICATION 3] IMPLICIT VisibleString -- YYYYMMDD
type Date = asn1.ApplicationElement

fn Date.new(val asn1.VisibleString) !asn1.ApplicationElement {
return asn1.ApplicationElement.from_element(val, 3, .implicit)!
}

// Issues: without defines this required tag and payload, this leads into panic RUNTIME ERROR
// 0x00000000: at ???: RUNTIME ERROR: invalid memory access
fn (d Date) tag() asn1.Tag {
return d.RawElement.tag()
}

fn (d Date) payload() ![]u8 {
return d.RawElement.payload()!
}

// Name ::= [APPLICATION 1] IMPLICIT SEQUENCE {
// givenName VisibleString,
// initial VisibleString,
Expand All @@ -204,15 +184,6 @@ fn Name.new(el NameEntry) !asn1.ApplicationElement {
return asn1.ApplicationElement.from_element(el, 1, .implicit)!
}

// Issues: without defines this required tag and payload, this leads into panic RUNTIME ERROR
fn (n Name) tag() asn1.Tag {
return n.RawElement.tag()
}

fn (n Name) payload() ![]u8 {
return n.RawElement.payload()!
}

struct NameEntry {
given_name asn1.VisibleString
initial asn1.VisibleString
Expand Down
2 changes: 1 addition & 1 deletion vlib/x/encoding/asn1/examples/examples3.v
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn Example.decode(bytes []u8) !Example {
oid_tipe := fields[2].unwrap_with_options('context_specific:1;explicit; inner:6')!
tipe := oid_tipe.into_object[asn1.ObjectIdentifier]()!

// then build your Example struc
// then build your Example structure
ex := Example{
greeting: greeting
answer: answer
Expand Down
Loading
Loading