24#include <opendht/infohash.h>
25#include <dhtnet/certstore.h>
47#include <sys/socket.h>
48#include <netinet/tcp.h>
49#include <netinet/in.h>
53#define close(x) closesocket(x)
79 TlsValidator::checkCallback = {{
105 TlsValidator::getterCallback = {{
134 TlsValidator::enforcedCheckType = {{
136 CheckValuesType::BOOLEAN,
137 CheckValuesType::BOOLEAN,
138 CheckValuesType::BOOLEAN,
139 CheckValuesType::BOOLEAN,
140 CheckValuesType::BOOLEAN,
141 CheckValuesType::BOOLEAN,
142 CheckValuesType::BOOLEAN,
143 CheckValuesType::BOOLEAN,
144 CheckValuesType::BOOLEAN,
145 CheckValuesType::BOOLEAN,
146 CheckValuesType::BOOLEAN,
147 CheckValuesType::BOOLEAN,
148 CheckValuesType::BOOLEAN,
149 CheckValuesType::BOOLEAN,
150 CheckValuesType::BOOLEAN,
151 CheckValuesType::BOOLEAN,
152 CheckValuesType::BOOLEAN,
153 CheckValuesType::BOOLEAN,
154 CheckValuesType::BOOLEAN,
155 CheckValuesType::BOOLEAN,
156 CheckValuesType::BOOLEAN,
222 TlsValidator::acceptedCheckValuesResult = {{
224 {{
true,
true,
true,
false,
false,
false}},
225 {{
false,
false,
true,
true,
false,
false}},
226 {{
false,
false,
true,
false,
true,
false}},
227 {{
false,
false,
true,
false,
false,
true}},
235 const std::string& certificate,
238 const std::string&
caList)
239 : certStore_(certStore)
240 , certificatePath_(certificate)
243 , certificateFound_(
false)
248 certificateFileFound_ =
true;
249 }
catch (
const std::exception&
e) {
254 x509crt_ = std::make_shared<dht::crypto::Certificate>(
certificate_raw);
255 certificateContent_ = x509crt_->getPacked();
256 certificateFound_ =
true;
257 }
catch (
const std::exception&
e) {
264 privateKeyFound_ =
true;
266 privateKeyMatch_ =
key_tmp.getPublicKey().getId() == x509crt_->getId();
267 }
catch (
const dht::crypto::DecryptError&
d) {
271 privateKeyFound_ =
true;
272 privateKeyPassword_ =
true;
273 }
catch (
const std::exception&
e) {
279 : certStore_(certStore)
282 x509crt_ = std::make_shared<dht::crypto::Certificate>(
certificate_raw);
283 certificateContent_ = x509crt_->getPacked();
284 certificateFound_ =
true;
285 }
catch (
const std::exception&
e) {
291 : certStore_(certStore)
292 , certificateFound_(
true)
296 throw std::invalid_argument(
"Certificate must be set");
298 certificateContent_ = x509crt_->getPacked();
299 }
catch (
const std::exception&
e) {
315 assert(acceptedCheckValuesResult[enforcedCheckType[
check]][result.first]);
317 switch (result.first) {
321 return std::string(CheckValuesNames[result.first]);
325 return result.second;
329 return result.second;
360std::map<std::string, std::string>
363 std::map<std::string, std::string>
ret;
364 if (
not certificateFound_) {
370 ret[std::string(CertificateCheckNames[
check])] = getStringValue(
check,
371 (this->*(checkCallback[
check]))());
380std::map<std::string, std::string>
383 std::map<std::string, std::string>
ret;
384 if (certificateFound_) {
393 val = CheckValuesNames[r.first];
404 ret[std::string(CertificateDetailsNames[
det])] =
val;
420 ? std::string(copy_buffer, size)
446 dht::toHex(
reinterpret_cast<uint8_t*
>(copy_buffer),
456TlsValidator::compareToCa()
460 return caValidationOutput_;
466 auto root_cas = certStore_.getTrustedCertificates();
471 if (
not caListPath_.empty()) {
472 if (std::filesystem::is_directory(caListPath_))
489 auto crts = x509crt_->getChain();
496 &caValidationOutput_,
507 return caValidationOutput_;
519int TlsValidator::verifyHostnameCertificate(const std::string& host, const uint16_t port)
522 unsigned int status = (
unsigned) -1;
523 const char *
errptr =
nullptr;
546 JAMI_ERR(
"Unable to create socket.");
558 memset(&name, 0,
sizeof(name));
579 JAMI_ERR(
"Unable to connect to hostname %s at port %d",
582 }
else if (
err > 0) {
599 JAMI_ERR(
"Unable to connect to hostname %s at port %d",
host.c_str(),
port);
614 JAMI_ERR(
"Unable to set TCP_NODELAY.");
627 JAMI_ERR(
"Unable to load credentials.");
682#if GNUTLS_VERSION_AT_LEAST_3_1_4
689 JAMI_ERR(
"Certificate validation failed - %s\n",
msg.data);
693 JAMI_ERR(
"Certificate validation failed with code 0x%x.", status);
720 JAMI_ERR(
"Hostname %s does not match certificate.",
host.c_str());
737 JAMI_DBG(
"Hostname %s seems to point to a valid server.",
host.c_str());
759 if (privateKeyFound_)
763 dht::crypto::PrivateKey
key_tmp(certificateContent_);
764 }
catch (
const std::exception&
e) {
768 JAMI_DBG(
"Key from %s seems valid.", certificatePath_.c_str());
847 if (
not privateKeyFound_)
894 if (privateKeyPath_.empty())
898 auto path = std::unique_ptr<char, decltype(free)&>(
strdup(privateKeyPath_.c_str()),
free);
902 _splitpath(certificatePath_.c_str(),
nullptr,
dir,
nullptr,
nullptr);
930 auto path = std::unique_ptr<char, decltype(free)&>(
strdup(certificatePath_.c_str()),
free);
934 _splitpath(certificatePath_.c_str(),
nullptr,
dir,
nullptr,
nullptr);
1109 return (x509crt_
and x509crt_->issuer);
1165 if (
not x509crt_->issuer) {
1166 auto icrt = certStore_.findIssuer(x509crt_);
1205 std::vector<uint8_t> data;
1206 x509crt_->getPublicKey().pack(data);
1208 }
catch (
const dht::crypto::CryptoException&
e) {
1430 if (
not certificateFound_)
1446 if (
not certificateFound_)
CheckResult getSignatureAlgorithm()
Return the algorithm used to sign the Key.
CheckResult privateKeyStoragePermissions()
CheckResult requirePrivateKeyPassword()
If the key need decryption.
CheckResult getIssuerUID()
If the certificate is not self signed, return the issuer UID.
CheckResult privateKeyDirectoryPermissions()
CheckResult getSerialNumber()
Return the certificate serial number.
CheckResult validAuthority()
The provided authority is invalid.
CheckResult activated()
If the activation value is in the past.
CheckResult keyMatch()
The provided key can be used along with the certificate.
CertificateCheck
All validation fields.
@ EXIST
Some operating systems require keys to have extra attributes
CheckResult getN()
The 'N' section of a DN (RFC4514)
CheckResult getO()
The 'O' section of a DN (RFC4514)
CheckResult notRevoked()
Check if the certificate has been revoked.
CheckResult getActivationDate()
Get the activation date.
CheckResult notSelfSigned()
The certificate is not self signed.
CheckResult getVersionNumber()
Return the certificate version.
CheckResult strongSigning()
If the algorithm used to sign the certificate is considered weak by modern standard.
CheckResult getPublicKeyId()
Return an hexadecimal identifier.
CheckResult authorityMatch()
Check if the authority match the certificate.
CheckResult getIssuer()
If the certificate is not self signed, return the issuer.
bool hasCa() const
A certificate authority has been provided.
CheckResult isCA()
If the certificate is not self signed, return the issuer.
CheckResult notExpired()
Check if the certificate is not expired.
CheckResult getUID()
The 'UID' section of a DN (RFC4514)
CheckResult getIssuerO()
If the certificate is not self signed, return the issuer O.
CheckResult getSubjectKeyAlgorithm()
The algorithm used to sign the certificate details (rather than the certificate itself)
bool isValid(bool verbose=false)
Check if all boolean check passed return true if there was no FAILED checks.
CheckResult getIssuerDN()
If the certificate is not self signed, return the issuer DN (RFC4514)
CheckResult outgoingServer()
The expected outgoing server domain.
CheckResult knownAuthority()
When an account require an authority known by the system (like /usr/share/ssl/certs) then the whole c...
CheckResult privateKeySelinuxAttributes()
SELinux provide additional key protection mechanism.
std::pair< CheckValues, std::string > CheckResult
CheckResult getPublicSignature()
An hexadecimal representation of the signature.
CheckResult getExpirationDate()
Get the expiration date.
CheckResult exist()
The file has been found.
CheckResult valid()
The certificate is invalid compared to the authority.
TlsValidator(const dhtnet::tls::CertificateStore &certStore, const std::string &certificate, const std::string &privatekey="", const std::string &privatekeyPasswd="", const std::string &caList="")
Create a TlsValidator for a given certificate.
@ NUMBER
The check value cannot be represented with a finite set of values.
@ ISO_DATE
The operating system doesn't support or require the check
@ UNSUPPORTED
Equivalent of a boolean "false"
@ CUSTOM
The check value is an ISO 8601 date YYYY-MM-DD[TH24:MM:SS+00:00]
@ FAILED
Equivalent of a boolean "true"
CheckResult getMd5Fingerprint()
Compute the key fingerprint.
CheckResult hasPrivateKey()
Check if the Validator have access to a private key.
std::map< std::string, std::string > getSerializedChecks()
Convert all checks results into a string map.
CheckResult getSubjectKey()
The subject public key.
CheckResult publicKeyStoragePermissions()
CertificateDetails
Informative fields about a certificate.
CheckResult getIssuerN()
If the certificate is not self signed, return the issuer N.
CheckResult privateKeyStorageLocation()
Certificate should be located in specific path on some operating systems.
CheckResult publicKeyStorageLocation()
Certificate should be located in specific path on some operating systems.
CheckResult getIssuerCN()
If the certificate is not self signed, return the issuer CN.
CheckResult getSha1Fingerprint()
Compute the key fingerprint.
std::map< std::string, std::string > getSerializedDetails()
Get a map with all common certificate details.
CheckResult publicKeySelinuxAttributes()
SELinux provide additional key protection mechanism.
CheckResult expectedOwner()
The CA and certificate provide conflicting ownership information.
CheckResult publicKeyDirectoryPermissions()
CheckResult getCN()
The 'CN' section of a DN (RFC4514)
#define JAMI_WARNING(formatstr,...)
std::vector< uint8_t > loadFile(const std::filesystem::path &path, const std::filesystem::path &default_dir)
Read the full content of a file at path.
static constexpr int version
static TlsValidator::CheckResult checkBinaryError(int err, char *copy_buffer, size_t resultSize)
Helper method to return UNSUPPORTED when an error is detected.
static TlsValidator::CheckResult checkError(int err, char *copy_buffer, size_t size)
Helper method to return UNSUPPORTED when an error is detected.
static TlsValidator::CheckResult formatDate(const time_t time)
Convert a time_t to an ISO date string.
static constexpr const char TRUE_STR[]
void emitSignal(Args... args)
static constexpr const char FALSE_STR[]
static constexpr char DATE[]
static constexpr char ISO_DATE[]
static constexpr char PASSED[]
static constexpr char UNSUPPORTED[]
static constexpr char FAILED[]
static constexpr char CUSTOM[]
static constexpr char PUBLIC_KEY_STORAGE_LOCATION[]
static constexpr char NOT_SELF_SIGNED[]
static constexpr char AUTHORITY_MISMATCH[]
static constexpr char STRONG_SIGNING[]
static constexpr char HAS_PRIVATE_KEY[]
static constexpr char PRIVATE_KEY_STORAGE_LOCATION[]
static constexpr char KNOWN_AUTHORITY[]
static constexpr char PRIVATE_KEY_DIRECTORY_PERMISSIONS[]
static constexpr char KEY_MATCH[]
static constexpr char UNEXPECTED_OWNER[]
static constexpr char PRIVATE_KEY_SELINUX_ATTRIBUTES[]
static constexpr char VALID[]
static constexpr char NOT_ACTIVATED[]
static constexpr char PRIVATE_KEY_STORAGE_PERMISSION[]
static constexpr char EXIST[]
static constexpr char VALID_AUTHORITY[]
static constexpr char PUBLIC_KEY_STORAGE_PERMISSION[]
static constexpr char NOT_REVOKED[]
static constexpr char PUBLIC_KEY_SELINUX_ATTRIBUTES[]
static constexpr char EXPIRED[]
static constexpr char PUBLIC_KEY_DIRECTORY_PERMISSIONS[]
static constexpr char CUSTOM[]
static constexpr char NUMBER[]
static constexpr char ISO_DATE[]
static constexpr char BOOLEAN[]
static constexpr char ISSUER_DN[]
static constexpr char ISSUER_CN[]
static constexpr char UID[]
static constexpr char PUBLIC_SIGNATURE[]
static constexpr char NEXT_EXPECTED_UPDATE_DATE[]
static constexpr char CN[]
static constexpr char ACTIVATION_DATE[]
static constexpr char OUTGOING_SERVER[]
static constexpr char SERIAL_NUMBER[]
static constexpr char EXPIRATION_DATE[]
static constexpr char MD5_FINGERPRINT[]
static constexpr char N[]
static constexpr char PUBLIC_KEY_ID[]
static constexpr char SHA1_FINGERPRINT[]
static constexpr char ISSUER_N[]
static constexpr char ISSUER_O[]
static constexpr char ISSUER[]
static constexpr char REQUIRE_PRIVATE_KEY_PASSWORD[]
static constexpr char SIGNATURE_ALGORITHM[]
static constexpr char SUBJECT_KEY[]
static constexpr char IS_CA[]
static constexpr char O[]
static constexpr char VERSION_NUMBER[]
static constexpr char SUBJECT_KEY_ALGORITHM[]
static constexpr char ISSUER_UID[]
This generic class represents a multidimensional enum class array.