From f3dbd0fbc8841ccbf357b8053d2cbd0d3e5f8f67 Mon Sep 17 00:00:00 2001 From: "Visal .In" Date: Sat, 22 Aug 2020 14:27:28 +0700 Subject: [PATCH] Support importKey certificate file --- src/rsa/import_key.ts | 39 ++++++++++++++++++++++++-------- tests/rsa/rsa.import_key.test.ts | 29 ++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/rsa/import_key.ts b/src/rsa/import_key.ts index 36503a9..2881137 100644 --- a/src/rsa/import_key.ts +++ b/src/rsa/import_key.ts @@ -6,6 +6,9 @@ import { os2ip } from "./primitives.ts"; type RSAImportKeyFormat = "auto" | "jwk" | "pem"; type RSAPublicKeyFormat = [[string, null], [[bigint, bigint]]]; +type RSACertKeyFormat = [ + [number, string, null, null, null, RSAPublicKeyFormat], +]; /** * Automatically detect the key format @@ -47,6 +50,25 @@ function rsa_import_jwk(key: JSONWebKey): RSAKey { }; } +/** + * + * https://tools.ietf.org/html/rfc5280#section-4.1 + * + * @param key + */ +function rsa_import_pem_cert(key: string): RSAKey { + const trimmedKey = key.substr(27, key.length - 52); + const parseKey = ber_simple( + ber_decode(base64_to_binary(trimmedKey)), + ) as RSACertKeyFormat; + + return { + length: get_key_size(parseKey[0][5][1][0][0]), + n: parseKey[0][5][1][0][0], + e: parseKey[0][5][1][0][1], + }; +} + /** * Import private key from Privacy-Enhanced Mail (PEM) format * https://tools.ietf.org/html/rfc5208 @@ -100,15 +122,14 @@ function rsa_import_pem_public(key: string): RSAKey { function rsa_import_pem(key: string): RSAKey { if (typeof key !== "string") throw new TypeError("PEM key must be string"); - if ( - key.indexOf("-----BEGIN RSA PRIVATE KEY-----") === 0 - ) { - return rsa_import_pem_private(key); - } - if ( - key.indexOf("-----BEGIN PUBLIC KEY-----") === 0 - ) { - return rsa_import_pem_public(key); + const maps: [string, (key: string) => RSAKey][] = [ + ["-----BEGIN RSA PRIVATE KEY-----", rsa_import_pem_private], + ["-----BEGIN PUBLIC KEY-----", rsa_import_pem_public], + ["-----BEGIN CERTIFICATE-----", rsa_import_pem_cert], + ]; + + for (const [prefix, func] of maps) { + if (key.indexOf(prefix) === 0) return func(key); } throw new TypeError("Unsupported key format"); diff --git a/tests/rsa/rsa.import_key.test.ts b/tests/rsa/rsa.import_key.test.ts index 603a19f..7478c08 100644 --- a/tests/rsa/rsa.import_key.test.ts +++ b/tests/rsa/rsa.import_key.test.ts @@ -22,3 +22,32 @@ Deno.test("RSA - Import JWK Public Key", () => { assertEquals(key.e, 65537n); assertEquals(key.length, 256); }); + +Deno.test("RSA - Import Certificate PEM", () => { + const cert = `-----BEGIN CERTIFICATE----- + MIIC8DCCAdgCAQMwDQYJKoZIhvcNAQELBQAwPDE6MDgGA1UEAwwxTXlTUUxfU2Vy + dmVyXzUuNy4xN19BdXRvX0dlbmVyYXRlZF9DQV9DZXJ0aWZpY2F0ZTAeFw0yMDA2 + MDMwNzExMjBaFw0zMDA2MDEwNzExMjBaMEAxPjA8BgNVBAMMNU15U1FMX1NlcnZl + cl81LjcuMTdfQXV0b19HZW5lcmF0ZWRfQ2xpZW50X0NlcnRpZmljYXRlMIIBIjAN + BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtupn4nzv5elNq6+L8MzuSuUYmwCt + EojEZ9vtv83DTQI24brXVk1/1ccOGe5hGGu4aTTpXU5LOb1V6v4robe0Vt3BuPsw + GHZRt1LE/BQcuuZ0f/TCBafdEdLLpUP5TBUCVomKvZFxu+5P44bJW1d4iWsXUkyZ + gO5TtF7x7PQvRVtsblaD4a8Et1qs58PNWN5AbOQw8GYokaSbkXDnP24ZTZbdNwu6 + W521oJuG9HFvIM6trGjoZR7N2NxJCUtq8OjTtmUqa5BVyTBJegp+pgLZEn/YDLag + ll2Gx8xBOp0axxpzbc7P0JODCz21sh4ttyhyMMVjNPbn/vitgKpn0sdctQIDAQAB + MA0GCSqGSIb3DQEBCwUAA4IBAQBbMXuLz2qZYqgZc/2CuD4w8E+sF4n1fWpdb9EP + GWsHiyevEOF15YNkGlqQ8r4+h87TfL+SR4gw3PqfXEXuCkM3FuWvCulPTp/cFb7z + T+EcNgGKuLbLpRdi0XpvyLtG9B5yi3nvhl8XHh31xFZ0WiTgwvdwUw/bQ+fKR6xQ + 8e0oj3SBjhcXmH5pmakFFeBjChIEPDkte5ImB6JwtwAlfvP/yTJEJxb9fUHEkR4A + Q258orSdJ6gNn0XC7grCTpPYpMv2foIE0lPR1BryDD+M0QeBsLENlVNFEtnNLTcI + UWFGFt5RctaF1ApP+inoTYapAQoDjTrOWcWYBJMkgKDk65Tg + -----END CERTIFICATE-----`; + + const key = RSA.importKey(cert); + assertEquals(key.e, 65537n); + assertEquals( + key.n, + 23090961311737573793101890708283924695433283000385054150823173852612673758230706931831331316346585281948637691806795052569468114184708524749728610979168598273283877538163829031755269185449374762314082288398270538054993384545276491531066649969558630423935152857250299602221281913410774031127740158653973996811337367884788028635132184093457045502358896056164012639638637637694971273993250785116955454220202034598919946428438516582026303702956399809398972276905876470428715345135826409789537975085486698172979761097583691702126455811212002371429452274581681294432992139097164326433615550289131259416635196384643694156981n, + ); + assertEquals(key.length, 256); +});