mirror of
https://github.com/QuasarApp/easyssl.git
synced 2025-04-26 21:14:32 +00:00
added support x509 certificates for qt
This commit is contained in:
parent
fcbf421535
commit
a84929b069
@ -25,9 +25,9 @@ if (ANDROID)
|
||||
endif()
|
||||
|
||||
if (NOT QT_VERSION_MAJOR)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Test REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Network Test REQUIRED)
|
||||
endif()
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Test REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Test REQUIRED)
|
||||
|
||||
include(submodules/CMake/QuasarApp.cmake)
|
||||
|
||||
|
@ -33,7 +33,7 @@ set(PRIVATE_INCUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/private")
|
||||
|
||||
add_library(${CURRENT_PROJECT} ${SOURCE_CPP} ${SOURCE_QRC})
|
||||
|
||||
target_link_libraries(${CURRENT_PROJECT} PUBLIC Qt${QT_VERSION_MAJOR}::Core )
|
||||
target_link_libraries(${CURRENT_PROJECT} PUBLIC Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Core )
|
||||
|
||||
if (EASYSSL_STATIC_SSL)
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "easysslutils.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/types.h>
|
||||
#include <QVector>
|
||||
|
||||
@ -57,4 +58,36 @@ BIO* EasySSLUtils::byteArrayToBio(const QByteArray& byteArray) {
|
||||
return bio;
|
||||
}
|
||||
|
||||
QByteArray EasySSLUtils::extractPublcKey(EVP_PKEY *ssl_keys) {
|
||||
if (!ssl_keys)
|
||||
return {};
|
||||
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
if (PEM_write_bio_PUBKEY(bio, ssl_keys) != 1) {
|
||||
BIO_free(bio);
|
||||
return {};
|
||||
}
|
||||
|
||||
QByteArray pubKey = bioToByteArray(bio);
|
||||
BIO_free(bio);
|
||||
|
||||
return pubKey;
|
||||
}
|
||||
|
||||
QByteArray EasySSLUtils::extractPrivateKey(EVP_PKEY *ssl_keys) {
|
||||
if (!ssl_keys)
|
||||
return {};
|
||||
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
if (PEM_write_bio_PrivateKey(bio, ssl_keys, nullptr, nullptr, 0, nullptr, nullptr) != 1) {
|
||||
BIO_free(bio);
|
||||
return {};
|
||||
}
|
||||
|
||||
QByteArray pKey = bioToByteArray(bio);
|
||||
BIO_free(bio);
|
||||
|
||||
return pKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -53,6 +53,21 @@ public:
|
||||
*/
|
||||
[[nodiscard("This pointer will not free automatically. Please free returned pointer after using.")]]
|
||||
static BIO *byteArrayToBio(const QByteArray &byteArray);
|
||||
|
||||
/**
|
||||
* @brief extractPublcKey This method extracts publick key from the ssl (pem) structure.
|
||||
* @param ssl_keys This is ssl keys objects.
|
||||
* @return bytes array of the extracted key.
|
||||
*/
|
||||
static QByteArray extractPublcKey(EVP_PKEY* ssl_keys);
|
||||
|
||||
/**
|
||||
* @brief extractPrivateKey This method extracts private key from the ssl (pem) structure.
|
||||
* @param ssl_keys This is ssl keys objects.
|
||||
* @return bytes array of the extracted key.
|
||||
*/
|
||||
static QByteArray extractPrivateKey(EVP_PKEY* ssl_keys);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
23
src/lib/src/public/easyssl/icertificate.cpp
Normal file
23
src/lib/src/public/easyssl/icertificate.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2023 QuasarApp.
|
||||
* Distributed under the GPLv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "icertificate.h"
|
||||
|
||||
|
||||
namespace EasySSL {
|
||||
|
||||
ICertificate::ICertificate(const QSharedPointer<ICrypto> &generator) {
|
||||
_keyGenerator = generator;
|
||||
}
|
||||
|
||||
const QSharedPointer<ICrypto> &ICertificate::keyGenerator() const {
|
||||
return _keyGenerator;
|
||||
}
|
||||
|
||||
}
|
71
src/lib/src/public/easyssl/icertificate.h
Normal file
71
src/lib/src/public/easyssl/icertificate.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2023 QuasarApp.
|
||||
* Distributed under the GPLv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#ifndef ICERTIFICATE_H
|
||||
#define ICERTIFICATE_H
|
||||
|
||||
#include <QSslCertificate>
|
||||
#include <QSslKey>
|
||||
#include "easyssl/icrypto.h"
|
||||
#include "global.h"
|
||||
#include <QByteArray>
|
||||
|
||||
namespace EasySSL {
|
||||
|
||||
/**
|
||||
* @brief The SslSrtData struct This structure contains base information for generate self signed ssl certefication.
|
||||
*/
|
||||
struct SslSrtData {
|
||||
QString country = "BY";
|
||||
QString organization = "QuasarApp";
|
||||
QString commonName = "";
|
||||
long long endTime = 31536000L; //1 year
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The SelfSignedSertificate struct contains qt certificate object and private key of them.
|
||||
*/
|
||||
struct EASYSSL_EXPORT SelfSignedSertificate {
|
||||
SelfSignedSertificate(){}
|
||||
SelfSignedSertificate(const SelfSignedSertificate & other) {
|
||||
crt = other.crt;
|
||||
key = other.key;
|
||||
};
|
||||
QSslCertificate crt;
|
||||
QSslKey key;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The ICertificate class is base interface for all certificate generators classes.
|
||||
*
|
||||
*/
|
||||
class EASYSSL_EXPORT ICertificate
|
||||
{
|
||||
public:
|
||||
|
||||
ICertificate(const QSharedPointer<ICrypto>& generator);
|
||||
|
||||
/**
|
||||
* @brief create This method create a self signed certificate.
|
||||
* @param certificateData This input extra data of certificate.
|
||||
* @return certificate data with private key.
|
||||
*/
|
||||
virtual SelfSignedSertificate create(const SslSrtData& certificateData) const = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief generator This method return private key generator.
|
||||
* @return private key generator.
|
||||
*/
|
||||
const QSharedPointer<ICrypto>& keyGenerator() const;
|
||||
|
||||
private:
|
||||
QSharedPointer<ICrypto> _keyGenerator;
|
||||
};
|
||||
|
||||
}
|
||||
#endif // ICERTIFICATE_H
|
28
src/lib/src/public/easyssl/icrypto.cpp
Normal file
28
src/lib/src/public/easyssl/icrypto.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2023 QuasarApp.
|
||||
* Distributed under the GPLv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#include "icrypto.h"
|
||||
|
||||
#include <easysslutils.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
namespace EasySSL {
|
||||
|
||||
bool EasySSL::ICrypto::makeKeys(QByteArray &pubKey, QByteArray &privKey) const
|
||||
{
|
||||
EVP_PKEY *keys = makeRawKeys();
|
||||
if (!keys)
|
||||
return false;
|
||||
|
||||
pubKey = EasySSLUtils::extractPublcKey(keys);
|
||||
privKey = EasySSLUtils::extractPrivateKey(keys);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -10,7 +10,9 @@
|
||||
#define I_CRYPTO_H
|
||||
|
||||
#include "global.h"
|
||||
#include "qssl.h"
|
||||
#include <QByteArray>
|
||||
#include <openssl/types.h>
|
||||
|
||||
namespace EasySSL {
|
||||
|
||||
@ -38,7 +40,19 @@ public:
|
||||
* @param privKey This is result private key.
|
||||
* @return true if keys generated successful.
|
||||
*/
|
||||
virtual bool makeKeys(QByteArray &pubKey, QByteArray &privKey) const = 0;
|
||||
bool makeKeys(QByteArray &pubKey, QByteArray &privKey) const;
|
||||
|
||||
/**
|
||||
* @brief makeKeys This method generate the public and private keys of the ECDSA.
|
||||
* @return pointer to generated keys.
|
||||
*/
|
||||
virtual EVP_PKEY * makeRawKeys() const = 0;
|
||||
|
||||
/**
|
||||
* @brief keyAlgorithm This method should be return Qt Key algorithm (needed for generate cetrificates.)
|
||||
* @return
|
||||
*/
|
||||
virtual QSsl::KeyAlgorithm keyAlgorithm() const = 0;
|
||||
|
||||
/**
|
||||
* @brief supportedFeatures This method should return supported featurs of the current encription alhorithm
|
||||
|
@ -20,37 +20,17 @@ RSASSL30::RSASSL30() {
|
||||
|
||||
}
|
||||
|
||||
bool RSASSL30::makeKeys(QByteArray &pubKey, QByteArray &privKey) const {
|
||||
EVP_PKEY * RSASSL30::makeRawKeys() const {
|
||||
|
||||
EVP_PKEY *pkey = nullptr;
|
||||
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
|
||||
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(nullptr, "RSA", nullptr);
|
||||
EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, 4096);
|
||||
|
||||
EVP_PKEY_keygen_init(pctx);
|
||||
EVP_PKEY_generate(pctx, &pkey);
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
|
||||
if (!pkey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
if (PEM_write_bio_PUBKEY(bio, pkey) != 1) {
|
||||
EVP_PKEY_free(pkey);
|
||||
return false;
|
||||
}
|
||||
pubKey = EasySSLUtils::bioToByteArray(bio);
|
||||
|
||||
if (PEM_write_bio_PrivateKey(bio, pkey, nullptr, nullptr, 0, nullptr, nullptr) != 1)
|
||||
{
|
||||
EVP_PKEY_free(pkey);
|
||||
return false;
|
||||
}
|
||||
|
||||
privKey = EasySSLUtils::bioToByteArray(bio);
|
||||
|
||||
return true;
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
ICrypto::Features RSASSL30::supportedFeatures() const {
|
||||
|
@ -1,3 +1,11 @@
|
||||
//#
|
||||
//# Copyright (C) 2021-2023 QuasarApp.
|
||||
//# Distributed under the GPLv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
|
||||
#ifndef RSASSL30_H
|
||||
#define RSASSL30_H
|
||||
|
||||
@ -14,10 +22,9 @@ class EASYSSL_EXPORT RSASSL30: public EasySSL::ICrypto
|
||||
public:
|
||||
RSASSL30();
|
||||
|
||||
bool makeKeys(QByteArray &pubKey, QByteArray &privKey) const override;
|
||||
EVP_PKEY *makeRawKeys() const override;
|
||||
Features supportedFeatures() const override;
|
||||
|
||||
|
||||
QByteArray signMessage(const QByteArray &inputData, const QByteArray &key) const override;
|
||||
bool checkSign(const QByteArray &inputData, const QByteArray &signature, const QByteArray &key) const override;
|
||||
|
||||
|
@ -1,6 +1,86 @@
|
||||
#include "x509.h"
|
||||
//#
|
||||
//# Copyright (C) 2021-2023 QuasarApp.
|
||||
//# Distributed under the GPLv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
X509::X509()
|
||||
{
|
||||
#include "x509.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <easysslutils.h>
|
||||
namespace EasySSL {
|
||||
|
||||
X509::X509(const QSharedPointer<ICrypto>& generator): ICertificate(generator) {
|
||||
|
||||
}
|
||||
|
||||
SelfSignedSertificate X509::create(const SslSrtData &certificateData) const {
|
||||
SelfSignedSertificate result;
|
||||
if (!(keyGenerator()->supportedFeatures() & ICrypto::Features::Signing)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
EVP_PKEY *pkey = keyGenerator()->makeRawKeys();
|
||||
|
||||
::X509 * x509 = nullptr;
|
||||
X509_NAME * name = nullptr;
|
||||
|
||||
x509 = X509_new();
|
||||
q_check_ptr(x509);
|
||||
ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
|
||||
X509_gmtime_adj(X509_get_notBefore(x509), 0); // not before current time
|
||||
X509_gmtime_adj(X509_get_notAfter(x509), certificateData.endTime); // not after a year from this point
|
||||
X509_set_pubkey(x509, pkey);
|
||||
name = X509_get_subject_name(x509);
|
||||
q_check_ptr(name);
|
||||
|
||||
unsigned char *C = reinterpret_cast<unsigned char *>(certificateData.country.toLatin1().data());
|
||||
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, C, -1, -1, 0);
|
||||
|
||||
unsigned char *O = reinterpret_cast<unsigned char *>(certificateData.organization.toLatin1().data());
|
||||
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, O, -1, -1, 0);
|
||||
|
||||
unsigned char *CN = reinterpret_cast<unsigned char *>(certificateData.commonName.toLatin1().data());
|
||||
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, CN, -1, -1, 0);
|
||||
|
||||
X509_set_issuer_name(x509, name);
|
||||
X509_sign(x509, pkey, EVP_sha256());
|
||||
|
||||
result.key = QSslKey(EasySSLUtils::extractPrivateKey(pkey), keyGenerator()->keyAlgorithm());
|
||||
if(result.key.isNull()) {
|
||||
EVP_PKEY_free(pkey);
|
||||
X509_free(x509);
|
||||
BIO_free_all(bp_public);
|
||||
BIO_free_all(bp_private);
|
||||
qCritical("Failed to generate a random private key");
|
||||
return {};
|
||||
}
|
||||
EVP_PKEY_free(pkey);
|
||||
BIO_free_all(bp_private);
|
||||
|
||||
BIO * bp_public = BIO_new(BIO_s_mem());
|
||||
q_check_ptr(bp_public);
|
||||
if(PEM_write_bio_X509(bp_public, x509) != 1){
|
||||
X509_free(x509);
|
||||
BIO_free_all(bp_public);
|
||||
qCritical("PEM_write_bio_PrivateKey");
|
||||
return {};
|
||||
}
|
||||
|
||||
result.crt = QSslCertificate(EasySSLUtils::bioToByteArray(bp_public));
|
||||
if(result.crt.isNull()) {
|
||||
X509_free(x509);
|
||||
BIO_free_all(bp_public);
|
||||
qCritical("Failed to generate a random client certificate");
|
||||
return {};
|
||||
}
|
||||
|
||||
X509_free(x509);
|
||||
BIO_free_all(bp_public);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,31 @@
|
||||
//#
|
||||
//# Copyright (C) 2021-2023 QuasarApp.
|
||||
//# Distributed under the GPLv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
#ifndef X509_H
|
||||
#define X509_H
|
||||
|
||||
#include "global.h"
|
||||
#include "icertificate.h"
|
||||
#include "icrypto.h"
|
||||
|
||||
class X509
|
||||
namespace EasySSL {
|
||||
|
||||
/**
|
||||
* @brief The X509 class This is wrapper of the ssl objects.
|
||||
*/
|
||||
class EASYSSL_EXPORT X509: public ICertificate
|
||||
{
|
||||
public:
|
||||
X509();
|
||||
X509(const QSharedPointer<ICrypto>& generator);
|
||||
|
||||
// ICertificate interface
|
||||
public:
|
||||
SelfSignedSertificate create(const SslSrtData& certificateData) const override;
|
||||
};
|
||||
|
||||
}
|
||||
#endif // X509_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user