blob: 4b7eb9b898dfe6ad10a3a07bbb0562ddf91d6dc0 [file]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.
*/
#pragma once
#include <openssl/ssl.h>
#include <openssl/pkcs12.h>
#ifdef WIN32
#include <windows.h>
#include <wincrypt.h>
#endif // WIN32
#include <memory>
#include <filesystem>
#include <optional>
#include <string>
#include <functional>
#include "WindowsCertStoreLocation.h"
namespace org::apache::nifi::minifi::utils::tls {
class ssl_error_category : public std::error_category {
public:
[[nodiscard]]
const char* name() const noexcept override {
return "ssl_error";
}
[[nodiscard]]
static const ssl_error_category& get();
[[nodiscard]]
std::string message(int value) const override;
};
std::error_code get_last_ssl_error_code();
struct EVP_PKEY_deleter {
void operator()(EVP_PKEY* pkey) const { EVP_PKEY_free(pkey); }
};
using EVP_PKEY_unique_ptr = std::unique_ptr<EVP_PKEY, EVP_PKEY_deleter>;
struct X509_deleter {
void operator()(X509* cert) const { X509_free(cert); }
};
using X509_unique_ptr = std::unique_ptr<X509, X509_deleter>;
struct BIO_deleter {
void operator()(BIO* bio) const { BIO_free(bio); }
};
using BIO_unique_ptr = std::unique_ptr<BIO, BIO_deleter>;
struct PKCS12_deleter {
void operator()(PKCS12* cert) const { PKCS12_free(cert); }
};
using PKCS12_unique_ptr = std::unique_ptr<PKCS12, PKCS12_deleter>;
#ifdef WIN32
class WindowsCertStore {
public:
WindowsCertStore(const WindowsCertStoreLocation& loc, const std::string& cert_store);
std::error_code error() const;
PCCERT_CONTEXT nextCert();
~WindowsCertStore();
private:
std::error_code error_;
HCERTSTORE store_ptr_;
PCCERT_CONTEXT cert_ctx_ptr_ = nullptr;
};
// Returns nullptr on errors
X509_unique_ptr convertWindowsCertificate(PCCERT_CONTEXT certificate);
// Returns nullptr on errors, or if the input is not an RSA key pair
EVP_PKEY_unique_ptr convertWindowsRsaKeyPair(std::span<BYTE> data);
// Returns nullptr if the certificate has no associated private key, or the private key could not be extracted
EVP_PKEY_unique_ptr extractPrivateKey(PCCERT_CONTEXT certificate);
#endif // WIN32
std::string getLatestOpenSSLErrorString();
std::optional<std::chrono::system_clock::time_point> getCertificateExpiration(const X509_unique_ptr& cert);
struct CertHandler {
std::function<std::error_code(X509_unique_ptr cert)> cert_cb;
std::function<std::error_code(X509_unique_ptr cert)> chain_cert_cb;
std::function<std::error_code(EVP_PKEY_unique_ptr priv_key)> priv_key_cb;
};
std::error_code processP12Certificate(const std::filesystem::path& cert_file, const std::string& passphrase, const CertHandler& handler);
std::error_code processPEMCertificate(const std::filesystem::path& cert_file, const std::optional<std::string>& passphrase, const CertHandler& handler);
} // namespace org::apache::nifi::minifi::utils::tls