mirror of
https://github.com/servo/servo
synced 2026-04-25 17:15:48 +02:00
script: Implement import key operation of RSA-PSS (#41157)
Start adding RSA-PSS support to WebCrypto API. This patch implements import key operation of RSA-PSS, with `rsa` crate. Testing: - Pass some WPT tests that were expected to fail. - Some new FAIL expectations are added. They were skipped by WPT when the import key operation of RSA-PSS had not been implemented, and requires other not-yet-implemented operations to pass. Fixes: #34362, and part of #41113 --------- Signed-off-by: Kingsley Yung <kingsley@kkoyung.dev>
This commit is contained in:
72
Cargo.lock
generated
72
Cargo.lock
generated
@@ -5054,6 +5054,9 @@ name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
dependencies = [
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
@@ -5827,6 +5830,23 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint-dig"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libm",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-traits",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.2.4"
|
||||
@@ -5863,6 +5883,17 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.2"
|
||||
@@ -6722,6 +6753,17 @@ dependencies = [
|
||||
"webrender_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs1"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
|
||||
dependencies = [
|
||||
"der",
|
||||
"pkcs8",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs8"
|
||||
version = "0.10.2"
|
||||
@@ -7356,6 +7398,28 @@ version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"digest",
|
||||
"num-bigint-dig",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"pkcs1",
|
||||
"pkcs8",
|
||||
"rand_core 0.6.4",
|
||||
"sha1",
|
||||
"sha2",
|
||||
"signature",
|
||||
"spki",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.37.0"
|
||||
@@ -7633,6 +7697,7 @@ dependencies = [
|
||||
"net_traits",
|
||||
"nom 8.0.0",
|
||||
"nom-rfc8288",
|
||||
"num-bigint-dig",
|
||||
"num-traits",
|
||||
"num_cpus",
|
||||
"p256",
|
||||
@@ -7647,6 +7712,7 @@ dependencies = [
|
||||
"rand 0.9.2",
|
||||
"range",
|
||||
"regex",
|
||||
"rsa",
|
||||
"rustc-hash 2.1.1",
|
||||
"script_bindings",
|
||||
"script_traits",
|
||||
@@ -8549,6 +8615,12 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b72d540d5c565dbe1f891d7e21ceb21d2649508306782f1066989fccb0b363d3"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "spirv"
|
||||
version = "0.3.0+sdk-1.3.268.0"
|
||||
|
||||
@@ -116,6 +116,7 @@ net_traits = { path = "components/shared/net" }
|
||||
nix = "0.30"
|
||||
nom = "8.0.0"
|
||||
nom-rfc8288 = "0.4.0"
|
||||
num-bigint-dig = "0.8"
|
||||
num-traits = "0.2"
|
||||
num_cpus = "1.17.0"
|
||||
openxr = "0.19"
|
||||
@@ -135,6 +136,7 @@ rayon = "1"
|
||||
read-fonts = "0.35.0"
|
||||
regex = "1.12"
|
||||
resvg = "0.45.0"
|
||||
rsa = { version = "0.9.9", features = ["sha1", "sha2"] }
|
||||
rustc-hash = "2.1.1"
|
||||
rustls = { version = "0.23", default-features = false, features = ["logging", "std", "tls12"] }
|
||||
rustls-pki-types = "1.13"
|
||||
|
||||
@@ -102,6 +102,7 @@ mime_guess = { workspace = true }
|
||||
net_traits = { workspace = true }
|
||||
nom = { workspace = true }
|
||||
nom-rfc8288 = { workspace = true }
|
||||
num-bigint-dig = { workspace = true }
|
||||
num-traits = { workspace = true }
|
||||
num_cpus = { workspace = true }
|
||||
p256 = { workspace = true }
|
||||
@@ -116,6 +117,7 @@ profile_traits = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
range = { path = "../range" }
|
||||
regex = { workspace = true }
|
||||
rsa = { workspace = true }
|
||||
rustc-hash = { workspace = true }
|
||||
script_bindings = { path = "../script_bindings" }
|
||||
script_traits = { workspace = true }
|
||||
|
||||
@@ -27,6 +27,8 @@ pub(crate) enum CryptoKeyOrCryptoKeyPair {
|
||||
|
||||
/// The underlying cryptographic data this key represents
|
||||
pub(crate) enum Handle {
|
||||
RsaPrivateKey(rsa::RsaPrivateKey),
|
||||
RsaPublicKey(rsa::RsaPublicKey),
|
||||
P256PrivateKey(p256::SecretKey),
|
||||
P384PrivateKey(p384::SecretKey),
|
||||
P521PrivateKey(p521::SecretKey),
|
||||
@@ -214,6 +216,8 @@ impl Handle {
|
||||
impl MallocSizeOf for Handle {
|
||||
fn size_of(&self, ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
|
||||
match self {
|
||||
Handle::RsaPrivateKey(private_key) => private_key.size_of(ops),
|
||||
Handle::RsaPublicKey(public_key) => public_key.size_of(ops),
|
||||
Handle::P256PrivateKey(private_key) => private_key.size_of(ops),
|
||||
Handle::P384PrivateKey(private_key) => private_key.size_of(ops),
|
||||
Handle::P521PrivateKey(private_key) => private_key.size_of(ops),
|
||||
|
||||
@@ -12,6 +12,7 @@ mod ed25519_operation;
|
||||
mod hkdf_operation;
|
||||
mod hmac_operation;
|
||||
mod pbkdf2_operation;
|
||||
mod rsa_pss_operation;
|
||||
mod sha3_operation;
|
||||
mod sha_operation;
|
||||
mod x25519_operation;
|
||||
@@ -37,7 +38,8 @@ use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::{
|
||||
AesKeyGenParams, Algorithm, AlgorithmIdentifier, Argon2Params, CShakeParams, EcKeyAlgorithm,
|
||||
EcKeyGenParams, EcKeyImportParams, EcdhKeyDeriveParams, EcdsaParams, HkdfParams,
|
||||
HmacImportParams, HmacKeyAlgorithm, HmacKeyGenParams, JsonWebKey, KeyAlgorithm, KeyFormat,
|
||||
Pbkdf2Params, RsaOtherPrimesInfo, SubtleCryptoMethods,
|
||||
Pbkdf2Params, RsaHashedImportParams, RsaHashedKeyAlgorithm, RsaKeyAlgorithm,
|
||||
RsaOtherPrimesInfo, SubtleCryptoMethods,
|
||||
};
|
||||
use crate::dom::bindings::codegen::UnionTypes::{
|
||||
ArrayBufferViewOrArrayBuffer, ArrayBufferViewOrArrayBufferOrJsonWebKey, ObjectOrString,
|
||||
@@ -1680,6 +1682,73 @@ impl SafeToJSValConvertible for SubtleKeyAlgorithm {
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/webcrypto/#dfn-RsaHashedKeyAlgorithm>
|
||||
#[derive(Clone, MallocSizeOf)]
|
||||
pub(crate) struct SubtleRsaHashedKeyAlgorithm {
|
||||
/// <https://w3c.github.io/webcrypto/#dom-keyalgorithm-name>
|
||||
name: String,
|
||||
|
||||
/// <https://w3c.github.io/webcrypto/#dfn-RsaKeyAlgorithm-modulusLength>
|
||||
modulus_length: u32,
|
||||
|
||||
/// <https://w3c.github.io/webcrypto/#dfn-RsaKeyAlgorithm-publicExponent>
|
||||
public_exponent: Vec<u8>,
|
||||
|
||||
/// <https://w3c.github.io/webcrypto/#dfn-RsaHashedKeyAlgorithm-hash>
|
||||
hash: Box<NormalizedAlgorithm>,
|
||||
}
|
||||
|
||||
impl SafeToJSValConvertible for SubtleRsaHashedKeyAlgorithm {
|
||||
fn safe_to_jsval(&self, cx: JSContext, rval: MutableHandleValue, can_gc: CanGc) {
|
||||
rooted!(in(*cx) let mut js_object = ptr::null_mut::<JSObject>());
|
||||
let public_exponent =
|
||||
create_buffer_source(cx, &self.public_exponent, js_object.handle_mut(), can_gc)
|
||||
.expect("Fail to convert publicExponent to Uint8Array");
|
||||
let key_algorithm = KeyAlgorithm {
|
||||
name: self.name.clone().into(),
|
||||
};
|
||||
let rsa_key_algorithm = RootedTraceableBox::new(RsaKeyAlgorithm {
|
||||
parent: key_algorithm,
|
||||
modulusLength: self.modulus_length,
|
||||
publicExponent: public_exponent,
|
||||
});
|
||||
let rsa_hashed_key_algorithm = RootedTraceableBox::new(RsaHashedKeyAlgorithm {
|
||||
parent: rsa_key_algorithm,
|
||||
hash: KeyAlgorithm {
|
||||
name: self.hash.name().into(),
|
||||
},
|
||||
});
|
||||
rsa_hashed_key_algorithm.safe_to_jsval(cx, rval, can_gc);
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/webcrypto/#dfn-RsaHashedImportParams>
|
||||
#[derive(Clone, MallocSizeOf)]
|
||||
struct SubtleRsaHashedImportParams {
|
||||
/// <https://w3c.github.io/webcrypto/#dom-algorithm-name>
|
||||
name: String,
|
||||
|
||||
/// <https://w3c.github.io/webcrypto/#dfn-RsaHashedImportParams-hash>
|
||||
hash: Box<NormalizedAlgorithm>,
|
||||
}
|
||||
|
||||
impl TryFrom<RootedTraceableBox<RsaHashedImportParams>> for SubtleRsaHashedImportParams {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: RootedTraceableBox<RsaHashedImportParams>) -> Result<Self, Self::Error> {
|
||||
let cx = GlobalScope::get_cx();
|
||||
Ok(SubtleRsaHashedImportParams {
|
||||
name: value.parent.name.to_string(),
|
||||
hash: Box::new(normalize_algorithm(
|
||||
cx,
|
||||
&Operation::Digest,
|
||||
&value.hash,
|
||||
CanGc::note(),
|
||||
)?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/webcrypto/#dfn-EcdsaParams>
|
||||
#[derive(Clone, Debug, MallocSizeOf)]
|
||||
struct SubtleEcdsaParams {
|
||||
@@ -2250,10 +2319,11 @@ enum ExportedKey {
|
||||
/// Union type of KeyAlgorithm and IDL dictionary types derived from it. Note that we actually use
|
||||
/// our "subtle" structs of the corresponding IDL dictionary types so that they can be easily
|
||||
/// passed to another threads.
|
||||
#[derive(Clone, Debug, MallocSizeOf)]
|
||||
#[derive(Clone, MallocSizeOf)]
|
||||
#[expect(clippy::enum_variant_names)]
|
||||
pub(crate) enum KeyAlgorithmAndDerivatives {
|
||||
KeyAlgorithm(SubtleKeyAlgorithm),
|
||||
RsaHashedKeyAlgorithm(SubtleRsaHashedKeyAlgorithm),
|
||||
EcKeyAlgorithm(SubtleEcKeyAlgorithm),
|
||||
AesKeyAlgorithm(SubtleAesKeyAlgorithm),
|
||||
HmacKeyAlgorithm(SubtleHmacKeyAlgorithm),
|
||||
@@ -2263,6 +2333,7 @@ impl KeyAlgorithmAndDerivatives {
|
||||
fn name(&self) -> &str {
|
||||
match self {
|
||||
KeyAlgorithmAndDerivatives::KeyAlgorithm(algo) => &algo.name,
|
||||
KeyAlgorithmAndDerivatives::RsaHashedKeyAlgorithm(algo) => &algo.name,
|
||||
KeyAlgorithmAndDerivatives::EcKeyAlgorithm(algo) => &algo.name,
|
||||
KeyAlgorithmAndDerivatives::AesKeyAlgorithm(algo) => &algo.name,
|
||||
KeyAlgorithmAndDerivatives::HmacKeyAlgorithm(algo) => &algo.name,
|
||||
@@ -2282,6 +2353,9 @@ impl SafeToJSValConvertible for KeyAlgorithmAndDerivatives {
|
||||
fn safe_to_jsval(&self, cx: JSContext, rval: MutableHandleValue, can_gc: CanGc) {
|
||||
match self {
|
||||
KeyAlgorithmAndDerivatives::KeyAlgorithm(algo) => algo.safe_to_jsval(cx, rval, can_gc),
|
||||
KeyAlgorithmAndDerivatives::RsaHashedKeyAlgorithm(algo) => {
|
||||
algo.safe_to_jsval(cx, rval, can_gc)
|
||||
},
|
||||
KeyAlgorithmAndDerivatives::EcKeyAlgorithm(algo) => {
|
||||
algo.safe_to_jsval(cx, rval, can_gc)
|
||||
},
|
||||
@@ -2452,6 +2526,7 @@ impl JsonWebKeyExt for JsonWebKey {
|
||||
#[derive(Clone, MallocSizeOf)]
|
||||
enum NormalizedAlgorithm {
|
||||
Algorithm(SubtleAlgorithm),
|
||||
RsaHashedImportParams(SubtleRsaHashedImportParams),
|
||||
EcdsaParams(SubtleEcdsaParams),
|
||||
EcKeyGenParams(SubtleEcKeyGenParams),
|
||||
EcKeyImportParams(SubtleEcKeyImportParams),
|
||||
@@ -2554,6 +2629,15 @@ fn normalize_algorithm(
|
||||
// NOTE: Step 10.1.3 is done by the `From` and `TryFrom` trait implementation of
|
||||
// "subtle" binding structs.
|
||||
let normalized_algorithm = match (alg_name, op) {
|
||||
// <https://w3c.github.io/webcrypto/#rsa-pss-registration>
|
||||
(ALG_RSA_PSS, Operation::ImportKey) => {
|
||||
let mut params = dictionary_from_jsval::<
|
||||
RootedTraceableBox<RsaHashedImportParams>,
|
||||
>(cx, value.handle(), can_gc)?;
|
||||
params.parent.name = DOMString::from(alg_name);
|
||||
NormalizedAlgorithm::RsaHashedImportParams(params.try_into()?)
|
||||
},
|
||||
|
||||
// <https://w3c.github.io/webcrypto/#ecdsa-registration>
|
||||
(ALG_ECDSA, Operation::Sign) => {
|
||||
let mut params = dictionary_from_jsval::<RootedTraceableBox<EcdsaParams>>(
|
||||
@@ -3086,6 +3170,7 @@ impl NormalizedAlgorithm {
|
||||
fn name(&self) -> &str {
|
||||
match self {
|
||||
NormalizedAlgorithm::Algorithm(algo) => &algo.name,
|
||||
NormalizedAlgorithm::RsaHashedImportParams(algo) => &algo.name,
|
||||
NormalizedAlgorithm::EcdsaParams(algo) => &algo.name,
|
||||
NormalizedAlgorithm::EcKeyGenParams(algo) => &algo.name,
|
||||
NormalizedAlgorithm::EcKeyImportParams(algo) => &algo.name,
|
||||
@@ -3291,6 +3376,17 @@ impl NormalizedAlgorithm {
|
||||
can_gc: CanGc,
|
||||
) -> Result<DomRoot<CryptoKey>, Error> {
|
||||
match (self.name(), self) {
|
||||
(ALG_RSA_PSS, NormalizedAlgorithm::RsaHashedImportParams(algo)) => {
|
||||
rsa_pss_operation::import_key(
|
||||
global,
|
||||
algo,
|
||||
format,
|
||||
key_data,
|
||||
extractable,
|
||||
usages,
|
||||
can_gc,
|
||||
)
|
||||
},
|
||||
(ALG_ECDSA, NormalizedAlgorithm::EcKeyImportParams(algo)) => {
|
||||
ecdsa_operation::import_key(
|
||||
global,
|
||||
|
||||
466
components/script/dom/subtlecrypto/rsa_pss_operation.rs
Normal file
466
components/script/dom/subtlecrypto/rsa_pss_operation.rs
Normal file
@@ -0,0 +1,466 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use base64ct::{Base64UrlUnpadded, Encoding};
|
||||
use pkcs8::der::asn1::BitString;
|
||||
use pkcs8::der::{AnyRef, Decode};
|
||||
use pkcs8::{PrivateKeyInfo, SubjectPublicKeyInfo};
|
||||
use rsa::pkcs1::{self, DecodeRsaPrivateKey};
|
||||
use rsa::traits::PublicKeyParts;
|
||||
use rsa::{BigUint, RsaPrivateKey, RsaPublicKey};
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{KeyType, KeyUsage};
|
||||
use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::{
|
||||
AlgorithmIdentifier, JsonWebKey, KeyFormat,
|
||||
};
|
||||
use crate::dom::bindings::error::Error;
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::cryptokey::{CryptoKey, Handle};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::subtlecrypto::{
|
||||
ALG_RSA_PSS, ALG_SHA1, ALG_SHA256, ALG_SHA384, ALG_SHA512, JsonWebKeyExt,
|
||||
KeyAlgorithmAndDerivatives, Operation, SubtleRsaHashedImportParams,
|
||||
SubtleRsaHashedKeyAlgorithm, normalize_algorithm,
|
||||
};
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
/// <https://w3c.github.io/webcrypto/#rsa-pss-operations-import-key>
|
||||
pub(crate) fn import_key(
|
||||
global: &GlobalScope,
|
||||
normalized_algorithm: &SubtleRsaHashedImportParams,
|
||||
format: KeyFormat,
|
||||
key_data: &[u8],
|
||||
extractable: bool,
|
||||
usages: Vec<KeyUsage>,
|
||||
can_gc: CanGc,
|
||||
) -> Result<DomRoot<CryptoKey>, Error> {
|
||||
// Step 1. Let keyData be the key data to be imported.
|
||||
|
||||
// Step 2.
|
||||
let (key_handle, key_type) = match format {
|
||||
// If format is "spki":
|
||||
KeyFormat::Spki => {
|
||||
// Step 2.1. If usages contains an entry which is not "verify" then throw a
|
||||
// SyntaxError.
|
||||
if usages.iter().any(|usage| *usage != KeyUsage::Verify) {
|
||||
return Err(Error::Syntax(Some(
|
||||
"Usages contains an entry which is not \"verify\"".to_string(),
|
||||
)));
|
||||
}
|
||||
|
||||
// Step 2.2. Let spki be the result of running the parse a subjectPublicKeyInfo
|
||||
// algorithm over keyData.
|
||||
// Step 2.3. If an error occurred while parsing, then throw a DataError.
|
||||
let spki =
|
||||
SubjectPublicKeyInfo::<AnyRef, BitString>::from_der(key_data).map_err(|_| {
|
||||
Error::Data(Some(
|
||||
"Fail to parse SubjectPublicKeyInfo over keyData".to_string(),
|
||||
))
|
||||
})?;
|
||||
|
||||
// Step 2.4. If the algorithm object identifier field of the algorithm
|
||||
// AlgorithmIdentifier field of spki is not equal to the rsaEncryption object
|
||||
// identifier defined in [RFC3447], then throw a DataError.
|
||||
if spki.algorithm.oid != pkcs1::ALGORITHM_OID {
|
||||
return Err(Error::Data(Some(
|
||||
"Algorithm object identifier of spki is not an rsaEncryption".to_string(),
|
||||
)));
|
||||
}
|
||||
|
||||
// Step 2.5. Let publicKey be the result of performing the parse an ASN.1 structure
|
||||
// algorithm, with data as the subjectPublicKeyInfo field of spki, structure as the
|
||||
// RSAPublicKey structure specified in Section A.1.1 of [RFC3447], and exactData set to
|
||||
// true.
|
||||
// Step 2.6. If an error occurred while parsing, or it can be determined that publicKey
|
||||
// is not a valid public key according to [RFC3447], then throw a DataError.
|
||||
let pkcs1_bytes = spki.subject_public_key.as_bytes().ok_or(Error::Data(Some(
|
||||
"Fail to parse byte sequence over SubjectPublicKey field of spki".to_string(),
|
||||
)))?;
|
||||
let rsa_public_key_structure =
|
||||
pkcs1::RsaPublicKey::try_from(pkcs1_bytes).map_err(|_| {
|
||||
Error::Data(Some(
|
||||
"SubjectPublicKey field of spki is not an RSAPublicKey structure"
|
||||
.to_string(),
|
||||
))
|
||||
})?;
|
||||
let n = BigUint::from_bytes_be(rsa_public_key_structure.modulus.as_bytes());
|
||||
let e = BigUint::from_bytes_be(rsa_public_key_structure.public_exponent.as_bytes());
|
||||
let public_key = RsaPublicKey::new(n, e).map_err(|_| {
|
||||
Error::Data(Some(
|
||||
"Fail to construct RSA public key from modulus and public exponent".to_string(),
|
||||
))
|
||||
})?;
|
||||
|
||||
// Step 2.7. Let key be a new CryptoKey that represents the RSA public key identified
|
||||
// by publicKey.
|
||||
// Step 2.8. Set the [[type]] internal slot of key to "public"
|
||||
// NOTE: Done in Step 3-8.
|
||||
let key_handle = Handle::RsaPublicKey(public_key);
|
||||
let key_type = KeyType::Public;
|
||||
(key_handle, key_type)
|
||||
},
|
||||
// If format is "pkcs8":
|
||||
KeyFormat::Pkcs8 => {
|
||||
// Step 2.1. If usages contains an entry which is not "sign" then throw a SyntaxError.
|
||||
if usages.iter().any(|usage| *usage != KeyUsage::Sign) {
|
||||
return Err(Error::Syntax(Some(
|
||||
"Usages contains an entry which is not \"sign\"".to_string(),
|
||||
)));
|
||||
}
|
||||
|
||||
// Step 2.2. Let privateKeyInfo be the result of running the parse a privateKeyInfo
|
||||
// algorithm over keyData.
|
||||
// Step 2.3. If an error occurred while parsing, then throw a DataError.
|
||||
let private_key_info = PrivateKeyInfo::from_der(key_data).map_err(|_| {
|
||||
Error::Data(Some(
|
||||
"Fail to parse PrivateKeyInfo over keyData".to_string(),
|
||||
))
|
||||
})?;
|
||||
|
||||
// Step 2.4. If the algorithm object identifier field of the privateKeyAlgorithm
|
||||
// PrivateKeyAlgorithm field of privateKeyInfo is not equal to the rsaEncryption object
|
||||
// identifier defined in [RFC3447], then throw a DataError.
|
||||
if private_key_info.algorithm.oid != pkcs1::ALGORITHM_OID {
|
||||
return Err(Error::Data(Some(
|
||||
"Algorithm object identifier of PrivateKeyInfo is not an rsaEncryption"
|
||||
.to_string(),
|
||||
)));
|
||||
}
|
||||
|
||||
// Step 2.5. Let rsaPrivateKey be the result of performing the parse an ASN.1 structure
|
||||
// algorithm, with data as the privateKey field of privateKeyInfo, structure as the
|
||||
// RSAPrivateKey structure specified in Section A.1.2 of [RFC3447], and exactData set
|
||||
// to true.
|
||||
// Step 2.6. If an error occurred while parsing, or if rsaPrivateKey is not a valid RSA
|
||||
// private key according to [RFC3447], then throw a DataError.
|
||||
let rsa_private_key = RsaPrivateKey::from_pkcs1_der(private_key_info.private_key)
|
||||
.map_err(|_| {
|
||||
Error::Data(Some(
|
||||
"PrivateKey field of PrivateKeyInfo is not an RSAPrivateKey structure"
|
||||
.to_string(),
|
||||
))
|
||||
})?;
|
||||
|
||||
// Step 2.7. Let key be a new CryptoKey that represents the RSA private key identified
|
||||
// by rsaPrivateKey.
|
||||
// Step 2.8. Set the [[type]] internal slot of key to "private"
|
||||
// NOTE: Done in Step 3-8.
|
||||
let key_handle = Handle::RsaPrivateKey(rsa_private_key);
|
||||
let key_type = KeyType::Private;
|
||||
(key_handle, key_type)
|
||||
},
|
||||
// If format is "jwk":
|
||||
KeyFormat::Jwk => {
|
||||
// Step 2.1.
|
||||
// If keyData is a JsonWebKey dictionary:
|
||||
// Let jwk equal keyData.
|
||||
// Otherwise:
|
||||
// Throw a DataError.
|
||||
let cx = GlobalScope::get_cx();
|
||||
let jwk = JsonWebKey::parse(cx, key_data)?;
|
||||
|
||||
// Step 2.2. If the d field of jwk is present and usages contains an entry which is not
|
||||
// "sign", or, if the d field of jwk is not present and usages contains an entry which
|
||||
// is not "verify" then throw a SyntaxError.
|
||||
if jwk.d.is_some() && usages.iter().any(|usage| *usage != KeyUsage::Sign) {
|
||||
return Err(Error::Syntax(Some(
|
||||
"The d field of jwk is present and usages contains an entry which is not \"sign\""
|
||||
.to_string()
|
||||
)));
|
||||
}
|
||||
if jwk.d.is_none() && usages.iter().any(|usage| *usage != KeyUsage::Verify) {
|
||||
return Err(Error::Syntax(Some(
|
||||
"The d field of jwk is not present and usages contains an entry which is not \"verify\""
|
||||
.to_string()
|
||||
)));
|
||||
}
|
||||
|
||||
// Step 2.3. If the kty field of jwk is not a case-sensitive string match to "RSA",
|
||||
// then throw a DataError.
|
||||
if jwk.kty.as_ref().is_none_or(|kty| kty != "RSA") {
|
||||
return Err(Error::Data(Some(
|
||||
"The kty field of jwk is not a case-sensitive string match to \"RSA\""
|
||||
.to_string(),
|
||||
)));
|
||||
}
|
||||
|
||||
// Step 2.4. If usages is non-empty and the use field of jwk is present and is not a
|
||||
// case-sensitive string match to "sig", then throw a DataError.
|
||||
if !usages.is_empty() && jwk.use_.as_ref().is_some_and(|use_| use_ != "sig") {
|
||||
return Err(Error::Data(Some(
|
||||
"Usages is non-empty and the use field of jwk is present and \
|
||||
is not a case-sensitive string match to \"sig\""
|
||||
.to_string(),
|
||||
)));
|
||||
}
|
||||
|
||||
// Step 2.5. If the key_ops field of jwk is present, and is invalid according to the
|
||||
// requirements of JSON Web Key [JWK] or does not contain all of the specified usages
|
||||
// values, then throw a DataError.
|
||||
jwk.check_key_ops(&usages)?;
|
||||
|
||||
// Step 2.6. If the ext field of jwk is present and has the value false and extractable
|
||||
// is true, then throw a DataError.
|
||||
if jwk.ext.is_some_and(|ext| !ext) && extractable {
|
||||
return Err(Error::Data(Some(
|
||||
"The ext field of jwk is present and \
|
||||
has the value false and extractable is true"
|
||||
.to_string(),
|
||||
)));
|
||||
}
|
||||
|
||||
// Step 2.7.
|
||||
// If the alg field of jwk is not present:
|
||||
// Let hash be undefined.
|
||||
// If the alg field is equal to the string "PS1":
|
||||
// Let hash be the string "SHA-1".
|
||||
// If the alg field is equal to the string "PS256":
|
||||
// Let hash be the string "SHA-256".
|
||||
// If the alg field is equal to the string "PS384":
|
||||
// Let hash be the string "SHA-384".
|
||||
// If the alg field is equal to the string "PS512":
|
||||
// Let hash be the string "SHA-512".
|
||||
// Otherwise:
|
||||
// Perform any key import steps defined by other applicable specifications, passing
|
||||
// format, jwk and obtaining hash.
|
||||
// If an error occurred or there are no applicable specifications, throw a DataError.
|
||||
let hash = match jwk.alg {
|
||||
None => None,
|
||||
Some(alg) => match &*alg.str() {
|
||||
"PS1" => Some(ALG_SHA1),
|
||||
"PS256" => Some(ALG_SHA256),
|
||||
"PS384" => Some(ALG_SHA384),
|
||||
"PS512" => Some(ALG_SHA512),
|
||||
_ => None,
|
||||
},
|
||||
};
|
||||
|
||||
// Step 2.8. If hash is not undefined:
|
||||
if let Some(hash) = hash {
|
||||
// Step 2.8.1. Let normalizedHash be the result of normalize an algorithm with alg
|
||||
// set to hash and op set to digest.
|
||||
let normalized_hash = normalize_algorithm(
|
||||
cx,
|
||||
&Operation::Digest,
|
||||
&AlgorithmIdentifier::String(DOMString::from(hash)),
|
||||
can_gc,
|
||||
)?;
|
||||
|
||||
// Step 2.8.2. If normalizedHash is not equal to the hash member of
|
||||
// normalizedAlgorithm, throw a DataError.
|
||||
if normalized_hash.name() != normalized_algorithm.hash.name() {
|
||||
return Err(Error::Data(Some(
|
||||
"The normalizedHash is not equal to the hash member of normalizedAlgorithm"
|
||||
.to_string(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2.9.
|
||||
match jwk.d {
|
||||
// If the d field of jwk is present:
|
||||
Some(d) => {
|
||||
// Step 2.9.1. If jwk does not meet the requirements of Section 6.3.2 of JSON
|
||||
// Web Algorithms [JWA], then throw a DataError.
|
||||
let n = Base64UrlUnpadded::decode_vec(
|
||||
&jwk.n
|
||||
.ok_or(Error::Data(Some(
|
||||
"The n field does not exist in jwk".to_string(),
|
||||
)))?
|
||||
.str(),
|
||||
)
|
||||
.map_err(|_| Error::Data(Some("Fail to decode n field of jwk".to_string())))?;
|
||||
let e = Base64UrlUnpadded::decode_vec(
|
||||
&jwk.e
|
||||
.ok_or(Error::Data(Some(
|
||||
"The e field does not exist in jwk".to_string(),
|
||||
)))?
|
||||
.str(),
|
||||
)
|
||||
.map_err(|_| Error::Data(Some("Fail to decode e field of jwk".to_string())))?;
|
||||
let d = Base64UrlUnpadded::decode_vec(&d.str()).map_err(|_| {
|
||||
Error::Data(Some("Fail to decode d field of jwk".to_string()))
|
||||
})?;
|
||||
let p = jwk
|
||||
.p
|
||||
.map(|p| Base64UrlUnpadded::decode_vec(&p.str()))
|
||||
.transpose()
|
||||
.map_err(|_| {
|
||||
Error::Data(Some("Fail to decode p field of jwk".to_string()))
|
||||
})?;
|
||||
let q = jwk
|
||||
.q
|
||||
.map(|q| Base64UrlUnpadded::decode_vec(&q.str()))
|
||||
.transpose()
|
||||
.map_err(|_| {
|
||||
Error::Data(Some("Fail to decode q field of jwk".to_string()))
|
||||
})?;
|
||||
let dp = jwk
|
||||
.dp
|
||||
.map(|dp| Base64UrlUnpadded::decode_vec(&dp.str()))
|
||||
.transpose()
|
||||
.map_err(|_| {
|
||||
Error::Data(Some("Fail to decode dp field of jwk".to_string()))
|
||||
})?;
|
||||
let dq = jwk
|
||||
.dq
|
||||
.map(|dq| Base64UrlUnpadded::decode_vec(&dq.str()))
|
||||
.transpose()
|
||||
.map_err(|_| {
|
||||
Error::Data(Some("Fail to decode dq field of jwk".to_string()))
|
||||
})?;
|
||||
let qi = jwk
|
||||
.qi
|
||||
.map(|qi| Base64UrlUnpadded::decode_vec(&qi.str()))
|
||||
.transpose()
|
||||
.map_err(|_| {
|
||||
Error::Data(Some("Fail to decode qi field of jwk".to_string()))
|
||||
})?;
|
||||
let mut primes = match (p, q, dp, dq, qi) {
|
||||
(Some(p), Some(q), Some(_dp), Some(_dq), Some(_qi)) => vec![p, q],
|
||||
(None, None, None, None, None) => Vec::new(),
|
||||
_ => return Err(Error::Data(Some(
|
||||
"The p, q, dp, dq, qi fields of jwk must be either all-present or all-absent"
|
||||
.to_string()
|
||||
))),
|
||||
};
|
||||
if let Some(oth) = jwk.oth {
|
||||
if primes.is_empty() {
|
||||
return Err(Error::Data(Some(
|
||||
"The oth field exists in jwk but one of p, q, dp, dq, qi is missing".to_string()
|
||||
)));
|
||||
}
|
||||
for other_prime in oth {
|
||||
let r = Base64UrlUnpadded::decode_vec(
|
||||
&other_prime
|
||||
.r
|
||||
.ok_or(Error::Data(Some(
|
||||
"The e field does not exist in oth field of jwk"
|
||||
.to_string(),
|
||||
)))?
|
||||
.str(),
|
||||
)
|
||||
.map_err(|_| {
|
||||
Error::Data(Some(
|
||||
"Fail to decode r field of oth field of jwk".to_string(),
|
||||
))
|
||||
})?;
|
||||
primes.push(r);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2.9.2. Let privateKey represents the RSA private key identified by
|
||||
// interpreting jwk according to Section 6.3.2 of JSON Web Algorithms [JWA].
|
||||
// Step 2.9.3. If privateKey is not a valid RSA private key according to
|
||||
// [RFC3447], then throw a DataError.
|
||||
let private_key = RsaPrivateKey::from_components(
|
||||
BigUint::from_bytes_be(&n),
|
||||
BigUint::from_bytes_be(&e),
|
||||
BigUint::from_bytes_be(&d),
|
||||
primes
|
||||
.into_iter()
|
||||
.map(|prime| BigUint::from_bytes_be(&prime))
|
||||
.collect(),
|
||||
)
|
||||
.map_err(|_| {
|
||||
Error::Data(Some(
|
||||
"Fail to construct RSA private key from values in jwk".to_string(),
|
||||
))
|
||||
})?;
|
||||
|
||||
// Step 2.9.4. Let key be a new CryptoKey object that represents privateKey.
|
||||
// Step 2.9.5. Set the [[type]] internal slot of key to "private"
|
||||
// NOTE: Done in Step 3-8.
|
||||
let key_handle = Handle::RsaPrivateKey(private_key);
|
||||
let key_type = KeyType::Private;
|
||||
(key_handle, key_type)
|
||||
},
|
||||
// Otherwise:
|
||||
None => {
|
||||
// Step 2.9.1. If jwk does not meet the requirements of Section 6.3.1 of JSON
|
||||
// Web Algorithms [JWA], then throw a DataError.
|
||||
let n = Base64UrlUnpadded::decode_vec(
|
||||
&jwk.n
|
||||
.ok_or(Error::Data(Some(
|
||||
"The n field does not exist in jwk".to_string(),
|
||||
)))?
|
||||
.str(),
|
||||
)
|
||||
.map_err(|_| Error::Data(Some("Fail to decode n field of jwk".to_string())))?;
|
||||
let e = Base64UrlUnpadded::decode_vec(
|
||||
&jwk.e
|
||||
.ok_or(Error::Data(Some(
|
||||
"The e field does not exist in jwk".to_string(),
|
||||
)))?
|
||||
.str(),
|
||||
)
|
||||
.map_err(|_| Error::Data(Some("Fail to decode e field of jwk".to_string())))?;
|
||||
|
||||
// Step 2.9.2. Let publicKey represent the RSA public key identified by
|
||||
// interpreting jwk according to Section 6.3.1 of JSON Web Algorithms [JWA].
|
||||
// Step 2.9.3. If publicKey can be determined to not be a valid RSA public key
|
||||
// according to [RFC3447], then throw a DataError.
|
||||
let public_key =
|
||||
RsaPublicKey::new(BigUint::from_bytes_be(&n), BigUint::from_bytes_be(&e))
|
||||
.map_err(|_| {
|
||||
Error::Data(Some(
|
||||
"Fail to construct RSA public key from values in jwk".to_string(),
|
||||
))
|
||||
})?;
|
||||
|
||||
// Step 2.9.4. Let key be a new CryptoKey representing publicKey.
|
||||
// Step 2.9.5. Set the [[type]] internal slot of key to "public"
|
||||
// NOTE: Done in Step 3-8.
|
||||
let key_handle = Handle::RsaPublicKey(public_key);
|
||||
let key_type = KeyType::Public;
|
||||
(key_handle, key_type)
|
||||
},
|
||||
}
|
||||
},
|
||||
// Otherwise:
|
||||
_ => {
|
||||
// throw a NotSupportedError.
|
||||
return Err(Error::NotSupported(Some(
|
||||
"Unsupported import key format for RSA key".to_string(),
|
||||
)));
|
||||
},
|
||||
};
|
||||
|
||||
// Step 3. Let algorithm be a new RsaHashedKeyAlgorithm dictionary.
|
||||
// Step 4. Set the name attribute of algorithm to "RSA-PSS"
|
||||
// Step 5. Set the modulusLength attribute of algorithm to the length, in bits, of the RSA
|
||||
// public modulus.
|
||||
// Step 6. Set the publicExponent attribute of algorithm to the BigInteger representation of
|
||||
// the RSA public exponent.
|
||||
// Step 7. Set the hash attribute of algorithm to the hash member of normalizedAlgorithm.
|
||||
// Step 8. Set the [[algorithm]] internal slot of key to algorithm
|
||||
let (modulus_length, public_exponent) = match &key_handle {
|
||||
Handle::RsaPrivateKey(private_key) => {
|
||||
(private_key.size() as u32 * 8, private_key.e().to_bytes_be())
|
||||
},
|
||||
Handle::RsaPublicKey(public_key) => {
|
||||
(public_key.size() as u32 * 8, public_key.e().to_bytes_be())
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let algorithm = SubtleRsaHashedKeyAlgorithm {
|
||||
name: ALG_RSA_PSS.to_string(),
|
||||
modulus_length,
|
||||
public_exponent,
|
||||
hash: normalized_algorithm.hash.clone(),
|
||||
};
|
||||
let key = CryptoKey::new(
|
||||
global,
|
||||
key_type,
|
||||
extractable,
|
||||
KeyAlgorithmAndDerivatives::RsaHashedKeyAlgorithm(algorithm),
|
||||
usages,
|
||||
key_handle,
|
||||
can_gc,
|
||||
);
|
||||
|
||||
// Step 9. Return key.
|
||||
Ok(key)
|
||||
}
|
||||
@@ -20,7 +20,10 @@ pub(crate) mod base {
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use js::realm::{AutoRealm, CurrentRealm};
|
||||
pub(crate) use js::rust::wrappers::Call;
|
||||
pub(crate) use js::rust::{HandleObject, HandleValue, MutableHandleObject, MutableHandleValue};
|
||||
pub(crate) use js::rust::{
|
||||
CustomTrace, HandleObject, HandleValue, MutableHandleObject, MutableHandleValue,
|
||||
};
|
||||
pub(crate) use js::typedarray;
|
||||
pub(crate) use js::typedarray::{
|
||||
ArrayBuffer, ArrayBufferView, Float32Array, Float64Array, Uint8Array, Uint8ClampedArray,
|
||||
};
|
||||
|
||||
@@ -56,6 +56,10 @@ interface SubtleCrypto {
|
||||
sequence<KeyUsage> keyUsages );
|
||||
};
|
||||
|
||||
// https://w3c.github.io/webcrypto/#big-integer
|
||||
|
||||
typedef Uint8Array BigInteger;
|
||||
|
||||
// https://w3c.github.io/webcrypto/#algorithm-dictionary
|
||||
|
||||
typedef (object or DOMString) AlgorithmIdentifier;
|
||||
@@ -72,6 +76,25 @@ dictionary KeyAlgorithm {
|
||||
required DOMString name;
|
||||
};
|
||||
|
||||
// https://w3c.github.io/webcrypto/#RsaKeyAlgorithm-dictionary
|
||||
|
||||
dictionary RsaKeyAlgorithm : KeyAlgorithm {
|
||||
required unsigned long modulusLength;
|
||||
required BigInteger publicExponent;
|
||||
};
|
||||
|
||||
// https://w3c.github.io/webcrypto/#RsaHashedKeyAlgorithm-dictionary
|
||||
|
||||
dictionary RsaHashedKeyAlgorithm : RsaKeyAlgorithm {
|
||||
required KeyAlgorithm hash;
|
||||
};
|
||||
|
||||
// https://w3c.github.io/webcrypto/#RsaHashedImportParams-dictionary
|
||||
|
||||
dictionary RsaHashedImportParams : Algorithm {
|
||||
required HashAlgorithmIdentifier hash;
|
||||
};
|
||||
|
||||
// https://w3c.github.io/webcrypto/#EcdsaParams-dictionary
|
||||
dictionary EcdsaParams : Algorithm {
|
||||
required HashAlgorithmIdentifier hash;
|
||||
|
||||
@@ -24,6 +24,10 @@ ignore = [
|
||||
"RUSTSEC-2025-0098",
|
||||
# The crate `unic-ucd-ident` is unmaintained.
|
||||
"RUSTSEC-2025-0100",
|
||||
# The crate `rsa` is vulnerable to Marvin Attack that leaks
|
||||
# cryptographic secret via side channel. Wait for a patch in stable
|
||||
# release version from upstream.
|
||||
"RUSTSEC-2023-0071",
|
||||
]
|
||||
|
||||
# This section is considered when running `cargo deny check licenses`
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -131,6 +131,30 @@
|
||||
[importVectorKeys step: RSASSA-PKCS1-v1_5 with SHA-512 verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-1 signing with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-256 signing with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-384 signing with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-512 signing with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-1 verification with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-256 verification with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-384 verification with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-512 verification with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[rsa_pkcs.https.any.html]
|
||||
[importVectorKeys step: RSASSA-PKCS1-v1_5 with SHA-1 verification]
|
||||
@@ -264,3 +288,27 @@
|
||||
|
||||
[importVectorKeys step: RSASSA-PKCS1-v1_5 with SHA-512 verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-1 signing with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-256 signing with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-384 signing with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-512 signing with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-1 verification with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-256 verification with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-384 verification with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
[RSASSA-PKCS1-v1_5 with SHA-512 verification with wrong algorithm name]
|
||||
expected: FAIL
|
||||
|
||||
@@ -287,6 +287,246 @@
|
||||
[importVectorKeys step: RSA-PSS with SHA-512, salted verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[rsa_pss.https.any.html]
|
||||
[importVectorKeys step: RSA-PSS with SHA-1 and no salt verification]
|
||||
@@ -576,3 +816,243 @@
|
||||
|
||||
[importVectorKeys step: RSA-PSS with SHA-512, salted verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted verification]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted verification with altered signature after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted with altered plaintext after call]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted using privateKey to verify]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted using publicKey to sign]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted no verify usage]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted round trip]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted verification failure with altered signature]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted verification failure with wrong saltLength]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1 and no salt verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256 and no salt verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384 and no salt verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512 and no salt verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-1, salted verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-256, salted verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-384, salted verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
[RSA-PSS with SHA-512, salted verification failure with altered plaintext]
|
||||
expected: FAIL
|
||||
|
||||
Reference in New Issue
Block a user