LibCrypto+LibWeb: Parse EC public key in parse_subject_public_key_info

Replicate what we are doing with RSA and parse both the private and
public key when parsing the ASN1.

The only thing that changed in the tests is the error message.
This commit is contained in:
devgianlu 2024-11-29 18:53:52 +01:00 committed by Andreas Kling
parent 1f7586ce14
commit 399b3d2430
Notes: github-actions[bot] 2024-11-30 10:18:40 +00:00
4 changed files with 32 additions and 52 deletions

View file

@ -335,6 +335,17 @@ ErrorOr<SubjectPublicKey> parse_subject_public_key_info(Crypto::ASN1::Decoder& d
EXIT_SCOPE();
return public_key;
}
if (public_key.algorithm.identifier.span() == ASN1::ec_public_key_encryption_oid.span()) {
auto maybe_key = Crypto::PK::EC::parse_ec_key(public_key.raw_key, false, current_scope);
if (maybe_key.is_error()) {
ERROR_WITH_SCOPE(maybe_key.release_error());
}
public_key.ec = move(maybe_key.release_value().public_key);
EXIT_SCOPE();
return public_key;
}
// https://datatracker.ietf.org/doc/html/rfc8410#section-9
// For all of the OIDs, the parameters MUST be absent.

View file

@ -92,6 +92,7 @@ struct Validity {
class SubjectPublicKey {
public:
Crypto::PK::RSAPublicKey<Crypto::UnsignedBigInteger> rsa;
Crypto::PK::ECPublicKey<Crypto::UnsignedBigInteger> ec;
AlgorithmIdentifier algorithm;
ByteBuffer raw_key;

View file

@ -2743,26 +2743,12 @@ WebIDL::ExceptionOr<GC::Ref<CryptoKey>> ECDH::import_key(AlgorithmParams const&
// 1. Let publicKey be the Elliptic Curve public key identified by performing
// the conversion steps defined in Section 2.3.4 of [SEC1] to the subjectPublicKey field of spki.
// The uncompressed point format MUST be supported.
auto public_key = spki.ec;
// 2. If the implementation does not support the compressed point format and a compressed point is provided, throw a DataError.
if (spki.raw_key[0] != 0x04)
return WebIDL::DataError::create(m_realm, "Unsupported key format"_string);
// 3. If a decode error occurs or an identity point is found, throw a DataError.
size_t coord_size;
if (named_curve == "P-256"sv)
coord_size = 32;
else if (named_curve == "P-384"sv)
coord_size = 48;
else if (named_curve == "P-521"sv)
coord_size = 66;
else
VERIFY_NOT_REACHED();
// 4. Let key be a new CryptoKey that represents publicKey.
auto public_key = ::Crypto::PK::ECPublicKey<> {
::Crypto::UnsignedBigInteger::import_data(spki.raw_key.data() + 1, coord_size),
::Crypto::UnsignedBigInteger::import_data(spki.raw_key.data() + 1 + coord_size, coord_size)
};
// NOTE: We already did this in parse_a_subject_public_key_info
key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { public_key });
} else {
// Otherwise:
@ -3047,36 +3033,18 @@ WebIDL::ExceptionOr<GC::Ref<CryptoKey>> ECDH::import_key(AlgorithmParams const&
if (normalized_algorithm.named_curve.is_one_of("P-256"sv, "P-384"sv, "P-521"sv)) {
auto key_bytes = key_data.get<ByteBuffer>();
size_t coord_size;
if (normalized_algorithm.named_curve == "P-256"sv)
coord_size = 32;
else if (normalized_algorithm.named_curve == "P-384"sv)
coord_size = 48;
else if (normalized_algorithm.named_curve == "P-521"sv)
coord_size = 66;
else
VERIFY_NOT_REACHED();
if (key_bytes.size() != 1 + 2 * coord_size)
return WebIDL::DataError::create(m_realm, "Invalid key size"_string);
// 1. Let Q be the Elliptic Curve public key on the curve identified by the namedCurve
// member of normalizedAlgorithm identified by performing the conversion steps
// defined in Section 2.3.4 of [SEC1] to keyData.
// The uncompressed point format MUST be supported.
// 2. If the implementation does not support the compressed point format and a compressed point is provided, throw a DataError.
if (key_bytes[0] != 0x04)
return WebIDL::DataError::create(m_realm, "Unsupported key format"_string);
// 3. If a decode error occurs or an identity point is found, throw a DataError.
// 4. Let key be a new CryptoKey that represents Q.
auto public_key = ::Crypto::PK::ECPublicKey<> {
::Crypto::UnsignedBigInteger::import_data(key_bytes.data() + 1, coord_size),
::Crypto::UnsignedBigInteger::import_data(key_bytes.data() + 1 + coord_size, coord_size)
};
auto maybe_public_key = ::Crypto::PK::EC::parse_ec_key(key_bytes, false, {});
if (maybe_public_key.is_error())
return WebIDL::DataError::create(m_realm, "Failed to parse key"_string);
key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { public_key });
// 4. Let key be a new CryptoKey that represents Q.
key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { maybe_public_key.release_value().public_key });
} else {
// Otherwise:
// 1. Perform any key import steps defined by other applicable specifications, passing format, keyData and obtaining key.

View file

@ -137,11 +137,11 @@ Fail Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDSA,
Fail Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDSA, namedCurve: P-521}, false, [sign, sign])
Fail Empty Usages: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDSA, namedCurve: P-521}, false, [])
Pass Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, true, [])
Optional Feature Unsupported Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDH, namedCurve: P-256}, true, []) Compressed point format not supported: DataError: Unsupported key format
Optional Feature Unsupported Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDH, namedCurve: P-256}, true, []) Compressed point format not supported: DataError: Error parsing subjectPublicKeyInfo: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: Unsupported public key format
Pass Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-256}, true, [])
Pass ECDH any JWK alg: P-256 bits (jwk, object(kty, crv, x, y, alg), {name: ECDH, namedCurve: P-256}, true, [])
Pass Good parameters: P-256 bits (raw, buffer(65), {name: ECDH, namedCurve: P-256}, true, [])
Optional Feature Unsupported Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDH, namedCurve: P-256}, true, []) Compressed point format not supported: DataError: Invalid key size
Optional Feature Unsupported Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDH, namedCurve: P-256}, true, []) Compressed point format not supported: DataError: Failed to parse key
Pass Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveKey])
Pass Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits, deriveKey])
Pass Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, true, [deriveBits])
@ -157,11 +157,11 @@ Pass Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, n
Pass ECDH any JWK alg: P-256 bits (jwk, object(kty, crv, x, y, d, alg), {name: ECDH, namedCurve: P-256}, true, [deriveKey, deriveBits, deriveKey, deriveBits])
Pass Empty Usages: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, true, [])
Pass Good parameters: P-256 bits (spki, buffer(91), {name: ECDH, namedCurve: P-256}, false, [])
Optional Feature Unsupported Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDH, namedCurve: P-256}, false, []) Compressed point format not supported: DataError: Unsupported key format
Optional Feature Unsupported Good parameters: P-256 bits (spki, buffer(59, compressed), {name: ECDH, namedCurve: P-256}, false, []) Compressed point format not supported: DataError: Error parsing subjectPublicKeyInfo: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: Unsupported public key format
Pass Good parameters: P-256 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-256}, false, [])
Pass ECDH any JWK alg: P-256 bits (jwk, object(kty, crv, x, y, alg), {name: ECDH, namedCurve: P-256}, false, [])
Pass Good parameters: P-256 bits (raw, buffer(65), {name: ECDH, namedCurve: P-256}, false, [])
Optional Feature Unsupported Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDH, namedCurve: P-256}, false, []) Compressed point format not supported: DataError: Invalid key size
Optional Feature Unsupported Good parameters: P-256 bits (raw, buffer(33, compressed), {name: ECDH, namedCurve: P-256}, false, []) Compressed point format not supported: DataError: Failed to parse key
Pass Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveKey])
Pass Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits, deriveKey])
Pass Good parameters: P-256 bits (pkcs8, buffer(138), {name: ECDH, namedCurve: P-256}, false, [deriveBits])
@ -177,11 +177,11 @@ Pass Good parameters: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, n
Pass ECDH any JWK alg: P-256 bits (jwk, object(kty, crv, x, y, d, alg), {name: ECDH, namedCurve: P-256}, false, [deriveKey, deriveBits, deriveKey, deriveBits])
Pass Empty Usages: P-256 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-256}, false, [])
Pass Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, true, [])
Optional Feature Unsupported Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDH, namedCurve: P-384}, true, []) Compressed point format not supported: DataError: Unsupported key format
Optional Feature Unsupported Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDH, namedCurve: P-384}, true, []) Compressed point format not supported: DataError: Error parsing subjectPublicKeyInfo: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: Unsupported public key format
Pass Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-384}, true, [])
Pass ECDH any JWK alg: P-384 bits (jwk, object(kty, crv, x, y, alg), {name: ECDH, namedCurve: P-384}, true, [])
Pass Good parameters: P-384 bits (raw, buffer(97), {name: ECDH, namedCurve: P-384}, true, [])
Optional Feature Unsupported Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDH, namedCurve: P-384}, true, []) Compressed point format not supported: DataError: Invalid key size
Optional Feature Unsupported Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDH, namedCurve: P-384}, true, []) Compressed point format not supported: DataError: Failed to parse key
Pass Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveKey])
Pass Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits, deriveKey])
Pass Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, true, [deriveBits])
@ -197,11 +197,11 @@ Pass Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, n
Pass ECDH any JWK alg: P-384 bits (jwk, object(kty, crv, x, y, d, alg), {name: ECDH, namedCurve: P-384}, true, [deriveKey, deriveBits, deriveKey, deriveBits])
Pass Empty Usages: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, true, [])
Pass Good parameters: P-384 bits (spki, buffer(120), {name: ECDH, namedCurve: P-384}, false, [])
Optional Feature Unsupported Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDH, namedCurve: P-384}, false, []) Compressed point format not supported: DataError: Unsupported key format
Optional Feature Unsupported Good parameters: P-384 bits (spki, buffer(72, compressed), {name: ECDH, namedCurve: P-384}, false, []) Compressed point format not supported: DataError: Error parsing subjectPublicKeyInfo: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: Unsupported public key format
Pass Good parameters: P-384 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-384}, false, [])
Pass ECDH any JWK alg: P-384 bits (jwk, object(kty, crv, x, y, alg), {name: ECDH, namedCurve: P-384}, false, [])
Pass Good parameters: P-384 bits (raw, buffer(97), {name: ECDH, namedCurve: P-384}, false, [])
Optional Feature Unsupported Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDH, namedCurve: P-384}, false, []) Compressed point format not supported: DataError: Invalid key size
Optional Feature Unsupported Good parameters: P-384 bits (raw, buffer(49, compressed), {name: ECDH, namedCurve: P-384}, false, []) Compressed point format not supported: DataError: Failed to parse key
Pass Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveKey])
Pass Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits, deriveKey])
Pass Good parameters: P-384 bits (pkcs8, buffer(185), {name: ECDH, namedCurve: P-384}, false, [deriveBits])
@ -217,11 +217,11 @@ Pass Good parameters: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, n
Pass ECDH any JWK alg: P-384 bits (jwk, object(kty, crv, x, y, d, alg), {name: ECDH, namedCurve: P-384}, false, [deriveKey, deriveBits, deriveKey, deriveBits])
Pass Empty Usages: P-384 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-384}, false, [])
Fail Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, true, [])
Optional Feature Unsupported Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, true, []) Compressed point format not supported: DataError: Unsupported key format
Optional Feature Unsupported Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, true, []) Compressed point format not supported: DataError: Error parsing subjectPublicKeyInfo: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: Unsupported public key format
Fail Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-521}, true, [])
Pass ECDH any JWK alg: P-521 bits (jwk, object(kty, crv, x, y, alg), {name: ECDH, namedCurve: P-521}, true, [])
Fail Good parameters: P-521 bits (raw, buffer(133), {name: ECDH, namedCurve: P-521}, true, [])
Optional Feature Unsupported Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDH, namedCurve: P-521}, true, []) Compressed point format not supported: DataError: Invalid key size
Optional Feature Unsupported Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDH, namedCurve: P-521}, true, []) Compressed point format not supported: DataError: Failed to parse key
Fail Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveKey])
Fail Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits, deriveKey])
Fail Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, true, [deriveBits])
@ -237,11 +237,11 @@ Fail Good parameters: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, n
Pass ECDH any JWK alg: P-521 bits (jwk, object(kty, crv, x, y, d, alg), {name: ECDH, namedCurve: P-521}, true, [deriveKey, deriveBits, deriveKey, deriveBits])
Pass Empty Usages: P-521 bits (jwk, object(kty, crv, x, y, d), {name: ECDH, namedCurve: P-521}, true, [])
Pass Good parameters: P-521 bits (spki, buffer(158), {name: ECDH, namedCurve: P-521}, false, [])
Optional Feature Unsupported Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, false, []) Compressed point format not supported: DataError: Unsupported key format
Optional Feature Unsupported Good parameters: P-521 bits (spki, buffer(90, compressed), {name: ECDH, namedCurve: P-521}, false, []) Compressed point format not supported: DataError: Error parsing subjectPublicKeyInfo: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: [ "SubjectPublicKeyInfo"sv ]: Unsupported public key format
Pass Good parameters: P-521 bits (jwk, object(kty, crv, x, y), {name: ECDH, namedCurve: P-521}, false, [])
Pass ECDH any JWK alg: P-521 bits (jwk, object(kty, crv, x, y, alg), {name: ECDH, namedCurve: P-521}, false, [])
Pass Good parameters: P-521 bits (raw, buffer(133), {name: ECDH, namedCurve: P-521}, false, [])
Optional Feature Unsupported Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDH, namedCurve: P-521}, false, []) Compressed point format not supported: DataError: Invalid key size
Optional Feature Unsupported Good parameters: P-521 bits (raw, buffer(67, compressed), {name: ECDH, namedCurve: P-521}, false, []) Compressed point format not supported: DataError: Failed to parse key
Pass Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveKey])
Pass Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits, deriveKey])
Pass Good parameters: P-521 bits (pkcs8, buffer(241), {name: ECDH, namedCurve: P-521}, false, [deriveBits])