Skip to content

Commit

Permalink
Integrity (SRI) (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
xan105 authored Oct 26, 2024
1 parent 9f96502 commit f374756
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 196 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ _ex: Win32 API (x86) requires "stdcall"._
]
```

- `integrity?: string` (none)

Subresource Integrity.

**Return**

An handle function to call library's symbol(s).
Expand Down
21 changes: 18 additions & 3 deletions lib/ffi-napi/open.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import { platform } from "node:process";
import { promisify } from "node:util";
import ffi from "ffi-napi";
import { Failure, attemptify, errorLookup } from "@xan105/error";
import { asBoolean, asArray } from "@xan105/is/opt";
import { asBoolean, asArray, asStringLike } from "@xan105/is/opt";
import {
shouldObj,
shouldObjWithinObj,
shouldStringNotEmpty
} from "@xan105/is/assert";
import { conventions } from "./util/abi.js";
import { hashFileSync } from "../util.js"

function load(path, option = {}){

Expand All @@ -28,7 +29,8 @@ function load(path, option = {}){
global: asBoolean(option.global) ?? false,
abi: conventions.includes(option.abi) ?
option.abi :
{"cdecl": "ms_cdecl"}[option.abi] ?? "default_abi"
{"cdecl": "ms_cdecl"}[option.abi] ?? "default_abi",
integrity: asStringLike(option.integrity, "SRI") ?? ""
};

const ext = {
Expand All @@ -40,7 +42,20 @@ function load(path, option = {}){
flags |= options.lazy ? ffi.DynamicLibrary.FLAGS.RTLD_LAZY : ffi.DynamicLibrary.FLAGS.RTLD_NOW;
flags |= options.global ? ffi.DynamicLibrary.FLAGS.RTLD_GLOBAL : ffi.DynamicLibrary.FLAGS.RTLD_LOCAL;

if (path.indexOf(ext) === -1) path += ext;
if (!path.endsWith(ext)) path += ext;

//sri
if(options.integrity){
const [ algo, expected ] = options.integrity.split("-");
const [ hash = "" ] = attemptify(hashFileSync)(path, algo);
if(hash !== expected){
throw new Failure("Integrity check failed ! Dylib loading has been aborted.", {
code: "ERR_INTEGRITY",
info : { path, algo, hash }
});
}
}

const [ dylib, err ] = attemptify(ffi.DynamicLibrary)(
path,
flags,
Expand Down
23 changes: 19 additions & 4 deletions lib/koffi/open.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import { platform } from "node:process";
import { promisify } from "node:util";
import koffi from "koffi";
import { Failure, attemptify } from "@xan105/error";
import { asBoolean, asArray } from "@xan105/is/opt";
import { asBoolean, asArray, asStringLike } from "@xan105/is/opt";
import {
shouldObj,
shouldObjWithinObj,
shouldStringNotEmpty
} from "@xan105/is/assert";
import { conventions } from "./util/abi.js";
import { hashFileSync } from "../util.js";

function load(path, option = {}){

Expand All @@ -26,20 +27,34 @@ function load(path, option = {}){
ignoreMissingSymbol: asBoolean(option.ignoreMissingSymbol) ?? false,
lazy: asBoolean(option.lazy) ?? false,
global: asBoolean(option.global) ?? false,
abi: conventions.includes(option.abi) ? option.abi : "cdecl"
abi: conventions.includes(option.abi) ? option.abi : "cdecl",
integrity: asStringLike(option.integrity, "SRI") ?? ""
};

const ext = {
"win32": ".dll",
"darwin": ".dylib",
}[platform] ?? ".so";

if (!path.endsWith(ext)) path += ext;

if (path.indexOf(ext) === -1) path += ext;
//sri
if(options.integrity){
const [ algo, expected ] = options.integrity.split("-");
const [ hash = "" ] = attemptify(hashFileSync)(path, algo);
if(hash !== expected){
throw new Failure("Integrity check failed ! Dylib loading has been aborted.", {
code: "ERR_INTEGRITY",
info : { path, algo, hash }
});
}
}

const [dylib, err] = attemptify(koffi.load)(path, {
lazy: options.lazy,
global: options.global
});

const handle = function(symbol, result, parameters){
try{
if (err) throw err;
Expand Down
22 changes: 22 additions & 0 deletions lib/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
Copyright (c) Anthony Beaumont
This source code is licensed under the MIT License
found in the LICENSE file in the root directory of this source tree.
*/

import { readFileSync } from "node:fs";
import { createHash } from "node:crypto";
import { shouldStringNotEmpty } from "@xan105/is/assert";

function hashFileSync(filePath, algo = "sha256"){

shouldStringNotEmpty(filePath);
shouldStringNotEmpty(algo);

const sum = createHash(algo);
const chunk = readFileSync(filePath);
sum.update(chunk);
return sum.digest("base64");
}

export { hashFileSync }
Loading

0 comments on commit f374756

Please sign in to comment.