Based on Nekogram. Key additions: - Rebrand to FoxiGram (app name, APK name, applicationId com.foxigram.app) - Embedded Xray (VLESS+Reality) proxy client via JNI libxray.so - Bundled hidden one-tap proxies (LTE + WiFi), read-only in UI - Auto-restore proxy on restart, rebind to active network (LTE/WiFi) - Server credentials externalized to git-ignored XrayServers.java (+ template) - libxray Go source included; compiled .so, keystore, google-services.json ignored
172 lines
6.7 KiB
C++
172 lines
6.7 KiB
C++
#ifndef BSSL_VERIFY_H_
|
|
#define BSSL_VERIFY_H_
|
|
|
|
#include <chrono>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <vector>
|
|
|
|
#include <openssl/pki/signature_verify_cache.h>
|
|
#include <openssl/pki/verify_error.h>
|
|
|
|
BSSL_NAMESPACE_BEGIN
|
|
|
|
class CertIssuerSourceStatic;
|
|
class TrustStoreInMemory;
|
|
class CertificateVerifyOptions;
|
|
class CertificateVerifyStatus;
|
|
|
|
class OPENSSL_EXPORT VerifyTrustStore {
|
|
public:
|
|
std::unique_ptr<TrustStoreInMemory> trust_store;
|
|
|
|
~VerifyTrustStore();
|
|
|
|
// FromDER returns a |TrustStore| derived from interpreting the |der_certs| as
|
|
// a bunch of DER-encoded certs, concatenated. In the event of a failure nullptr
|
|
// e is returned and a diagnostic string is placed in |out_diagnostic|
|
|
static std::unique_ptr<VerifyTrustStore> FromDER(
|
|
std::string_view der_certs, std::string *out_diagnostic);
|
|
|
|
// FromDER returns a |TrustStore| consisting of the supplied DER-encoded
|
|
// certs in |der_certs|. In the event of a failure nullptr is returned and a
|
|
// diagnostic string is placed in |out_diagnostic|
|
|
static std::unique_ptr<VerifyTrustStore> FromDER(
|
|
const std::vector<std::string_view> &der_certs,
|
|
std::string *out_diagnostic);
|
|
};
|
|
|
|
class OPENSSL_EXPORT CertPool {
|
|
public:
|
|
CertPool();
|
|
CertPool(const CertPool &) = delete;
|
|
CertPool &operator=(const CertPool &) = delete;
|
|
virtual ~CertPool();
|
|
|
|
// FromCerts returns a |CertPool| consisting of the supplied DER-encoded
|
|
// certs in |der_certs|. In the event of a failure nullptr is returned and a
|
|
// diagnostic string is placed in |out_diagnostic|
|
|
static std::unique_ptr<CertPool> FromCerts(
|
|
const std::vector<std::string_view> &der_certs,
|
|
std::string *out_diagnostic);
|
|
|
|
private:
|
|
friend std::optional<std::vector<std::vector<std::string>>>
|
|
CertificateVerifyInternal(const CertificateVerifyOptions &opts,
|
|
VerifyError *out_error,
|
|
CertificateVerifyStatus *out_status,
|
|
bool all_paths);
|
|
std::unique_ptr<CertIssuerSourceStatic> impl_;
|
|
};
|
|
|
|
// CertificateVerifyOptions contains all the options for a certificate verification.
|
|
class OPENSSL_EXPORT CertificateVerifyOptions {
|
|
public:
|
|
// The key purpose (extended key usage) to check for during verification.
|
|
enum class KeyPurpose {
|
|
ANY_EKU,
|
|
SERVER_AUTH,
|
|
CLIENT_AUTH,
|
|
SERVER_AUTH_STRICT,
|
|
CLIENT_AUTH_STRICT,
|
|
SERVER_AUTH_STRICT_LEAF,
|
|
CLIENT_AUTH_STRICT_LEAF,
|
|
RCS_MLS_CLIENT_AUTH,
|
|
};
|
|
|
|
CertificateVerifyOptions();
|
|
CertificateVerifyOptions(const CertificateVerifyOptions &) = delete;
|
|
CertificateVerifyOptions &operator=(const CertificateVerifyOptions &) =
|
|
delete;
|
|
|
|
KeyPurpose key_purpose = KeyPurpose::SERVER_AUTH;
|
|
std::string_view leaf_cert;
|
|
std::vector<std::string_view> intermediates;
|
|
|
|
// extra_intermediates optionally points to a pool of common intermediates.
|
|
const CertPool *extra_intermediates = nullptr;
|
|
// trust_store points to the set of root certificates to trust.
|
|
const VerifyTrustStore *trust_store = nullptr;
|
|
// min_rsa_modulus_length is the minimum acceptable RSA key size in a chain.
|
|
size_t min_rsa_modulus_length = 1024;
|
|
// time is the time in POSIX seconds since the POSIX epoch at which to
|
|
// validate the chain. It defaults to the current time if not set.
|
|
std::optional<int64_t> time;
|
|
// insecurely_allow_sha1 allows verification of signatures that use SHA-1
|
|
// message digests. This option is insecure and should not be used.
|
|
bool insecurely_allow_sha1 = false;
|
|
|
|
// max_iteration_count, if not zero, limits the number of times path building
|
|
// will try to append an intermediate to a potential path. This bounds the
|
|
// amount of time that a verification attempt can take, at the risk of
|
|
// rejecting cases that would be solved if only more effort were used.
|
|
uint32_t max_iteration_count = 0;
|
|
|
|
// Sets an optional deadline for completing path building. It defaults
|
|
// to std::chrono::time_point::max() if it not set. If |deadline| has a
|
|
// value that has passed based on comparison to
|
|
// std::chrono::steady_clock::now(), and path building has not completed,
|
|
// path building will stop. Note that this is not a hard limit, there is no
|
|
// guarantee how far past |deadline| time will be when path building is
|
|
// aborted.
|
|
std::optional<std::chrono::time_point<std::chrono::steady_clock>> deadline;
|
|
|
|
// max_path_building_depth, if not zero, limits the depth of the path that the
|
|
// path building algorithm attempts to build between leafs and roots. Using
|
|
// this comes at the risk of rejecting cases that would be solved if only one
|
|
// more certificate is added to the path.
|
|
uint32_t max_path_building_depth = 0;
|
|
|
|
// signature_verify_cache, if not nullptr, points to an object implementing a
|
|
// signature verification cache derived from
|
|
// <openssl/pki/signature_verify_cache.h>
|
|
SignatureVerifyCache *signature_verify_cache = nullptr;
|
|
};
|
|
|
|
// CertificateVerifyStatus describes the status of a certificate verification
|
|
// attempt.
|
|
class OPENSSL_EXPORT CertificateVerifyStatus {
|
|
public:
|
|
CertificateVerifyStatus();
|
|
|
|
// IterationCount returns the total number of attempted certificate additions
|
|
// to any potential path while performing path building for verification. It
|
|
// is the same value which may be bound by max_iteration_count in
|
|
// CertificateVerifyOptions.
|
|
size_t IterationCount() const;
|
|
|
|
// MaxDepthSeen returns the maximum path depth seen during path building.
|
|
size_t MaxDepthSeen() const;
|
|
|
|
private:
|
|
friend std::optional<std::vector<std::vector<std::string>>>
|
|
CertificateVerifyInternal(const CertificateVerifyOptions &opts,
|
|
VerifyError *out_error,
|
|
CertificateVerifyStatus *out_status,
|
|
bool all_paths);
|
|
size_t iteration_count_ = 0;
|
|
size_t max_depth_seen_ = 0;
|
|
};
|
|
|
|
// Verify verifies |opts.leaf_cert| using the other values in |opts|. It
|
|
// returns either an error, or else a validated chain from leaf to root.
|
|
//
|
|
// In the event of an error return, |out_error| will be updated with information
|
|
// about the error. It may be |nullptr|.
|
|
//
|
|
// Status information about the verification will be returned in |out_status|.
|
|
// It may be |nullptr|.
|
|
OPENSSL_EXPORT std::optional<std::vector<std::string>> CertificateVerify(
|
|
const CertificateVerifyOptions &opts, VerifyError *out_error = nullptr,
|
|
CertificateVerifyStatus *out_status = nullptr);
|
|
|
|
// VerifyAllPaths verifies |opts.leaf_cert| using the other values in |opts|,
|
|
// and returns all possible valid chains from the leaf to a root. If no chains
|
|
// exist, it returns an error.
|
|
OPENSSL_EXPORT std::optional<std::vector<std::vector<std::string>>>
|
|
CertificateVerifyAllPaths(const CertificateVerifyOptions &opts);
|
|
|
|
BSSL_NAMESPACE_END
|
|
|
|
#endif // BSSL_VERIFY_H_
|