summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorstelar7 <dudedbz@gmail.com>2023-04-12 21:35:06 +0200
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2023-04-15 09:03:47 +0330
commit4043c89310c6c99a3848a359d6a18539fefbbead (patch)
treeb0cd3e8bb1b1815ad0c5798db07cf4bfcd3a2c2b /Userland/Libraries
parent0329ddf46a0d24303fac5954bf3c70d5f3fe577c (diff)
downloadserenity-4043c89310c6c99a3848a359d6a18539fefbbead.zip
LibTLS: Change CertificateKeyAlgorithm from enum to struct
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibCrypto/Hash/HashManager.h1
-rw-r--r--Userland/Libraries/LibTLS/Certificate.cpp119
-rw-r--r--Userland/Libraries/LibTLS/Certificate.h85
-rw-r--r--Userland/Libraries/LibTLS/TLSv12.cpp26
4 files changed, 97 insertions, 134 deletions
diff --git a/Userland/Libraries/LibCrypto/Hash/HashManager.h b/Userland/Libraries/LibCrypto/Hash/HashManager.h
index b9a1670f45..e23a14dbdf 100644
--- a/Userland/Libraries/LibCrypto/Hash/HashManager.h
+++ b/Userland/Libraries/LibCrypto/Hash/HashManager.h
@@ -18,6 +18,7 @@ namespace Crypto {
namespace Hash {
enum class HashKind {
+ Unknown,
None,
SHA1,
SHA256,
diff --git a/Userland/Libraries/LibTLS/Certificate.cpp b/Userland/Libraries/LibTLS/Certificate.cpp
index f857d22c38..839538cc74 100644
--- a/Userland/Libraries/LibTLS/Certificate.cpp
+++ b/Userland/Libraries/LibTLS/Certificate.cpp
@@ -11,51 +11,9 @@
#include <LibCrypto/ASN1/ASN1.h>
#include <LibCrypto/ASN1/DER.h>
#include <LibCrypto/ASN1/PEM.h>
-#include <LibTLS/Extensions.h>
namespace TLS {
-constexpr static Array<int, 7>
- rsa_encryption_oid { 1, 2, 840, 113549, 1, 1, 1 },
- rsa_md5_encryption_oid { 1, 2, 840, 113549, 1, 1, 4 },
- rsa_sha1_encryption_oid { 1, 2, 840, 113549, 1, 1, 5 },
- rsa_sha256_encryption_oid { 1, 2, 840, 113549, 1, 1, 11 },
- rsa_sha384_encryption_oid { 1, 2, 840, 113549, 1, 1, 12 },
- rsa_sha512_encryption_oid { 1, 2, 840, 113549, 1, 1, 13 },
- rsa_sha224_encryption_oid { 1, 2, 840, 113549, 1, 1, 14 },
- ecdsa_with_sha224_encryption_oid { 1, 2, 840, 10045, 4, 3, 1 },
- ecdsa_with_sha256_encryption_oid { 1, 2, 840, 10045, 4, 3, 2 },
- ecdsa_with_sha384_encryption_oid { 1, 2, 840, 10045, 4, 3, 3 },
- ecdsa_with_sha512_encryption_oid { 1, 2, 840, 10045, 4, 3, 3 },
- ec_public_key_encryption_oid { 1, 2, 840, 10045, 2, 1 };
-
-constexpr static Array<Array<int, 7>, 9> known_algorithm_identifiers {
- rsa_encryption_oid,
- rsa_md5_encryption_oid,
- rsa_sha1_encryption_oid,
- rsa_sha256_encryption_oid,
- rsa_sha384_encryption_oid,
- rsa_sha512_encryption_oid,
- ecdsa_with_sha256_encryption_oid,
- ecdsa_with_sha384_encryption_oid,
- ec_public_key_encryption_oid
-};
-
-constexpr static Array<int, 7>
- curve_ansip384r1 { 1, 3, 132, 0, 34 },
- curve_prime256 { 1, 2, 840, 10045, 3, 1, 7 };
-
-constexpr static Array<Array<int, 7>, 9> known_curve_identifiers {
- curve_ansip384r1,
- curve_prime256
-};
-
-constexpr static Array<int, 4>
- key_usage_oid { 2, 5, 29, 15 },
- subject_alternative_name_oid { 2, 5, 29, 17 },
- issuer_alternative_name_oid { 2, 5, 29, 18 },
- basic_constraints_oid { 2, 5, 29, 19 };
-
#define ERROR_WITH_SCOPE(error) \
do { \
return Error::from_string_view(TRY(String::formatted("{}: {}", current_scope, error))); \
@@ -122,34 +80,6 @@ static ErrorOr<SupportedGroup> oid_to_curve(Vector<int> curve)
return Error::from_string_view(TRY(String::formatted("Unknown curve oid {}", curve)));
}
-static ErrorOr<CertificateKeyAlgorithm> oid_to_algorithm(Vector<int> algorithm)
-{
- if (algorithm == rsa_encryption_oid)
- return CertificateKeyAlgorithm::RSA_RSA;
- else if (algorithm == rsa_md5_encryption_oid)
- return CertificateKeyAlgorithm::RSA_MD5;
- else if (algorithm == rsa_sha1_encryption_oid)
- return CertificateKeyAlgorithm::RSA_SHA1;
- else if (algorithm == rsa_sha256_encryption_oid)
- return CertificateKeyAlgorithm::RSA_SHA256;
- else if (algorithm == rsa_sha384_encryption_oid)
- return CertificateKeyAlgorithm::RSA_SHA384;
- else if (algorithm == rsa_sha512_encryption_oid)
- return CertificateKeyAlgorithm::RSA_SHA512;
- else if (algorithm == rsa_sha224_encryption_oid)
- return CertificateKeyAlgorithm::RSA_SHA224;
- else if (algorithm == ecdsa_with_sha224_encryption_oid)
- return CertificateKeyAlgorithm::ECDSA_SHA224;
- else if (algorithm == ecdsa_with_sha256_encryption_oid)
- return CertificateKeyAlgorithm::ECDSA_SHA256;
- else if (algorithm == ecdsa_with_sha384_encryption_oid)
- return CertificateKeyAlgorithm::ECDSA_SHA384;
- else if (algorithm == ecdsa_with_sha512_encryption_oid)
- return CertificateKeyAlgorithm::ECDSA_SHA512;
-
- return Error::from_string_view(TRY(String::formatted("Unknown algorithm oid {}", algorithm)));
-}
-
static ErrorOr<Crypto::UnsignedBigInteger> parse_version(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
{
// Version ::= INTEGER {v1(0), v2(1), v3(2)}
@@ -203,7 +133,7 @@ static ErrorOr<SupportedGroup> parse_ec_parameters(Crypto::ASN1::Decoder& decode
return oid_to_curve(named_curve);
}
-static ErrorOr<CertificateKeyAlgorithm> parse_algorithm_identifier(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
+static ErrorOr<AlgorithmIdentifier> parse_algorithm_identifier(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
{
// AlgorithmIdentifier{ALGORITHM:SupportedAlgorithms} ::= SEQUENCE {
// algorithm ALGORITHM.&id({SupportedAlgorithms}),
@@ -264,7 +194,7 @@ static ErrorOr<CertificateKeyAlgorithm> parse_algorithm_identifier(Crypto::ASN1:
POP_SCOPE();
EXIT_SCOPE();
- return oid_to_algorithm(algorithm);
+ return AlgorithmIdentifier(algorithm);
}
// When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or
@@ -288,7 +218,7 @@ static ErrorOr<CertificateKeyAlgorithm> parse_algorithm_identifier(Crypto::ASN1:
if (is_no_parameter_algorithm) {
EXIT_SCOPE();
- return oid_to_algorithm(algorithm);
+ return AlgorithmIdentifier(algorithm);
}
if (algorithm.span() == ec_public_key_encryption_oid.span()) {
@@ -297,7 +227,7 @@ static ErrorOr<CertificateKeyAlgorithm> parse_algorithm_identifier(Crypto::ASN1:
if (decoder.eof()) {
EXIT_SCOPE();
- return oid_to_algorithm(algorithm);
+ return AlgorithmIdentifier(algorithm);
}
auto tag = TRY(decoder.peek());
@@ -308,16 +238,14 @@ static ErrorOr<CertificateKeyAlgorithm> parse_algorithm_identifier(Crypto::ASN1:
POP_SCOPE();
EXIT_SCOPE();
- return oid_to_algorithm(algorithm);
+ return AlgorithmIdentifier(algorithm);
}
- auto ec_parameters = TRY(parse_ec_parameters(decoder, current_scope));
- EXIT_SCOPE();
+ auto algorithm_identifier = AlgorithmIdentifier(algorithm);
+ algorithm_identifier.ec_parameters = TRY(parse_ec_parameters(decoder, current_scope));
- if (ec_parameters == SupportedGroup::SECP256R1)
- return CertificateKeyAlgorithm::ECDSA_SECP256R1;
- else if (ec_parameters == SupportedGroup::SECP384R1)
- return CertificateKeyAlgorithm::ECDSA_SECP384R1;
+ EXIT_SCOPE();
+ return algorithm_identifier;
}
ERROR_WITH_SCOPE(TRY(String::formatted("Unhandled parameters for algorithm {}", algorithm)));
@@ -432,27 +360,29 @@ static ErrorOr<SubjectPublicKey> parse_subject_public_key_info(Crypto::ASN1::Dec
READ_OBJECT(BitString, Crypto::ASN1::BitStringView, value);
POP_SCOPE();
- switch (public_key.algorithm) {
- case CertificateKeyAlgorithm::ECDSA_SECP256R1:
- case CertificateKeyAlgorithm::ECDSA_SECP384R1: {
- public_key.raw_key = TRY(ByteBuffer::copy(value.raw_bytes()));
- break;
- }
- case CertificateKeyAlgorithm::RSA_RSA: {
- public_key.raw_key = TRY(ByteBuffer::copy(value.raw_bytes()));
+ public_key.raw_key = TRY(ByteBuffer::copy(value.raw_bytes()));
+
+ if (public_key.algorithm.identifier.span() == rsa_encryption_oid.span()) {
auto key = Crypto::PK::RSA::parse_rsa_key(value.raw_bytes());
if (!key.public_key.length()) {
return Error::from_string_literal("Invalid RSA key");
}
public_key.rsa = move(key.public_key);
- break;
- }
- default: {
- ERROR_WITH_SCOPE(TRY(String::formatted("Unknown algorithm {}", static_cast<u8>(public_key.algorithm))));
+
+ EXIT_SCOPE();
+ return public_key;
}
+
+ if (public_key.algorithm.identifier.span() == ec_public_key_encryption_oid.span()) {
+ // Note: Raw key is already stored, so we can just exit out at this point.
+ EXIT_SCOPE();
+ return public_key;
}
+ String algo_oid = TRY(String::join("."sv, public_key.algorithm.identifier));
+ ERROR_WITH_SCOPE(TRY(String::formatted("Unhandled algorithm {}", algo_oid)));
+
EXIT_SCOPE();
return public_key;
}
@@ -822,8 +752,7 @@ ErrorOr<Certificate> Certificate::parse_certificate(ReadonlyBytes buffer, bool)
Certificate certificate = TRY(parse_tbs_certificate(decoder, current_scope));
certificate.original_asn1 = TRY(ByteBuffer::copy(buffer));
- CertificateKeyAlgorithm signature_algorithm = TRY(parse_algorithm_identifier(decoder, current_scope));
- certificate.signature_algorithm = signature_algorithm;
+ certificate.signature_algorithm = TRY(parse_algorithm_identifier(decoder, current_scope));
PUSH_SCOPE("signature"sv);
READ_OBJECT(BitString, Crypto::ASN1::BitStringView, signature);
diff --git a/Userland/Libraries/LibTLS/Certificate.h b/Userland/Libraries/LibTLS/Certificate.h
index 464809fe43..612c7ca11a 100644
--- a/Userland/Libraries/LibTLS/Certificate.h
+++ b/Userland/Libraries/LibTLS/Certificate.h
@@ -15,9 +15,51 @@
#include <LibCore/DateTime.h>
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
#include <LibCrypto/PK/RSA.h>
+#include <LibTLS/Extensions.h>
namespace TLS {
+constexpr static Array<int, 7>
+ rsa_encryption_oid { 1, 2, 840, 113549, 1, 1, 1 },
+ rsa_md5_encryption_oid { 1, 2, 840, 113549, 1, 1, 4 },
+ rsa_sha1_encryption_oid { 1, 2, 840, 113549, 1, 1, 5 },
+ rsa_sha256_encryption_oid { 1, 2, 840, 113549, 1, 1, 11 },
+ rsa_sha384_encryption_oid { 1, 2, 840, 113549, 1, 1, 12 },
+ rsa_sha512_encryption_oid { 1, 2, 840, 113549, 1, 1, 13 },
+ rsa_sha224_encryption_oid { 1, 2, 840, 113549, 1, 1, 14 },
+ ecdsa_with_sha224_encryption_oid { 1, 2, 840, 10045, 4, 3, 1 },
+ ecdsa_with_sha256_encryption_oid { 1, 2, 840, 10045, 4, 3, 2 },
+ ecdsa_with_sha384_encryption_oid { 1, 2, 840, 10045, 4, 3, 3 },
+ ecdsa_with_sha512_encryption_oid { 1, 2, 840, 10045, 4, 3, 3 },
+ ec_public_key_encryption_oid { 1, 2, 840, 10045, 2, 1 };
+
+constexpr static Array<Array<int, 7>, 9> known_algorithm_identifiers {
+ rsa_encryption_oid,
+ rsa_md5_encryption_oid,
+ rsa_sha1_encryption_oid,
+ rsa_sha256_encryption_oid,
+ rsa_sha384_encryption_oid,
+ rsa_sha512_encryption_oid,
+ ecdsa_with_sha256_encryption_oid,
+ ecdsa_with_sha384_encryption_oid,
+ ec_public_key_encryption_oid
+};
+
+constexpr static Array<int, 7>
+ curve_ansip384r1 { 1, 3, 132, 0, 34 },
+ curve_prime256 { 1, 2, 840, 10045, 3, 1, 7 };
+
+constexpr static Array<Array<int, 7>, 9> known_curve_identifiers {
+ curve_ansip384r1,
+ curve_prime256
+};
+
+constexpr static Array<int, 4>
+ key_usage_oid { 2, 5, 29, 15 },
+ subject_alternative_name_oid { 2, 5, 29, 17 },
+ issuer_alternative_name_oid { 2, 5, 29, 18 },
+ basic_constraints_oid { 2, 5, 29, 19 };
+
#define _ENUM(key, value) key,
#define __ENUM_OBJECT_CLASS \
@@ -129,28 +171,18 @@ constexpr static StringView enum_value(AttributeType object_class)
#undef __ENUM_ATTRIBUTE_TYPE
}
-enum class CertificateKeyAlgorithm : u8 {
- Unsupported = 0x00,
- RSA_RSA = 0x01,
- RSA_MD2 = 0x2,
- RSA_MD4 = 0x3,
- RSA_MD5 = 0x04,
- RSA_SHA1 = 0x05,
- RSA_OAEP = 0x6,
- RSAES_OAEP = 0x7,
- RSA_MGF1 = 0x8,
- RSA_SPECIFIED = 0x9,
- RSA_PSS = 0xa,
- RSA_SHA256 = 0x0b,
- RSA_SHA384 = 0x0c,
- RSA_SHA512 = 0x0d,
- RSA_SHA224 = 0xe,
- ECDSA_SHA224 = 0x10,
- ECDSA_SHA256 = 0x11,
- ECDSA_SHA384 = 0x12,
- ECDSA_SHA512 = 0x13,
- ECDSA_SECP256R1 = 0x14,
- ECDSA_SECP384R1 = 0x15,
+struct AlgorithmIdentifier {
+ AlgorithmIdentifier()
+ {
+ }
+
+ explicit AlgorithmIdentifier(Vector<int, 9> identifier)
+ : identifier(identifier)
+ {
+ }
+
+ Vector<int, 9> identifier;
+ SupportedGroup ec_parameters {};
};
struct BasicConstraints {
@@ -215,16 +247,15 @@ class SubjectPublicKey {
public:
Crypto::PK::RSAPublicKey<Crypto::UnsignedBigInteger> rsa;
- CertificateKeyAlgorithm algorithm { CertificateKeyAlgorithm::Unsupported };
+ AlgorithmIdentifier algorithm;
ByteBuffer raw_key;
};
class Certificate {
public:
u16 version { 0 };
- CertificateKeyAlgorithm algorithm { CertificateKeyAlgorithm::Unsupported };
- CertificateKeyAlgorithm ec_algorithm { CertificateKeyAlgorithm::Unsupported };
- SubjectPublicKey public_key {};
+ AlgorithmIdentifier algorithm;
+ SubjectPublicKey public_key;
ByteBuffer exponent {};
Crypto::PK::RSAPrivateKey<Crypto::UnsignedBigInteger> private_key {};
RelativeDistinguishedName issuer, subject;
@@ -237,7 +268,7 @@ public:
ByteBuffer fingerprint {};
ByteBuffer der {};
ByteBuffer data {};
- CertificateKeyAlgorithm signature_algorithm { CertificateKeyAlgorithm::Unsupported };
+ AlgorithmIdentifier signature_algorithm;
ByteBuffer signature_value {};
ByteBuffer original_asn1 {};
bool is_allowed_to_sign_certificate { false };
diff --git a/Userland/Libraries/LibTLS/TLSv12.cpp b/Userland/Libraries/LibTLS/TLSv12.cpp
index 4f0b785b03..caf762f065 100644
--- a/Userland/Libraries/LibTLS/TLSv12.cpp
+++ b/Userland/Libraries/LibTLS/TLSv12.cpp
@@ -344,22 +344,24 @@ bool Context::verify_chain(StringView host) const
bool Context::verify_certificate_pair(Certificate const& subject, Certificate const& issuer) const
{
- Crypto::Hash::HashKind kind;
- switch (subject.signature_algorithm) {
- case CertificateKeyAlgorithm::RSA_SHA1:
+ Crypto::Hash::HashKind kind = Crypto::Hash::HashKind::Unknown;
+ auto identifier = subject.signature_algorithm.identifier;
+
+ if (identifier == rsa_encryption_oid)
+ kind = Crypto::Hash::HashKind::None;
+ if (identifier == rsa_md5_encryption_oid)
+ kind = Crypto::Hash::HashKind::MD5;
+ if (identifier == rsa_sha1_encryption_oid)
kind = Crypto::Hash::HashKind::SHA1;
- break;
- case CertificateKeyAlgorithm::RSA_SHA256:
+ if (identifier == rsa_sha256_encryption_oid)
kind = Crypto::Hash::HashKind::SHA256;
- break;
- case CertificateKeyAlgorithm::RSA_SHA384:
+ if (identifier == rsa_sha384_encryption_oid)
kind = Crypto::Hash::HashKind::SHA384;
- break;
- case CertificateKeyAlgorithm::RSA_SHA512:
+ if (identifier == rsa_sha512_encryption_oid)
kind = Crypto::Hash::HashKind::SHA512;
- break;
- default:
- dbgln("verify_certificate_pair: Unknown signature algorithm, expected RSA with SHA1/256/384/512, got {}", (u8)subject.signature_algorithm);
+
+ if (kind == Crypto::Hash::HashKind::Unknown) {
+ dbgln("verify_certificate_pair: Unknown signature algorithm, expected RSA with SHA1/256/384/512, got OID {}", identifier);
return false;
}