import type { WrappedBuffer } from "@sammo/util"; const crypto = globalThis.crypto; export function randomBytes(length: number): Buffer { const buffer = Buffer.alloc(length); crypto.getRandomValues(buffer); return buffer; } //TODO: 필요할때마다 확장 export type ValidPEMType = 'PUBLIC KEY' | 'EC PRIVATE KEY' | 'CERTIFICATE'; /** * PEM string에 내부 타입으로 WrappedBuffer를 보관한 형태 */ // eslint-disable-next-line @typescript-eslint/ban-types export type PEMString = string & { /** 타입구분자. 항상 undefined일 것이다 */ _pem_b_type?: T; _pem_type?: S; } export function encodePEM(data: T, pemType: S): PEMString; export function encodePEM(data: Buffer, pemType: ValidPEMType): string; export function encodePEM(data: Buffer, pemType: ValidPEMType): string { const base64text = data.toString('base64'); const splitText = base64text.match(/.{1,64}/g)?.join('\n') ?? ''; return `-----BEGIN ${pemType}----- ${splitText} -----END ${pemType}----- `; } // eslint-disable-next-line @typescript-eslint/no-explicit-any type InferPEMType> = Exclude; // eslint-disable-next-line @typescript-eslint/no-explicit-any type InferPEMBuffer> = Exclude; // eslint-disable-next-line @typescript-eslint/no-explicit-any export function decodePEM>(pem: T, pemType: InferPEMType): InferPEMBuffer[]; export function decodePEM(pem: string, pemType?: ValidPEMType): Buffer[]; export function decodePEM(pem: string, pemType?: ValidPEMType): Buffer[] { const tag = pemType ?? "[A-Z0-9 ]+"; const pattern = new RegExp(`-{5}BEGIN ${tag}-{5}([a-zA-Z0-9=+\\/\\n\\r]+)-{5}END ${tag}-{5}`, "g"); const res: Buffer[] = []; let matches: RegExpExecArray | null = null; // eslint-disable-next-line no-cond-assign while (matches = pattern.exec(pem)) { const base64 = matches[1] .replace(/\r/g, "") .replace(/\n/g, ""); res.push(Buffer.from(base64, 'base64')); } return res; } // eslint-disable-next-line @typescript-eslint/no-explicit-any export function decodeSinglePEM>(pem: T, pemType: InferPEMType): InferPEMBuffer; export function decodeSinglePEM(pem: string, pemType?: ValidPEMType): Buffer; export function decodeSinglePEM(pem: string, pemType?: ValidPEMType): Buffer { const res = decodePEM(pem, pemType); if (res.length != 1) { throw new Error("invalid pem"); } return res[0]; }