Loading .vscode/settings.json +1 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,7 @@ "phensley", "Pico", "Pixelfed", "PKCS", "popd", "poppanator", "proto", Loading CHANGES.md +7 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,13 @@ Version 1.5.0 To be released. - Fedify now accepts PEM-PKCS#1 besides PEM-SPKI for RSA public keys. [[#209]] - Added `importPkcs1()` function. [#209]: https://github.com/fedify-dev/fedify/issues/209 Version 1.4.1 ------------- Loading src/runtime/key.test.ts +20 −3 Original line number Diff line number Diff line Loading @@ -5,11 +5,12 @@ import { exportMultibaseKey, exportSpki, importMultibaseKey, importPkcs1, importSpki, } from "./key.ts"; // cSpell: disable const rsaPem = "-----BEGIN PUBLIC KEY-----\n" + const rsaSpki = "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxsRuvCkgJtflBTl4OVsm\n" + "nt/J1mQfZasfJtN33dcZ3d1lJroxmgmMu69zjGEAwkNbMQaWNLqC4eogkJaeJ4RR\n" + "5MHYXkL9nNilVoTkjX5BVit3puzs7XJ7WQnKQgQMI+ezn24GHsZ/v1JIo77lerX5\n" + Loading @@ -20,6 +21,17 @@ const rsaPem = "-----BEGIN PUBLIC KEY-----\n" + "-----END PUBLIC KEY-----\n"; // cSpell: enable // cSpell: disable const rsaPkcs1 = "-----BEGIN RSA PUBLIC KEY-----\n" + "MIIBCgKCAQEAxsRuvCkgJtflBTl4OVsmnt/J1mQfZasfJtN33dcZ3d1lJroxmgmM\n" + "u69zjGEAwkNbMQaWNLqC4eogkJaeJ4RR5MHYXkL9nNilVoTkjX5BVit3puzs7XJ7\n" + "WQnKQgQMI+ezn24GHsZ/v1JIo77lerX5k4HNwTNVt+yaZVQWaOMR3+6FwziQR6kd\n" + "0VuG9/a9dgAnz2cEoORRC1i4W7IZaB1sZnh1WbHbevlGd72HSXll5rocPIHn8gq6\n" + "xpBgpHwRphlRsgn4KHaJ6brXDIJjrnQhIe/YUBOGj/ImSEXhRwlFerKsoAVnZ0Hw\n" + "bfa46qk44TAt8CyoPMWmpK6pt0ng4pQ2uwIDAQAB\n" + "-----END RSA PUBLIC KEY-----\n"; // cSpell: enable const rsaJwk = { alg: "RS256", // cSpell: disable Loading Loading @@ -67,7 +79,7 @@ const ed25519Multibase = "z6MksHj1MJnidCtDiyYW9ugNFftoX9fLK4bornTxmMZ6X7vq"; // cSpell: enable test("importSpki()", async () => { const rsaKey = await importSpki(rsaPem); const rsaKey = await importSpki(rsaSpki); assertEquals(await exportJwk(rsaKey), rsaJwk); const ed25519Key = await importSpki(ed25519Pem); Loading @@ -77,13 +89,18 @@ test("importSpki()", async () => { test("exportSpki()", async () => { const rsaKey = await importJwk(rsaJwk, "public"); const rsaSpki = await exportSpki(rsaKey); assertEquals(rsaSpki, rsaPem); assertEquals(rsaSpki, rsaSpki); const ed25519Key = await importJwk(ed25519Jwk, "public"); const ed25519Spki = await exportSpki(ed25519Key); assertEquals(ed25519Spki, ed25519Pem); }); test("importPkcs1()", async () => { const rsaKey = await importPkcs1(rsaPkcs1); assertEquals(await exportJwk(rsaKey), rsaJwk); }); test("importMultibase()", async () => { const rsaKey = await importMultibaseKey(rsaMultibase); assertEquals(await exportJwk(rsaKey), rsaJwk); Loading src/runtime/key.ts +16 −1 Original line number Diff line number Diff line import { createPublicKey } from "node:crypto"; import { concat } from "@std/bytes/concat"; import { decodeBase64, encodeBase64 } from "@std/encoding/base64"; import { decodeBase64Url } from "@std/encoding/base64url"; Loading @@ -6,6 +5,7 @@ import { decodeHex } from "@std/encoding/hex"; import { Integer, Sequence } from "asn1js"; import { decode, encode } from "multibase"; import { addPrefix, getCodeFromData, rmPrefix } from "multicodec"; import { createPublicKey } from "node:crypto"; import { PublicKeyInfo } from "pkijs"; import { validateCryptoKey } from "../sig/key.ts"; Loading Loading @@ -65,6 +65,19 @@ export async function exportSpki(key: CryptoKey): Promise<string> { return `-----BEGIN PUBLIC KEY-----\n${pem}\n-----END PUBLIC KEY-----\n`; } /** * Imports a PEM-PKCS#1 formatted public key. * @param pem The PEM-PKCS#1 formatted public key. * @returns The imported public key. * @throws {TypeError} If the key is invalid or unsupported. * @since 1.5.0 */ export function importPkcs1(pem: string): Promise<CryptoKey> { const key = createPublicKey({ key: pem, format: "pem", type: "pkcs1" }); const spki = key.export({ type: "spki", format: "pem" }) as string; return importSpki(spki); } /** * Imports a [Multibase]-encoded public key. * Loading Loading @@ -153,3 +166,5 @@ export async function exportMultibaseKey(key: CryptoKey): Promise<string> { const encoded = encode("base58btc", prefixed); return new TextDecoder().decode(encoded); } // cSpell: ignore multicodec pkijs Loading
.vscode/settings.json +1 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,7 @@ "phensley", "Pico", "Pixelfed", "PKCS", "popd", "poppanator", "proto", Loading
CHANGES.md +7 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,13 @@ Version 1.5.0 To be released. - Fedify now accepts PEM-PKCS#1 besides PEM-SPKI for RSA public keys. [[#209]] - Added `importPkcs1()` function. [#209]: https://github.com/fedify-dev/fedify/issues/209 Version 1.4.1 ------------- Loading
src/runtime/key.test.ts +20 −3 Original line number Diff line number Diff line Loading @@ -5,11 +5,12 @@ import { exportMultibaseKey, exportSpki, importMultibaseKey, importPkcs1, importSpki, } from "./key.ts"; // cSpell: disable const rsaPem = "-----BEGIN PUBLIC KEY-----\n" + const rsaSpki = "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxsRuvCkgJtflBTl4OVsm\n" + "nt/J1mQfZasfJtN33dcZ3d1lJroxmgmMu69zjGEAwkNbMQaWNLqC4eogkJaeJ4RR\n" + "5MHYXkL9nNilVoTkjX5BVit3puzs7XJ7WQnKQgQMI+ezn24GHsZ/v1JIo77lerX5\n" + Loading @@ -20,6 +21,17 @@ const rsaPem = "-----BEGIN PUBLIC KEY-----\n" + "-----END PUBLIC KEY-----\n"; // cSpell: enable // cSpell: disable const rsaPkcs1 = "-----BEGIN RSA PUBLIC KEY-----\n" + "MIIBCgKCAQEAxsRuvCkgJtflBTl4OVsmnt/J1mQfZasfJtN33dcZ3d1lJroxmgmM\n" + "u69zjGEAwkNbMQaWNLqC4eogkJaeJ4RR5MHYXkL9nNilVoTkjX5BVit3puzs7XJ7\n" + "WQnKQgQMI+ezn24GHsZ/v1JIo77lerX5k4HNwTNVt+yaZVQWaOMR3+6FwziQR6kd\n" + "0VuG9/a9dgAnz2cEoORRC1i4W7IZaB1sZnh1WbHbevlGd72HSXll5rocPIHn8gq6\n" + "xpBgpHwRphlRsgn4KHaJ6brXDIJjrnQhIe/YUBOGj/ImSEXhRwlFerKsoAVnZ0Hw\n" + "bfa46qk44TAt8CyoPMWmpK6pt0ng4pQ2uwIDAQAB\n" + "-----END RSA PUBLIC KEY-----\n"; // cSpell: enable const rsaJwk = { alg: "RS256", // cSpell: disable Loading Loading @@ -67,7 +79,7 @@ const ed25519Multibase = "z6MksHj1MJnidCtDiyYW9ugNFftoX9fLK4bornTxmMZ6X7vq"; // cSpell: enable test("importSpki()", async () => { const rsaKey = await importSpki(rsaPem); const rsaKey = await importSpki(rsaSpki); assertEquals(await exportJwk(rsaKey), rsaJwk); const ed25519Key = await importSpki(ed25519Pem); Loading @@ -77,13 +89,18 @@ test("importSpki()", async () => { test("exportSpki()", async () => { const rsaKey = await importJwk(rsaJwk, "public"); const rsaSpki = await exportSpki(rsaKey); assertEquals(rsaSpki, rsaPem); assertEquals(rsaSpki, rsaSpki); const ed25519Key = await importJwk(ed25519Jwk, "public"); const ed25519Spki = await exportSpki(ed25519Key); assertEquals(ed25519Spki, ed25519Pem); }); test("importPkcs1()", async () => { const rsaKey = await importPkcs1(rsaPkcs1); assertEquals(await exportJwk(rsaKey), rsaJwk); }); test("importMultibase()", async () => { const rsaKey = await importMultibaseKey(rsaMultibase); assertEquals(await exportJwk(rsaKey), rsaJwk); Loading
src/runtime/key.ts +16 −1 Original line number Diff line number Diff line import { createPublicKey } from "node:crypto"; import { concat } from "@std/bytes/concat"; import { decodeBase64, encodeBase64 } from "@std/encoding/base64"; import { decodeBase64Url } from "@std/encoding/base64url"; Loading @@ -6,6 +5,7 @@ import { decodeHex } from "@std/encoding/hex"; import { Integer, Sequence } from "asn1js"; import { decode, encode } from "multibase"; import { addPrefix, getCodeFromData, rmPrefix } from "multicodec"; import { createPublicKey } from "node:crypto"; import { PublicKeyInfo } from "pkijs"; import { validateCryptoKey } from "../sig/key.ts"; Loading Loading @@ -65,6 +65,19 @@ export async function exportSpki(key: CryptoKey): Promise<string> { return `-----BEGIN PUBLIC KEY-----\n${pem}\n-----END PUBLIC KEY-----\n`; } /** * Imports a PEM-PKCS#1 formatted public key. * @param pem The PEM-PKCS#1 formatted public key. * @returns The imported public key. * @throws {TypeError} If the key is invalid or unsupported. * @since 1.5.0 */ export function importPkcs1(pem: string): Promise<CryptoKey> { const key = createPublicKey({ key: pem, format: "pem", type: "pkcs1" }); const spki = key.export({ type: "spki", format: "pem" }) as string; return importSpki(spki); } /** * Imports a [Multibase]-encoded public key. * Loading Loading @@ -153,3 +166,5 @@ export async function exportMultibaseKey(key: CryptoKey): Promise<string> { const encoded = encode("base58btc", prefixed); return new TextDecoder().decode(encoded); } // cSpell: ignore multicodec pkijs