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
302 lines
10 KiB
C++
302 lines
10 KiB
C++
// Copyright 2016 The Chromium Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#ifndef BSSL_PKI_OCSP_H_
|
|
#define BSSL_PKI_OCSP_H_
|
|
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <openssl/base.h>
|
|
#include <openssl/pki/ocsp.h>
|
|
|
|
#include "input.h"
|
|
#include "parse_values.h"
|
|
#include "parser.h"
|
|
#include "signature_algorithm.h"
|
|
|
|
BSSL_NAMESPACE_BEGIN
|
|
|
|
class ParsedCertificate;
|
|
|
|
// OCSPCertID contains a representation of a DER-encoded RFC 6960 "CertID".
|
|
//
|
|
// CertID ::= SEQUENCE {
|
|
// hashAlgorithm AlgorithmIdentifier,
|
|
// issuerNameHash OCTET STRING, -- Hash of issuer's DN
|
|
// issuerKeyHash OCTET STRING, -- Hash of issuer's public key
|
|
// serialNumber CertificateSerialNumber
|
|
// }
|
|
struct OPENSSL_EXPORT OCSPCertID {
|
|
OCSPCertID();
|
|
~OCSPCertID();
|
|
|
|
DigestAlgorithm hash_algorithm;
|
|
der::Input issuer_name_hash;
|
|
der::Input issuer_key_hash;
|
|
der::Input serial_number;
|
|
};
|
|
|
|
// OCSPCertStatus contains a representation of a DER-encoded RFC 6960
|
|
// "CertStatus". |revocation_time| and |has_reason| are only valid when
|
|
// |status| is REVOKED. |revocation_reason| is only valid when |has_reason| is
|
|
// true.
|
|
//
|
|
// CertStatus ::= CHOICE {
|
|
// good [0] IMPLICIT NULL,
|
|
// revoked [1] IMPLICIT RevokedInfo,
|
|
// unknown [2] IMPLICIT UnknownInfo
|
|
// }
|
|
//
|
|
// RevokedInfo ::= SEQUENCE {
|
|
// revocationTime GeneralizedTime,
|
|
// revocationReason [0] EXPLICIT CRLReason OPTIONAL
|
|
// }
|
|
//
|
|
// UnknownInfo ::= NULL
|
|
//
|
|
// CRLReason ::= ENUMERATED {
|
|
// unspecified (0),
|
|
// keyCompromise (1),
|
|
// cACompromise (2),
|
|
// affiliationChanged (3),
|
|
// superseded (4),
|
|
// cessationOfOperation (5),
|
|
// certificateHold (6),
|
|
// -- value 7 is not used
|
|
// removeFromCRL (8),
|
|
// privilegeWithdrawn (9),
|
|
// aACompromise (10)
|
|
// }
|
|
// (from RFC 5280)
|
|
struct OCSPCertStatus {
|
|
// Correspond to the values of CRLReason
|
|
enum class RevocationReason {
|
|
UNSPECIFIED = 0,
|
|
KEY_COMPROMISE = 1,
|
|
CA_COMPROMISE = 2,
|
|
AFFILIATION_CHANGED = 3,
|
|
SUPERSEDED = 4,
|
|
CESSATION_OF_OPERATION = 5,
|
|
CERTIFICATE_HOLD = 6,
|
|
UNUSED = 7,
|
|
REMOVE_FROM_CRL = 8,
|
|
PRIVILEGE_WITHDRAWN = 9,
|
|
AA_COMPROMISE = 10,
|
|
|
|
LAST = AA_COMPROMISE,
|
|
};
|
|
|
|
OCSPRevocationStatus status;
|
|
der::GeneralizedTime revocation_time;
|
|
bool has_reason;
|
|
RevocationReason revocation_reason;
|
|
};
|
|
|
|
// OCSPSingleResponse contains a representation of a DER-encoded RFC 6960
|
|
// "SingleResponse". The |cert_id_tlv| and |extensions| fields are pointers to
|
|
// the original object and are only valid as long as it is alive. They also
|
|
// aren't verified until they are parsed. |next_update| is only valid if
|
|
// |has_next_update| is true and |extensions| is only valid if |has_extensions|
|
|
// is true.
|
|
//
|
|
// SingleResponse ::= SEQUENCE {
|
|
// certID CertID,
|
|
// certStatus CertStatus,
|
|
// thisUpdate GeneralizedTime,
|
|
// nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
|
|
// singleExtensions [1] EXPLICIT Extensions OPTIONAL
|
|
// }
|
|
struct OPENSSL_EXPORT OCSPSingleResponse {
|
|
OCSPSingleResponse();
|
|
~OCSPSingleResponse();
|
|
|
|
der::Input cert_id_tlv;
|
|
OCSPCertStatus cert_status;
|
|
der::GeneralizedTime this_update;
|
|
bool has_next_update;
|
|
der::GeneralizedTime next_update;
|
|
bool has_extensions;
|
|
der::Input extensions;
|
|
};
|
|
|
|
// OCSPResponseData contains a representation of a DER-encoded RFC 6960
|
|
// "ResponseData". The |responses| and |extensions| fields are pointers to the
|
|
// original object and are only valid as long as it is alive. They also aren't
|
|
// verified until they are parsed into OCSPSingleResponse and ParsedExtensions.
|
|
// |extensions| is only valid if |has_extensions| is true.
|
|
//
|
|
// ResponseData ::= SEQUENCE {
|
|
// version [0] EXPLICIT Version DEFAULT v1,
|
|
// responderID ResponderID,
|
|
// producedAt GeneralizedTime,
|
|
// responses SEQUENCE OF SingleResponse,
|
|
// responseExtensions [1] EXPLICIT Extensions OPTIONAL
|
|
// }
|
|
struct OPENSSL_EXPORT OCSPResponseData {
|
|
enum class ResponderType { NAME, KEY_HASH };
|
|
|
|
struct ResponderID {
|
|
ResponderType type;
|
|
der::Input name;
|
|
der::Input key_hash;
|
|
};
|
|
|
|
OCSPResponseData();
|
|
~OCSPResponseData();
|
|
|
|
uint8_t version;
|
|
OCSPResponseData::ResponderID responder_id;
|
|
der::GeneralizedTime produced_at;
|
|
std::vector<der::Input> responses;
|
|
bool has_extensions;
|
|
der::Input extensions;
|
|
};
|
|
|
|
// OCSPResponse contains a representation of a DER-encoded RFC 6960
|
|
// "OCSPResponse" and the corresponding "BasicOCSPResponse". The |data| field
|
|
// is a pointer to the original object and are only valid as long is it is
|
|
// alive. The |data| field isn't verified until it is parsed into an
|
|
// OCSPResponseData. |data|, |signature_algorithm|, |signature|, and
|
|
// |has_certs| is only valid if |status| is SUCCESSFUL. |certs| is only valid
|
|
// if |has_certs| is true.
|
|
//
|
|
// OCSPResponse ::= SEQUENCE {
|
|
// responseStatus OCSPResponseStatus,
|
|
// responseBytes [0] EXPLICIT ResponseBytes OPTIONAL
|
|
// }
|
|
//
|
|
// ResponseBytes ::= SEQUENCE {
|
|
// responseType OBJECT IDENTIFIER,
|
|
// response OCTET STRING
|
|
// }
|
|
//
|
|
// BasicOCSPResponse ::= SEQUENCE {
|
|
// tbsResponseData ResponseData,
|
|
// signatureAlgorithm AlgorithmIdentifier,
|
|
// signature BIT STRING,
|
|
// certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
|
|
// }
|
|
//
|
|
// OCSPResponseStatus ::= ENUMERATED {
|
|
// successful (0), -- Response has valid confirmations
|
|
// malformedRequest (1), -- Illegal confirmation request
|
|
// internalError (2), -- Internal error in issuer
|
|
// tryLater (3), -- Try again later
|
|
// -- (4) is not used
|
|
// sigRequired (5), -- Must sign the request
|
|
// unauthorized (6) -- Request unauthorized
|
|
// }
|
|
struct OPENSSL_EXPORT OCSPResponse {
|
|
// Correspond to the values of OCSPResponseStatus
|
|
enum class ResponseStatus {
|
|
SUCCESSFUL = 0,
|
|
MALFORMED_REQUEST = 1,
|
|
INTERNAL_ERROR = 2,
|
|
TRY_LATER = 3,
|
|
UNUSED = 4,
|
|
SIG_REQUIRED = 5,
|
|
UNAUTHORIZED = 6,
|
|
|
|
LAST = UNAUTHORIZED,
|
|
};
|
|
|
|
OCSPResponse();
|
|
~OCSPResponse();
|
|
|
|
ResponseStatus status;
|
|
der::Input data;
|
|
SignatureAlgorithm signature_algorithm;
|
|
der::BitString signature;
|
|
bool has_certs;
|
|
std::vector<der::Input> certs;
|
|
};
|
|
|
|
// From RFC 6960:
|
|
//
|
|
// id-pkix-ocsp OBJECT IDENTIFIER ::= { id-ad-ocsp }
|
|
// id-pkix-ocsp-basic OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 }
|
|
//
|
|
// In dotted notation: 1.3.6.1.5.5.7.48.1.1
|
|
inline constexpr uint8_t kBasicOCSPResponseOid[] = {
|
|
0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01};
|
|
|
|
// Parses a DER-encoded OCSP "CertID" as specified by RFC 6960. Returns true on
|
|
// success and sets the results in |out|.
|
|
//
|
|
// On failure |out| has an undefined state. Some of its fields may have been
|
|
// updated during parsing, whereas others may not have been changed.
|
|
OPENSSL_EXPORT bool ParseOCSPCertID(der::Input raw_tlv, OCSPCertID *out);
|
|
|
|
// Parses a DER-encoded OCSP "SingleResponse" as specified by RFC 6960. Returns
|
|
// true on success and sets the results in |out|. The resulting |out|
|
|
// references data from |raw_tlv| and is only valid for the lifetime of
|
|
// |raw_tlv|.
|
|
//
|
|
// On failure |out| has an undefined state. Some of its fields may have been
|
|
// updated during parsing, whereas others may not have been changed.
|
|
OPENSSL_EXPORT bool ParseOCSPSingleResponse(der::Input raw_tlv,
|
|
OCSPSingleResponse *out);
|
|
|
|
// Parses a DER-encoded OCSP "ResponseData" as specified by RFC 6960. Returns
|
|
// true on success and sets the results in |out|. The resulting |out|
|
|
// references data from |raw_tlv| and is only valid for the lifetime of
|
|
// |raw_tlv|.
|
|
//
|
|
// On failure |out| has an undefined state. Some of its fields may have been
|
|
// updated during parsing, whereas others may not have been changed.
|
|
OPENSSL_EXPORT bool ParseOCSPResponseData(der::Input raw_tlv,
|
|
OCSPResponseData *out);
|
|
|
|
// Parses a DER-encoded "OCSPResponse" as specified by RFC 6960. Returns true
|
|
// on success and sets the results in |out|. The resulting |out|
|
|
// references data from |raw_tlv| and is only valid for the lifetime of
|
|
// |raw_tlv|.
|
|
//
|
|
// On failure |out| has an undefined state. Some of its fields may have been
|
|
// updated during parsing, whereas others may not have been changed.
|
|
OPENSSL_EXPORT bool ParseOCSPResponse(der::Input raw_tlv, OCSPResponse *out);
|
|
|
|
// Checks the revocation status of |certificate| by using the DER-encoded
|
|
// |raw_response|.
|
|
//
|
|
// Arguments are the same as above, except that it takes already parsed
|
|
// instances of the certificate and issuer certificate.
|
|
[[nodiscard]] OPENSSL_EXPORT OCSPRevocationStatus CheckOCSP(
|
|
std::string_view raw_response, const ParsedCertificate *certificate,
|
|
const ParsedCertificate *issuer_certificate,
|
|
int64_t verify_time_epoch_seconds, std::optional<int64_t> max_age_seconds,
|
|
OCSPVerifyResult::ResponseStatus *response_details);
|
|
|
|
// Creates a DER-encoded OCSPRequest for |cert|. The request is fairly basic:
|
|
// * No signature
|
|
// * No requestorName
|
|
// * No extensions
|
|
// * Uses SHA1 for all hashes.
|
|
//
|
|
// Returns true on success and fills |request_der| with the resulting bytes.
|
|
OPENSSL_EXPORT bool CreateOCSPRequest(const ParsedCertificate *cert,
|
|
const ParsedCertificate *issuer,
|
|
std::vector<uint8_t> *request_der);
|
|
|
|
// Creates a URL to issue a GET request for OCSP information for |cert|.
|
|
OPENSSL_EXPORT std::optional<std::string> CreateOCSPGetURL(
|
|
const ParsedCertificate *cert, const ParsedCertificate *issuer,
|
|
std::string_view ocsp_responder_url);
|
|
|
|
BSSL_NAMESPACE_END
|
|
|
|
#endif // BSSL_PKI_OCSP_H_
|