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:
Marshall Greenblatt 2015-12-18 13:03:03 -05:00
parent 07e845ed31
commit 12f19e3a33
9 changed files with 531 additions and 22 deletions

View File

@ -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;

View File

@ -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_

View File

@ -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.
///

View File

@ -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_;
}

View File

@ -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);

View File

@ -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,

View File

@ -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.

View File

@ -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

View File

@ -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 "&nbsp;";
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());