104 lines
4.0 KiB
JavaScript
104 lines
4.0 KiB
JavaScript
|
|
// Copyright (c) Microsoft Corporation.
|
||
|
|
// Licensed under the MIT License.
|
||
|
|
import { RSA_PKCS1_OAEP_PADDING, RSA_PKCS1_PADDING } from "constants";
|
||
|
|
import { publicEncrypt } from "node:crypto";
|
||
|
|
import { createVerify } from "./crypto.js";
|
||
|
|
import { convertJWKtoPEM } from "./conversions.js";
|
||
|
|
import { LocalCryptographyUnsupportedError } from "./models.js";
|
||
|
|
/**
|
||
|
|
* An RSA cryptography provider supporting RSA algorithms.
|
||
|
|
*/
|
||
|
|
export class RsaCryptographyProvider {
|
||
|
|
constructor(key) {
|
||
|
|
/**
|
||
|
|
* The set of algorithms this provider supports
|
||
|
|
*/
|
||
|
|
this.applicableAlgorithms = [
|
||
|
|
"RSA1_5",
|
||
|
|
"RSA-OAEP",
|
||
|
|
"PS256",
|
||
|
|
"RS256",
|
||
|
|
"PS384",
|
||
|
|
"RS384",
|
||
|
|
"PS512",
|
||
|
|
"RS512",
|
||
|
|
];
|
||
|
|
/**
|
||
|
|
* The set of operations this provider supports
|
||
|
|
*/
|
||
|
|
this.applicableOperations = [
|
||
|
|
"encrypt",
|
||
|
|
"wrapKey",
|
||
|
|
"verifyData",
|
||
|
|
];
|
||
|
|
/**
|
||
|
|
* Mapping between signature algorithms and their corresponding hash algorithms. Externally used for testing.
|
||
|
|
* @internal
|
||
|
|
*/
|
||
|
|
this.signatureAlgorithmToHashAlgorithm = {
|
||
|
|
PS256: "SHA256",
|
||
|
|
RS256: "SHA256",
|
||
|
|
PS384: "SHA384",
|
||
|
|
RS384: "SHA384",
|
||
|
|
PS512: "SHA512",
|
||
|
|
RS512: "SHA512",
|
||
|
|
};
|
||
|
|
this.key = key;
|
||
|
|
}
|
||
|
|
isSupported(algorithm, operation) {
|
||
|
|
return (this.applicableAlgorithms.includes(algorithm) && this.applicableOperations.includes(operation));
|
||
|
|
}
|
||
|
|
encrypt(encryptParameters, _options) {
|
||
|
|
this.ensureValid();
|
||
|
|
const keyPEM = convertJWKtoPEM(this.key);
|
||
|
|
const padding = encryptParameters.algorithm === "RSA1_5" ? RSA_PKCS1_PADDING : RSA_PKCS1_OAEP_PADDING;
|
||
|
|
return Promise.resolve({
|
||
|
|
algorithm: encryptParameters.algorithm,
|
||
|
|
keyID: this.key.kid,
|
||
|
|
result: publicEncrypt({ key: keyPEM, padding: padding }, Buffer.from(encryptParameters.plaintext)),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
decrypt(_decryptParameters, _options) {
|
||
|
|
throw new LocalCryptographyUnsupportedError("Decrypting using a local JsonWebKey is not supported.");
|
||
|
|
}
|
||
|
|
wrapKey(algorithm, keyToWrap, _options) {
|
||
|
|
this.ensureValid();
|
||
|
|
const keyPEM = convertJWKtoPEM(this.key);
|
||
|
|
const padding = algorithm === "RSA1_5" ? RSA_PKCS1_PADDING : RSA_PKCS1_OAEP_PADDING;
|
||
|
|
return Promise.resolve({
|
||
|
|
algorithm: algorithm,
|
||
|
|
result: publicEncrypt({ key: keyPEM, padding }, Buffer.from(keyToWrap)),
|
||
|
|
keyID: this.key.kid,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
unwrapKey(_algorithm, _encryptedKey, _options) {
|
||
|
|
throw new LocalCryptographyUnsupportedError("Unwrapping a key using a local JsonWebKey is not supported.");
|
||
|
|
}
|
||
|
|
sign(_algorithm, _digest, _options) {
|
||
|
|
throw new LocalCryptographyUnsupportedError("Signing a digest using a local JsonWebKey is not supported.");
|
||
|
|
}
|
||
|
|
signData(_algorithm, _data, _options) {
|
||
|
|
throw new LocalCryptographyUnsupportedError("Signing a block of data using a local JsonWebKey is not supported.");
|
||
|
|
}
|
||
|
|
async verify(_algorithm, _digest, _signature, _options) {
|
||
|
|
throw new LocalCryptographyUnsupportedError("Verifying a digest using a local JsonWebKey is not supported.");
|
||
|
|
}
|
||
|
|
verifyData(algorithm, data, signature, _options) {
|
||
|
|
this.ensureValid();
|
||
|
|
const keyPEM = convertJWKtoPEM(this.key);
|
||
|
|
const verifier = createVerify(algorithm, data);
|
||
|
|
return Promise.resolve({
|
||
|
|
result: verifier.verify(keyPEM, Buffer.from(signature)),
|
||
|
|
keyID: this.key.kid,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
ensureValid() {
|
||
|
|
var _a, _b;
|
||
|
|
if (this.key &&
|
||
|
|
((_a = this.key.kty) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== "RSA" &&
|
||
|
|
((_b = this.key.kty) === null || _b === void 0 ? void 0 : _b.toUpperCase()) !== "RSA-HSM") {
|
||
|
|
throw new Error("Key type does not match the algorithm RSA");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//# sourceMappingURL=rsaCryptographyProvider.js.map
|