Skip to content

Commit

Permalink
feat: add binascii functions for zero dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
commenthol committed Jul 27, 2024
1 parent 0316412 commit 8b3f22e
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 1.3.0-0 (2024-07-27)

- feat: add binascii functions for zero dependencies (#633af73)
- feat: change to ESM (#0316412)
- docs: fix CI status badge (#a9f74c7)

# 1.2.0 (2024-07-27)

- feat: fix pkcs7 padding for encryption to match compatibility with ansible-vault (#5dc1426)
Expand Down
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
The MIT License (MIT)

Copyright (c) 2019- commenthol
Copyright (c) 2014 Michał Budzyński (@michalbe)

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
encrypt

```js
const { Vault } = require('ansible-vault')
import { Vault } from 'ansible-vault'

const v = new Vault({ password: 'pa$$w0rd' })
v.encrypt('superSecret123').then(console.log)
Expand All @@ -28,7 +28,7 @@ const vault = v.encryptSync('superSecret123')
decrypt

```js
const { Vault } = require('ansible-vault')
import { Vault } from 'ansible-vault'

const vault = `$ANSIBLE_VAULT;1.1;AES256
33383239333036363833303565653032383832663162356533343630623030613133623032636566
Expand Down
46 changes: 44 additions & 2 deletions lib/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,39 @@

var util = require('util');
var crypto = require('crypto');
var binascii = require('binascii');

/**
* @license MIT
* @copyright Copyright (c) 2014 Michał Budzyński (@michalbe)
* @see https://github.com/michalbe/binascii
* @see https://docs.python.org/2/library/binascii.html
*/

/**
* @param {string} str
* @returns {string}
*/
function hexlify(str) {
let result = '';
for (let i = 0, l = str.length; i < l; i++) {
const digit = str.charCodeAt(i).toString(16);
const padded = ('00' + digit).slice(-2);
result += padded;
}
return result
}

/**
* @param {string} str
* @returns {string}
*/
function unhexlify(str) {
let result = '';
for (var i = 0, l = str.length; i < l; i += 2) {
result += String.fromCharCode(parseInt(str.slice(i, i + 2), 16));
}
return result
}

/**
* pkcs7 pad
Expand All @@ -11,6 +43,7 @@ var binascii = require('binascii');
* @returns {Buffer}
*/
function pad(messageLength, blocksize) {
if (blocksize > 256) throw new Error("can't pad blocks larger 256 bytes")
const padLength = blocksize - (messageLength % blocksize);
return Buffer.alloc(padLength, Buffer.from([padLength]))
}
Expand All @@ -33,7 +66,12 @@ function unpad(padded, blocksize) {
return padded.subarray(0, len - byte)
}

const { hexlify, unhexlify } = binascii;
var pkcs7 = /*#__PURE__*/Object.freeze({
__proto__: null,
pad: pad,
unpad: unpad
});

const pbkdf2 = util.promisify(crypto.pbkdf2);

const HEADER = '$ANSIBLE_VAULT';
Expand Down Expand Up @@ -225,6 +263,7 @@ class Vault {

return (
header +
// @ts-expect-error
hexlify(hex)
.match(/.{1,80}/g)
.join('\n')
Expand Down Expand Up @@ -285,3 +324,6 @@ class Vault {
}

exports.Vault = Vault;
exports.hexlify = hexlify;
exports.pkcs7 = pkcs7;
exports.unhexlify = unhexlify;
13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,18 @@
"module": "./src/index.js",
"types": "./types/index.d.ts",
"files": [
"lib",
"src",
"types"
],
"exports": {
".": {
"import": "./src/index.js",
"require": "./lib/index.cjs",
"types": "./types/index.d.ts"
},
"./package.json": "./package.json"
},
"scripts": {
"build": "rollup -c rollup.config.js",
"clear": "rimraf lib types",
Expand All @@ -33,9 +42,7 @@
"test": "mocha",
"types": "tsc"
},
"dependencies": {
"binascii": "0.0.2"
},
"dependencies": {},
"devDependencies": {
"@types/node": "^20.14.12",
"c8": "^10.1.2",
Expand Down
32 changes: 32 additions & 0 deletions src/binascii.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @license MIT
* @copyright Copyright (c) 2014 Michał Budzyński (@michalbe)
* @see https://github.com/michalbe/binascii
* @see https://docs.python.org/2/library/binascii.html
*/

/**
* @param {string} str
* @returns {string}
*/
export function hexlify(str) {
let result = ''
for (let i = 0, l = str.length; i < l; i++) {
const digit = str.charCodeAt(i).toString(16)
const padded = ('00' + digit).slice(-2)
result += padded
}
return result
}

/**
* @param {string} str
* @returns {string}
*/
export function unhexlify(str) {
let result = ''
for (var i = 0, l = str.length; i < l; i += 2) {
result += String.fromCharCode(parseInt(str.slice(i, i + 2), 16))
}
return result
}
6 changes: 4 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { promisify } from 'util'
import crypto from 'crypto'
import binascii from 'binascii'
import { hexlify, unhexlify } from './binascii.js'
import * as pkcs7 from './pkcs7.js'

const { hexlify, unhexlify } = binascii
const pbkdf2 = promisify(crypto.pbkdf2)

const HEADER = '$ANSIBLE_VAULT'
Expand Down Expand Up @@ -195,6 +194,7 @@ export class Vault {

return (
header +
// @ts-expect-error
hexlify(hex)
.match(/.{1,80}/g)
.join('\n')
Expand Down Expand Up @@ -253,3 +253,5 @@ export class Vault {
return this._decipher(unpacked, derivedKey)
}
}

export { hexlify, unhexlify, pkcs7 }
36 changes: 36 additions & 0 deletions test/binascii.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import assert from 'node:assert'
import { hexlify, unhexlify } from '../src/binascii.js'

describe('binascii', function () {
it('shall return a string', function () {
assert.equal(hexlify(''), '')
})

it('shall hexlify char', function () {
assert.equal(hexlify('A'), '41')
})

it('shall hexlify string', function () {
assert.equal(hexlify('Pamietamy 44'), '50616d696574616d79203434')
})

it('shall hexlify binary data', function () {
assert.equal(hexlify("7z¼¯'\u001c"), '377abcaf271c')
})

it('shall ensure that single-digit codes are correctly padded', function () {
assert.equal(hexlify('\n'), '0a')
})

it('shall unhexlify char', function () {
assert.equal(unhexlify(hexlify('A')), 'A')
})

it('shall unhexlify string', function () {
assert.equal(unhexlify('50616d696574616d79203434'), 'Pamietamy 44')
})

it('shall unhexlify binary data', function () {
assert.equal(unhexlify('377abcaf271c'), "7z¼¯'\u001c")
})
})
16 changes: 16 additions & 0 deletions types/binascii.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @license MIT
* @copyright Copyright (c) 2014 Michał Budzyński (@michalbe)
* @see https://github.com/michalbe/binascii
* @see https://docs.python.org/2/library/binascii.html
*/
/**
* @param {string} str
* @returns {string}
*/
export function hexlify(str: string): string;
/**
* @param {string} str
* @returns {string}
*/
export function unhexlify(str: string): string;
5 changes: 4 additions & 1 deletion types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,7 @@ export type Unpacked = {
ciphertext: Buffer;
};
declare const PASSWORD: unique symbol;
export {};
import { hexlify } from './binascii.js';
import { unhexlify } from './binascii.js';
import * as pkcs7 from './pkcs7.js';
export { hexlify, unhexlify, pkcs7 };

0 comments on commit 8b3f22e

Please sign in to comment.