mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-28 14:02:51 +00:00
LibWeb: Support RSA-PSS
in WebCryptoAPI
This commit is contained in:
parent
3eeb35e787
commit
e05ee9d297
Notes:
github-actions[bot]
2025-01-17 11:44:17 +00:00
Author: https://github.com/devgianlu
Commit: e05ee9d297
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3252
Reviewed-by: https://github.com/gmta ✅
10 changed files with 1417 additions and 57 deletions
|
@ -512,6 +512,19 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> RsaOaepParams::from_value(
|
|||
return adopt_own<AlgorithmParams>(*new RsaOaepParams { move(label) });
|
||||
}
|
||||
|
||||
RsaPssParams::~RsaPssParams() = default;
|
||||
|
||||
// https://w3c.github.io/webcrypto/#RsaPssParams-dictionary
|
||||
JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> RsaPssParams::from_value(JS::VM& vm, JS::Value value)
|
||||
{
|
||||
auto& object = value.as_object();
|
||||
|
||||
auto salt_length_value = TRY(object.get("saltLength"));
|
||||
auto salt_length = TRY(salt_length_value.to_u32(vm));
|
||||
|
||||
return adopt_own<AlgorithmParams>(*new RsaPssParams { salt_length });
|
||||
}
|
||||
|
||||
EcdsaParams::~EcdsaParams() = default;
|
||||
|
||||
JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> EcdsaParams::from_value(JS::VM& vm, JS::Value value)
|
||||
|
@ -1228,6 +1241,585 @@ WebIDL::ExceptionOr<GC::Ref<JS::Object>> RSAOAEP::export_key(Bindings::KeyFormat
|
|||
return GC::Ref { *result };
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webcrypto/#rsa-pss-operations
|
||||
WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>> RSAPSS::generate_key(AlgorithmParams const& params, bool extractable, Vector<Bindings::KeyUsage> const& key_usages)
|
||||
{
|
||||
// 1. If usages contains a value which is not one of "sign" or "verify", then throw a SyntaxError.
|
||||
for (auto const& usage : key_usages) {
|
||||
if (usage != Bindings::KeyUsage::Sign && usage != Bindings::KeyUsage::Verify) {
|
||||
return WebIDL::SyntaxError::create(m_realm, MUST(String::formatted("Invalid key usage '{}'", idl_enum_to_string(usage))));
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Generate an RSA key pair, as defined in [RFC3447], with RSA modulus length equal to the modulusLength member of normalizedAlgorithm
|
||||
// and RSA public exponent equal to the publicExponent member of normalizedAlgorithm.
|
||||
// 3. If performing the operation results in an error, then throw an OperationError.
|
||||
auto const& normalized_algorithm = static_cast<RsaHashedKeyGenParams const&>(params);
|
||||
auto maybe_key_pair = ::Crypto::PK::RSA::generate_key_pair(normalized_algorithm.modulus_length, normalized_algorithm.public_exponent);
|
||||
if (maybe_key_pair.is_error())
|
||||
return WebIDL::OperationError::create(m_realm, "Failed to generate RSA key pair"_string);
|
||||
|
||||
auto key_pair = maybe_key_pair.release_value();
|
||||
|
||||
// 4. Let algorithm be a new RsaHashedKeyAlgorithm object.
|
||||
auto algorithm = RsaHashedKeyAlgorithm::create(m_realm);
|
||||
|
||||
// 5. Set the name attribute of algorithm to "RSA-PSS".
|
||||
algorithm->set_name("RSA-PSS"_string);
|
||||
|
||||
// 6. Set the modulusLength attribute of algorithm to equal the modulusLength member of normalizedAlgorithm.
|
||||
algorithm->set_modulus_length(normalized_algorithm.modulus_length);
|
||||
|
||||
// 7. Set the publicExponent attribute of algorithm to equal the publicExponent member of normalizedAlgorithm.
|
||||
TRY(algorithm->set_public_exponent(normalized_algorithm.public_exponent));
|
||||
|
||||
// 8. Set the hash attribute of algorithm to equal the hash member of normalizedAlgorithm.
|
||||
algorithm->set_hash(normalized_algorithm.hash);
|
||||
|
||||
// 9. Let publicKey be a new CryptoKey representing the public key of the generated key pair.
|
||||
auto public_key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { key_pair.public_key });
|
||||
|
||||
// 10. Set the [[type]] internal slot of publicKey to "public"
|
||||
public_key->set_type(Bindings::KeyType::Public);
|
||||
|
||||
// 11. Set the [[algorithm]] internal slot of publicKey to algorithm.
|
||||
public_key->set_algorithm(algorithm);
|
||||
|
||||
// 12. Set the [[extractable]] internal slot of publicKey to true.
|
||||
public_key->set_extractable(true);
|
||||
|
||||
// 13. Set the [[usages]] internal slot of publicKey to be the usage intersection of usages and [ "verify" ].
|
||||
public_key->set_usages(usage_intersection(key_usages, { { Bindings::KeyUsage::Verify } }));
|
||||
|
||||
// 14. Let privateKey be a new CryptoKey representing the private key of the generated key pair.
|
||||
auto private_key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { key_pair.private_key });
|
||||
|
||||
// 15. Set the [[type]] internal slot of privateKey to "private"
|
||||
private_key->set_type(Bindings::KeyType::Private);
|
||||
|
||||
// 16. Set the [[algorithm]] internal slot of privateKey to algorithm.
|
||||
private_key->set_algorithm(algorithm);
|
||||
|
||||
// 17. Set the [[extractable]] internal slot of privateKey to extractable.
|
||||
private_key->set_extractable(extractable);
|
||||
|
||||
// 18. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "sign" ].
|
||||
private_key->set_usages(usage_intersection(key_usages, { { Bindings::KeyUsage::Sign } }));
|
||||
|
||||
// 19. Let result be a new CryptoKeyPair dictionary.
|
||||
// 20. Set the publicKey attribute of result to be publicKey.
|
||||
// 21. Set the privateKey attribute of result to be privateKey.
|
||||
// 22. Return result.
|
||||
return Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>> { CryptoKeyPair::create(m_realm, public_key, private_key) };
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webcrypto/#rsa-pss-operations
|
||||
WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> RSAPSS::sign(AlgorithmParams const& params, GC::Ref<CryptoKey> key, ByteBuffer const& message)
|
||||
{
|
||||
auto& realm = *m_realm;
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// 1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.
|
||||
if (key->type() != Bindings::KeyType::Private)
|
||||
return WebIDL::InvalidAccessError::create(realm, "Key is not a private key"_string);
|
||||
|
||||
auto const& private_key = key->handle().get<::Crypto::PK::RSAPrivateKey<>>();
|
||||
auto pss_params = static_cast<RsaPssParams const&>(params);
|
||||
auto hash = TRY(verify_cast<RsaHashedKeyAlgorithm>(*key->algorithm()).hash().name(vm));
|
||||
|
||||
// 3. Perform the signature generation operation defined in Section 8.1 of [RFC3447] with the key represented by the [[handle]] internal slot
|
||||
// of key as the signer's private key, K, and the contents of message as the message to be signed, M, and using the hash function specified
|
||||
// by the hash attribute of the [[algorithm]] internal slot of key as the Hash option, MGF1 (defined in Section B.2.1 of [RFC3447])
|
||||
// as the MGF option and the saltLength member of normalizedAlgorithm as the salt length option for the EMSA-PSS-ENCODE operation.
|
||||
Optional<::Crypto::Hash::HashKind> hash_kind = {};
|
||||
if (hash == "SHA-1")
|
||||
hash_kind = ::Crypto::Hash::HashKind::SHA1;
|
||||
else if (hash == "SHA-256")
|
||||
hash_kind = ::Crypto::Hash::HashKind::SHA256;
|
||||
else if (hash == "SHA-384")
|
||||
hash_kind = ::Crypto::Hash::HashKind::SHA384;
|
||||
else if (hash == "SHA-512")
|
||||
hash_kind = ::Crypto::Hash::HashKind::SHA512;
|
||||
|
||||
// 4. If performing the operation results in an error, then throw an OperationError.
|
||||
if (!hash_kind.has_value()) {
|
||||
auto error_message = MUST(String::formatted("Invalid hash function '{}'", hash));
|
||||
return WebIDL::OperationError::create(realm, error_message);
|
||||
}
|
||||
|
||||
// 5. Let signature be the signature, S, that results from performing the operation.
|
||||
auto rsa = ::Crypto::PK::RSA_PSS_EMSA { *hash_kind, private_key };
|
||||
rsa.set_salt_length(pss_params.salt_length);
|
||||
|
||||
auto maybe_signature = rsa.sign(message);
|
||||
if (maybe_signature.is_error())
|
||||
return WebIDL::OperationError::create(realm, "Failed to sign message"_string);
|
||||
|
||||
// 6. Return signature.
|
||||
return JS::ArrayBuffer::create(realm, maybe_signature.release_value());
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webcrypto/#rsa-pss-operations
|
||||
WebIDL::ExceptionOr<JS::Value> RSAPSS::verify(AlgorithmParams const& params, GC::Ref<CryptoKey> key, ByteBuffer const& signature, ByteBuffer const& message)
|
||||
{
|
||||
auto& realm = *m_realm;
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// 1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.
|
||||
if (key->type() != Bindings::KeyType::Public)
|
||||
return WebIDL::InvalidAccessError::create(realm, "Key is not a public key"_string);
|
||||
|
||||
auto const& public_key = key->handle().get<::Crypto::PK::RSAPublicKey<>>();
|
||||
auto pss_params = static_cast<RsaPssParams const&>(params);
|
||||
auto hash = TRY(verify_cast<RsaHashedKeyAlgorithm>(*key->algorithm()).hash().name(vm));
|
||||
|
||||
// 2. Perform the signature verification operation defined in Section 8.1 of [RFC3447] with the key represented by the [[handle]] internal slot
|
||||
// of key as the signer's RSA public key and the contents of message as M and the contents of signature as S and using the hash function specified
|
||||
// by the hash attribute of the [[algorithm]] internal slot of key as the Hash option, MGF1 (defined in Section B.2.1 of [RFC3447])
|
||||
// as the MGF option and the saltLength member of normalizedAlgorithm as the salt length option for the EMSA-PSS-VERIFY operation.
|
||||
Optional<::Crypto::Hash::HashKind> hash_kind = {};
|
||||
if (hash == "SHA-1")
|
||||
hash_kind = ::Crypto::Hash::HashKind::SHA1;
|
||||
else if (hash == "SHA-256")
|
||||
hash_kind = ::Crypto::Hash::HashKind::SHA256;
|
||||
else if (hash == "SHA-384")
|
||||
hash_kind = ::Crypto::Hash::HashKind::SHA384;
|
||||
else if (hash == "SHA-512")
|
||||
hash_kind = ::Crypto::Hash::HashKind::SHA512;
|
||||
|
||||
if (!hash_kind.has_value()) {
|
||||
auto error_message = MUST(String::formatted("Invalid hash function '{}'", hash));
|
||||
return WebIDL::OperationError::create(realm, error_message);
|
||||
}
|
||||
|
||||
// 3. Let result be a boolean with the value true if the result of the operation was "valid signature" and the value false otherwise.
|
||||
auto rsa = ::Crypto::PK::RSA_PSS_EMSA { *hash_kind, public_key };
|
||||
rsa.set_salt_length(pss_params.salt_length);
|
||||
|
||||
auto maybe_verification = rsa.verify(message, signature);
|
||||
if (maybe_verification.is_error())
|
||||
return WebIDL::OperationError::create(realm, "Failed to verify message"_string);
|
||||
|
||||
return JS::Value { maybe_verification.release_value() };
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webcrypto/#rsa-pss-operations
|
||||
WebIDL::ExceptionOr<GC::Ref<CryptoKey>> RSAPSS::import_key(AlgorithmParams const& params, Bindings::KeyFormat key_format, CryptoKey::InternalKeyData key_data, bool extractable, Vector<Bindings::KeyUsage> const& usages)
|
||||
{
|
||||
auto& realm = *m_realm;
|
||||
|
||||
// 1. Let keyData be the key data to be imported.
|
||||
|
||||
GC::Ptr<CryptoKey> key = nullptr;
|
||||
auto const& normalized_algorithm = static_cast<RsaHashedImportParams const&>(params);
|
||||
|
||||
// 2. -> If format is "spki":
|
||||
if (key_format == Bindings::KeyFormat::Spki) {
|
||||
// 1. If usages contains an entry which is not "verify" then throw a SyntaxError.
|
||||
for (auto const& usage : usages) {
|
||||
if (usage != Bindings::KeyUsage::Verify) {
|
||||
return WebIDL::SyntaxError::create(m_realm, MUST(String::formatted("Invalid key usage '{}'", idl_enum_to_string(usage))));
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY(key_data.has<ByteBuffer>());
|
||||
|
||||
// 2. Let spki be the result of running the parse a subjectPublicKeyInfo algorithm over keyData.
|
||||
// 3. If an error occurred while parsing, then throw a DataError.
|
||||
auto spki = TRY(parse_a_subject_public_key_info(m_realm, key_data.get<ByteBuffer>()));
|
||||
|
||||
// 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.identifier != ::Crypto::ASN1::rsa_encryption_oid)
|
||||
return WebIDL::DataError::create(m_realm, "Algorithm object identifier is not the rsaEncryption object identifier"_string);
|
||||
|
||||
// 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.
|
||||
// NOTE: We already did this in parse_a_subject_public_key_info
|
||||
auto& public_key = spki.rsa;
|
||||
|
||||
// 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.
|
||||
// FIXME: Validate the public key
|
||||
|
||||
// 7. Let key be a new CryptoKey that represents the RSA public key identified by publicKey.
|
||||
key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { public_key });
|
||||
|
||||
// 8. Set the [[type]] internal slot of key to "public"
|
||||
key->set_type(Bindings::KeyType::Public);
|
||||
}
|
||||
|
||||
// -> If format is "pkcs8":
|
||||
else if (key_format == Bindings::KeyFormat::Pkcs8) {
|
||||
// 1. If usages contains an entry which is not "sign" then throw a SyntaxError.
|
||||
for (auto const& usage : usages) {
|
||||
if (usage != Bindings::KeyUsage::Sign) {
|
||||
return WebIDL::SyntaxError::create(m_realm, MUST(String::formatted("Invalid key usage '{}'", idl_enum_to_string(usage))));
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY(key_data.has<ByteBuffer>());
|
||||
|
||||
// 2. Let privateKeyInfo be the result of running the parse a privateKeyInfo algorithm over keyData.
|
||||
// 3. If an error occurred while parsing, then throw a DataError.
|
||||
auto private_key_info = TRY(parse_a_private_key_info(m_realm, key_data.get<ByteBuffer>()));
|
||||
|
||||
// 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.identifier != ::Crypto::ASN1::rsa_encryption_oid)
|
||||
return WebIDL::DataError::create(m_realm, "Algorithm object identifier is not the rsaEncryption object identifier"_string);
|
||||
|
||||
// 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.
|
||||
// NOTE: We already did this in parse_a_private_key_info
|
||||
auto& rsa_private_key = private_key_info.rsa;
|
||||
|
||||
// 6. If an error occurred while parsing, or if rsaPrivateKey is not
|
||||
// a valid RSA private key according to [RFC3447], then throw a DataError.
|
||||
// FIXME: Validate the private key
|
||||
|
||||
// 7. Let key be a new CryptoKey that represents the RSA private key identified by rsaPrivateKey.
|
||||
key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { rsa_private_key });
|
||||
|
||||
// 8. Set the [[type]] internal slot of key to "private"
|
||||
key->set_type(Bindings::KeyType::Private);
|
||||
}
|
||||
|
||||
// -> If format is "jwk":
|
||||
else if (key_format == Bindings::KeyFormat::Jwk) {
|
||||
// 1. -> If keyData is a JsonWebKey dictionary:
|
||||
// Let jwk equal keyData.
|
||||
// -> Otherwise:
|
||||
// Throw a DataError.
|
||||
if (!key_data.has<Bindings::JsonWebKey>())
|
||||
return WebIDL::DataError::create(m_realm, "keyData is not a JsonWebKey dictionary"_string);
|
||||
auto& jwk = key_data.get<Bindings::JsonWebKey>();
|
||||
|
||||
// 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.has_value()) {
|
||||
for (auto const& usage : usages) {
|
||||
if (usage != Bindings::KeyUsage::Sign) {
|
||||
return WebIDL::SyntaxError::create(m_realm, MUST(String::formatted("Invalid key usage '{}'", Bindings::idl_enum_to_string(usage))));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (auto const& usage : usages) {
|
||||
if (usage != Bindings::KeyUsage::Verify) {
|
||||
return WebIDL::SyntaxError::create(m_realm, MUST(String::formatted("Invalid key usage '{}'", Bindings::idl_enum_to_string(usage))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. If the kty field of jwk is not a case-sensitive string match to "RSA", then throw a DataError.
|
||||
if (jwk.kty != "RSA"_string)
|
||||
return WebIDL::DataError::create(m_realm, "Invalid key type"_string);
|
||||
|
||||
// 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.has_value() && *jwk.use != "sig"_string)
|
||||
return WebIDL::DataError::create(m_realm, "Invalid use field"_string);
|
||||
|
||||
// 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.
|
||||
TRY(validate_jwk_key_ops(realm, jwk, usages));
|
||||
|
||||
// 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.has_value() && !*jwk.ext && extractable)
|
||||
return WebIDL::DataError::create(m_realm, "Invalid ext field"_string);
|
||||
|
||||
Optional<String> hash = {};
|
||||
// 7. -> If the alg field of jwk is not present:
|
||||
if (!jwk.alg.has_value()) {
|
||||
// Let hash be undefined.
|
||||
}
|
||||
// -> If the alg field of jwk is equal to "PS1":
|
||||
else if (jwk.alg == "PS1"sv) {
|
||||
// Let hash be the string "SHA-1".
|
||||
hash = "SHA-1"_string;
|
||||
}
|
||||
// -> If the alg field of jwk is equal to "PS256":
|
||||
else if (jwk.alg == "PS256"sv) {
|
||||
// Let hash be the string "SHA-256".
|
||||
hash = "SHA-256"_string;
|
||||
}
|
||||
// -> If the alg field of jwk is equal to "PS384":
|
||||
else if (jwk.alg == "PS384"sv) {
|
||||
// Let hash be the string "SHA-384".
|
||||
hash = "SHA-384"_string;
|
||||
}
|
||||
// -> If the alg field of jwk is equal to "PS512":
|
||||
else if (jwk.alg == "PS512"sv) {
|
||||
// Let hash be the string "SHA-512".
|
||||
hash = "SHA-512"_string;
|
||||
}
|
||||
// -> Otherwise:
|
||||
else {
|
||||
// FIXME: Support 'other applicable specifications'
|
||||
// 1. Perform any key import steps defined by other applicable specifications, passing format, jwk and obtaining hash.
|
||||
// 2. If an error occurred or there are no applicable specifications, throw a DataError.
|
||||
return WebIDL::DataError::create(m_realm, "Invalid alg field"_string);
|
||||
}
|
||||
|
||||
// 8. If hash is not undefined:
|
||||
if (hash.has_value()) {
|
||||
// 1. Let normalizedHash be the result of normalize an algorithm with alg set to hash and op set to digest.
|
||||
auto normalized_hash = TRY(normalize_an_algorithm(m_realm, AlgorithmIdentifier { *hash }, "digest"_string));
|
||||
|
||||
// 2. If normalizedHash is not equal to the hash member of normalizedAlgorithm, throw a DataError.
|
||||
if (normalized_hash.parameter->name != TRY(normalized_algorithm.hash.name(realm.vm())))
|
||||
return WebIDL::DataError::create(m_realm, "Invalid hash"_string);
|
||||
}
|
||||
|
||||
// 9. -> If the d field of jwk is present:
|
||||
if (jwk.d.has_value()) {
|
||||
// 1. If jwk does not meet the requirements of Section 6.3.2 of JSON Web Algorithms [JWA], then throw a DataError.
|
||||
bool meets_requirements = jwk.e.has_value() && jwk.n.has_value() && jwk.d.has_value();
|
||||
if (jwk.p.has_value() || jwk.q.has_value() || jwk.dp.has_value() || jwk.dq.has_value() || jwk.qi.has_value())
|
||||
meets_requirements |= jwk.p.has_value() && jwk.q.has_value() && jwk.dp.has_value() && jwk.dq.has_value() && jwk.qi.has_value();
|
||||
|
||||
if (jwk.oth.has_value()) {
|
||||
// FIXME: We don't support > 2 primes in RSA keys
|
||||
meets_requirements = false;
|
||||
}
|
||||
|
||||
if (!meets_requirements)
|
||||
return WebIDL::DataError::create(m_realm, "Invalid JWK private key"_string);
|
||||
|
||||
// FIXME: Spec error, it should say 'the RSA private key identified by interpreting jwk according to section 6.3.2'
|
||||
// 2. Let privateKey represent the RSA public key identified by interpreting jwk according to Section 6.3.1 of JSON Web Algorithms [JWA].
|
||||
auto private_key = TRY(parse_jwk_rsa_private_key(realm, jwk));
|
||||
|
||||
// FIXME: Spec error, it should say 'not to be a valid RSA private key'
|
||||
// 3. If privateKey can be determined to not be a valid RSA public key according to [RFC3447], then throw a DataError.
|
||||
// FIXME: Validate the private key
|
||||
|
||||
// 4. Let key be a new CryptoKey representing privateKey.
|
||||
key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { private_key });
|
||||
|
||||
// 5. Set the [[type]] internal slot of key to "private"
|
||||
key->set_type(Bindings::KeyType::Private);
|
||||
}
|
||||
|
||||
// -> Otherwise:
|
||||
else {
|
||||
// 1. If jwk does not meet the requirements of Section 6.3.1 of JSON Web Algorithms [JWA], then throw a DataError.
|
||||
if (!jwk.e.has_value() || !jwk.n.has_value())
|
||||
return WebIDL::DataError::create(m_realm, "Invalid JWK public key"_string);
|
||||
|
||||
// 2. Let publicKey represent the RSA public key identified by interpreting jwk according to Section 6.3.1 of JSON Web Algorithms [JWA].
|
||||
auto public_key = TRY(parse_jwk_rsa_public_key(realm, jwk));
|
||||
|
||||
// 3. If publicKey can be determined to not be a valid RSA public key according to [RFC3447], then throw a DataError.
|
||||
// FIXME: Validate the public key
|
||||
|
||||
// 4. Let key be a new CryptoKey representing publicKey.
|
||||
key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { public_key });
|
||||
|
||||
// 5. Set the [[type]] internal slot of key to "public"
|
||||
key->set_type(Bindings::KeyType::Public);
|
||||
}
|
||||
}
|
||||
|
||||
// -> Otherwise: throw a NotSupportedError.
|
||||
else {
|
||||
return WebIDL::NotSupportedError::create(m_realm, "Unsupported key format"_string);
|
||||
}
|
||||
|
||||
// 3. Let algorithm be a new RsaHashedKeyAlgorithm.
|
||||
auto algorithm = RsaHashedKeyAlgorithm::create(m_realm);
|
||||
|
||||
// 4. Set the name attribute of algorithm to "RSA-PSS"
|
||||
algorithm->set_name("RSA-PSS"_string);
|
||||
|
||||
// 5. Set the modulusLength attribute of algorithm to the length, in bits, of the RSA public modulus.
|
||||
// 6. Set the publicExponent attribute of algorithm to the BigInteger representation of the RSA public exponent.
|
||||
TRY(key->handle().visit(
|
||||
[&](::Crypto::PK::RSAPublicKey<> const& public_key) -> WebIDL::ExceptionOr<void> {
|
||||
algorithm->set_modulus_length(public_key.modulus().trimmed_byte_length() * 8);
|
||||
TRY(algorithm->set_public_exponent(public_key.public_exponent()));
|
||||
return {};
|
||||
},
|
||||
[&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> WebIDL::ExceptionOr<void> {
|
||||
algorithm->set_modulus_length(private_key.modulus().trimmed_byte_length() * 8);
|
||||
TRY(algorithm->set_public_exponent(private_key.public_exponent()));
|
||||
return {};
|
||||
},
|
||||
[](auto) -> WebIDL::ExceptionOr<void> { VERIFY_NOT_REACHED(); }));
|
||||
|
||||
// 7. Set the hash attribute of algorithm to the hash member of normalizedAlgorithm.
|
||||
algorithm->set_hash(normalized_algorithm.hash);
|
||||
|
||||
// 8. Set the [[algorithm]] internal slot of key to algorithm
|
||||
key->set_algorithm(algorithm);
|
||||
|
||||
// 9. Return key.
|
||||
return GC::Ref { *key };
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webcrypto/#rsa-pss-operations
|
||||
WebIDL::ExceptionOr<GC::Ref<JS::Object>> RSAPSS::export_key(Bindings::KeyFormat format, GC::Ref<CryptoKey> key)
|
||||
{
|
||||
auto& realm = *m_realm;
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// 1. Let key be the key to be exported.
|
||||
|
||||
// 2. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.
|
||||
// Note: In our impl this is always accessible
|
||||
auto const& handle = key->handle();
|
||||
|
||||
GC::Ptr<JS::Object> result = nullptr;
|
||||
|
||||
// 3. If format is "spki"
|
||||
if (format == Bindings::KeyFormat::Spki) {
|
||||
// 1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.
|
||||
if (key->type() != Bindings::KeyType::Public)
|
||||
return WebIDL::InvalidAccessError::create(realm, "Key is not public"_string);
|
||||
|
||||
// 2. Let data be an instance of the subjectPublicKeyInfo ASN.1 structure defined in [RFC5280] with the following properties:
|
||||
// - Set the algorithm field to an AlgorithmIdentifier ASN.1 type with the following properties:
|
||||
// - Set the algorithm field to the OID rsaEncryption defined in [RFC3447].
|
||||
// - Set the params field to the ASN.1 type NULL.
|
||||
// - Set the subjectPublicKey field to the result of DER-encoding an RSAPublicKey ASN.1 type, as defined in [RFC3447], Appendix A.1.1,
|
||||
// that represents the RSA public key represented by the [[handle]] internal slot of key
|
||||
auto maybe_data = handle.visit(
|
||||
[&](::Crypto::PK::RSAPublicKey<> const& public_key) -> ErrorOr<ByteBuffer> {
|
||||
return TRY(::Crypto::PK::wrap_in_subject_public_key_info(public_key, ::Crypto::ASN1::rsa_encryption_oid, nullptr));
|
||||
},
|
||||
[](auto) -> ErrorOr<ByteBuffer> {
|
||||
VERIFY_NOT_REACHED();
|
||||
});
|
||||
// FIXME: clang-format butchers the visit if we do the TRY inline
|
||||
auto data = TRY_OR_THROW_OOM(vm, maybe_data);
|
||||
|
||||
// 3. Let result be the result of creating an ArrayBuffer containing data.
|
||||
result = JS::ArrayBuffer::create(realm, data);
|
||||
}
|
||||
|
||||
// If format is "pkcs8"
|
||||
else if (format == Bindings::KeyFormat::Pkcs8) {
|
||||
// 1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.
|
||||
if (key->type() != Bindings::KeyType::Private)
|
||||
return WebIDL::InvalidAccessError::create(realm, "Key is not private"_string);
|
||||
|
||||
// 2. Let data be the result of encoding a privateKeyInfo structure with the following properties:
|
||||
// - Set the version field to 0.
|
||||
// - Set the privateKeyAlgorithm field to an PrivateKeyAlgorithmIdentifier ASN.1 type with the following properties:
|
||||
// - - Set the algorithm field to the OID rsaEncryption defined in [RFC3447].
|
||||
// - - Set the params field to the ASN.1 type NULL.
|
||||
// - Set the privateKey field to the result of DER-encoding an RSAPrivateKey ASN.1 type, as defined in [RFC3447], Appendix A.1.2,
|
||||
// that represents the RSA private key represented by the [[handle]] internal slot of key
|
||||
auto maybe_data = handle.visit(
|
||||
[&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> ErrorOr<ByteBuffer> {
|
||||
return TRY(::Crypto::PK::wrap_in_private_key_info(private_key, ::Crypto::ASN1::rsa_encryption_oid, nullptr));
|
||||
},
|
||||
[](auto) -> ErrorOr<ByteBuffer> {
|
||||
VERIFY_NOT_REACHED();
|
||||
});
|
||||
|
||||
// FIXME: clang-format butchers the visit if we do the TRY inline
|
||||
auto data = TRY_OR_THROW_OOM(vm, maybe_data);
|
||||
|
||||
// 3. Let result be the result of creating an ArrayBuffer containing data.
|
||||
result = JS::ArrayBuffer::create(realm, data);
|
||||
}
|
||||
|
||||
// If format is "jwk"
|
||||
else if (format == Bindings::KeyFormat::Jwk) {
|
||||
// 1. Let jwk be a new JsonWebKey dictionary.
|
||||
Bindings::JsonWebKey jwk = {};
|
||||
|
||||
// 2. Set the kty attribute of jwk to the string "RSA".
|
||||
jwk.kty = "RSA"_string;
|
||||
|
||||
// 3. Let hash be the name attribute of the hash attribute of the [[algorithm]] internal slot of key.
|
||||
auto hash = TRY(verify_cast<RsaHashedKeyAlgorithm>(*key->algorithm()).hash().name(vm));
|
||||
|
||||
// 4. If hash is "SHA-1":
|
||||
// - Set the alg attribute of jwk to the string "PS1".
|
||||
if (hash == "SHA-1"sv) {
|
||||
jwk.alg = "PS1"_string;
|
||||
}
|
||||
// If hash is "SHA-256":
|
||||
// - Set the alg attribute of jwk to the string "PS256".
|
||||
else if (hash == "SHA-256"sv) {
|
||||
jwk.alg = "PS256"_string;
|
||||
}
|
||||
// If hash is "SHA-384":
|
||||
// - Set the alg attribute of jwk to the string "PS384".
|
||||
else if (hash == "SHA-384"sv) {
|
||||
jwk.alg = "PS384"_string;
|
||||
}
|
||||
// If hash is "SHA-512":
|
||||
// - Set the alg attribute of jwk to the string "PS512".
|
||||
else if (hash == "SHA-512"sv) {
|
||||
jwk.alg = "PS512"_string;
|
||||
} else {
|
||||
// FIXME: Support 'other applicable specifications'
|
||||
// - Perform any key export steps defined by other applicable specifications,
|
||||
// passing format and the hash attribute of the [[algorithm]] internal slot of key and obtaining alg.
|
||||
// - Set the alg attribute of jwk to alg.
|
||||
return WebIDL::NotSupportedError::create(realm, TRY_OR_THROW_OOM(vm, String::formatted("Unsupported hash algorithm '{}'", hash)));
|
||||
}
|
||||
|
||||
// 5. Set the attributes n and e of jwk according to the corresponding definitions in JSON Web Algorithms [JWA], Section 6.3.1.
|
||||
auto maybe_error = handle.visit(
|
||||
[&](::Crypto::PK::RSAPublicKey<> const& public_key) -> ErrorOr<void> {
|
||||
jwk.n = TRY(base64_url_uint_encode(public_key.modulus()));
|
||||
jwk.e = TRY(base64_url_uint_encode(public_key.public_exponent()));
|
||||
return {};
|
||||
},
|
||||
// 6. If the [[type]] internal slot of key is "private":
|
||||
[&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> ErrorOr<void> {
|
||||
jwk.n = TRY(base64_url_uint_encode(private_key.modulus()));
|
||||
jwk.e = TRY(base64_url_uint_encode(private_key.public_exponent()));
|
||||
|
||||
// 1. Set the attributes named d, p, q, dp, dq, and qi of jwk according to the corresponding definitions
|
||||
// in JSON Web Algorithms [JWA], Section 6.3.2.
|
||||
jwk.d = TRY(base64_url_uint_encode(private_key.private_exponent()));
|
||||
jwk.p = TRY(base64_url_uint_encode(private_key.prime1()));
|
||||
jwk.q = TRY(base64_url_uint_encode(private_key.prime2()));
|
||||
jwk.dp = TRY(base64_url_uint_encode(private_key.exponent1()));
|
||||
jwk.dq = TRY(base64_url_uint_encode(private_key.exponent2()));
|
||||
jwk.qi = TRY(base64_url_uint_encode(private_key.coefficient()));
|
||||
|
||||
// 2. If the underlying RSA private key represented by the [[handle]] internal slot of key is represented by more than two primes,
|
||||
// set the attribute named oth of jwk according to the corresponding definition in JSON Web Algorithms [JWA], Section 6.3.2.7
|
||||
// FIXME: We don't support more than 2 primes on RSA keys
|
||||
return {};
|
||||
},
|
||||
[](auto) -> ErrorOr<void> {
|
||||
VERIFY_NOT_REACHED();
|
||||
});
|
||||
// FIXME: clang-format butchers the visit if we do the TRY inline
|
||||
TRY_OR_THROW_OOM(vm, maybe_error);
|
||||
|
||||
// 7. Set the key_ops attribute of jwk to the usages attribute of key.
|
||||
jwk.key_ops = Vector<String> {};
|
||||
jwk.key_ops->ensure_capacity(key->internal_usages().size());
|
||||
for (auto const& usage : key->internal_usages()) {
|
||||
jwk.key_ops->append(Bindings::idl_enum_to_string(usage));
|
||||
}
|
||||
|
||||
// 8. Set the ext attribute of jwk to the [[extractable]] internal slot of key.
|
||||
jwk.ext = key->extractable();
|
||||
|
||||
// 9. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].
|
||||
result = TRY(jwk.to_object(realm));
|
||||
}
|
||||
|
||||
// Otherwise throw a NotSupportedError.
|
||||
else {
|
||||
return WebIDL::NotSupportedError::create(realm, TRY_OR_THROW_OOM(vm, String::formatted("Exporting to format {} is not supported", Bindings::idl_enum_to_string(format))));
|
||||
}
|
||||
|
||||
// 8. Return result
|
||||
return GC::Ref { *result };
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webcrypto/#aes-cbc-operations
|
||||
WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> AesCbc::encrypt(AlgorithmParams const& params, GC::Ref<CryptoKey> key, ByteBuffer const& plaintext)
|
||||
{
|
||||
|
|
|
@ -195,6 +195,20 @@ struct RsaOaepParams : public AlgorithmParams {
|
|||
static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
|
||||
};
|
||||
|
||||
// https://w3c.github.io/webcrypto/#dfn-RsaPssParams
|
||||
struct RsaPssParams : public AlgorithmParams {
|
||||
virtual ~RsaPssParams() override;
|
||||
|
||||
RsaPssParams(WebIDL::UnsignedLong salt_length)
|
||||
: salt_length(salt_length)
|
||||
{
|
||||
}
|
||||
|
||||
WebIDL::UnsignedLong salt_length;
|
||||
|
||||
static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
|
||||
};
|
||||
|
||||
// https://w3c.github.io/webcrypto/#dfn-EcdsaParams
|
||||
struct EcdsaParams : public AlgorithmParams {
|
||||
virtual ~EcdsaParams() override;
|
||||
|
@ -377,6 +391,25 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class RSAPSS : public AlgorithmMethods {
|
||||
public:
|
||||
virtual WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> sign(AlgorithmParams const&, GC::Ref<CryptoKey>, ByteBuffer const&) override;
|
||||
virtual WebIDL::ExceptionOr<JS::Value> verify(AlgorithmParams const&, GC::Ref<CryptoKey>, ByteBuffer const&, ByteBuffer const&) override;
|
||||
|
||||
virtual WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
|
||||
|
||||
virtual WebIDL::ExceptionOr<GC::Ref<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
|
||||
virtual WebIDL::ExceptionOr<GC::Ref<JS::Object>> export_key(Bindings::KeyFormat, GC::Ref<CryptoKey>) override;
|
||||
|
||||
static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new RSAPSS(realm)); }
|
||||
|
||||
private:
|
||||
explicit RSAPSS(JS::Realm& realm)
|
||||
: AlgorithmMethods(realm)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class AesCbc : public AlgorithmMethods {
|
||||
public:
|
||||
virtual WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> encrypt(AlgorithmParams const&, GC::Ref<CryptoKey>, ByteBuffer const&) override;
|
||||
|
|
|
@ -1079,11 +1079,11 @@ SupportedAlgorithmsMap const& supported_algorithms()
|
|||
// FIXME: define_an_algorithm<RSAESPKCS1>("exportKey"_string, "RSASSA-PKCS1-v1_5"_string);
|
||||
|
||||
// https://w3c.github.io/webcrypto/#rsa-pss-registration
|
||||
// FIXME: define_an_algorithm<RSAPSS>("sign"_string, "RSA-PSS"_string);
|
||||
// FIXME: define_an_algorithm<RSAPSS>("verify"_string, "RSA-PSS"_string);
|
||||
// FIXME: define_an_algorithm<RSAPSS, RsaHashedKeyGenParams>("generateKey"_string, "RSA-PSS"_string);
|
||||
// FIXME: define_an_algorithm<RSAPSS, RsaHashedImportParams>("importKey"_string, "RSA-PSS"_string);
|
||||
// FIXME: define_an_algorithm<RSAPSS>("exportKey"_string, "RSA-PSS"_string);
|
||||
define_an_algorithm<RSAPSS, RsaPssParams>("sign"_string, "RSA-PSS"_string);
|
||||
define_an_algorithm<RSAPSS, RsaPssParams>("verify"_string, "RSA-PSS"_string);
|
||||
define_an_algorithm<RSAPSS, RsaHashedKeyGenParams>("generateKey"_string, "RSA-PSS"_string);
|
||||
define_an_algorithm<RSAPSS, RsaHashedImportParams>("importKey"_string, "RSA-PSS"_string);
|
||||
define_an_algorithm<RSAPSS>("exportKey"_string, "RSA-PSS"_string);
|
||||
|
||||
// https://w3c.github.io/webcrypto/#rsa-oaep-registration
|
||||
define_an_algorithm<RSAOAEP, RsaOaepParams>("encrypt"_string, "RSA-OAEP"_string);
|
||||
|
|
|
@ -2,8 +2,8 @@ Harness status: OK
|
|||
|
||||
Found 1056 tests
|
||||
|
||||
480 Pass
|
||||
576 Fail
|
||||
528 Pass
|
||||
528 Fail
|
||||
Pass Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-1, name: RSA-OAEP}, true, [encrypt])
|
||||
Pass Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-OAEP}, true, [encrypt])
|
||||
Pass Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-1, name: RSA-OAEP}, true, [wrapKey, encrypt])
|
||||
|
@ -492,10 +492,10 @@ Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-1, name: RSA-PSS}
|
|||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-1, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-1, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-1, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
|
@ -504,10 +504,10 @@ Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-1, name: RSA-PSS}
|
|||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-1, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-1, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-256, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
|
@ -516,10 +516,10 @@ Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-256, name: RSA-PS
|
|||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-256, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-256, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-256, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
|
@ -528,10 +528,10 @@ Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-256, name: RSA-PS
|
|||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-256, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-256, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-384, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
|
@ -540,10 +540,10 @@ Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-384, name: RSA-PS
|
|||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-384, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-384, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-384, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
|
@ -552,10 +552,10 @@ Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-384, name: RSA-PS
|
|||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-384, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-384, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-512, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
|
@ -564,10 +564,10 @@ Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-512, name: RSA-PS
|
|||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-512, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-512, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-512, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
|
@ -576,10 +576,10 @@ Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-512, name: RSA-PS
|
|||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-512, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 1024 bits (pkcs8, buffer(636), {hash: SHA-512, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 1024 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 1024 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-1, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
|
@ -588,10 +588,10 @@ Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-1, name: RSA-PSS}
|
|||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-1, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-1, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-1, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
|
@ -600,10 +600,10 @@ Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-1, name: RSA-PSS}
|
|||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-1, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-1, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-256, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
|
@ -612,10 +612,10 @@ Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-256, name: RSA-PS
|
|||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-256, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-256, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-256, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
|
@ -624,10 +624,10 @@ Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-256, name: RSA-PS
|
|||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-256, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-256, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-384, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
|
@ -636,10 +636,10 @@ Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-384, name: RSA-PS
|
|||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-384, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-384, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-384, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
|
@ -648,10 +648,10 @@ Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-384, name: RSA-PS
|
|||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-384, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-384, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-512, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
|
@ -660,10 +660,10 @@ Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-512, name: RSA-PS
|
|||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-512, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-512, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-512, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
|
@ -672,10 +672,10 @@ Fail Good parameters: 2048 bits (spki, buffer(294), {hash: SHA-512, name: RSA-PS
|
|||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-512, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 2048 bits (pkcs8, buffer(1218), {hash: SHA-512, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 2048 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 2048 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 2048 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-1, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
|
@ -684,10 +684,10 @@ Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-1, name: RSA-PSS}
|
|||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-1, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-1, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-1, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
|
@ -696,10 +696,10 @@ Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-1, name: RSA-PSS}
|
|||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-1, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-1, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-1, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-1, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-256, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
|
@ -708,10 +708,10 @@ Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-256, name: RSA-PS
|
|||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-256, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-256, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-256, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
|
@ -720,10 +720,10 @@ Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-256, name: RSA-PS
|
|||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-256, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-256, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-256, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-256, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-256, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-384, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
|
@ -732,10 +732,10 @@ Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-384, name: RSA-PS
|
|||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-384, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-384, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-384, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
|
@ -744,10 +744,10 @@ Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-384, name: RSA-PS
|
|||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-384, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-384, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-384, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-384, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-384, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-512, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, true, [verify])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
|
@ -756,10 +756,10 @@ Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-512, name: RSA-PS
|
|||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, true, [verify, verify])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-512, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-512, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, true, [sign])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, true, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Pass Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, true, [])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-512, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, false, [verify])
|
||||
Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
|
@ -768,10 +768,10 @@ Fail Good parameters: 4096 bits (spki, buffer(550), {hash: SHA-512, name: RSA-PS
|
|||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e), {hash: SHA-512, name: RSA-PSS}, false, [verify, verify])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-512, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 4096 bits (pkcs8, buffer(2376), {hash: SHA-512, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 4096 bits (pkcs8, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, false, [sign])
|
||||
Fail Good parameters: 4096 bits (jwk, object(kty, n, e, d, p, q, dp, dq, qi), {hash: SHA-512, name: RSA-PSS}, false, [sign, sign])
|
||||
Fail Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Pass Empty Usages: 4096 bits (jwk, object(spki, pkcs8, jwk), {hash: SHA-512, name: RSA-PSS}, false, [])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-1, name: RSASSA-PKCS1-v1_5}, true, [verify])
|
||||
Fail Good parameters: 1024 bits (jwk, object(kty, n, e), {hash: SHA-1, name: RSASSA-PKCS1-v1_5}, true, [verify])
|
||||
Fail Good parameters: 1024 bits (spki, buffer(162), {hash: SHA-1, name: RSASSA-PKCS1-v1_5}, true, [])
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 97 tests
|
||||
|
||||
97 Pass
|
||||
Pass setup
|
||||
Pass RSA-PSS with SHA-1 and no salt verification
|
||||
Pass RSA-PSS with SHA-256 and no salt verification
|
||||
Pass RSA-PSS with SHA-384 and no salt verification
|
||||
Pass RSA-PSS with SHA-512 and no salt verification
|
||||
Pass RSA-PSS with SHA-1, salted verification
|
||||
Pass RSA-PSS with SHA-256, salted verification
|
||||
Pass RSA-PSS with SHA-384, salted verification
|
||||
Pass RSA-PSS with SHA-512, salted verification
|
||||
Pass RSA-PSS with SHA-1 and no salt verification with altered signature after call
|
||||
Pass RSA-PSS with SHA-256 and no salt verification with altered signature after call
|
||||
Pass RSA-PSS with SHA-384 and no salt verification with altered signature after call
|
||||
Pass RSA-PSS with SHA-512 and no salt verification with altered signature after call
|
||||
Pass RSA-PSS with SHA-1, salted verification with altered signature after call
|
||||
Pass RSA-PSS with SHA-256, salted verification with altered signature after call
|
||||
Pass RSA-PSS with SHA-384, salted verification with altered signature after call
|
||||
Pass RSA-PSS with SHA-512, salted verification with altered signature after call
|
||||
Pass RSA-PSS with SHA-1 and no salt with altered plaintext after call
|
||||
Pass RSA-PSS with SHA-256 and no salt with altered plaintext after call
|
||||
Pass RSA-PSS with SHA-384 and no salt with altered plaintext after call
|
||||
Pass RSA-PSS with SHA-512 and no salt with altered plaintext after call
|
||||
Pass RSA-PSS with SHA-1, salted with altered plaintext after call
|
||||
Pass RSA-PSS with SHA-256, salted with altered plaintext after call
|
||||
Pass RSA-PSS with SHA-384, salted with altered plaintext after call
|
||||
Pass RSA-PSS with SHA-512, salted with altered plaintext after call
|
||||
Pass RSA-PSS with SHA-1 and no salt using privateKey to verify
|
||||
Pass RSA-PSS with SHA-256 and no salt using privateKey to verify
|
||||
Pass RSA-PSS with SHA-384 and no salt using privateKey to verify
|
||||
Pass RSA-PSS with SHA-512 and no salt using privateKey to verify
|
||||
Pass RSA-PSS with SHA-1, salted using privateKey to verify
|
||||
Pass RSA-PSS with SHA-256, salted using privateKey to verify
|
||||
Pass RSA-PSS with SHA-384, salted using privateKey to verify
|
||||
Pass RSA-PSS with SHA-512, salted using privateKey to verify
|
||||
Pass RSA-PSS with SHA-1 and no salt using publicKey to sign
|
||||
Pass RSA-PSS with SHA-256 and no salt using publicKey to sign
|
||||
Pass RSA-PSS with SHA-384 and no salt using publicKey to sign
|
||||
Pass RSA-PSS with SHA-512 and no salt using publicKey to sign
|
||||
Pass RSA-PSS with SHA-1, salted using publicKey to sign
|
||||
Pass RSA-PSS with SHA-256, salted using publicKey to sign
|
||||
Pass RSA-PSS with SHA-384, salted using publicKey to sign
|
||||
Pass RSA-PSS with SHA-512, salted using publicKey to sign
|
||||
Pass RSA-PSS with SHA-1 and no salt no verify usage
|
||||
Pass RSA-PSS with SHA-256 and no salt no verify usage
|
||||
Pass RSA-PSS with SHA-384 and no salt no verify usage
|
||||
Pass RSA-PSS with SHA-512 and no salt no verify usage
|
||||
Pass RSA-PSS with SHA-1, salted no verify usage
|
||||
Pass RSA-PSS with SHA-256, salted no verify usage
|
||||
Pass RSA-PSS with SHA-384, salted no verify usage
|
||||
Pass RSA-PSS with SHA-512, salted no verify usage
|
||||
Pass RSA-PSS with SHA-1 and no salt round trip
|
||||
Pass RSA-PSS with SHA-256 and no salt round trip
|
||||
Pass RSA-PSS with SHA-384 and no salt round trip
|
||||
Pass RSA-PSS with SHA-512 and no salt round trip
|
||||
Pass RSA-PSS with SHA-1, salted round trip
|
||||
Pass RSA-PSS with SHA-256, salted round trip
|
||||
Pass RSA-PSS with SHA-384, salted round trip
|
||||
Pass RSA-PSS with SHA-512, salted round trip
|
||||
Pass RSA-PSS with SHA-1 and no salt signing with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-256 and no salt signing with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-384 and no salt signing with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-512 and no salt signing with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-1, salted signing with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-256, salted signing with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-384, salted signing with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-512, salted signing with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-1 and no salt verification with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-256 and no salt verification with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-384 and no salt verification with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-512 and no salt verification with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-1, salted verification with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-256, salted verification with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-384, salted verification with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-512, salted verification with wrong algorithm name
|
||||
Pass RSA-PSS with SHA-1 and no salt verification failure with altered signature
|
||||
Pass RSA-PSS with SHA-256 and no salt verification failure with altered signature
|
||||
Pass RSA-PSS with SHA-384 and no salt verification failure with altered signature
|
||||
Pass RSA-PSS with SHA-512 and no salt verification failure with altered signature
|
||||
Pass RSA-PSS with SHA-1, salted verification failure with altered signature
|
||||
Pass RSA-PSS with SHA-256, salted verification failure with altered signature
|
||||
Pass RSA-PSS with SHA-384, salted verification failure with altered signature
|
||||
Pass RSA-PSS with SHA-512, salted verification failure with altered signature
|
||||
Pass RSA-PSS with SHA-1 and no salt verification failure with wrong saltLength
|
||||
Pass RSA-PSS with SHA-256 and no salt verification failure with wrong saltLength
|
||||
Pass RSA-PSS with SHA-384 and no salt verification failure with wrong saltLength
|
||||
Pass RSA-PSS with SHA-512 and no salt verification failure with wrong saltLength
|
||||
Pass RSA-PSS with SHA-1, salted verification failure with wrong saltLength
|
||||
Pass RSA-PSS with SHA-256, salted verification failure with wrong saltLength
|
||||
Pass RSA-PSS with SHA-384, salted verification failure with wrong saltLength
|
||||
Pass RSA-PSS with SHA-512, salted verification failure with wrong saltLength
|
||||
Pass RSA-PSS with SHA-1 and no salt verification failure with altered plaintext
|
||||
Pass RSA-PSS with SHA-256 and no salt verification failure with altered plaintext
|
||||
Pass RSA-PSS with SHA-384 and no salt verification failure with altered plaintext
|
||||
Pass RSA-PSS with SHA-512 and no salt verification failure with altered plaintext
|
||||
Pass RSA-PSS with SHA-1, salted verification failure with altered plaintext
|
||||
Pass RSA-PSS with SHA-256, salted verification failure with altered plaintext
|
||||
Pass RSA-PSS with SHA-384, salted verification failure with altered plaintext
|
||||
Pass RSA-PSS with SHA-512, salted verification failure with altered plaintext
|
|
@ -1,9 +1,12 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 309 tests
|
||||
Found 333 tests
|
||||
|
||||
309 Pass
|
||||
312 Pass
|
||||
21 Fail
|
||||
Pass setup
|
||||
Fail Can wrap and unwrap RSA-PSS public key keys using spki and RSA-OAEP
|
||||
Fail Can wrap and unwrap RSA-PSS public key keys using jwk and RSA-OAEP
|
||||
Pass Can wrap and unwrap RSA-OAEP public key keys using spki and RSA-OAEP
|
||||
Pass Can wrap and unwrap RSA-OAEP public key keys using jwk and RSA-OAEP
|
||||
Pass Can wrap and unwrap ECDSA public key keys using spki and RSA-OAEP
|
||||
|
@ -73,6 +76,13 @@ Pass Can wrap and unwrap HMAC keys as non-extractable using raw and RSA-OAEP
|
|||
Pass Can wrap and unwrap HMAC keys using jwk and RSA-OAEP
|
||||
Pass Can wrap and unwrap HMAC keys as non-extractable using jwk and RSA-OAEP
|
||||
Pass Can unwrap HMAC non-extractable keys using jwk and RSA-OAEP
|
||||
Fail Can wrap and unwrap RSA-PSS public key keys using spki and AES-CTR
|
||||
Fail Can wrap and unwrap RSA-PSS public key keys using jwk and AES-CTR
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys using pkcs8 and AES-CTR
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys as non-extractable using pkcs8 and AES-CTR
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys using jwk and AES-CTR
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys as non-extractable using jwk and AES-CTR
|
||||
Pass Can unwrap RSA-PSS private key non-extractable keys using jwk and AES-CTR
|
||||
Pass Can wrap and unwrap RSA-OAEP public key keys using spki and AES-CTR
|
||||
Pass Can wrap and unwrap RSA-OAEP public key keys using jwk and AES-CTR
|
||||
Pass Can wrap and unwrap RSA-OAEP private key keys using pkcs8 and AES-CTR
|
||||
|
@ -147,6 +157,13 @@ Pass Can wrap and unwrap HMAC keys as non-extractable using raw and AES-CTR
|
|||
Pass Can wrap and unwrap HMAC keys using jwk and AES-CTR
|
||||
Pass Can wrap and unwrap HMAC keys as non-extractable using jwk and AES-CTR
|
||||
Pass Can unwrap HMAC non-extractable keys using jwk and AES-CTR
|
||||
Fail Can wrap and unwrap RSA-PSS public key keys using spki and AES-CBC
|
||||
Fail Can wrap and unwrap RSA-PSS public key keys using jwk and AES-CBC
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys using pkcs8 and AES-CBC
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys as non-extractable using pkcs8 and AES-CBC
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys using jwk and AES-CBC
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys as non-extractable using jwk and AES-CBC
|
||||
Pass Can unwrap RSA-PSS private key non-extractable keys using jwk and AES-CBC
|
||||
Pass Can wrap and unwrap RSA-OAEP public key keys using spki and AES-CBC
|
||||
Pass Can wrap and unwrap RSA-OAEP public key keys using jwk and AES-CBC
|
||||
Pass Can wrap and unwrap RSA-OAEP private key keys using pkcs8 and AES-CBC
|
||||
|
@ -221,6 +238,13 @@ Pass Can wrap and unwrap HMAC keys as non-extractable using raw and AES-CBC
|
|||
Pass Can wrap and unwrap HMAC keys using jwk and AES-CBC
|
||||
Pass Can wrap and unwrap HMAC keys as non-extractable using jwk and AES-CBC
|
||||
Pass Can unwrap HMAC non-extractable keys using jwk and AES-CBC
|
||||
Fail Can wrap and unwrap RSA-PSS public key keys using spki and AES-GCM
|
||||
Fail Can wrap and unwrap RSA-PSS public key keys using jwk and AES-GCM
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys using pkcs8 and AES-GCM
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys as non-extractable using pkcs8 and AES-GCM
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys using jwk and AES-GCM
|
||||
Fail Can wrap and unwrap RSA-PSS private key keys as non-extractable using jwk and AES-GCM
|
||||
Pass Can unwrap RSA-PSS private key non-extractable keys using jwk and AES-GCM
|
||||
Pass Can wrap and unwrap RSA-OAEP public key keys using spki and AES-GCM
|
||||
Pass Can wrap and unwrap RSA-OAEP public key keys using jwk and AES-GCM
|
||||
Pass Can wrap and unwrap RSA-OAEP private key keys using pkcs8 and AES-GCM
|
||||
|
@ -295,6 +319,7 @@ Pass Can wrap and unwrap HMAC keys as non-extractable using raw and AES-GCM
|
|||
Pass Can wrap and unwrap HMAC keys using jwk and AES-GCM
|
||||
Pass Can wrap and unwrap HMAC keys as non-extractable using jwk and AES-GCM
|
||||
Pass Can unwrap HMAC non-extractable keys using jwk and AES-GCM
|
||||
Fail Can wrap and unwrap RSA-PSS public key keys using jwk and AES-KW
|
||||
Pass Can wrap and unwrap RSA-OAEP public key keys using jwk and AES-KW
|
||||
Pass Can wrap and unwrap Ed25519 private key keys using pkcs8 and AES-KW
|
||||
Pass Can wrap and unwrap Ed25519 private key keys as non-extractable using pkcs8 and AES-KW
|
||||
|
|
|
@ -0,0 +1,438 @@
|
|||
|
||||
function run_test() {
|
||||
setup({explicit_done: true});
|
||||
|
||||
var subtle = self.crypto.subtle; // Change to test prefixed implementations
|
||||
|
||||
// When are all these tests really done? When all the promises they use have resolved.
|
||||
var all_promises = [];
|
||||
|
||||
// Source file [algorithm_name]_vectors.js provides the getTestVectors method
|
||||
// for the algorithm that drives these tests.
|
||||
var testVectors = getTestVectors();
|
||||
|
||||
// Test verification first, because signing tests rely on that working
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.verify(vector.algorithm, vector.publicKey, vector.signature, vector.plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_true(is_verified, "Signature verified");
|
||||
}, function(err) {
|
||||
assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
|
||||
return operation;
|
||||
}, vector.name + " verification");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested verification.
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " verification");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Test verification with an altered buffer after call
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
var signature = copyBuffer(vector.signature);
|
||||
var operation = subtle.verify(vector.algorithm, vector.publicKey, signature, vector.plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_true(is_verified, "Signature verified");
|
||||
}, function(err) {
|
||||
assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
|
||||
signature[0] = 255 - signature[0];
|
||||
return operation;
|
||||
}, vector.name + " verification with altered signature after call");
|
||||
}, function(err) {
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " verification with altered signature after call");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for successful verification even if plaintext is altered after call.
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
var plaintext = copyBuffer(vector.plaintext);
|
||||
var operation = subtle.verify(vector.algorithm, vector.publicKey, vector.signature, plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_true(is_verified, "Signature verified");
|
||||
}, function(err) {
|
||||
assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
|
||||
plaintext[0] = 255 - plaintext[0];
|
||||
return operation;
|
||||
}, vector.name + " with altered plaintext after call");
|
||||
}, function(err) {
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " with altered plaintext after call");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for failures due to using privateKey to verify.
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
return subtle.verify(vector.algorithm, vector.privateKey, vector.signature, vector.plaintext)
|
||||
.then(function(plaintext) {
|
||||
assert_unreached("Should have thrown error for using privateKey to verify in " + vector.name + ": " + err.message + "'");
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'");
|
||||
});
|
||||
}, vector.name + " using privateKey to verify");
|
||||
|
||||
}, function(err) {
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " using privateKey to verify");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for failures due to using publicKey to sign.
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
return subtle.sign(vector.algorithm, vector.publicKey, vector.plaintext)
|
||||
.then(function(signature) {
|
||||
assert_unreached("Should have thrown error for using publicKey to sign in " + vector.name + ": " + err.message + "'");
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'");
|
||||
});
|
||||
}, vector.name + " using publicKey to sign");
|
||||
}, function(err) {
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " using publicKey to sign");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for failures due to no "verify" usage.
|
||||
testVectors.forEach(function(originalVector) {
|
||||
var vector = Object.assign({}, originalVector);
|
||||
|
||||
var promise = importVectorKeys(vector, [], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
return subtle.verify(vector.algorithm, vector.publicKey, vector.signature, vector.plaintext)
|
||||
.then(function(plaintext) {
|
||||
assert_unreached("Should have thrown error for no verify usage in " + vector.name + ": " + err.message + "'");
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'");
|
||||
});
|
||||
}, vector.name + " no verify usage");
|
||||
}, function(err) {
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " no verify usage");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Check for successful signing and verification.
|
||||
testVectors.forEach(function(vector) {
|
||||
// RSA signing is deterministic with PKCS#1 v1.5, or PSS with zero-length salts.
|
||||
const isDeterministic = !("saltLength" in vector.algorithm) || vector.algorithm.saltLength == 0;
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
return subtle.sign(vector.algorithm, vector.privateKey, vector.plaintext)
|
||||
.then(function(signature) {
|
||||
if (isDeterministic) {
|
||||
// If deterministic, we can check the output matches. Otherwise, we can only check it verifies.
|
||||
assert_true(equalBuffers(signature, vector.signature), "Signing did not give the expected output");
|
||||
}
|
||||
// Can we verify the new signature?
|
||||
return subtle.verify(vector.algorithm, vector.publicKey, signature, vector.plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_true(is_verified, "Round trip verifies");
|
||||
return signature;
|
||||
}, function(err) {
|
||||
assert_unreached("verify error for test " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
})
|
||||
.then(function(priorSignature) {
|
||||
// Will a second signing give us different signature? It should for PSS with non-empty salt
|
||||
return subtle.sign(vector.algorithm, vector.privateKey, vector.plaintext)
|
||||
.then(function(signature) {
|
||||
if (isDeterministic) {
|
||||
assert_true(equalBuffers(priorSignature, signature), "Two signings with empty salt give same signature")
|
||||
} else {
|
||||
assert_false(equalBuffers(priorSignature, signature), "Two signings with a salt give different signatures")
|
||||
}
|
||||
}, function(err) {
|
||||
assert_unreached("second time verify error for test " + vector.name + ": '" + err.message + "'");
|
||||
});
|
||||
}, function(err) {
|
||||
assert_unreached("sign error for test " + vector.name + ": '" + err.message + "'");
|
||||
});
|
||||
}, vector.name + " round trip");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested signing or verifying
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " round trip");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
|
||||
// Test signing with the wrong algorithm
|
||||
testVectors.forEach(function(vector) {
|
||||
// Want to get the key for the wrong algorithm
|
||||
var alteredVector = Object.assign({}, vector);
|
||||
alteredVector.algorithm = Object.assign({}, vector.algorithm);
|
||||
if (vector.algorithm.name === "RSA-PSS") {
|
||||
alteredVector.algorithm.name = "RSASSA-PKCS1-v1_5";
|
||||
} else {
|
||||
alteredVector.algorithm.name = "RSA-PSS";
|
||||
}
|
||||
|
||||
var promise = importVectorKeys(alteredVector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.sign(vector.algorithm, alteredVector.privateKey, vector.plaintext)
|
||||
.then(function(signature) {
|
||||
assert_unreached("Signing should not have succeeded for " + vector.name);
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'");
|
||||
});
|
||||
|
||||
return operation;
|
||||
}, vector.name + " signing with wrong algorithm name");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested verification.
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " signing with wrong algorithm name");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Test verification with the wrong algorithm
|
||||
testVectors.forEach(function(vector) {
|
||||
// Want to get the key for the wrong algorithm
|
||||
var alteredVector = Object.assign({}, vector);
|
||||
alteredVector.algorithm = Object.assign({}, vector.algorithm);
|
||||
if (vector.algorithm.name === "RSA-PSS") {
|
||||
alteredVector.algorithm.name = "RSASSA-PKCS1-v1_5";
|
||||
} else {
|
||||
alteredVector.algorithm.name = "RSA-PSS";
|
||||
}
|
||||
|
||||
var promise = importVectorKeys(alteredVector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
// Some tests are sign only
|
||||
if (!("signature" in vector)) {
|
||||
return;
|
||||
}
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.verify(vector.algorithm, alteredVector.publicKey, vector.signature, vector.plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_unreached("Verification should not have succeeded for " + vector.name);
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'");
|
||||
});
|
||||
|
||||
return operation;
|
||||
}, vector.name + " verification with wrong algorithm name");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested verification.
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " verification with wrong algorithm name");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Verification should fail with wrong signature
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
var signature = copyBuffer(vector.signature);
|
||||
signature[0] = 255 - signature[0];
|
||||
var operation = subtle.verify(vector.algorithm, vector.publicKey, signature, vector.plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_false(is_verified, "Signature NOT verified");
|
||||
}, function(err) {
|
||||
assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
|
||||
return operation;
|
||||
}, vector.name + " verification failure with altered signature");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested verification.
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " verification failure with altered signature");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// [RSA-PSS] Verification should fail with wrong saltLength
|
||||
testVectors.forEach(function(vector) {
|
||||
if (vector.algorithm.name === "RSA-PSS") {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
const saltLength = vector.algorithm.saltLength === 32 ? 48 : 32;
|
||||
var operation = subtle.verify({ ...vector.algorithm, saltLength }, vector.publicKey, vector.signature, vector.plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_false(is_verified, "Signature NOT verified");
|
||||
}, function(err) {
|
||||
assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
|
||||
return operation;
|
||||
}, vector.name + " verification failure with wrong saltLength");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested verification.
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " verification failure with wrong saltLength");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
}
|
||||
});
|
||||
|
||||
// Verification should fail with wrong plaintext
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
var plaintext = copyBuffer(vector.plaintext);
|
||||
plaintext[0] = 255 - plaintext[0];
|
||||
var operation = subtle.verify(vector.algorithm, vector.publicKey, vector.signature, plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_false(is_verified, "Signature NOT verified");
|
||||
}, function(err) {
|
||||
assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
|
||||
return operation;
|
||||
}, vector.name + " verification failure with altered plaintext");
|
||||
|
||||
}, function(err) {
|
||||
// We need a failed test if the importVectorKey operation fails, so
|
||||
// we know we never tested verification.
|
||||
promise_test(function(test) {
|
||||
assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''");
|
||||
}, "importVectorKeys step: " + vector.name + " verification failure with altered plaintext");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
|
||||
promise_test(function() {
|
||||
return Promise.all(all_promises)
|
||||
.then(function() {done();})
|
||||
.catch(function() {done();})
|
||||
}, "setup");
|
||||
|
||||
// A test vector has all needed fields for signing and verifying, EXCEPT that the
|
||||
// key field may be null. This function replaces that null with the Correct
|
||||
// CryptoKey object.
|
||||
//
|
||||
// Returns a Promise that yields an updated vector on success.
|
||||
function importVectorKeys(vector, publicKeyUsages, privateKeyUsages) {
|
||||
var publicPromise, privatePromise;
|
||||
|
||||
if (vector.publicKey !== null) {
|
||||
publicPromise = new Promise(function(resolve, reject) {
|
||||
resolve(vector);
|
||||
});
|
||||
} else {
|
||||
publicPromise = subtle.importKey(vector.publicKeyFormat, vector.publicKeyBuffer, {name: vector.algorithm.name, hash: vector.hash}, false, publicKeyUsages)
|
||||
.then(function(key) {
|
||||
vector.publicKey = key;
|
||||
return vector;
|
||||
}); // Returns a copy of the sourceBuffer it is sent.
|
||||
}
|
||||
|
||||
if (vector.privateKey !== null) {
|
||||
privatePromise = new Promise(function(resolve, reject) {
|
||||
resolve(vector);
|
||||
});
|
||||
} else {
|
||||
privatePromise = subtle.importKey(vector.privateKeyFormat, vector.privateKeyBuffer, {name: vector.algorithm.name, hash: vector.hash}, false, privateKeyUsages)
|
||||
.then(function(key) {
|
||||
vector.privateKey = key;
|
||||
return vector;
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.all([publicPromise, privatePromise]);
|
||||
}
|
||||
|
||||
// Returns a copy of the sourceBuffer it is sent.
|
||||
function copyBuffer(sourceBuffer) {
|
||||
var source = new Uint8Array(sourceBuffer);
|
||||
var copy = new Uint8Array(sourceBuffer.byteLength)
|
||||
|
||||
for (var i=0; i<source.byteLength; i++) {
|
||||
copy[i] = source[i];
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
function equalBuffers(a, b) {
|
||||
if (a.byteLength !== b.byteLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var aBytes = new Uint8Array(a);
|
||||
var bBytes = new Uint8Array(b);
|
||||
|
||||
for (var i=0; i<a.byteLength; i++) {
|
||||
if (aBytes[i] !== bBytes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>WebCryptoAPI: sign() and verify() Using RSA-PSS</title>
|
||||
<meta name="timeout" content="long">
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<script src="rsa_pss_vectors.js"></script>
|
||||
<script src="rsa.js"></script>
|
||||
<div id=log></div>
|
||||
<script src="../../WebCryptoAPI/sign_verify/rsa_pss.https.any.js"></script>
|
|
@ -0,0 +1,6 @@
|
|||
// META: title=WebCryptoAPI: sign() and verify() Using RSA-PSS
|
||||
// META: script=rsa_pss_vectors.js
|
||||
// META: script=rsa.js
|
||||
// META: timeout=long
|
||||
|
||||
run_test();
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue