feat: format scripts

This commit is contained in:
2025-01-19 09:50:44 +08:00
parent b3cf9ba7c5
commit 5379fbde8d

View File

@@ -1,7 +1,7 @@
import {crypto} from "jsr:@std/crypto"; import { crypto } from "jsr:@std/crypto";
import {decodeBase64} from "jsr:@std/encoding/base64"; import { decodeBase64 } from "jsr:@std/encoding/base64";
import {encodeBase64Url} from "jsr:@std/encoding/base64url"; import { encodeBase64Url } from "jsr:@std/encoding/base64url";
import {decodeHex, encodeHex} from "jsr:@std/encoding/hex"; import { decodeHex, encodeHex } from "jsr:@std/encoding/hex";
// IMPORTANT: ONLY supports ECDSA P256 and P384 // IMPORTANT: ONLY supports ECDSA P256 and P384
@@ -89,7 +89,7 @@ class BinaryWriter {
} }
writeNumber(num: number) { writeNumber(num: number) {
const n = new Uint8Array(1) const n = new Uint8Array(1);
n[0] = num; n[0] = num;
this.writeBytes(n); this.writeBytes(n);
} }
@@ -145,7 +145,12 @@ class SshSignature {
hashAlgorithm: string; hashAlgorithm: string;
signature: SshSignatureValue; signature: SshSignatureValue;
constructor(publicKey: SshPublicKey, namespace: string, hashAlgorithm: string, signature: SshSignatureValue) { constructor(
publicKey: SshPublicKey,
namespace: string,
hashAlgorithm: string,
signature: SshSignatureValue,
) {
this.publicKey = publicKey; this.publicKey = publicKey;
this.namespace = namespace; this.namespace = namespace;
this.hashAlgorithm = hashAlgorithm; this.hashAlgorithm = hashAlgorithm;
@@ -202,7 +207,11 @@ class SshSignature {
return await crypto.subtle.verify( return await crypto.subtle.verify(
{ {
name: "ECDSA", name: "ECDSA",
hash: {name: (this.publicKey.algorithm === "nistp256") ? "SHA-256" : "SHA-384"}, hash: {
name: (this.publicKey.algorithm === "nistp256")
? "SHA-256"
: "SHA-384",
},
}, },
publicKey, publicKey,
signature, signature,
@@ -253,7 +262,11 @@ class SshSignatureValue {
ecSignatureR: Uint8Array; ecSignatureR: Uint8Array;
ecSignatureS: Uint8Array; ecSignatureS: Uint8Array;
constructor(signatureAlgorithm: string, ecSignatureR: Uint8Array, ecSignatureS: Uint8Array) { constructor(
signatureAlgorithm: string,
ecSignatureR: Uint8Array,
ecSignatureS: Uint8Array,
) {
this.signatureAlgorithm = signatureAlgorithm; this.signatureAlgorithm = signatureAlgorithm;
this.ecSignatureR = ecSignatureR; this.ecSignatureR = ecSignatureR;
this.ecSignatureS = ecSignatureS; this.ecSignatureS = ecSignatureS;
@@ -296,7 +309,9 @@ class SshSignatureValue {
writer.writeNumber(2); writer.writeNumber(2);
const rFirstByte = this.ecSignatureR[0]; const rFirstByte = this.ecSignatureR[0];
writer.writeNumber(((rFirstByte >= 0x80) ? 1 : 0) + this.ecSignatureR.byteLength); writer.writeNumber(
((rFirstByte >= 0x80) ? 1 : 0) + this.ecSignatureR.byteLength,
);
if (rFirstByte >= 0x80) { if (rFirstByte >= 0x80) {
writer.writeNumber(0); writer.writeNumber(0);
} }
@@ -304,7 +319,9 @@ class SshSignatureValue {
writer.writeNumber(2); writer.writeNumber(2);
const sFirstByte = this.ecSignatureS[0]; const sFirstByte = this.ecSignatureS[0];
writer.writeNumber(((sFirstByte >= 0x80) ? 1 : 0) + this.ecSignatureS.byteLength); writer.writeNumber(
((sFirstByte >= 0x80) ? 1 : 0) + this.ecSignatureS.byteLength,
);
if (sFirstByte >= 0x80) { if (sFirstByte >= 0x80) {
writer.writeNumber(0); writer.writeNumber(0);
} }
@@ -318,7 +335,11 @@ class SshPublicKey {
algorithm: string; algorithm: string;
publicKeyPoint: Uint8Array; publicKeyPoint: Uint8Array;
constructor(signatureAlgorithm: string, algorithm: string, publicKeyPoint: Uint8Array) { constructor(
signatureAlgorithm: string,
algorithm: string,
publicKeyPoint: Uint8Array,
) {
this.signatureAlgorithm = signatureAlgorithm; this.signatureAlgorithm = signatureAlgorithm;
this.algorithm = algorithm; this.algorithm = algorithm;
this.publicKeyPoint = publicKeyPoint; this.publicKeyPoint = publicKeyPoint;
@@ -332,15 +353,25 @@ class SshPublicKey {
if (signatureAlgorithm !== `ecdsa-sha2-${curveAlgorithm}`) { if (signatureAlgorithm !== `ecdsa-sha2-${curveAlgorithm}`) {
throw `Not supported signature algorithm ${signatureAlgorithm} or curve algorithm ${curveAlgorithm}`; throw `Not supported signature algorithm ${signatureAlgorithm} or curve algorithm ${curveAlgorithm}`;
} }
return new SshPublicKey(signatureAlgorithm, curveAlgorithm, publicKeyPoint); return new SshPublicKey(
signatureAlgorithm,
curveAlgorithm,
publicKeyPoint,
);
} }
toDer(): Uint8Array { toDer(): Uint8Array {
const writer = new BinaryWriter(); const writer = new BinaryWriter();
if (this.algorithm === "nistp256") { if (this.algorithm === "nistp256") {
writer.writeBytes(decodeHex("3059301306072a8648ce3d020106082a8648ce3d030107034200")); writer.writeBytes(
decodeHex(
"3059301306072a8648ce3d020106082a8648ce3d030107034200",
),
);
} else { } else {
writer.writeBytes(decodeHex("3076301006072a8648ce3d020106052b81040022036200")); writer.writeBytes(
decodeHex("3076301006072a8648ce3d020106052b81040022036200"),
);
} }
writer.writeBytes(this.asPoint()); writer.writeBytes(this.asPoint());
return writer.toArray(); return writer.toArray();
@@ -366,7 +397,9 @@ class SshPublicKey {
toJwk(): any { toJwk(): any {
if (this.publicKeyPoint[0] !== 0x04) { if (this.publicKeyPoint[0] !== 0x04) {
throw `Invalid EC public key point: ${encodeHex(this.publicKeyPoint)}`; throw `Invalid EC public key point: ${
encodeHex(this.publicKeyPoint)
}`;
} }
let coordinateLength; let coordinateLength;
if (this.algorithm === "nistp256") { if (this.algorithm === "nistp256") {
@@ -377,7 +410,10 @@ class SshPublicKey {
throw `Not supported algorithm: ${this.algorithm}`; throw `Not supported algorithm: ${this.algorithm}`;
} }
const x = this.publicKeyPoint.slice(1, coordinateLength + 1); const x = this.publicKeyPoint.slice(1, coordinateLength + 1);
const y = this.publicKeyPoint.slice(coordinateLength + 1, coordinateLength + coordinateLength + 1); const y = this.publicKeyPoint.slice(
coordinateLength + 1,
coordinateLength + coordinateLength + 1,
);
return { return {
crv: (this.algorithm === "nistp256") ? "P-256" : "P-384", crv: (this.algorithm === "nistp256") ? "P-256" : "P-384",
ext: true, ext: true,
@@ -412,18 +448,27 @@ function parsePemToArray(pem: string): Uint8Array {
return decodeBase64(innerPem.join("")); return decodeBase64(innerPem.join(""));
} }
async function digestString(data: string, algorithm: string): Promise<Uint8Array> { async function digestString(
data: string,
algorithm: string,
): Promise<Uint8Array> {
const hashAlgorithm = normalizeHashAlgorithm(algorithm); const hashAlgorithm = normalizeHashAlgorithm(algorithm);
const messageBuffer = new TextEncoder().encode(data); const messageBuffer = new TextEncoder().encode(data);
const hashBuffer = await crypto.subtle.digest(hashAlgorithm, messageBuffer); const hashBuffer = await crypto.subtle.digest(hashAlgorithm, messageBuffer);
return new Uint8Array(hashBuffer); return new Uint8Array(hashBuffer);
} }
async function digestFile(filename: string, algorithm: string): Promise<Uint8Array> { async function digestFile(
filename: string,
algorithm: string,
): Promise<Uint8Array> {
const hashAlgorithm = normalizeHashAlgorithm(algorithm); const hashAlgorithm = normalizeHashAlgorithm(algorithm);
const file = await Deno.open(filename, {read: true}); const file = await Deno.open(filename, { read: true });
const readableStream = file.readable; const readableStream = file.readable;
const hashBuffer = await crypto.subtle.digest(hashAlgorithm, readableStream); const hashBuffer = await crypto.subtle.digest(
hashAlgorithm,
readableStream,
);
return new Uint8Array(hashBuffer); return new Uint8Array(hashBuffer);
} }
@@ -461,7 +506,9 @@ WRxFFw==
-----END SSH SIGNATURE-----`; -----END SSH SIGNATURE-----`;
const sshSignature = SshSignature.parsePem(TEST_SIG); const sshSignature = SshSignature.parsePem(TEST_SIG);
const data = new TextDecoder(ENCODING_UTF8).decode(decodeBase64("aGVsbG8gaGF0dGVyIDIwMjUK")); const data = new TextDecoder(ENCODING_UTF8).decode(
decodeBase64("aGVsbG8gaGF0dGVyIDIwMjUK"),
);
console.log(await sshSignature.verifyString(data)); console.log(await sshSignature.verifyString(data));
} }