Skip to content

Commit

Permalink
feat(schema): Add APPLICATION tags support
Browse files Browse the repository at this point in the history
  • Loading branch information
li0ard committed Oct 6, 2024
1 parent adf4c45 commit c2ab98a
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/schema/src/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface IAsn1PropOptions {
optional?: boolean;
defaultValue?: unknown;
context?: number;
application?: number;
implicit?: boolean;
converter?: IAsnConverter;
repeated?: AsnRepeatType;
Expand Down
51 changes: 50 additions & 1 deletion packages/schema/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface IAsnSchemaItem {
optional?: boolean;
defaultValue?: unknown;
context?: number;
application?: number;
implicit?: boolean;
converter?: IAsnConverter;
repeated?: AsnRepeatType;
Expand Down Expand Up @@ -168,7 +169,55 @@ export class AsnSchemaStorage {
value: [asn1Item],
}));
}
} else {
}
else if (item.application !== null && item.application !== undefined) {
// APPLICATION
if(item.implicit) {
// IMPLICIT
if (typeof item.type === "number" || isConvertible(item.type)) {
const Container = item.repeated
? asn1js.Constructed
: asn1js.Primitive;
asn1Value.push(new Container({
name,
optional,
idBlock: {
tagClass:2,
tagNumber: item.application,
},
}));
} else {
this.cache(item.type);
const isRepeated = !!item.repeated;
let value = !isRepeated
? this.get(item.type, true).schema
: asn1Item;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value = "valueBlock" in value ? (value as asn1js.Sequence).valueBlock.value : (value as any).value;
asn1Value.push(new asn1js.Constructed({
name: !isRepeated ? name : "",
optional,
idBlock: {
tagClass: 2,
tagNumber: item.application,
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: value as any,
}));
}
} else {
// EXPLICIT
asn1Value.push(new asn1js.Constructed({
optional,
idBlock: {
tagClass: 2,
tagNumber: item.application
},
value: [asn1Item]
}))
}
}
else {
// UNIVERSAL
asn1Item.optional = optional;
asn1Value.push(asn1Item);
Expand Down
42 changes: 41 additions & 1 deletion packages/schema/src/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,47 @@ export class AsnSerializer {
value: [asn1Item],
}));
}
} else if (schemaItem.repeated) {
}
else if (typeof schemaItem.application === "number") {
// APPLICATION
if (schemaItem.implicit) {
// IMPLICIT
if (!schemaItem.repeated
&& (typeof schemaItem.type === "number" || isConvertible(schemaItem.type))) {
const value: { valueHex?: ArrayBuffer, value?: ArrayBuffer; } = {};
value.valueHex = asn1Item instanceof asn1js.Null ? asn1Item.valueBeforeDecodeView : asn1Item.valueBlock.toBER();
asn1Value.push(new asn1js.Primitive({
optional: schemaItem.optional,
idBlock: {
tagClass: 2,
tagNumber: schemaItem.application,
},
...value,
}));
} else {
asn1Value.push(new asn1js.Constructed({
optional: schemaItem.optional,
idBlock: {
tagClass: 2,
tagNumber: schemaItem.application,
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: (asn1Item as any).valueBlock.value,
}));
}
} else {
// EXPLICIT
asn1Value.push(new asn1js.Constructed({
optional: schemaItem.optional,
idBlock: {
tagClass: 2,
tagNumber: schemaItem.application,
},
value: [asn1Item],
}));
}
}
else if (schemaItem.repeated) {
asn1Value = asn1Value.concat(asn1Item);
} else {
// UNIVERSAL
Expand Down
51 changes: 51 additions & 0 deletions packages/schema/test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,57 @@ context("Test", () => {
});
});

context("APPLICATION", () => {
context("IMPLICIT", () => {
class Test {
@src.AsnProp({
type: src.OctetString,
application: 33,
implicit: true,
})
public value = new src.OctetString();
}

it("serialize", () => {
const obj = new Test();
obj.value = new src.OctetString([1, 2, 3, 4, 5]);
const buf = src.AsnSerializer.serialize(obj);
console.log(Buffer.from(buf).toString("hex"))
assertBuffer(Buffer.from(buf), Buffer.from("30085f21050102030405", "hex"));
});

it("parse", () => {
const obj = src.AsnParser.parse(new Uint8Array(Buffer.from("30085f21050102030405", "hex")).buffer, Test);
assert.strictEqual(obj.value.byteLength, 5);
});
})

context("EXPLICIT", () => {

class Test {
@src.AsnProp({
type: src.AsnPropTypes.OctetString,
application: 152,
})
public value!: ArrayBuffer;
}

it("serialize", () => {
const obj = new Test();
obj.value = new Uint8Array([1, 2, 3, 4, 5]).buffer;
const buf = src.AsnSerializer.serialize(obj);
assertBuffer(Buffer.from(buf), Buffer.from("300b7f81180704050102030405", "hex"));
});

it("parse", () => {
const obj = src.AsnParser.parse(new Uint8Array(Buffer.from("300b7f81180704050102030405", "hex")).buffer, Test);
console.log(obj)
assert.strictEqual(obj.value.byteLength, 5);
});

});
})

context("CONTEXT-SPECIFIC", () => {

context("IMPLICIT", () => {
Expand Down

0 comments on commit c2ab98a

Please sign in to comment.