Expose additional SSL certificate information.
- Provide access to the full certificate issuer chain (issue #1530) - Add several missing certificate error codes to cef_errorcode_t (issue #1784) - Provide the full certificate status bitmask (issue #1790)
This commit is contained in:
parent
07e845ed31
commit
12f19e3a33
|
@ -126,6 +126,24 @@ typedef struct _cef_sslinfo_t {
|
|||
///
|
||||
cef_base_t base;
|
||||
|
||||
///
|
||||
// Returns a bitmask containing any and all problems verifying the server
|
||||
// certificate.
|
||||
///
|
||||
cef_cert_status_t (CEF_CALLBACK *get_cert_status)(
|
||||
struct _cef_sslinfo_t* self);
|
||||
|
||||
///
|
||||
// Returns true (1) if the certificate status has any error, major or minor.
|
||||
///
|
||||
int (CEF_CALLBACK *is_cert_status_error)(struct _cef_sslinfo_t* self);
|
||||
|
||||
///
|
||||
// Returns true (1) if the certificate status represents only minor errors
|
||||
// (e.g. failure to verify certificate revocation).
|
||||
///
|
||||
int (CEF_CALLBACK *is_cert_status_minor_error)(struct _cef_sslinfo_t* self);
|
||||
|
||||
///
|
||||
// Returns the subject of the X.509 certificate. For HTTPS server certificates
|
||||
// this represents the web server. The common name of the subject should
|
||||
|
@ -170,6 +188,28 @@ typedef struct _cef_sslinfo_t {
|
|||
///
|
||||
struct _cef_binary_value_t* (CEF_CALLBACK *get_pemencoded)(
|
||||
struct _cef_sslinfo_t* self);
|
||||
|
||||
///
|
||||
// Returns the number of certificates in the issuer chain. If 0, the
|
||||
// certificate is self-signed.
|
||||
///
|
||||
size_t (CEF_CALLBACK *get_issuer_chain_size)(struct _cef_sslinfo_t* self);
|
||||
|
||||
///
|
||||
// Returns the DER encoded data for the certificate issuer chain. If we failed
|
||||
// to encode a certificate in the chain it is still present in the array but
|
||||
// is an NULL string.
|
||||
///
|
||||
void (CEF_CALLBACK *get_derencoded_issuer_chain)(struct _cef_sslinfo_t* self,
|
||||
size_t* chainCount, struct _cef_binary_value_t** chain);
|
||||
|
||||
///
|
||||
// Returns the PEM encoded data for the certificate issuer chain. If we failed
|
||||
// to encode a certificate in the chain it is still present in the array but
|
||||
// is an NULL string.
|
||||
///
|
||||
void (CEF_CALLBACK *get_pemencoded_issuer_chain)(struct _cef_sslinfo_t* self,
|
||||
size_t* chainCount, struct _cef_binary_value_t** chain);
|
||||
} cef_sslinfo_t;
|
||||
|
||||
|
||||
|
|
|
@ -111,6 +111,28 @@ class CefSSLCertPrincipal : public virtual CefBase {
|
|||
/*--cef(source=library)--*/
|
||||
class CefSSLInfo : public virtual CefBase {
|
||||
public:
|
||||
typedef std::vector<CefRefPtr<CefBinaryValue> > IssuerChainBinaryList;
|
||||
|
||||
///
|
||||
// Returns a bitmask containing any and all problems verifying the server
|
||||
// certificate.
|
||||
///
|
||||
/*--cef(default_retval=CERT_STATUS_NONE)--*/
|
||||
virtual cef_cert_status_t GetCertStatus() =0;
|
||||
|
||||
///
|
||||
// Returns true if the certificate status has any error, major or minor.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool IsCertStatusError() =0;
|
||||
|
||||
///
|
||||
// Returns true if the certificate status represents only minor errors
|
||||
// (e.g. failure to verify certificate revocation).
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool IsCertStatusMinorError() =0;
|
||||
|
||||
///
|
||||
// Returns the subject of the X.509 certificate. For HTTPS server
|
||||
// certificates this represents the web server. The common name of the
|
||||
|
@ -157,6 +179,29 @@ class CefSSLInfo : public virtual CefBase {
|
|||
///
|
||||
/*--cef()--*/
|
||||
virtual CefRefPtr<CefBinaryValue> GetPEMEncoded() =0;
|
||||
|
||||
///
|
||||
// Returns the number of certificates in the issuer chain.
|
||||
// If 0, the certificate is self-signed.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual size_t GetIssuerChainSize() =0;
|
||||
|
||||
///
|
||||
// Returns the DER encoded data for the certificate issuer chain.
|
||||
// If we failed to encode a certificate in the chain it is still
|
||||
// present in the array but is an empty string.
|
||||
///
|
||||
/*--cef(count_func=chain:GetIssuerChainSize)--*/
|
||||
virtual void GetDEREncodedIssuerChain(IssuerChainBinaryList& chain) =0;
|
||||
|
||||
///
|
||||
// Returns the PEM encoded data for the certificate issuer chain.
|
||||
// If we failed to encode a certificate in the chain it is still
|
||||
// present in the array but is an empty string.
|
||||
///
|
||||
/*--cef(count_func=chain:GetIssuerChainSize)--*/
|
||||
virtual void GetPEMEncodedIssuerChain(IssuerChainBinaryList& chain) =0;
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_SSL_INFO_H_
|
||||
|
|
|
@ -866,6 +866,7 @@ typedef enum {
|
|||
ERR_SSL_VERSION_OR_CIPHER_MISMATCH = -113,
|
||||
ERR_SSL_RENEGOTIATION_REQUESTED = -114,
|
||||
ERR_CERT_COMMON_NAME_INVALID = -200,
|
||||
ERR_CERT_BEGIN = ERR_CERT_COMMON_NAME_INVALID,
|
||||
ERR_CERT_DATE_INVALID = -201,
|
||||
ERR_CERT_AUTHORITY_INVALID = -202,
|
||||
ERR_CERT_CONTAINS_ERRORS = -203,
|
||||
|
@ -873,7 +874,13 @@ typedef enum {
|
|||
ERR_CERT_UNABLE_TO_CHECK_REVOCATION = -205,
|
||||
ERR_CERT_REVOKED = -206,
|
||||
ERR_CERT_INVALID = -207,
|
||||
ERR_CERT_END = -208,
|
||||
ERR_CERT_WEAK_SIGNATURE_ALGORITHM = -208,
|
||||
// -209 is available: was ERR_CERT_NOT_IN_DNS.
|
||||
ERR_CERT_NON_UNIQUE_NAME = -210,
|
||||
ERR_CERT_WEAK_KEY = -211,
|
||||
ERR_CERT_NAME_CONSTRAINT_VIOLATION = -212,
|
||||
ERR_CERT_VALIDITY_TOO_LONG = -213,
|
||||
ERR_CERT_END = ERR_CERT_VALIDITY_TOO_LONG,
|
||||
ERR_INVALID_URL = -300,
|
||||
ERR_DISALLOWED_URL_SCHEME = -301,
|
||||
ERR_UNKNOWN_URL_SCHEME = -302,
|
||||
|
@ -890,6 +897,38 @@ typedef enum {
|
|||
ERR_INSECURE_RESPONSE = -501,
|
||||
} cef_errorcode_t;
|
||||
|
||||
///
|
||||
// Supported certificate status code values. See net\cert\cert_status_flags.h
|
||||
// for more information. CERT_STATUS_NONE is new in CEF because we use an
|
||||
// enum while cert_status_flags.h uses a typedef and static const variables.
|
||||
///
|
||||
typedef enum {
|
||||
CERT_STATUS_NONE = 0,
|
||||
CERT_STATUS_COMMON_NAME_INVALID = 1 << 0,
|
||||
CERT_STATUS_DATE_INVALID = 1 << 1,
|
||||
CERT_STATUS_AUTHORITY_INVALID = 1 << 2,
|
||||
// 1 << 3 is reserved for ERR_CERT_CONTAINS_ERRORS (not useful with WinHTTP).
|
||||
CERT_STATUS_NO_REVOCATION_MECHANISM = 1 << 4,
|
||||
CERT_STATUS_UNABLE_TO_CHECK_REVOCATION = 1 << 5,
|
||||
CERT_STATUS_REVOKED = 1 << 6,
|
||||
CERT_STATUS_INVALID = 1 << 7,
|
||||
CERT_STATUS_WEAK_SIGNATURE_ALGORITHM = 1 << 8,
|
||||
// 1 << 9 was used for CERT_STATUS_NOT_IN_DNS
|
||||
CERT_STATUS_NON_UNIQUE_NAME = 1 << 10,
|
||||
CERT_STATUS_WEAK_KEY = 1 << 11,
|
||||
// 1 << 12 was used for CERT_STATUS_WEAK_DH_KEY
|
||||
CERT_STATUS_PINNED_KEY_MISSING = 1 << 13,
|
||||
CERT_STATUS_NAME_CONSTRAINT_VIOLATION = 1 << 14,
|
||||
CERT_STATUS_VALIDITY_TOO_LONG = 1 << 15,
|
||||
|
||||
// Bits 16 to 31 are for non-error statuses.
|
||||
CERT_STATUS_IS_EV = 1 << 16,
|
||||
CERT_STATUS_REV_CHECKING_ENABLED = 1 << 17,
|
||||
// Bit 18 was CERT_STATUS_IS_DNSSEC
|
||||
CERT_STATUS_SHA1_SIGNATURE_PRESENT = 1 << 19,
|
||||
CERT_STATUS_CT_COMPLIANCE_FAILED = 1 << 20,
|
||||
} cef_cert_status_t;
|
||||
|
||||
///
|
||||
// The manner in which a link click should be opened.
|
||||
///
|
||||
|
|
|
@ -6,10 +6,34 @@
|
|||
#include "libcef/browser/ssl_cert_principal_impl.h"
|
||||
#include "libcef/common/time_util.h"
|
||||
|
||||
#include "net/cert/cert_status_flags.h"
|
||||
#include "net/cert/x509_certificate.h"
|
||||
|
||||
CefSSLInfoImpl::CefSSLInfoImpl(const net::SSLInfo& value) {
|
||||
namespace {
|
||||
|
||||
void EncodeCertificate(
|
||||
const net::X509Certificate::OSCertHandle& os_handle,
|
||||
CefRefPtr<CefBinaryValue>& der_encoded,
|
||||
CefRefPtr<CefBinaryValue>& pem_encoded) {
|
||||
std::string encoded;
|
||||
if (net::X509Certificate::GetDEREncoded(os_handle, &encoded)) {
|
||||
der_encoded = CefBinaryValue::Create(encoded.c_str(),
|
||||
encoded.size());
|
||||
}
|
||||
encoded.clear();
|
||||
if (net::X509Certificate::GetPEMEncoded(os_handle, &encoded)) {
|
||||
pem_encoded = CefBinaryValue::Create(encoded.c_str(),
|
||||
encoded.size());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefSSLInfoImpl::CefSSLInfoImpl(const net::SSLInfo& value)
|
||||
: cert_status_(CERT_STATUS_NONE) {
|
||||
if (value.cert.get()) {
|
||||
cert_status_ = static_cast<cef_cert_status_t>(value.cert_status);
|
||||
|
||||
subject_ = new CefSSLCertPrincipalImpl(value.cert->subject());
|
||||
issuer_ = new CefSSLCertPrincipalImpl(value.cert->issuer());
|
||||
|
||||
|
@ -26,21 +50,36 @@ CefSSLInfoImpl::CefSSLInfoImpl(const net::SSLInfo& value) {
|
|||
cef_time_from_basetime(valid_expiry, valid_expiry_);
|
||||
|
||||
net::X509Certificate::OSCertHandle os_handle = value.cert->os_cert_handle();
|
||||
if (os_handle) {
|
||||
std::string encoded;
|
||||
if (value.cert->GetDEREncoded(os_handle, &encoded)) {
|
||||
der_encoded_ = CefBinaryValue::Create(encoded.c_str(),
|
||||
encoded.size());
|
||||
}
|
||||
encoded.clear();
|
||||
if (value.cert->GetPEMEncoded(os_handle, &encoded)) {
|
||||
pem_encoded_ = CefBinaryValue::Create(encoded.c_str(),
|
||||
encoded.size());
|
||||
}
|
||||
if (os_handle)
|
||||
EncodeCertificate(os_handle, der_encoded_, pem_encoded_);
|
||||
|
||||
const net::X509Certificate::OSCertHandles& issuer_chain =
|
||||
value.cert->GetIntermediateCertificates();
|
||||
for (net::X509Certificate::OSCertHandles::const_iterator it =
|
||||
issuer_chain.begin(); it != issuer_chain.end(); it++) {
|
||||
CefRefPtr<CefBinaryValue> der_encoded, pem_encoded;
|
||||
EncodeCertificate(*it, der_encoded, pem_encoded);
|
||||
|
||||
// Add each to the chain, even if one conversion unexpectedly failed.
|
||||
// GetIssuerChainSize depends on these being the same length.
|
||||
der_encoded_issuer_chain_.push_back(der_encoded);
|
||||
pem_encoded_issuer_chain_.push_back(pem_encoded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cef_cert_status_t CefSSLInfoImpl::GetCertStatus() {
|
||||
return cert_status_;
|
||||
}
|
||||
|
||||
bool CefSSLInfoImpl::IsCertStatusError() {
|
||||
return net::IsCertStatusError(cert_status_);
|
||||
}
|
||||
|
||||
bool CefSSLInfoImpl::IsCertStatusMinorError() {
|
||||
return net::IsCertStatusMinorError(cert_status_);
|
||||
}
|
||||
|
||||
CefRefPtr<CefSSLCertPrincipal> CefSSLInfoImpl::GetSubject() {
|
||||
return subject_;
|
||||
}
|
||||
|
@ -68,3 +107,17 @@ CefRefPtr<CefBinaryValue> CefSSLInfoImpl::GetDEREncoded() {
|
|||
CefRefPtr<CefBinaryValue> CefSSLInfoImpl::GetPEMEncoded() {
|
||||
return pem_encoded_;
|
||||
}
|
||||
|
||||
size_t CefSSLInfoImpl::GetIssuerChainSize() {
|
||||
return der_encoded_issuer_chain_.size();
|
||||
}
|
||||
|
||||
void CefSSLInfoImpl::GetDEREncodedIssuerChain(
|
||||
CefSSLInfo::IssuerChainBinaryList& chain) {
|
||||
chain = der_encoded_issuer_chain_;
|
||||
}
|
||||
|
||||
void CefSSLInfoImpl::GetPEMEncodedIssuerChain(
|
||||
CefSSLInfo::IssuerChainBinaryList& chain) {
|
||||
chain = pem_encoded_issuer_chain_;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ class CefSSLInfoImpl : public CefSSLInfo {
|
|||
explicit CefSSLInfoImpl(const net::SSLInfo& value);
|
||||
|
||||
// CefSSLInfo methods.
|
||||
cef_cert_status_t GetCertStatus() override;
|
||||
bool IsCertStatusError() override;
|
||||
bool IsCertStatusMinorError() override;
|
||||
CefRefPtr<CefSSLCertPrincipal> GetSubject() override;
|
||||
CefRefPtr<CefSSLCertPrincipal> GetIssuer() override;
|
||||
CefRefPtr<CefBinaryValue> GetSerialNumber() override;
|
||||
|
@ -23,8 +26,12 @@ class CefSSLInfoImpl : public CefSSLInfo {
|
|||
CefTime GetValidExpiry() override;
|
||||
CefRefPtr<CefBinaryValue> GetDEREncoded() override;
|
||||
CefRefPtr<CefBinaryValue> GetPEMEncoded() override;
|
||||
size_t GetIssuerChainSize() override;
|
||||
void GetDEREncodedIssuerChain(IssuerChainBinaryList& chain) override;
|
||||
void GetPEMEncodedIssuerChain(IssuerChainBinaryList& chain) override;
|
||||
|
||||
private:
|
||||
cef_cert_status_t cert_status_;
|
||||
CefRefPtr<CefSSLCertPrincipal> subject_;
|
||||
CefRefPtr<CefSSLCertPrincipal> issuer_;
|
||||
CefRefPtr<CefBinaryValue> serial_number_;
|
||||
|
@ -32,6 +39,8 @@ class CefSSLInfoImpl : public CefSSLInfo {
|
|||
CefTime valid_expiry_;
|
||||
CefRefPtr<CefBinaryValue> der_encoded_;
|
||||
CefRefPtr<CefBinaryValue> pem_encoded_;
|
||||
IssuerChainBinaryList der_encoded_issuer_chain_;
|
||||
IssuerChainBinaryList pem_encoded_issuer_chain_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CefSSLInfoImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefSSLInfoImpl);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
// for more information.
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
#include "libcef_dll/cpptoc/binary_value_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/sslcert_principal_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/sslinfo_cpptoc.h"
|
||||
|
@ -19,6 +20,50 @@ namespace {
|
|||
|
||||
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||
|
||||
cef_cert_status_t CEF_CALLBACK sslinfo_get_cert_status(
|
||||
struct _cef_sslinfo_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return CERT_STATUS_NONE;
|
||||
|
||||
// Execute
|
||||
cef_cert_status_t _retval = CefSSLInfoCppToC::Get(self)->GetCertStatus();
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK sslinfo_is_cert_status_error(struct _cef_sslinfo_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
bool _retval = CefSSLInfoCppToC::Get(self)->IsCertStatusError();
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK sslinfo_is_cert_status_minor_error(
|
||||
struct _cef_sslinfo_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
bool _retval = CefSSLInfoCppToC::Get(self)->IsCertStatusMinorError();
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
cef_sslcert_principal_t* CEF_CALLBACK sslinfo_get_subject(
|
||||
struct _cef_sslinfo_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
@ -127,12 +172,101 @@ struct _cef_binary_value_t* CEF_CALLBACK sslinfo_get_pemencoded(
|
|||
return CefBinaryValueCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
size_t CEF_CALLBACK sslinfo_get_issuer_chain_size(struct _cef_sslinfo_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
size_t _retval = CefSSLInfoCppToC::Get(self)->GetIssuerChainSize();
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void CEF_CALLBACK sslinfo_get_derencoded_issuer_chain(
|
||||
struct _cef_sslinfo_t* self, size_t* chainCount,
|
||||
struct _cef_binary_value_t** chain) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: chain; type: refptr_vec_same_byref
|
||||
DCHECK(chainCount && (*chainCount == 0 || chain));
|
||||
if (!chainCount || (*chainCount > 0 && !chain))
|
||||
return;
|
||||
|
||||
// Translate param: chain; type: refptr_vec_same_byref
|
||||
std::vector<CefRefPtr<CefBinaryValue> > chainList;
|
||||
if (chainCount && *chainCount > 0 && chain) {
|
||||
for (size_t i = 0; i < *chainCount; ++i) {
|
||||
chainList.push_back(CefBinaryValueCppToC::Unwrap(chain[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
CefSSLInfoCppToC::Get(self)->GetDEREncodedIssuerChain(
|
||||
chainList);
|
||||
|
||||
// Restore param: chain; type: refptr_vec_same_byref
|
||||
if (chainCount && chain) {
|
||||
*chainCount = std::min(chainList.size(), *chainCount);
|
||||
if (*chainCount > 0) {
|
||||
for (size_t i = 0; i < *chainCount; ++i) {
|
||||
chain[i] = CefBinaryValueCppToC::Wrap(chainList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CEF_CALLBACK sslinfo_get_pemencoded_issuer_chain(
|
||||
struct _cef_sslinfo_t* self, size_t* chainCount,
|
||||
struct _cef_binary_value_t** chain) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: chain; type: refptr_vec_same_byref
|
||||
DCHECK(chainCount && (*chainCount == 0 || chain));
|
||||
if (!chainCount || (*chainCount > 0 && !chain))
|
||||
return;
|
||||
|
||||
// Translate param: chain; type: refptr_vec_same_byref
|
||||
std::vector<CefRefPtr<CefBinaryValue> > chainList;
|
||||
if (chainCount && *chainCount > 0 && chain) {
|
||||
for (size_t i = 0; i < *chainCount; ++i) {
|
||||
chainList.push_back(CefBinaryValueCppToC::Unwrap(chain[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
CefSSLInfoCppToC::Get(self)->GetPEMEncodedIssuerChain(
|
||||
chainList);
|
||||
|
||||
// Restore param: chain; type: refptr_vec_same_byref
|
||||
if (chainCount && chain) {
|
||||
*chainCount = std::min(chainList.size(), *chainCount);
|
||||
if (*chainCount > 0) {
|
||||
for (size_t i = 0; i < *chainCount; ++i) {
|
||||
chain[i] = CefBinaryValueCppToC::Wrap(chainList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefSSLInfoCppToC::CefSSLInfoCppToC() {
|
||||
GetStruct()->get_cert_status = sslinfo_get_cert_status;
|
||||
GetStruct()->is_cert_status_error = sslinfo_is_cert_status_error;
|
||||
GetStruct()->is_cert_status_minor_error = sslinfo_is_cert_status_minor_error;
|
||||
GetStruct()->get_subject = sslinfo_get_subject;
|
||||
GetStruct()->get_issuer = sslinfo_get_issuer;
|
||||
GetStruct()->get_serial_number = sslinfo_get_serial_number;
|
||||
|
@ -140,6 +274,11 @@ CefSSLInfoCppToC::CefSSLInfoCppToC() {
|
|||
GetStruct()->get_valid_expiry = sslinfo_get_valid_expiry;
|
||||
GetStruct()->get_derencoded = sslinfo_get_derencoded;
|
||||
GetStruct()->get_pemencoded = sslinfo_get_pemencoded;
|
||||
GetStruct()->get_issuer_chain_size = sslinfo_get_issuer_chain_size;
|
||||
GetStruct()->get_derencoded_issuer_chain =
|
||||
sslinfo_get_derencoded_issuer_chain;
|
||||
GetStruct()->get_pemencoded_issuer_chain =
|
||||
sslinfo_get_pemencoded_issuer_chain;
|
||||
}
|
||||
|
||||
template<> CefRefPtr<CefSSLInfo> CefCppToC<CefSSLInfoCppToC, CefSSLInfo,
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
// for more information.
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
#include "libcef_dll/ctocpp/binary_value_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/sslcert_principal_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/sslinfo_ctocpp.h"
|
||||
|
@ -17,6 +18,48 @@
|
|||
|
||||
// VIRTUAL METHODS - Body may be edited by hand.
|
||||
|
||||
cef_cert_status_t CefSSLInfoCToCpp::GetCertStatus() {
|
||||
cef_sslinfo_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_cert_status))
|
||||
return CERT_STATUS_NONE;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
cef_cert_status_t _retval = _struct->get_cert_status(_struct);
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
bool CefSSLInfoCToCpp::IsCertStatusError() {
|
||||
cef_sslinfo_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, is_cert_status_error))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->is_cert_status_error(_struct);
|
||||
|
||||
// Return type: bool
|
||||
return _retval?true:false;
|
||||
}
|
||||
|
||||
bool CefSSLInfoCToCpp::IsCertStatusMinorError() {
|
||||
cef_sslinfo_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, is_cert_status_minor_error))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->is_cert_status_minor_error(_struct);
|
||||
|
||||
// Return type: bool
|
||||
return _retval?true:false;
|
||||
}
|
||||
|
||||
CefRefPtr<CefSSLCertPrincipal> CefSSLInfoCToCpp::GetSubject() {
|
||||
cef_sslinfo_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_subject))
|
||||
|
@ -115,6 +158,98 @@ CefRefPtr<CefBinaryValue> CefSSLInfoCToCpp::GetPEMEncoded() {
|
|||
return CefBinaryValueCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
size_t CefSSLInfoCToCpp::GetIssuerChainSize() {
|
||||
cef_sslinfo_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_issuer_chain_size))
|
||||
return 0;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
size_t _retval = _struct->get_issuer_chain_size(_struct);
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void CefSSLInfoCToCpp::GetDEREncodedIssuerChain(IssuerChainBinaryList& chain) {
|
||||
cef_sslinfo_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_derencoded_issuer_chain))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Translate param: chain; type: refptr_vec_same_byref
|
||||
size_t chainSize = chain.size();
|
||||
size_t chainCount = std::max(GetIssuerChainSize(), chainSize);
|
||||
cef_binary_value_t** chainList = NULL;
|
||||
if (chainCount > 0) {
|
||||
chainList = new cef_binary_value_t*[chainCount];
|
||||
DCHECK(chainList);
|
||||
if (chainList) {
|
||||
memset(chainList, 0, sizeof(cef_binary_value_t*)*chainCount);
|
||||
}
|
||||
if (chainList && chainSize > 0) {
|
||||
for (size_t i = 0; i < chainSize; ++i) {
|
||||
chainList[i] = CefBinaryValueCToCpp::Unwrap(chain[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
_struct->get_derencoded_issuer_chain(_struct,
|
||||
&chainCount,
|
||||
chainList);
|
||||
|
||||
// Restore param:chain; type: refptr_vec_same_byref
|
||||
chain.clear();
|
||||
if (chainCount > 0 && chainList) {
|
||||
for (size_t i = 0; i < chainCount; ++i) {
|
||||
chain.push_back(CefBinaryValueCToCpp::Wrap(chainList[i]));
|
||||
}
|
||||
delete [] chainList;
|
||||
}
|
||||
}
|
||||
|
||||
void CefSSLInfoCToCpp::GetPEMEncodedIssuerChain(IssuerChainBinaryList& chain) {
|
||||
cef_sslinfo_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_pemencoded_issuer_chain))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Translate param: chain; type: refptr_vec_same_byref
|
||||
size_t chainSize = chain.size();
|
||||
size_t chainCount = std::max(GetIssuerChainSize(), chainSize);
|
||||
cef_binary_value_t** chainList = NULL;
|
||||
if (chainCount > 0) {
|
||||
chainList = new cef_binary_value_t*[chainCount];
|
||||
DCHECK(chainList);
|
||||
if (chainList) {
|
||||
memset(chainList, 0, sizeof(cef_binary_value_t*)*chainCount);
|
||||
}
|
||||
if (chainList && chainSize > 0) {
|
||||
for (size_t i = 0; i < chainSize; ++i) {
|
||||
chainList[i] = CefBinaryValueCToCpp::Unwrap(chain[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
_struct->get_pemencoded_issuer_chain(_struct,
|
||||
&chainCount,
|
||||
chainList);
|
||||
|
||||
// Restore param:chain; type: refptr_vec_same_byref
|
||||
chain.clear();
|
||||
if (chainCount > 0 && chainList) {
|
||||
for (size_t i = 0; i < chainCount; ++i) {
|
||||
chain.push_back(CefBinaryValueCToCpp::Wrap(chainList[i]));
|
||||
}
|
||||
delete [] chainList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@ class CefSSLInfoCToCpp
|
|||
CefSSLInfoCToCpp();
|
||||
|
||||
// CefSSLInfo methods.
|
||||
cef_cert_status_t GetCertStatus() OVERRIDE;
|
||||
bool IsCertStatusError() OVERRIDE;
|
||||
bool IsCertStatusMinorError() OVERRIDE;
|
||||
CefRefPtr<CefSSLCertPrincipal> GetSubject() OVERRIDE;
|
||||
CefRefPtr<CefSSLCertPrincipal> GetIssuer() OVERRIDE;
|
||||
CefRefPtr<CefBinaryValue> GetSerialNumber() OVERRIDE;
|
||||
|
@ -37,6 +40,9 @@ class CefSSLInfoCToCpp
|
|||
CefTime GetValidExpiry() OVERRIDE;
|
||||
CefRefPtr<CefBinaryValue> GetDEREncoded() OVERRIDE;
|
||||
CefRefPtr<CefBinaryValue> GetPEMEncoded() OVERRIDE;
|
||||
size_t GetIssuerChainSize() OVERRIDE;
|
||||
void GetDEREncodedIssuerChain(IssuerChainBinaryList& chain) OVERRIDE;
|
||||
void GetPEMEncodedIssuerChain(IssuerChainBinaryList& chain) OVERRIDE;
|
||||
};
|
||||
|
||||
#endif // USING_CEF_SHARED
|
||||
|
|
|
@ -82,6 +82,33 @@ std::string GetBinaryString(CefRefPtr<CefBinaryValue> value) {
|
|||
return CefBase64Encode(src.data(), src.size());
|
||||
}
|
||||
|
||||
std::string GetCertStatusString(cef_cert_status_t status) {
|
||||
#define FLAG(flag) if (status & flag) result += std::string(#flag) + "<br/>"
|
||||
std::string result;
|
||||
|
||||
FLAG(CERT_STATUS_COMMON_NAME_INVALID);
|
||||
FLAG(CERT_STATUS_DATE_INVALID);
|
||||
FLAG(CERT_STATUS_AUTHORITY_INVALID);
|
||||
FLAG(CERT_STATUS_NO_REVOCATION_MECHANISM);
|
||||
FLAG(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION);
|
||||
FLAG(CERT_STATUS_REVOKED);
|
||||
FLAG(CERT_STATUS_INVALID);
|
||||
FLAG(CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
|
||||
FLAG(CERT_STATUS_NON_UNIQUE_NAME);
|
||||
FLAG(CERT_STATUS_WEAK_KEY);
|
||||
FLAG(CERT_STATUS_PINNED_KEY_MISSING);
|
||||
FLAG(CERT_STATUS_NAME_CONSTRAINT_VIOLATION);
|
||||
FLAG(CERT_STATUS_VALIDITY_TOO_LONG);
|
||||
FLAG(CERT_STATUS_IS_EV);
|
||||
FLAG(CERT_STATUS_REV_CHECKING_ENABLED);
|
||||
FLAG(CERT_STATUS_SHA1_SIGNATURE_PRESENT);
|
||||
FLAG(CERT_STATUS_CT_COMPLIANCE_FAILED);
|
||||
|
||||
if (result.empty())
|
||||
return " ";
|
||||
return result;
|
||||
}
|
||||
|
||||
// Load a data: URI containing the error message.
|
||||
void LoadErrorPage(CefRefPtr<CefFrame> frame,
|
||||
const std::string& failed_url,
|
||||
|
@ -539,7 +566,8 @@ bool ClientHandler::OnCertificateError(
|
|||
CefRefPtr<CefSSLCertPrincipal> subject = ssl_info->GetSubject();
|
||||
CefRefPtr<CefSSLCertPrincipal> issuer = ssl_info->GetIssuer();
|
||||
|
||||
// Build a table showing certificate information.
|
||||
// Build a table showing certificate information. Various types of invalid
|
||||
// certificates can be tested using https://badssl.com/.
|
||||
std::stringstream ss;
|
||||
ss << "X.509 Certificate Information:"
|
||||
"<table border=1><tr><th>Field</th><th>Value</th></tr>" <<
|
||||
|
@ -551,17 +579,32 @@ bool ClientHandler::OnCertificateError(
|
|||
"</td></tr>"
|
||||
"<tr><td>Serial #*</td><td>" <<
|
||||
GetBinaryString(ssl_info->GetSerialNumber()) << "</td></tr>"
|
||||
"<tr><td>Status</td><td>" <<
|
||||
GetCertStatusString(ssl_info->GetCertStatus()) << "</td></tr>"
|
||||
"<tr><td>Valid Start</td><td>" <<
|
||||
GetTimeString(ssl_info->GetValidStart()) << "</td></tr>"
|
||||
"<tr><td>Valid Expiry</td><td>" <<
|
||||
GetTimeString(ssl_info->GetValidExpiry()) << "</td></tr>"
|
||||
"<tr><td>DER Encoded*</td>"
|
||||
"<td style=\"max-width:800px;overflow:scroll;\">" <<
|
||||
GetBinaryString(ssl_info->GetDEREncoded()) << "</td></tr>"
|
||||
"<tr><td>PEM Encoded*</td>"
|
||||
"<td style=\"max-width:800px;overflow:scroll;\">" <<
|
||||
GetBinaryString(ssl_info->GetPEMEncoded()) << "</td></tr>"
|
||||
"</table> * Displayed value is base64 encoded.";
|
||||
GetTimeString(ssl_info->GetValidExpiry()) << "</td></tr>";
|
||||
|
||||
CefSSLInfo::IssuerChainBinaryList der_chain_list;
|
||||
CefSSLInfo::IssuerChainBinaryList pem_chain_list;
|
||||
ssl_info->GetDEREncodedIssuerChain(der_chain_list);
|
||||
ssl_info->GetPEMEncodedIssuerChain(pem_chain_list);
|
||||
DCHECK_EQ(der_chain_list.size(), pem_chain_list.size());
|
||||
|
||||
der_chain_list.insert(der_chain_list.begin(), ssl_info->GetDEREncoded());
|
||||
pem_chain_list.insert(pem_chain_list.begin(), ssl_info->GetPEMEncoded());
|
||||
|
||||
for (size_t i = 0U; i < der_chain_list.size(); ++i) {
|
||||
ss << "<tr><td>DER Encoded*</td>"
|
||||
"<td style=\"max-width:800px;overflow:scroll;\">" <<
|
||||
GetBinaryString(der_chain_list[i]) << "</td></tr>"
|
||||
"<tr><td>PEM Encoded*</td>"
|
||||
"<td style=\"max-width:800px;overflow:scroll;\">" <<
|
||||
GetBinaryString(pem_chain_list[i]) << "</td></tr>";
|
||||
}
|
||||
|
||||
ss << "</table> * Displayed value is base64 encoded.";
|
||||
|
||||
// Load the error page.
|
||||
LoadErrorPage(browser->GetMainFrame(), request_url, cert_error, ss.str());
|
||||
|
|
Loading…
Reference in New Issue