feat: add deno-github-mod.ts, update deno-sshsig-mod.ts

This commit is contained in:
2025-01-19 14:42:36 +08:00
parent b057454890
commit c2e741ef16
2 changed files with 59 additions and 4 deletions

View File

@@ -0,0 +1,38 @@
import {
getFetchAutoProxyInit,
} from "https://hatter.ink/script/fetch/library/deno-fetch-auto-proxy-mod.ts?202501191421";
export class SshKey {
algorithm: string;
material: string;
description?: string;
constructor(
algorithm: string,
material: string,
description: string | undefined,
) {
this.algorithm = algorithm;
this.material = material;
this.description = description;
}
static parseSshKey(key: string): SshKey {
const keyParts = key.split(/\s+/);
if (keyParts.length < 2 || keyParts.length > 3) {
throw `Bad SSH key format ${key}`;
}
return new SshKey(
keyParts[0],
keyParts[1],
(keyParts.length > 2) ? keyParts[2] : undefined,
);
}
}
export async function fetchKeys(username: string): Promise<Array<SshKey>> {
const url = `https://github.com/${username}.keys`;
const response = await fetch(url, getFetchAutoProxyInit());
const responseText = await response.text();
return responseText.trim().split("\n").map((k) => SshKey.parseSshKey(k));
}

View File

@@ -1,5 +1,5 @@
import { crypto } from "jsr:@std/crypto"; import { crypto } from "jsr:@std/crypto";
import { decodeBase64 } from "jsr:@std/encoding/base64"; import { decodeBase64, encodeBase64 } 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";
@@ -139,7 +139,7 @@ class BinaryReader {
} }
} }
class SshSignature { export class SshSignature {
publicKey: SshPublicKey; publicKey: SshPublicKey;
namespace: string; namespace: string;
hashAlgorithm: string; hashAlgorithm: string;
@@ -257,7 +257,7 @@ class SshSignature {
} }
} }
class SshSignatureValue { export class SshSignatureValue {
signatureAlgorithm: string; signatureAlgorithm: string;
ecSignatureR: Uint8Array; ecSignatureR: Uint8Array;
ecSignatureS: Uint8Array; ecSignatureS: Uint8Array;
@@ -330,16 +330,19 @@ class SshSignatureValue {
} }
} }
class SshPublicKey { export class SshPublicKey {
raw: Uint8Array;
signatureAlgorithm: string; signatureAlgorithm: string;
algorithm: string; algorithm: string;
publicKeyPoint: Uint8Array; publicKeyPoint: Uint8Array;
constructor( constructor(
raw: Uint8Array,
signatureAlgorithm: string, signatureAlgorithm: string,
algorithm: string, algorithm: string,
publicKeyPoint: Uint8Array, publicKeyPoint: Uint8Array,
) { ) {
this.raw = raw;
this.signatureAlgorithm = signatureAlgorithm; this.signatureAlgorithm = signatureAlgorithm;
this.algorithm = algorithm; this.algorithm = algorithm;
this.publicKeyPoint = publicKeyPoint; this.publicKeyPoint = publicKeyPoint;
@@ -354,12 +357,22 @@ class SshPublicKey {
throw `Not supported signature algorithm ${signatureAlgorithm} or curve algorithm ${curveAlgorithm}`; throw `Not supported signature algorithm ${signatureAlgorithm} or curve algorithm ${curveAlgorithm}`;
} }
return new SshPublicKey( return new SshPublicKey(
buffer,
signatureAlgorithm, signatureAlgorithm,
curveAlgorithm, curveAlgorithm,
publicKeyPoint, publicKeyPoint,
); );
} }
toSshKeyFormat(description?: string | undefined): string {
const suffix = description ? ` ${description}` : "";
return `${this.signatureAlgorithm} ${this.asRawBase64()}${suffix}`;
}
asRawBase64(): string {
return encodeBase64(this.raw);
}
toDer(): Uint8Array { toDer(): Uint8Array {
const writer = new BinaryWriter(); const writer = new BinaryWriter();
if (this.algorithm === "nistp256") { if (this.algorithm === "nistp256") {
@@ -395,6 +408,7 @@ class SshPublicKey {
); );
} }
// deno-lint-ignore no-explicit-any
toJwk(): any { toJwk(): any {
if (this.publicKeyPoint[0] !== 0x04) { if (this.publicKeyPoint[0] !== 0x04) {
throw `Invalid EC public key point: ${ throw `Invalid EC public key point: ${
@@ -509,6 +523,9 @@ WRxFFw==
const data = new TextDecoder(ENCODING_UTF8).decode( const data = new TextDecoder(ENCODING_UTF8).decode(
decodeBase64("aGVsbG8gaGF0dGVyIDIwMjUK"), decodeBase64("aGVsbG8gaGF0dGVyIDIwMjUK"),
); );
console.log(
sshSignature.publicKey.toSshKeyFormat(),
);
console.log(await sshSignature.verifyString(data)); console.log(await sshSignature.verifyString(data));
} }