Skip to content

Commit

Permalink
Merge pull request #32 from mittwald/fix/ca-cert-reload
Browse files Browse the repository at this point in the history
Load new CA Certificate from file on certificate error
  • Loading branch information
YannikBramkamp authored Apr 29, 2022
2 parents 1366ab7 + 11d53de commit 5185cfa
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ const client = new Vault({
### Kubernetes In-Cluster Example

```js
const cert = await fs.readFile("../vault-cacert", "utf8");
const client = new Vault({
vaultAddress: "https://vault:8200",
vaultCaCertificate: cert,
vaultCaCertificatePath: "../vault-cacert",
});

const k8sauth = client.KubernetesAuth({
Expand Down
43 changes: 35 additions & 8 deletions src/Vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { resolveURL } from "./util";
import { TotpVaultClient } from "./engines/totp";
import { KVVaultClient } from "./engines/kv";
import { KV2VaultClient } from "./engines";
import { promises as fs } from "fs";

export type VaultHTTPMethods = "GET" | "POST" | "DELETE" | "LIST";
export interface HTTPGETParameters {
Expand All @@ -18,6 +19,7 @@ export interface IVaultConfig {
vaultAddress?: string;
vaultToken?: string;
vaultCaCertificate?: string;
vaultCaCertificatePath?: string;
vaultNamespace?: string;
apiVersion?: string;
}
Expand Down Expand Up @@ -133,6 +135,10 @@ export class Vault {
}
const uri = resolveURL(this.config.vaultAddress!, this.config.apiVersion!, ...path);

if (this.config.vaultCaCertificatePath && !this.config.vaultCaCertificate) {
await this.loadCACert();
}

const requestOptions: request.Options = {
method,
uri: uri.toString(),
Expand All @@ -149,18 +155,32 @@ export class Vault {
qs: parameters,
};

let res = await request(requestOptions);
let res;
let retry = false;
try {
res = await request(requestOptions);
} catch (e) {
if (e.error && e.error.code === "CERT_SIGNATURE_FAILURE" && this.config.vaultCaCertificatePath) {
await this.loadCACert();
requestOptions.ca = this.config.vaultCaCertificate;
retry = true;
} else {
throw e;
}
}

if (this.tokenClient && options.retryWithTokenRenew && res.statusCode === 403) {
// token could be expired, try a new one
await this.tokenClient.login();
res = await request({
...requestOptions,
headers: {
...requestOptions.headers,
"X-Vault-Token": this.token,
},
});
requestOptions.headers = {
...requestOptions.headers,
"X-Vault-Token": this.token,
};
retry = true;
}

if (retry) {
res = await request(requestOptions);
}

if (!options.acceptedReturnCodes?.includes(res.statusCode)) {
Expand Down Expand Up @@ -202,4 +222,11 @@ export class Vault {

return errors.some((e) => e.includes(expectedMsg));
}

private async loadCACert(): Promise<void> {
if (this.config.vaultCaCertificatePath) {
const cert = await fs.readFile(this.config.vaultCaCertificatePath, "utf8");
this.config.vaultCaCertificate = cert;
}
}
}
4 changes: 2 additions & 2 deletions tests/engines/transit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,14 @@ describe("Transit Vault Client", () => {
expect(dec).toEqual("hello");
});

test("should respond with 500 if the keyID for decryption is invalid", async () => {
test("should respond with 400 if the keyID for decryption is invalid", async () => {
const encrypted = await client.encryptText("500test", "plainText");
const invalidKeyID = "invalid";
await client.create(invalidKeyID);
try {
await client.decryptText(invalidKeyID, encrypted);
} catch (err) {
expect(err.response.statusCode).toEqual(500);
expect(err.response.statusCode).toEqual(400);
}
});

Expand Down

0 comments on commit 5185cfa

Please sign in to comment.