Compare commits

..

12 Commits

12 changed files with 108 additions and 54 deletions

17
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: build
on: [push]
jobs:
build:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: "22"
- run: npm clean-install
- run: npm run build
- name: check dist files
run: |
test $(git status --porcelain | tee /dev/stderr | wc -l) -eq 0
- run: npm test

3
.prettierignore Normal file
View File

@ -0,0 +1,3 @@
package.json
package-lock.json
dist/

5
.prettierrc.json Normal file
View File

@ -0,0 +1,5 @@
{
"singleQuote": true,
"trailingComma": "none",
"useTabs": true
}

View File

@ -1,7 +1,7 @@
# @root/asn1 # [@root/asn1](https://git.rootprojects.org/root/asn1.js)
Built by [The Root Company](https://therootcompany.com) Built by [The Root Company](https://therootcompany.com)
for [Greenlock](https://greenlock.domains) for [Greenlock](https://git.rootprojects.org/root/greenlock.js)
and [Keypairs.js](https://git.rootprojects.org/root/keypairs.js) and [Keypairs.js](https://git.rootprojects.org/root/keypairs.js)
Lightweight, Zero-Dependency ASN.1 encoder and decoder for Node.js and Browsers, Lightweight, Zero-Dependency ASN.1 encoder and decoder for Node.js and Browsers,
@ -386,10 +386,7 @@ Our goal is to operate as a sustainable community.
Your contributions - both in code and _especially_ monetarily - Your contributions - both in code and _especially_ monetarily -
help to not just this project, but also our broader work help to not just this project, but also our broader work
of [projects](https://rootprojects.org) that fuel the **Indie Web**. of [projects](https://therootcompany.com) that fuel the **Indie Web**.
Also, we chat on [Keybase](https://keybase.io)
in [#rootprojects](https://keybase.io/team/rootprojects)
# Commercial Support # Commercial Support

View File

@ -1,28 +1,42 @@
#!/bin/bash #!/bin/sh
set -e
set -u
# TODO convert to JS # TODO have GPT rewrite this script in JS for running on Windows
cat parser.js packer.js > all.tmp.js
sed -i '' '/use strict/d' all.tmp.js
sed -i '' '/require/d' all.tmp.js
sed -i '' '/exports/d' all.tmp.js
echo ';(function () {' > dist/asn1.js fn_sed_i() { (
echo "'use strict';" >> dist/asn1.js b_pattern="${1}"
echo "var ASN1 = window.ASN1 = {};" >> dist/asn1.js b_path="${2}"
echo "var Enc = window.Encoding;" >> dist/asn1.js if sed --version 2>&1 | grep -q -F GNU; then
cat all.tmp.js >> dist/asn1.js sed -i "${b_pattern}" "${b_path}"
rm all.tmp.js else
echo '}());' >> dist/asn1.js sed -i '' "${b_pattern}" "${b_path}"
fi
); }
rm dist/*.gz cat parser.js packer.js > ./all.tmp.js
fn_sed_i '/use strict/d' ./all.tmp.js
fn_sed_i '/require/d' ./all.tmp.js
fn_sed_i '/exports/d' ./all.tmp.js
cat node_modules/@root/encoding/dist/encoding.all.js > all.js {
cat dist/asn1.js >> all.js echo ';(function () {'
uglifyjs dist/asn1.js > dist/asn1.min.js echo "'use strict';"
gzip dist/asn1.min.js echo "var ASN1 = window.ASN1 = {};"
uglifyjs dist/asn1.js > dist/asn1.min.js echo "var Enc = window.Encoding;"
cat ./all.tmp.js
} > ./dist/asn1.js
rm ./all.tmp.js
echo '}());' >> ./dist/asn1.js
mv all.js dist/asn1.all.js rm -f ./dist/*.gz
uglifyjs dist/asn1.all.js > dist/asn1.all.min.js
gzip dist/asn1.all.min.js npm clean-install
uglifyjs dist/asn1.all.js > dist/asn1.all.min.js cat ./node_modules/@root/encoding/dist/encoding.all.js > ./all.js
cat ./dist/asn1.js >> ./all.js
npx -p uglify-js@3.19.2 uglifyjs ./dist/asn1.js -o ./dist/asn1.min.js
gzip -k ./dist/asn1.min.js
mv ./all.js ./dist/asn1.all.js
npx -p uglify-js@3.19.2 uglifyjs ./dist/asn1.all.js -o ./dist/asn1.all.min.js
gzip -k ./dist/asn1.all.min.js

6
dist/asn1.all.js vendored
View File

@ -291,9 +291,9 @@ ASN1.parseVerbose = function parseAsn1Helper(buf, opts) {
index += 2 + child.lengthSize + child.length; index += 2 + child.lengthSize + child.length;
//console.warn('2 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', (2 + child.lengthSize + child.length)); //console.warn('2 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', (2 + child.lengthSize + child.length));
if (index > 2 + asn1.lengthSize + asn1.length) { if (index > 2 + asn1.lengthSize + asn1.length) {
if (!eager) { //if (!eager) {
console.error(JSON.stringify(asn1, ASN1._replacer, 2)); // console.error(JSON.stringify(asn1, ASN1._replacer, 2));
} //}
throw new Error( throw new Error(
'Parse error: child value length (' + 'Parse error: child value length (' +
child.length + child.length +

File diff suppressed because one or more lines are too long

6
dist/asn1.js vendored
View File

@ -92,9 +92,9 @@ ASN1.parseVerbose = function parseAsn1Helper(buf, opts) {
index += 2 + child.lengthSize + child.length; index += 2 + child.lengthSize + child.length;
//console.warn('2 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', (2 + child.lengthSize + child.length)); //console.warn('2 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', (2 + child.lengthSize + child.length));
if (index > 2 + asn1.lengthSize + asn1.length) { if (index > 2 + asn1.lengthSize + asn1.length) {
if (!eager) { //if (!eager) {
console.error(JSON.stringify(asn1, ASN1._replacer, 2)); // console.error(JSON.stringify(asn1, ASN1._replacer, 2));
} //}
throw new Error( throw new Error(
'Parse error: child value length (' + 'Parse error: child value length (' +
child.length + child.length +

2
dist/asn1.min.js vendored
View File

@ -1 +1 @@
(function(){"use strict";var ASN1=window.ASN1={};var Enc=window.Encoding;ASN1.ELOOPN=102;ASN1.ELOOP="uASN1.js Error: iterated over "+ASN1.ELOOPN+"+ elements (probably a malformed file)";ASN1.EDEEPN=60;ASN1.EDEEP="uASN1.js Error: element nested "+ASN1.EDEEPN+"+ layers deep (probably a malformed file)";ASN1.CTYPES=[48,49,160,161];ASN1.VTYPES=[1,2,5,6,12,130];ASN1.parseVerbose=function parseAsn1Helper(buf,opts){if(!opts){opts={}}function parseAsn1(buf,depth,eager){if(depth.length>=ASN1.EDEEPN){throw new Error(ASN1.EDEEP)}var index=2;var asn1={type:buf[0],lengthSize:0,length:buf[1]};var child;var iters=0;var adjust=0;var adjustedLen;if(128&asn1.length){asn1.lengthSize=127&asn1.length;asn1.length=parseInt(Enc.bufToHex(buf.slice(index,index+asn1.lengthSize)),16);index+=asn1.lengthSize}if(0===buf[index]&&(2===asn1.type||3===asn1.type)){if(asn1.length>1){index+=1;adjust=-1}}adjustedLen=asn1.length+adjust;function parseChildren(eager){asn1.children=[];while(iters<ASN1.ELOOPN&&index<2+asn1.length+asn1.lengthSize){iters+=1;depth.length+=1;child=parseAsn1(buf.slice(index,index+adjustedLen),depth,eager);depth.length-=1;index+=2+child.lengthSize+child.length;if(index>2+asn1.lengthSize+asn1.length){if(!eager){console.error(JSON.stringify(asn1,ASN1._replacer,2))}throw new Error("Parse error: child value length ("+child.length+") is greater than remaining parent length ("+(asn1.length-index)+" = "+asn1.length+" - "+index+")")}asn1.children.push(child)}if(index!==2+asn1.lengthSize+asn1.length){throw new Error("premature end-of-file")}if(iters>=ASN1.ELOOPN){throw new Error(ASN1.ELOOP)}delete asn1.value;return asn1}if(-1!==ASN1.CTYPES.indexOf(asn1.type)){return parseChildren(eager)}asn1.value=buf.slice(index,index+adjustedLen);if(opts.json){asn1.value=Enc.bufToHex(asn1.value)}if(-1!==ASN1.VTYPES.indexOf(asn1.type)){return asn1}try{return parseChildren(true)}catch(e){asn1.children.length=0;return asn1}}var asn1=parseAsn1(buf,[]);var len=buf.byteLength||buf.length;if(len!==2+asn1.lengthSize+asn1.length){throw new Error("Length of buffer does not match length of ASN.1 sequence.")}return asn1};ASN1._toArray=function toArray(next,opts){var typ=opts.json?Enc.numToHex(next.type):next.type;var val=next.value;if(val){if("string"!==typeof val&&opts.json){val=Enc.bufToHex(val)}return[typ,val]}return[typ,next.children.map(function(child){return toArray(child,opts)})]};ASN1.parse=function(opts){var opts2={json:false!==opts.json};var verbose=ASN1.parseVerbose(opts.der,opts2);if(opts.verbose){return verbose}return ASN1._toArray(verbose,opts2)};ASN1._replacer=function(k,v){if("type"===k){return"0x"+Enc.numToHex(v)}if(v&&"value"===k){return"0x"+Enc.bufToHex(v.data||v)}return v};function Any(){var args=Array.prototype.slice.call(arguments);var typ=args.shift();var str=args.join("").replace(/\s+/g,"").toLowerCase();var len=str.length/2;var lenlen=0;var hex=typ;if("number"===typeof hex){hex=Enc.numToHex(hex)}if(len!==Math.round(len)){throw new Error("invalid hex")}if(len>127){lenlen+=1;while(len>255){lenlen+=1;len=len>>8}}if(lenlen){hex+=Enc.numToHex(128+lenlen)}return hex+Enc.numToHex(str.length/2)+str}ASN1.Any=Any;ASN1.UInt=function UINT(){var str=Array.prototype.slice.call(arguments).join("");var first=parseInt(str.slice(0,2),16);if(128&first){str="00"+str}return Any("02",str)};ASN1.BitStr=function BITSTR(){var str=Array.prototype.slice.call(arguments).join("");return Any("03","00"+str)};ASN1._toArray=function toArray(next,opts){var typ=opts.json?Enc.numToHex(next.type):next.type;var val=next.value;if(val){if("string"!==typeof val&&opts.json){val=Enc.bufToHex(val)}return[typ,val]}return[typ,next.children.map(function(child){return toArray(child,opts)})]};ASN1._pack=function(arr){var typ=arr[0];if("number"===typeof arr[0]){typ=Enc.numToHex(arr[0])}var str="";if(Array.isArray(arr[1])){arr[1].forEach(function(a){str+=ASN1._pack(a)})}else if("string"===typeof arr[1]){str=arr[1]}else if(arr[1].byteLength){str=Enc.bufToHex(arr[1])}else{throw new Error("unexpected array")}if("03"===typ){return ASN1.BitStr(str)}else if("02"===typ){return ASN1.UInt(str)}else{return Any(typ,str)}};ASN1.pack=function(asn1,opts){if(!opts){opts={}}if(!Array.isArray(asn1)){asn1=ASN1._toArray(asn1,{json:true})}var result=ASN1._pack(asn1);if(opts.json){return result}return Enc.hexToBuf(result)}})(); (function(){"use strict";var ASN1=window.ASN1={};var Enc=window.Encoding;ASN1.ELOOPN=102;ASN1.ELOOP="uASN1.js Error: iterated over "+ASN1.ELOOPN+"+ elements (probably a malformed file)";ASN1.EDEEPN=60;ASN1.EDEEP="uASN1.js Error: element nested "+ASN1.EDEEPN+"+ layers deep (probably a malformed file)";ASN1.CTYPES=[48,49,160,161];ASN1.VTYPES=[1,2,5,6,12,130];ASN1.parseVerbose=function parseAsn1Helper(buf,opts){if(!opts){opts={}}function parseAsn1(buf,depth,eager){if(depth.length>=ASN1.EDEEPN){throw new Error(ASN1.EDEEP)}var index=2;var asn1={type:buf[0],lengthSize:0,length:buf[1]};var child;var iters=0;var adjust=0;var adjustedLen;if(128&asn1.length){asn1.lengthSize=127&asn1.length;asn1.length=parseInt(Enc.bufToHex(buf.slice(index,index+asn1.lengthSize)),16);index+=asn1.lengthSize}if(0===buf[index]&&(2===asn1.type||3===asn1.type)){if(asn1.length>1){index+=1;adjust=-1}}adjustedLen=asn1.length+adjust;function parseChildren(eager){asn1.children=[];while(iters<ASN1.ELOOPN&&index<2+asn1.length+asn1.lengthSize){iters+=1;depth.length+=1;child=parseAsn1(buf.slice(index,index+adjustedLen),depth,eager);depth.length-=1;index+=2+child.lengthSize+child.length;if(index>2+asn1.lengthSize+asn1.length){throw new Error("Parse error: child value length ("+child.length+") is greater than remaining parent length ("+(asn1.length-index)+" = "+asn1.length+" - "+index+")")}asn1.children.push(child)}if(index!==2+asn1.lengthSize+asn1.length){throw new Error("premature end-of-file")}if(iters>=ASN1.ELOOPN){throw new Error(ASN1.ELOOP)}delete asn1.value;return asn1}if(-1!==ASN1.CTYPES.indexOf(asn1.type)){return parseChildren(eager)}asn1.value=buf.slice(index,index+adjustedLen);if(opts.json){asn1.value=Enc.bufToHex(asn1.value)}if(-1!==ASN1.VTYPES.indexOf(asn1.type)){return asn1}try{return parseChildren(true)}catch(e){asn1.children.length=0;return asn1}}var asn1=parseAsn1(buf,[]);var len=buf.byteLength||buf.length;if(len!==2+asn1.lengthSize+asn1.length){throw new Error("Length of buffer does not match length of ASN.1 sequence.")}return asn1};ASN1._toArray=function toArray(next,opts){var typ=opts.json?Enc.numToHex(next.type):next.type;var val=next.value;if(val){if("string"!==typeof val&&opts.json){val=Enc.bufToHex(val)}return[typ,val]}return[typ,next.children.map(function(child){return toArray(child,opts)})]};ASN1.parse=function(opts){var opts2={json:false!==opts.json};var verbose=ASN1.parseVerbose(opts.der,opts2);if(opts.verbose){return verbose}return ASN1._toArray(verbose,opts2)};ASN1._replacer=function(k,v){if("type"===k){return"0x"+Enc.numToHex(v)}if(v&&"value"===k){return"0x"+Enc.bufToHex(v.data||v)}return v};function Any(){var args=Array.prototype.slice.call(arguments);var typ=args.shift();var str=args.join("").replace(/\s+/g,"").toLowerCase();var len=str.length/2;var lenlen=0;var hex=typ;if("number"===typeof hex){hex=Enc.numToHex(hex)}if(len!==Math.round(len)){throw new Error("invalid hex")}if(len>127){lenlen+=1;while(len>255){lenlen+=1;len=len>>8}}if(lenlen){hex+=Enc.numToHex(128+lenlen)}return hex+Enc.numToHex(str.length/2)+str}ASN1.Any=Any;ASN1.UInt=function UINT(){var str=Array.prototype.slice.call(arguments).join("");var first=parseInt(str.slice(0,2),16);if(128&first){str="00"+str}return Any("02",str)};ASN1.BitStr=function BITSTR(){var str=Array.prototype.slice.call(arguments).join("");return Any("03","00"+str)};ASN1._toArray=function toArray(next,opts){var typ=opts.json?Enc.numToHex(next.type):next.type;var val=next.value;if(val){if("string"!==typeof val&&opts.json){val=Enc.bufToHex(val)}return[typ,val]}return[typ,next.children.map(function(child){return toArray(child,opts)})]};ASN1._pack=function(arr){var typ=arr[0];if("number"===typeof arr[0]){typ=Enc.numToHex(arr[0])}var str="";if(Array.isArray(arr[1])){arr[1].forEach(function(a){str+=ASN1._pack(a)})}else if("string"===typeof arr[1]){str=arr[1]}else if(arr[1].byteLength){str=Enc.bufToHex(arr[1])}else{throw new Error("unexpected array")}if("03"===typ){return ASN1.BitStr(str)}else if("02"===typ){return ASN1.UInt(str)}else{return Any(typ,str)}};ASN1.pack=function(asn1,opts){if(!opts){opts={}}if(!Array.isArray(asn1)){asn1=ASN1._toArray(asn1,{json:true})}var result=ASN1._pack(asn1);if(opts.json){return result}return Enc.hexToBuf(result)}})();

33
package-lock.json generated
View File

@ -1,19 +1,32 @@
{ {
"name": "@root/asn1", "name": "@root/asn1",
"version": "1.0.0", "version": "1.0.1",
"lockfileVersion": 1, "lockfileVersion": 3,
"requires": true, "requires": true,
"dependencies": { "packages": {
"@root/encoding": { "": {
"name": "@root/asn1",
"version": "1.0.1",
"license": "MPL-2.0",
"dependencies": {
"@root/encoding": "^1.0.1"
},
"devDependencies": {
"@root/pem": "^1.0.4"
}
},
"node_modules/@root/encoding": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/@root/encoding/-/encoding-1.0.1.tgz", "resolved": "https://registry.npmjs.org/@root/encoding/-/encoding-1.0.1.tgz",
"integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ==" "integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ==",
"license": "MPL-2.0"
}, },
"@root/pem": { "node_modules/@root/pem": {
"version": "1.0.3", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/@root/pem/-/pem-1.0.3.tgz", "resolved": "https://registry.npmjs.org/@root/pem/-/pem-1.0.4.tgz",
"integrity": "sha512-6iFwsbwm6YzWdfjogHzLTYkA1KWdeEkutVX2BBVfhyWoE9q0vp89G7mAcLIhi0QTRd199AMOacHWFq+gTyQkVA==", "integrity": "sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA==",
"dev": true "dev": true,
"license": "MPL-2.0"
} }
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@root/asn1", "name": "@root/asn1",
"version": "1.0.0", "version": "1.0.1",
"description": "VanillaJS, Lightweight, Zero-Dependency, ASN.1 encoder and decoder.", "description": "VanillaJS, Lightweight, Zero-Dependency, ASN.1 encoder and decoder.",
"main": "index.js", "main": "index.js",
"browser": { "browser": {
@ -13,7 +13,12 @@
"dist" "dist"
], ],
"scripts": { "scripts": {
"test": "node tests" "bump": "npm version -m \"chore(release): bump to v%s\"",
"build": "sh ./build.sh",
"fmt": "npm run basetag-rebase && npm run prettier",
"test": "node ./tests/",
"--------": "--------------------------------------------------------------------------",
"prettier": "npx -p prettier@2 -- prettier --write '**/*.{md,js,jsx,json,css,html,vue}'"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -25,10 +30,10 @@
"x509", "x509",
"PEM" "PEM"
], ],
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", "author": "AJ ONeal <aj@therootcompany.com> (https://therootcompany.com/)",
"license": "MPL-2.0", "license": "MPL-2.0",
"devDependencies": { "devDependencies": {
"@root/pem": "^1.0.3" "@root/pem": "^1.0.4"
}, },
"dependencies": { "dependencies": {
"@root/encoding": "^1.0.1" "@root/encoding": "^1.0.1"

View File

@ -91,9 +91,9 @@ ASN1.parseVerbose = function parseAsn1Helper(buf, opts) {
index += 2 + child.lengthSize + child.length; index += 2 + child.lengthSize + child.length;
//console.warn('2 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', (2 + child.lengthSize + child.length)); //console.warn('2 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', (2 + child.lengthSize + child.length));
if (index > 2 + asn1.lengthSize + asn1.length) { if (index > 2 + asn1.lengthSize + asn1.length) {
if (!eager) { //if (!eager) {
console.error(JSON.stringify(asn1, ASN1._replacer, 2)); // console.error(JSON.stringify(asn1, ASN1._replacer, 2));
} //}
throw new Error( throw new Error(
'Parse error: child value length (' + 'Parse error: child value length (' +
child.length + child.length +