Skip to content

Commit

Permalink
feat: add support for PKCS8 keys (#129)
Browse files Browse the repository at this point in the history
* feat: add support for PKCS8 keys

---------

Co-authored-by: Samuel El-Borai <[email protected]>
  • Loading branch information
Uzlopak and dgellow authored Jul 21, 2024
1 parent 699b851 commit 0c60e8a
Show file tree
Hide file tree
Showing 3 changed files with 305 additions and 80 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Finds a private key through various user-(un)specified methods. Order of precede
3. `PRIVATE_KEY_PATH` environment variable or explicit `env.PRIVATE_KEY_PATH` option
4. Any file w/ `.pem` extension in current working dir

Supports both PKCS1 (i.e `-----BEGIN RSA PRIVATE KEY-----`) and PKCS8 (i.e `-----BEGIN PRIVATE KEY-----`).

## Usage

<table>
Expand Down
52 changes: 43 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { resolve } from "path";
import { existsSync, readdirSync, readFileSync } from "fs";

import { VERSION } from "./version";

type Options = {
Expand All @@ -13,8 +12,19 @@ type Options = {
cwd?: string;
};

const begin = "-----BEGIN RSA PRIVATE KEY-----";
const end = "-----END RSA PRIVATE KEY-----";
const pkcs1Begin = "-----BEGIN RSA PRIVATE KEY-----";
const pkcs1End = "-----END RSA PRIVATE KEY-----";

const pkcs8Begin = "-----BEGIN PRIVATE KEY-----";
const pkcs8End = "-----END PRIVATE KEY-----";

function isPKCS1(privateKey: string): boolean {
return privateKey.includes(pkcs1Begin) && privateKey.includes(pkcs1End);
}

function isPKCS8(privateKey: string): boolean {
return privateKey.includes(pkcs8Begin) && privateKey.includes(pkcs8End);
}

export function getPrivateKey(options: Options = {}): string | null {
const env = options.env || process.env;
Expand All @@ -32,15 +42,31 @@ export function getPrivateKey(options: Options = {}): string | null {
privateKey = Buffer.from(privateKey, "base64").toString();
}

if (privateKey.includes(begin) && privateKey.includes(end)) {
// newlines are escaped
if (privateKey.indexOf("\\n") !== -1) {
privateKey = privateKey.replace(/\\n/g, "\n");
// newlines are potentially escaped
if (privateKey.indexOf("\\n") !== -1) {
privateKey = privateKey.replace(/\\n/g, "\n");
}

if (isPKCS1(privateKey)) {
// newlines are missing
if (privateKey.indexOf("\n") === -1) {
privateKey = addNewlines({
privateKey,
begin: pkcs1Begin,
end: pkcs1End,
});
}
return privateKey;
}

if (isPKCS8(privateKey)) {
// newlines are missing
if (privateKey.indexOf("\n") === -1) {
privateKey = addNewlines(privateKey);
privateKey = addNewlines({
privateKey,
begin: pkcs8Begin,
end: pkcs8End,
});
}
return privateKey;
}
Expand Down Expand Up @@ -76,7 +102,15 @@ function isBase64(str: string): boolean {
return Buffer.from(str, "base64").toString("base64") === str;
}

function addNewlines(privateKey: string): string {
function addNewlines({
privateKey,
begin,
end,
}: {
privateKey: string;
begin: string;
end: string;
}): string {
const middleLength = privateKey.length - begin.length - end.length - 2;
const middle = privateKey.substr(begin.length + 1, middleLength);
return `${begin}\n${middle.trim().replace(/\s+/g, "\n")}\n${end}`;
Expand Down
Loading

0 comments on commit 0c60e8a

Please sign in to comment.