Skip to content

Commit

Permalink
add verify metho to PublicKey class
Browse files Browse the repository at this point in the history
  • Loading branch information
tasshi-me committed Oct 27, 2024
1 parent b0b4e3c commit a631d1b
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 71 deletions.
3 changes: 1 addition & 2 deletions src/plugin/core/crypto/private-key.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import RSA from "node-rsa";
import { uuid } from "./uuid";
import { sign } from "./sign";
import type { PublicKeyInterface } from "./public-key";

export interface PrivateKeyInterface extends PublicKeyInterface {
export interface PrivateKeyInterface {
exportPrivateKey(): string;
exportPublicKey(): Buffer;
uuid(): string;
Expand Down
10 changes: 10 additions & 0 deletions src/plugin/core/crypto/public-key.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import RSA from "node-rsa";
import { uuid } from "./uuid";
import crypto from "crypto";

export interface PublicKeyInterface {
exportPublicKey(): Buffer;
uuid(): string;
verify(data: Buffer, signature: Buffer): boolean;
}

export class PublicKey implements PublicKeyInterface {
Expand Down Expand Up @@ -45,4 +47,12 @@ export class PublicKey implements PublicKeyInterface {
public uuid(): string {
return uuid(this.exportPublicKey());
}

public verify(data: Buffer, signature: Buffer): boolean {
const pem = this.key.exportKey("pkcs1-public-pem");
const verifier = crypto.createVerify("RSA-SHA1");
verifier.update(data);

return verifier.verify(pem, signature);
}
}
78 changes: 9 additions & 69 deletions src/plugin/core/plugin-zip/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import crypto from "crypto";
import path from "path";
import fs from "fs";
import RSA from "node-rsa";
import yauzl from "yauzl";

import type { PluginZipInterface } from "../index";
import { PluginZip } from "../index";
import { PrivateKey } from "../../crypto";
import { PrivateKey, PublicKey } from "../../crypto";
import { ContentsZip } from "../contents-zip";
import { ZipFileDriver } from "../../driver";

const contentsZipPath = path.join(__dirname, "fixtures", "contents.zip");

Expand All @@ -33,72 +31,14 @@ describe("PluginZip", () => {
});
});

const streamToBuffer = async (
stream: NodeJS.ReadableStream,
): Promise<Buffer> => {
const buffers: Buffer[] = [];
for await (const data of stream) {
buffers.push(Buffer.from(data));
}
return Buffer.concat(buffers);
};

const readZipContents = (
zipEntry: yauzl.ZipFile,
): Promise<Map<any, Buffer>> => {
const zipContentsMap = new Map();
const streamToBufferPromises: Array<Promise<void>> = [];
return new Promise((resolve, reject) => {
zipEntry.on("entry", (entry) => {
zipEntry.openReadStream(entry, (err, stream) => {
if (err) {
reject(err);
}
streamToBufferPromises.push(
streamToBuffer(stream).then((buffer) => {
zipContentsMap.set(entry.fileName, buffer);
}),
);
});
});
zipEntry.on("end", () => {
Promise.all(streamToBufferPromises).then(() => resolve(zipContentsMap));
});
});
};

const verifyPlugin = async (plugin: PluginZipInterface): Promise<void> => {
const fromBuffer = (buffer: Buffer) =>
new Promise<yauzl.ZipFile>((resolve, reject) => {
yauzl.fromBuffer(buffer, (err, zipfile) => {
if (err) {
reject(err);
}
resolve(zipfile);
});
});
const zipEntry = await fromBuffer(plugin.buffer);
const zipContentsMap = await readZipContents(zipEntry);
const contentZip = zipContentsMap.get("contents.zip");
expect(contentZip).toBeDefined();
if (contentZip === undefined) {
throw new Error("contentZip is undefined");
}
const verifier = crypto.createVerify("RSA-SHA1");
verifier.update(contentZip);
const zipFile = new ZipFileDriver(plugin.buffer);

const publicKey = zipContentsMap.get("PUBKEY");
if (publicKey === undefined) {
throw new Error("PUBKEY is undefined");
}
const signature = zipContentsMap.get("SIGNATURE");
if (signature === undefined) {
throw new Error("SIGNATURE is undefined");
}
expect(verifier.verify(derToPem(publicKey), signature)).toBe(true);
};
const publicKeyBuffer = await zipFile.readFile("PUBKEY");
const publicKey = await PublicKey.importKey(publicKeyBuffer);

const contentsZip = await zipFile.readFile("contents.zip");
const signature = await zipFile.readFile("SIGNATURE");

const derToPem = (der: Buffer) => {
const key = new RSA(der, "pkcs8-public-der");
return key.exportKey("pkcs1-public-pem");
expect(publicKey.verify(contentsZip, signature)).toBe(true);
};

0 comments on commit a631d1b

Please sign in to comment.