diff --git a/packages/auto-id/package.json b/packages/auto-id/package.json index fee29945..c3a70e4c 100644 --- a/packages/auto-id/package.json +++ b/packages/auto-id/package.json @@ -12,18 +12,18 @@ "@autonomys/auto-utils": "workspace:*", "@peculiar/asn1-schema": "^2.3.8", "@peculiar/asn1-x509": "^2.3.8", - "asn1-ts": "^8.0.2" + "asn1js": "^3.0.5" }, "files": [ "dist", "README.md" ], "devDependencies": { - "@types/node": "^20.12.12", "@types/jest": "^29.5.12", + "@types/node": "^20.12.12", "jest": "^29.7.0", "ts-jest": "^29.1.4", "ts-node": "^10.9.2", "typescript": "^5.4.5" } -} \ No newline at end of file +} diff --git a/packages/auto-id/src/utils.ts b/packages/auto-id/src/utils.ts index a770215f..62093fe2 100644 --- a/packages/auto-id/src/utils.ts +++ b/packages/auto-id/src/utils.ts @@ -1,77 +1,23 @@ -import { - ASN1Construction, - ASN1TagClass, - ASN1UniversalType, - DERElement, - ObjectIdentifier, -} from 'asn1-ts' - -/** - * Represents an ASN.1 AlgorithmIdentifier structure commonly used in cryptographic protocols. - * This class handles the construction and DER encoding of an algorithm identifier, which typically - * consists of an algorithm OID and optional parameters. - */ -class AlgorithmIdentifier { - public algorithm: ObjectIdentifier - public parameters: null - - /** - * Creates an instance of AlgorithmIdentifier. - * - * @param algorithm The ObjectIdentifier of the algorithm. - * @param parameters The parameters of the algorithm, generally null in many cryptographic uses. - */ - constructor(algorithm: ObjectIdentifier, parameters: null = null) { - this.algorithm = algorithm - this.parameters = parameters - } - - /** - * Encodes this AlgorithmIdentifier into its DER (Distinguished Encoding Rules) format. - * - * @returns Uint8Array containing the DER encoded bytes of the AlgorithmIdentifier. - */ - public toDER(): Uint8Array { - const sequenceElement = new DERElement( - ASN1TagClass.universal, - ASN1Construction.constructed, - ASN1UniversalType.sequence, - ) - - const oidElement = new DERElement( - ASN1TagClass.universal, - ASN1Construction.primitive, - ASN1UniversalType.objectIdentifier, - ) - oidElement.objectIdentifier = this.algorithm - - const nullElement = new DERElement( - ASN1TagClass.universal, - ASN1Construction.primitive, - ASN1UniversalType.nill, - ) - - sequenceElement.sequence = [oidElement, nullElement] - - return sequenceElement.toBytes() - } -} +import { ObjectIdentifier } from 'asn1js' /** * Encodes a given string representation of an OID into its DER format. * This function is specifically used to encode signature algorithm OIDs. * * @param oid The string representation of the ObjectIdentifier to be encoded. - * @returns Uint8Array containing the DER encoded OID. - * @example - * ```ts - * const oid = '1.2.840.113549.1.1.11' // Example OID for SHA-256 with RSA Encryption - * const derEncodedOID = derEncodeSignatureAlgorithmOID(oid) - * console.log(new Uint8Array(derEncodedOID)) // Logs the DER encoded bytes - * ``` + * @returns Uint8Array containing the DER encoded OID along with NULL params of X.509 signature algorithm. */ export function derEncodeSignatureAlgorithmOID(oid: string): Uint8Array { - const numbers = oid.split('.').map((n) => parseInt(n, 10)) // Convert the string parts to numbers - const algorithmIdentifier = new AlgorithmIdentifier(new ObjectIdentifier(numbers)) - return algorithmIdentifier.toDER() + const objectIdentifier = new ObjectIdentifier({ value: oid }) + const berArrayBuffer = objectIdentifier.toBER(false) + + // Typically, in X.509, the algorithm identifier is followed by parameters; for many algorithms, this is just NULL. + const nullParameter = [0x05, 0x00] // DER encoding for NULL + + // Calculate the total length including OID and NULL parameter + const totalLength = berArrayBuffer.byteLength + nullParameter.length + + const sequenceHeader = [0x30, totalLength] // 0x30 is the DER tag for SEQUENCE + + return new Uint8Array([...sequenceHeader, ...new Uint8Array(berArrayBuffer), ...nullParameter]) } diff --git a/packages/auto-id/tests/utils.test.ts b/packages/auto-id/tests/utils.test.ts index 67ee6701..1b58b8dc 100644 --- a/packages/auto-id/tests/utils.test.ts +++ b/packages/auto-id/tests/utils.test.ts @@ -1,4 +1,5 @@ import { AsnParser } from '@peculiar/asn1-schema' // A library to parse ASN.1 +// TODO: See why X509Certificate (from crypto) is not compatible argument. import { Certificate } from '@peculiar/asn1-x509' // Assuming X.509 certificate handling import fs from 'fs' import { derEncodeSignatureAlgorithmOID } from '../src/utils' @@ -16,14 +17,14 @@ describe('Verify crypto functions', () => { const signatureAlgorithmOID = cert.signatureAlgorithm.algorithm // DER encode the OID - const derEncodedOID = derEncodeSignatureAlgorithmOID(signatureAlgorithmOID.toString()) + const derEncodedOID = derEncodeSignatureAlgorithmOID(signatureAlgorithmOID) + // + // console.log(Buffer.from(derEncodedOID)) - // Expected DER encoded OID from a known good implementation (example hex string) - const fromRustImplementation = new Uint8Array( - Buffer.from('300d06092a864886f70d01010b0500', 'hex'), - ) + // Convert derEncodedOID to hex string for comparison + const derEncodedOIDHex = Buffer.from(derEncodedOID).toString('hex') - // Compare the DER encoded OID with the expected result - expect(new Uint8Array(derEncodedOID)).toEqual(fromRustImplementation) + // Expected DER encoded OID from the result of tests in https://github.com/subspace/subspace/blob/d875a5aac35c1732eec61ce4359782eff58ff6fc/domains/pallets/auto-id/src/tests.rs#L127 + expect(derEncodedOIDHex).toEqual('300d06092a864886f70d01010b0500') }) }) diff --git a/yarn.lock b/yarn.lock index b8296033..d2d7b95a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -36,7 +36,7 @@ __metadata: "@peculiar/asn1-x509": "npm:^2.3.8" "@types/jest": "npm:^29.5.12" "@types/node": "npm:^20.12.12" - asn1-ts: "npm:^8.0.2" + asn1js: "npm:^3.0.5" jest: "npm:^29.7.0" ts-jest: "npm:^29.1.4" ts-node: "npm:^10.9.2" @@ -1825,15 +1825,6 @@ __metadata: languageName: node linkType: hard -"asn1-ts@npm:^8.0.2": - version: 8.0.2 - resolution: "asn1-ts@npm:8.0.2" - dependencies: - tslib: "npm:^2.4.1" - checksum: 10c0/37ca66c319730ae7a2762642a3bb867b298a1ad721a11f859f900332b39117497fd337ba16e7d4c4f7dc9bd6f5e577d8d49c07edcc7fdebeff1d42d7a66a3112 - languageName: node - linkType: hard - "asn1js@npm:^3.0.5": version: 3.0.5 resolution: "asn1js@npm:3.0.5" @@ -4866,7 +4857,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.6.1": +"tslib@npm:^2.4.0, tslib@npm:^2.6.1": version: 2.6.3 resolution: "tslib@npm:2.6.3" checksum: 10c0/2598aef53d9dbe711af75522464b2104724d6467b26a60f2bdac8297d2b5f1f6b86a71f61717384aa8fd897240467aaa7bcc36a0700a0faf751293d1331db39a