Skip to content

Commit

Permalink
Merge pull request #35 from redegade/master
Browse files Browse the repository at this point in the history
add sign and verify to transit api
  • Loading branch information
Lucaber authored May 23, 2022
2 parents 5185cfa + b274fe3 commit abe026e
Show file tree
Hide file tree
Showing 5 changed files with 376 additions and 1 deletion.
73 changes: 73 additions & 0 deletions src/engines/transit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,19 @@ import {
ITransitEncryptOptionsSingle,
ITransitEncryptResponseBatch,
ITransitEncryptResponseSingle,
ITransitSignOptionsSingle,
ITransitSignOptionsBatch,
ITransitExportOptions,
ITransitExportResponse,
ITransitListResponse,
ITransitReadResponse,
ITransitUpdateOptions,
ITransitSignResponseSingle,
ITransitSignResponseBatch,
ITransitVerifyOptionsSingle,
ITransitVerifyResponseSingle,
ITransitVerifyOptionsBatch,
ITransitVerifyResponseBatch,
} from "./transit_types";
import { validateKeyName } from "../util";

Expand Down Expand Up @@ -210,6 +218,71 @@ export class TransitVaultClient extends AbstractVaultClient {
});
}

/**
* Returns the cryptographic signature of the given data using the named key and the specified hash algorithm
* @see https://www.vaultproject.io/api-docs/secret/transit#sign-data
* @param key
* @param options
*
* @param options.input Specifies the base64 encoded input data. One of input or batch_input must be supplied.
* @param options.batch_input Specifies a list of items for processing. When this parameter is set, any supplied 'input' or 'context' parameters will be ignored.
* @param options.key_version Specifies the version of the key to use for encryption. If not set, uses the latest version. Must be greater than or equal to the key's min_encryption_version, if set.
* @param options.context Base64 encoded context for key derivation. Required if key derivation is enabled.
* @param options.hash_algorithm Specifies the hash algorithm to use for supporting key types.
* @param options.prehashed Set to true when the input is already hashed. When set, input is expected to be base64-encoded binary hashed data, not hex-formatted.
* @param options.signature_algorithm When using a RSA key, specifies the RSA signature algorithm to use for signing.
* @param options.marshaling_algorithm Specifies the way in which the signature should be marshaled.
*/
public async sign(key: string, options: ITransitSignOptionsSingle): Promise<ITransitSignResponseSingle>;
public async sign(key: string, options: ITransitSignOptionsBatch): Promise<ITransitSignResponseBatch>;
public async sign(
key: string,
options: ITransitSignOptionsSingle | ITransitSignOptionsBatch,
): Promise<ITransitSignResponseSingle | ITransitSignResponseBatch> {
validateKeyName(key);
return this.rawWrite(["sign", key], options).then((res) => {
if ("batch_input" in options) {
transitChecker.ITransitSignResponseBatch.check(res);
} else {
transitChecker.ITransitSignResponseSingle.check(res);
}
return res;
});
}

/**
* Returns whether the provided signature is valid for the given data.
* @see https://www.vaultproject.io/api-docs/secret/transit#verify-signed-data
* @param key
* @param options
*
* @param options.input Specifies the base64 encoded input data. One of input or batch_input must be supplied.
* @param options.batch_input Specifies a list of items for processing. When this parameter is set, any supplied 'input', 'hmac' or 'signature' parameters will be ignored. All items in the batch must consistently supply either 'hmac' or 'signature' parameters.
* @param options.signature Specifies the signature output from the /transit/sign function. Either this must be supplied or hmac must be supplied.
* @param options.hmac Specifies the signature output from the /transit/hmac function. Either this must be supplied or signature must be supplied.
* @param options.hash_algorithm Specifies the hash algorithm to use.
* @param options.context Base64 encoded context for key derivation.
* @param options.prehashed Set to true when the input is already hashed.
* @param options.signature_algorithm When using a RSA key, specifies the RSA signature algorithm to use for signature verification.
* @param options.marshaling_algorithm Specifies the way in which the signature was originally marshaled.
*/
public async verify(key: string, options: ITransitVerifyOptionsSingle): Promise<ITransitVerifyResponseSingle>;
public async verify(key: string, options: ITransitVerifyOptionsBatch): Promise<ITransitVerifyResponseBatch>;
public async verify(
key: string,
options: ITransitVerifyOptionsSingle | ITransitVerifyOptionsBatch,
): Promise<ITransitVerifyResponseSingle | ITransitVerifyResponseBatch> {
validateKeyName(key);
return this.rawWrite(["verify", key], options).then((res) => {
if ("batch_input" in options) {
transitChecker.ITransitVerifyResponseBatch.check(res);
} else {
transitChecker.ITransitVerifyResponseSingle.check(res);
}
return res;
});
}

/**
* Encrypts the specified plaintext with default options using the named key.
* @param key
Expand Down
108 changes: 108 additions & 0 deletions src/engines/transit_types-ti.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import * as t from "ts-interface-checker";

export const ITransitKeyType = t.union(t.lit("aes256-gcm96"), t.lit("chacha20-poly1305"), t.lit("d25519"), t.lit("ecdsa-p256"), t.lit("rsa-2048"), t.lit("rsa-4096"));

export const ITransitSignHashAlgorithm = t.union(t.lit("sha1"), t.lit("sha2-224"), t.lit("sha2-256"), t.lit("sha2-384"), t.lit("sha2-512"), t.lit("sha3-224"), t.lit("sha3-256"), t.lit("sha3-384"), t.lit("sha3-512"));

export const ITransitSignSignatureAlgorithm = t.union(t.lit("pss"), t.lit("pkcs1v15"));

export const ITransitSignMarshalingAlgorithm = t.union(t.lit("asn1"), t.lit("jws"));

export const ITransitBatchPlaintext = t.array(t.iface([], {
"plaintext": "string",
"context": t.opt("string"),
Expand All @@ -21,6 +27,29 @@ export const ITransitBatchCiphertext = t.array(t.iface([], {
"context": t.opt("string"),
}));

export const ITransitSignBatchInput = t.array(t.iface([], {
"input": "string",
"context": t.opt("string"),
}));

export const ITransitVerifyBatchInputSignature = t.array(t.iface([], {
"input": "string",
"signature": "string",
"context": t.opt("string"),
}));

export const ITransitVerifyBatchInputHMAC = t.array(t.iface([], {
"input": "string",
"hmac": "string",
"context": t.opt("string"),
}));

export const ITransitSignBatchOutput = t.array(t.iface([], {
"signature": t.opt("string"),
"publickey": t.opt("string"),
"error": t.opt("string"),
}));

export const ITransitCreateOptions = t.iface([], {
"convergent_encryption": t.opt("boolean"),
"derived": t.opt("boolean"),
Expand Down Expand Up @@ -136,11 +165,82 @@ export const ITransitDecryptRawResponseBatch = t.iface([], {
}),
});

export const ITransitSignOptionsSingle = t.iface([], {
"key_version": t.opt("number"),
"hash_algorithm": t.opt("ITransitSignHashAlgorithm"),
"input": "string",
"context": t.opt("string"),
"prehashed": t.opt("boolean"),
"signature_algorithm": t.opt("ITransitSignSignatureAlgorithm"),
"marshaling_algorithm": t.opt("ITransitSignMarshalingAlgorithm"),
});

export const ITransitSignOptionsBatch = t.iface([], {
"key_version": t.opt("number"),
"hash_algorithm": t.opt("ITransitSignHashAlgorithm"),
"batch_input": "ITransitSignBatchInput",
"prehashed": t.opt("boolean"),
"signature_algorithm": t.opt("ITransitSignSignatureAlgorithm"),
"marshaling_algorithm": t.opt("ITransitSignMarshalingAlgorithm"),
});

export const ITransitSignResponseSingle = t.iface([], {
"data": t.iface([], {
"signature": t.union("string", "undefined"),
}),
});

export const ITransitSignResponseBatch = t.iface([], {
"data": t.iface([], {
"batch_results": "ITransitSignBatchOutput",
}),
});

export const ITransitVerifyOptionsSingle = t.iface([], {
"input": "string",
"signature": t.opt("string"),
"hmac": t.opt("string"),
"hash_algorithm": t.opt("ITransitSignHashAlgorithm"),
"context": t.opt("string"),
"prehashed": t.opt("boolean"),
"signature_algorithm": t.opt("ITransitSignSignatureAlgorithm"),
"marshaling_algorithm": t.opt("ITransitSignMarshalingAlgorithm"),
});

export const ITransitVerifyOptionsBatch = t.iface([], {
"batch_input": t.union("ITransitVerifyBatchInputSignature", "ITransitVerifyBatchInputHMAC"),
"hash_algorithm": t.opt("ITransitSignHashAlgorithm"),
"prehashed": t.opt("boolean"),
"signature_algorithm": t.opt("ITransitSignSignatureAlgorithm"),
"marshaling_algorithm": t.opt("ITransitSignMarshalingAlgorithm"),
});

export const ITransitVerifyResponseSingle = t.iface([], {
"data": t.iface([], {
"valid": "boolean",
}),
});

export const ITransitVerifyResponseBatch = t.iface([], {
"data": t.iface([], {
"batch_results": t.array(t.iface([], {
"valid": "boolean",
})),
}),
});

const exportedTypeSuite: t.ITypeSuite = {
ITransitKeyType,
ITransitSignHashAlgorithm,
ITransitSignSignatureAlgorithm,
ITransitSignMarshalingAlgorithm,
ITransitBatchPlaintext,
ITransitRawBatchPlaintext,
ITransitBatchCiphertext,
ITransitSignBatchInput,
ITransitVerifyBatchInputSignature,
ITransitVerifyBatchInputHMAC,
ITransitSignBatchOutput,
ITransitCreateOptions,
ITransitReadResponse,
ITransitListResponse,
Expand All @@ -156,5 +256,13 @@ const exportedTypeSuite: t.ITypeSuite = {
ITransitDecryptResponseSingle,
ITransitDecryptResponseBatch,
ITransitDecryptRawResponseBatch,
ITransitSignOptionsSingle,
ITransitSignOptionsBatch,
ITransitSignResponseSingle,
ITransitSignResponseBatch,
ITransitVerifyOptionsSingle,
ITransitVerifyOptionsBatch,
ITransitVerifyResponseSingle,
ITransitVerifyResponseBatch,
};
export default exportedTypeSuite;
91 changes: 91 additions & 0 deletions src/engines/transit_types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
export type ITransitKeyType = "aes256-gcm96" | "chacha20-poly1305" | "d25519" | "ecdsa-p256" | "rsa-2048" | "rsa-4096";
export type ITransitSignHashAlgorithm =
| "sha1"
| "sha2-224"
| "sha2-256"
| "sha2-384"
| "sha2-512"
| "sha3-224"
| "sha3-256"
| "sha3-384"
| "sha3-512";
export type ITransitSignSignatureAlgorithm = "pss" | "pkcs1v15";
export type ITransitSignMarshalingAlgorithm = "asn1" | "jws";

export type ITransitBatchPlaintext = Array<{
plaintext: string;
Expand All @@ -12,6 +24,25 @@ export type ITransitBatchCiphertext = Array<{
ciphertext: string;
context?: string;
}>;
export type ITransitSignBatchInput = Array<{
input: string;
context?: string;
}>;
export type ITransitVerifyBatchInputSignature = Array<{
input: string;
signature: string;
context?: string;
}>;
export type ITransitVerifyBatchInputHMAC = Array<{
input: string;
hmac: string;
context?: string;
}>;
export type ITransitSignBatchOutput = Array<{
signature?: string;
publickey?: string;
error?: string;
}>;

export interface ITransitCreateOptions {
convergent_encryption?: boolean;
Expand Down Expand Up @@ -127,3 +158,63 @@ export interface ITransitDecryptRawResponseBatch {
batch_results: ITransitRawBatchPlaintext;
};
}

export interface ITransitSignOptionsSingle {
key_version?: number;
hash_algorithm?: ITransitSignHashAlgorithm;
input: string;
context?: string;
prehashed?: boolean;
signature_algorithm?: ITransitSignSignatureAlgorithm;
marshaling_algorithm?: ITransitSignMarshalingAlgorithm;
}
export interface ITransitSignOptionsBatch {
key_version?: number;
hash_algorithm?: ITransitSignHashAlgorithm;
batch_input: ITransitSignBatchInput;
prehashed?: boolean;
signature_algorithm?: ITransitSignSignatureAlgorithm;
marshaling_algorithm?: ITransitSignMarshalingAlgorithm;
}

export interface ITransitSignResponseSingle {
data: {
signature: string | undefined;
};
}
export interface ITransitSignResponseBatch {
data: {
batch_results: ITransitSignBatchOutput;
};
}

export interface ITransitVerifyOptionsSingle {
input: string;
signature?: string;
hmac?: string;
hash_algorithm?: ITransitSignHashAlgorithm;
context?: string;
prehashed?: boolean;
signature_algorithm?: ITransitSignSignatureAlgorithm;
marshaling_algorithm?: ITransitSignMarshalingAlgorithm;
}
export interface ITransitVerifyOptionsBatch {
batch_input: ITransitVerifyBatchInputSignature | ITransitVerifyBatchInputHMAC;
hash_algorithm?: ITransitSignHashAlgorithm;
prehashed?: boolean;
signature_algorithm?: ITransitSignSignatureAlgorithm;
marshaling_algorithm?: ITransitSignMarshalingAlgorithm;
}

export interface ITransitVerifyResponseSingle {
data: {
valid: boolean;
};
}
export interface ITransitVerifyResponseBatch {
data: {
batch_results: Array<{
valid: boolean;
}>;
};
}
Loading

0 comments on commit abe026e

Please sign in to comment.