mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1026398 - Add support for RSA-OAEP to WebCrypto API r=rbarnes,bz,dkeeler
* * * Bug 1026398 - Add RSA-OAEP tests r=rbarnes
This commit is contained in:
parent
c15523f3cf
commit
04422d6b32
@ -24,6 +24,7 @@
|
||||
#define WEBCRYPTO_ALG_PBKDF2 "PBKDF2"
|
||||
#define WEBCRYPTO_ALG_RSAES_PKCS1 "RSAES-PKCS1-v1_5"
|
||||
#define WEBCRYPTO_ALG_RSASSA_PKCS1 "RSASSA-PKCS1-v1_5"
|
||||
#define WEBCRYPTO_ALG_RSA_OAEP "RSA-OAEP"
|
||||
|
||||
// WebCrypto key formats
|
||||
#define WEBCRYPTO_KEY_FORMAT_RAW "raw"
|
||||
@ -146,6 +147,8 @@ MapAlgorithmNameToMechanism(const nsString& aName)
|
||||
mechanism = CKM_RSA_PKCS;
|
||||
} else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
|
||||
mechanism = CKM_RSA_PKCS;
|
||||
} else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
|
||||
mechanism = CKM_RSA_PKCS_OAEP;
|
||||
}
|
||||
|
||||
return mechanism;
|
||||
|
@ -303,7 +303,7 @@ class AesTask : public ReturnArrayBufferViewTask
|
||||
{
|
||||
public:
|
||||
AesTask(JSContext* aCx, const ObjectOrString& aAlgorithm,
|
||||
mozilla::dom::CryptoKey& aKey, const CryptoOperationData& aData,
|
||||
CryptoKey& aKey, const CryptoOperationData& aData,
|
||||
bool aEncrypt)
|
||||
: mSymKey(aKey.GetSymKey())
|
||||
, mEncrypt(aEncrypt)
|
||||
@ -480,7 +480,7 @@ class RsaesPkcs1Task : public ReturnArrayBufferViewTask
|
||||
{
|
||||
public:
|
||||
RsaesPkcs1Task(JSContext* aCx, const ObjectOrString& aAlgorithm,
|
||||
mozilla::dom::CryptoKey& aKey, const CryptoOperationData& aData,
|
||||
CryptoKey& aKey, const CryptoOperationData& aData,
|
||||
bool aEncrypt)
|
||||
: mPrivKey(aKey.GetPrivateKey())
|
||||
, mPubKey(aKey.GetPublicKey())
|
||||
@ -549,11 +549,134 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class RsaOaepTask : public ReturnArrayBufferViewTask
|
||||
{
|
||||
public:
|
||||
RsaOaepTask(JSContext* aCx, const ObjectOrString& aAlgorithm,
|
||||
CryptoKey& aKey, const CryptoOperationData& aData,
|
||||
bool aEncrypt)
|
||||
: mPrivKey(aKey.GetPrivateKey())
|
||||
, mPubKey(aKey.GetPublicKey())
|
||||
, mEncrypt(aEncrypt)
|
||||
{
|
||||
Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_RSA_OAEP);
|
||||
|
||||
ATTEMPT_BUFFER_INIT(mData, aData);
|
||||
|
||||
if (mEncrypt) {
|
||||
if (!mPubKey) {
|
||||
mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||
return;
|
||||
}
|
||||
mStrength = SECKEY_PublicKeyStrength(mPubKey);
|
||||
} else {
|
||||
if (!mPrivKey) {
|
||||
mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||
return;
|
||||
}
|
||||
mStrength = PK11_GetPrivateModulusLen(mPrivKey);
|
||||
}
|
||||
|
||||
RootedDictionary<RsaOaepParams> params(aCx);
|
||||
mEarlyRv = Coerce(aCx, params, aAlgorithm);
|
||||
if (NS_FAILED(mEarlyRv)) {
|
||||
mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.mLabel.WasPassed() && !params.mLabel.Value().IsNull()) {
|
||||
ATTEMPT_BUFFER_INIT(mLabel, params.mLabel.Value().Value());
|
||||
}
|
||||
// Otherwise mLabel remains the empty octet string, as intended
|
||||
|
||||
// Look up the MGF based on the KeyAlgorithm.
|
||||
// static_cast is safe because we only get here if the algorithm name
|
||||
// is RSA-OAEP, and that only happens if we've constructed
|
||||
// an RsaHashedKeyAlgorithm.
|
||||
// TODO: Add As* methods to KeyAlgorithm (Bug 1036734)
|
||||
nsRefPtr<RsaHashedKeyAlgorithm> rsaAlg =
|
||||
static_cast<RsaHashedKeyAlgorithm*>(aKey.Algorithm());
|
||||
mHashMechanism = rsaAlg->Hash()->Mechanism();
|
||||
|
||||
switch (mHashMechanism) {
|
||||
case CKM_SHA_1:
|
||||
mMgfMechanism = CKG_MGF1_SHA1; break;
|
||||
case CKM_SHA256:
|
||||
mMgfMechanism = CKG_MGF1_SHA256; break;
|
||||
case CKM_SHA384:
|
||||
mMgfMechanism = CKG_MGF1_SHA384; break;
|
||||
case CKM_SHA512:
|
||||
mMgfMechanism = CKG_MGF1_SHA512; break;
|
||||
default: {
|
||||
mEarlyRv = NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CK_MECHANISM_TYPE mHashMechanism;
|
||||
CK_MECHANISM_TYPE mMgfMechanism;
|
||||
ScopedSECKEYPrivateKey mPrivKey;
|
||||
ScopedSECKEYPublicKey mPubKey;
|
||||
CryptoBuffer mLabel;
|
||||
CryptoBuffer mData;
|
||||
uint32_t mStrength;
|
||||
bool mEncrypt;
|
||||
|
||||
virtual nsresult DoCrypto() MOZ_OVERRIDE
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Ciphertext is an integer mod the modulus, so it will be
|
||||
// no longer than mStrength octets
|
||||
if (!mResult.SetLength(mStrength)) {
|
||||
return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
CK_RSA_PKCS_OAEP_PARAMS oaepParams;
|
||||
oaepParams.source = CKZ_DATA_SPECIFIED;
|
||||
|
||||
oaepParams.pSourceData = mLabel.Length() ? mLabel.Elements() : nullptr;
|
||||
oaepParams.ulSourceDataLen = mLabel.Length();
|
||||
|
||||
oaepParams.mgf = mMgfMechanism;
|
||||
oaepParams.hashAlg = mHashMechanism;
|
||||
|
||||
SECItem param;
|
||||
param.type = siBuffer;
|
||||
param.data = (unsigned char*) &oaepParams;
|
||||
param.len = sizeof(oaepParams);
|
||||
|
||||
uint32_t outLen;
|
||||
if (mEncrypt) {
|
||||
// PK11_PubEncrypt() checks the plaintext's length and fails if it is too
|
||||
// long to encrypt, i.e. if it is longer than (k - 2hLen - 2) with 'k'
|
||||
// being the length in octets of the RSA modulus n and 'hLen' being the
|
||||
// output length in octets of the chosen hash function.
|
||||
// <https://tools.ietf.org/html/rfc3447#section-7.1>
|
||||
rv = MapSECStatus(PK11_PubEncrypt(
|
||||
mPubKey.get(), CKM_RSA_PKCS_OAEP, ¶m,
|
||||
mResult.Elements(), &outLen, mResult.Length(),
|
||||
mData.Elements(), mData.Length(), nullptr));
|
||||
} else {
|
||||
rv = MapSECStatus(PK11_PrivDecrypt(
|
||||
mPrivKey.get(), CKM_RSA_PKCS_OAEP, ¶m,
|
||||
mResult.Elements(), &outLen, mResult.Length(),
|
||||
mData.Elements(), mData.Length()));
|
||||
}
|
||||
mResult.SetLength(outLen);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_OPERATION_ERR);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
class HmacTask : public WebCryptoTask
|
||||
{
|
||||
public:
|
||||
HmacTask(JSContext* aCx, const ObjectOrString& aAlgorithm,
|
||||
mozilla::dom::CryptoKey& aKey,
|
||||
CryptoKey& aKey,
|
||||
const CryptoOperationData& aSignature,
|
||||
const CryptoOperationData& aData,
|
||||
bool aSign)
|
||||
@ -656,7 +779,7 @@ class RsassaPkcs1Task : public WebCryptoTask
|
||||
{
|
||||
public:
|
||||
RsassaPkcs1Task(JSContext* aCx, const ObjectOrString& aAlgorithm,
|
||||
mozilla::dom::CryptoKey& aKey,
|
||||
CryptoKey& aKey,
|
||||
const CryptoOperationData& aSignature,
|
||||
const CryptoOperationData& aData,
|
||||
bool aSign)
|
||||
@ -1017,7 +1140,8 @@ public:
|
||||
}
|
||||
|
||||
// If this is RSA with a hash, cache the hash name
|
||||
if (mAlgName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
|
||||
if (mAlgName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1) ||
|
||||
mAlgName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
|
||||
RootedDictionary<RsaHashedImportParams> params(aCx);
|
||||
mEarlyRv = Coerce(aCx, params, aAlgorithm);
|
||||
if (NS_FAILED(mEarlyRv) || !params.mHash.WasPassed()) {
|
||||
@ -1088,15 +1212,14 @@ private:
|
||||
{
|
||||
// Construct an appropriate KeyAlgorithm
|
||||
nsIGlobalObject* global = mKey->GetParentObject();
|
||||
if (mAlgName.EqualsLiteral(WEBCRYPTO_ALG_RSAES_PKCS1)) {
|
||||
if (mAlgName.EqualsLiteral(WEBCRYPTO_ALG_RSAES_PKCS1) ||
|
||||
mAlgName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
|
||||
if ((mKey->GetKeyType() == CryptoKey::PUBLIC &&
|
||||
mKey->HasUsageOtherThan(CryptoKey::ENCRYPT)) ||
|
||||
(mKey->GetKeyType() == CryptoKey::PRIVATE &&
|
||||
mKey->HasUsageOtherThan(CryptoKey::DECRYPT))) {
|
||||
return NS_ERROR_DOM_DATA_ERR;
|
||||
}
|
||||
|
||||
mKey->SetAlgorithm(new RsaKeyAlgorithm(global, mAlgName, mModulusLength, mPublicExponent));
|
||||
} else if (mAlgName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
|
||||
if ((mKey->GetKeyType() == CryptoKey::PUBLIC &&
|
||||
mKey->HasUsageOtherThan(CryptoKey::VERIFY)) ||
|
||||
@ -1104,16 +1227,23 @@ private:
|
||||
mKey->HasUsageOtherThan(CryptoKey::SIGN))) {
|
||||
return NS_ERROR_DOM_DATA_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<RsaHashedKeyAlgorithm> algorithm = new RsaHashedKeyAlgorithm(
|
||||
global,
|
||||
mAlgName,
|
||||
mModulusLength,
|
||||
mPublicExponent,
|
||||
mHashName);
|
||||
// Construct an appropriate KeyAlgorithm
|
||||
if (mAlgName.EqualsLiteral(WEBCRYPTO_ALG_RSAES_PKCS1)) {
|
||||
mKey->SetAlgorithm(new RsaKeyAlgorithm(global, mAlgName, mModulusLength, mPublicExponent));
|
||||
} else if (mAlgName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1) ||
|
||||
mAlgName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
|
||||
nsRefPtr<RsaHashedKeyAlgorithm> algorithm =
|
||||
new RsaHashedKeyAlgorithm(global, mAlgName,
|
||||
mModulusLength, mPublicExponent, mHashName);
|
||||
if (algorithm->Mechanism() == UNKNOWN_CK_MECHANISM) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
if (algorithm->Hash()->Mechanism() == UNKNOWN_CK_MECHANISM) {
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
mKey->SetAlgorithm(algorithm);
|
||||
}
|
||||
|
||||
@ -1345,7 +1475,8 @@ public:
|
||||
// Construct an appropriate KeyAlorithm
|
||||
KeyAlgorithm* algorithm;
|
||||
uint32_t privateAllowedUsages = 0, publicAllowedUsages = 0;
|
||||
if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
|
||||
if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1) ||
|
||||
algName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
|
||||
RootedDictionary<RsaHashedKeyGenParams> params(aCx);
|
||||
mEarlyRv = Coerce(aCx, params, aAlgorithm);
|
||||
if (NS_FAILED(mEarlyRv) || !params.mModulusLength.WasPassed() ||
|
||||
@ -1380,9 +1511,6 @@ public:
|
||||
mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||
return;
|
||||
}
|
||||
|
||||
privateAllowedUsages = CryptoKey::SIGN;
|
||||
publicAllowedUsages = CryptoKey::VERIFY;
|
||||
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSAES_PKCS1)) {
|
||||
RootedDictionary<RsaKeyGenParams> params(aCx);
|
||||
mEarlyRv = Coerce(aCx, params, aAlgorithm);
|
||||
@ -1411,14 +1539,21 @@ public:
|
||||
mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||
return;
|
||||
}
|
||||
|
||||
privateAllowedUsages = CryptoKey::DECRYPT | CryptoKey::UNWRAPKEY;
|
||||
publicAllowedUsages = CryptoKey::ENCRYPT | CryptoKey::WRAPKEY;
|
||||
} else {
|
||||
mEarlyRv = NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set key usages.
|
||||
if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
|
||||
privateAllowedUsages = CryptoKey::SIGN;
|
||||
publicAllowedUsages = CryptoKey::VERIFY;
|
||||
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSAES_PKCS1) ||
|
||||
algName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
|
||||
privateAllowedUsages = CryptoKey::DECRYPT | CryptoKey::UNWRAPKEY;
|
||||
publicAllowedUsages = CryptoKey::ENCRYPT | CryptoKey::WRAPKEY;
|
||||
}
|
||||
|
||||
mKeyPair->PrivateKey()->SetExtractable(aExtractable);
|
||||
mKeyPair->PrivateKey()->SetType(CryptoKey::PRIVATE);
|
||||
|
||||
@ -1676,6 +1811,8 @@ WebCryptoTask::EncryptDecryptTask(JSContext* aCx,
|
||||
return new AesTask(aCx, aAlgorithm, aKey, aData, aEncrypt);
|
||||
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSAES_PKCS1)) {
|
||||
return new RsaesPkcs1Task(aCx, aAlgorithm, aKey, aData, aEncrypt);
|
||||
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
|
||||
return new RsaOaepTask(aCx, aAlgorithm, aKey, aData, aEncrypt);
|
||||
}
|
||||
|
||||
return new FailureTask(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
@ -1748,7 +1885,8 @@ WebCryptoTask::ImportKeyTask(JSContext* aCx,
|
||||
return new ImportSymmetricKeyTask(aCx, aFormat, aKeyData, aAlgorithm,
|
||||
aExtractable, aKeyUsages);
|
||||
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSAES_PKCS1) ||
|
||||
algName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
|
||||
algName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1) ||
|
||||
algName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
|
||||
return new ImportRsaKeyTask(aCx, aFormat, aKeyData, aAlgorithm,
|
||||
aExtractable, aKeyUsages);
|
||||
} else {
|
||||
@ -1790,7 +1928,8 @@ WebCryptoTask::GenerateKeyTask(JSContext* aCx,
|
||||
algName.EqualsASCII(WEBCRYPTO_ALG_HMAC)) {
|
||||
return new GenerateSymmetricKeyTask(aCx, aAlgorithm, aExtractable, aKeyUsages);
|
||||
} else if (algName.EqualsASCII(WEBCRYPTO_ALG_RSAES_PKCS1) ||
|
||||
algName.EqualsASCII(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
|
||||
algName.EqualsASCII(WEBCRYPTO_ALG_RSASSA_PKCS1) ||
|
||||
algName.EqualsASCII(WEBCRYPTO_ALG_RSA_OAEP)) {
|
||||
return new GenerateAsymmetricKeyTask(aCx, aAlgorithm, aExtractable, aKeyUsages);
|
||||
} else {
|
||||
return new FailureTask(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
|
@ -1,6 +1,6 @@
|
||||
[DEFAULT]
|
||||
# Bug 1010743 - Re-enable WebCrypto tests on b2g-desktop
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk')
|
||||
# Bug 1010743 - Re-enable WebCrypto tests on b2g
|
||||
skip-if = (buildapp == 'b2g')
|
||||
support-files =
|
||||
test-array.js
|
||||
test-vectors.js
|
||||
|
@ -311,6 +311,50 @@ tv = {
|
||||
),
|
||||
},
|
||||
|
||||
// RSA test vectors, oaep-vect.txt, Example 1.1: A 1024-bit RSA Key Pair
|
||||
// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip>
|
||||
rsaoaep: {
|
||||
pkcs8: util.hex2abv(
|
||||
"30820276020100300d06092a864886f70d0101010500048202603082025c0201" +
|
||||
"0002818100a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae" +
|
||||
"4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630" +
|
||||
"f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fa" +
|
||||
"b9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de" +
|
||||
"88d39f16fb020301000102818053339cfdb79fc8466a655c7316aca85c55fd8f" +
|
||||
"6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a55" +
|
||||
"3d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c4831" +
|
||||
"16ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0c" +
|
||||
"f539e9cfcdd3de653729ead5d1024100d32737e7267ffe1341b2d5c0d150a81b" +
|
||||
"586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1" +
|
||||
"c11c520c2f26a471dcad212eac7ca39d024100cc8853d1d54da630fac004f471" +
|
||||
"f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0d" +
|
||||
"d852be2419b2af72bfe9a030e860b0288b5d7702400e12bf1718e9cef5599ba1" +
|
||||
"c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2" +
|
||||
"d76819967d4671acc6431e4037968db37878e695c102410095297b0f95a2fa67" +
|
||||
"d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda" +
|
||||
"866efef13c459e1a631386b7e354c899f5f112ca85d7158302404f456c502493" +
|
||||
"bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbe" +
|
||||
"fd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1"
|
||||
),
|
||||
spki: util.hex2abv(
|
||||
"30819f300d06092a864886f70d010101050003818d0030818902818100a8b3b2" +
|
||||
"84af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0" +
|
||||
"b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae8" +
|
||||
"33c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef739" +
|
||||
"2dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb020301" +
|
||||
"0001"
|
||||
),
|
||||
data: util.hex2abv(
|
||||
"6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34"
|
||||
),
|
||||
result: util.hex2abv(
|
||||
"354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb" +
|
||||
"21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535f" +
|
||||
"a9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426" +
|
||||
"d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a"
|
||||
),
|
||||
},
|
||||
|
||||
// RFC 6070 <http://tools.ietf.org/html/rfc6070>
|
||||
pbkdf2_sha1: {
|
||||
password: new TextEncoder("utf-8").encode("passwordPASSWORDpassword"),
|
||||
|
@ -154,7 +154,7 @@ TestArray.addTest(
|
||||
"Import / export round-trip with 'pkcs8'",
|
||||
function() {
|
||||
var that = this;
|
||||
var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA1" };
|
||||
var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-1" };
|
||||
|
||||
function doExport(x) {
|
||||
if (!hasKeyFields(x)) {
|
||||
@ -186,7 +186,7 @@ TestArray.addTest(
|
||||
"Import failure with format 'pkcs8'",
|
||||
function() {
|
||||
var that = this;
|
||||
var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA1" };
|
||||
var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-1" };
|
||||
|
||||
crypto.subtle.importKey("pkcs8", tv.negative_pkcs8, alg, true, ["encrypt"])
|
||||
.then(error(that), complete(that));
|
||||
@ -1150,3 +1150,127 @@ TestArray.addTest(
|
||||
.then( memcmp_complete(that, tv.pbkdf2_sha256.derived), fail );
|
||||
}
|
||||
);*/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
TestArray.addTest(
|
||||
"RSA-OAEP encrypt/decrypt round-trip",
|
||||
function () {
|
||||
var that = this;
|
||||
var privKey, pubKey;
|
||||
var alg = {name: "RSA-OAEP", hash: "SHA-1"};
|
||||
|
||||
var privKey, pubKey;
|
||||
function setPriv(x) { privKey = x; }
|
||||
function setPub(x) { pubKey = x; }
|
||||
function doEncrypt() {
|
||||
return crypto.subtle.encrypt(alg, pubKey, tv.rsaoaep.data);
|
||||
}
|
||||
function doDecrypt(x) {
|
||||
return crypto.subtle.decrypt(alg, privKey, x);
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
crypto.subtle.importKey("pkcs8", tv.rsaoaep.pkcs8, alg, false, ['decrypt'])
|
||||
.then(setPriv, error(that)),
|
||||
crypto.subtle.importKey("spki", tv.rsaoaep.spki, alg, false, ['encrypt'])
|
||||
.then(setPub, error(that))
|
||||
]).then(doEncrypt, error(that))
|
||||
.then(doDecrypt, error(that))
|
||||
.then(
|
||||
memcmp_complete(that, tv.rsaoaep.data),
|
||||
error(that)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
TestArray.addTest(
|
||||
"RSA-OAEP key generation and encrypt/decrypt round-trip (SHA-256)",
|
||||
function () {
|
||||
var that = this;
|
||||
var alg = {
|
||||
name: "RSA-OAEP",
|
||||
hash: "SHA-256",
|
||||
modulusLength: 2048,
|
||||
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
|
||||
};
|
||||
|
||||
var privKey, pubKey, data = crypto.getRandomValues(new Uint8Array(128));
|
||||
function setKey(x) { pubKey = x.publicKey; privKey = x.privateKey; }
|
||||
function doEncrypt() {
|
||||
return crypto.subtle.encrypt(alg, pubKey, data);
|
||||
}
|
||||
function doDecrypt(x) {
|
||||
return crypto.subtle.decrypt(alg, privKey, x);
|
||||
}
|
||||
|
||||
crypto.subtle.generateKey(alg, false, ['encrypt', 'decrypt'])
|
||||
.then(setKey, error(that))
|
||||
.then(doEncrypt, error(that))
|
||||
.then(doDecrypt, error(that))
|
||||
.then(
|
||||
memcmp_complete(that, data),
|
||||
error(that)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
TestArray.addTest(
|
||||
"RSA-OAEP decryption known answer",
|
||||
function () {
|
||||
var that = this;
|
||||
var alg = {name: "RSA-OAEP", hash: "SHA-1"};
|
||||
|
||||
function doDecrypt(x) {
|
||||
return crypto.subtle.decrypt(alg, x, tv.rsaoaep.result);
|
||||
}
|
||||
function fail() { error(that); }
|
||||
|
||||
crypto.subtle.importKey("pkcs8", tv.rsaoaep.pkcs8, alg, false, ['decrypt'])
|
||||
.then( doDecrypt, fail )
|
||||
.then( memcmp_complete(that, tv.rsaoaep.data), fail );
|
||||
}
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
TestArray.addTest(
|
||||
"RSA-OAEP input data length checks (2048-bit key)",
|
||||
function () {
|
||||
var that = this;
|
||||
var privKey, pubKey;
|
||||
var alg = {
|
||||
name: "RSA-OAEP",
|
||||
hash: "SHA-1",
|
||||
modulusLength: 2048,
|
||||
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
|
||||
};
|
||||
|
||||
var privKey, pubKey;
|
||||
function setKey(x) { pubKey = x.publicKey; privKey = x.privateKey; }
|
||||
function doEncrypt(n) {
|
||||
return function () {
|
||||
return crypto.subtle.encrypt(alg, pubKey, new Uint8Array(n));
|
||||
}
|
||||
}
|
||||
|
||||
crypto.subtle.generateKey(alg, false, ['encrypt'])
|
||||
.then(setKey, error(that))
|
||||
.then(doEncrypt(214), error(that))
|
||||
.then(doEncrypt(215), error(that))
|
||||
.then(error(that), complete(that));
|
||||
}
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
TestArray.addTest(
|
||||
"RSA-OAEP key import with invalid hash",
|
||||
function () {
|
||||
var that = this;
|
||||
var alg = {name: "RSA-OAEP", hash: "SHA-123"};
|
||||
|
||||
crypto.subtle.importKey("pkcs8", tv.rsaoaep.pkcs8, alg, false, ['decrypt'])
|
||||
.then(error(that), complete(that));
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -95,6 +95,10 @@ dictionary RsaHashedKeyGenParams : RsaKeyGenParams {
|
||||
AlgorithmIdentifier hash;
|
||||
};
|
||||
|
||||
dictionary RsaOaepParams : Algorithm {
|
||||
CryptoOperationData? label;
|
||||
};
|
||||
|
||||
dictionary DhKeyGenParams : Algorithm {
|
||||
BigInteger prime;
|
||||
BigInteger generator;
|
||||
|
@ -395,9 +395,11 @@ PK11_PBEKeyGen
|
||||
PK11_PQG_DestroyParams
|
||||
PK11_PQG_DestroyVerify
|
||||
PK11_PQG_ParamGen
|
||||
PK11_PrivDecrypt
|
||||
PK11_PrivDecryptPKCS1
|
||||
PK11_ProtectedAuthenticationPath
|
||||
PK11_PubDeriveWithKDF
|
||||
PK11_PubEncrypt
|
||||
PK11_PubEncryptPKCS1
|
||||
PK11_PubUnwrapSymKey
|
||||
PK11_PubWrapSymKey
|
||||
|
Loading…
Reference in New Issue
Block a user