feat: format scripts
This commit is contained in:
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user