mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Add method for cert&key generation
This commit is contained in:
@ -42,6 +42,8 @@ namespace NSCertificate
|
||||
OPENSSL_DECL std::wstring GetSignatureMethod(const int& nAlg);
|
||||
|
||||
OPENSSL_DECL ICertificate* CreateInstance(const int& type = CERTIFICATE_ENGINE_TYPE_DEFAULT);
|
||||
|
||||
OPENSSL_DECL ICertificate* GenerateByAlg(const std::string& key_alg, const std::map<std::wstring, std::wstring>& props = std::map<std::wstring, std::wstring>());
|
||||
};
|
||||
|
||||
#endif // _XML_CERTIFICATE_COMMON_H_
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "../../../common/base_export.h"
|
||||
|
||||
#ifdef COMMON_OPENSSL_BUILDING_INTERNAL
|
||||
|
||||
@ -317,6 +317,21 @@ namespace NSCertificate
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ICertificate* GenerateByAlg(const std::string& key_alg, const std::map<std::wstring, std::wstring>& props)
|
||||
{
|
||||
#ifdef SUPPORT_OPENSSL
|
||||
CCertificate_openssl* pCert = new CCertificate_openssl();
|
||||
bool bIsGenerated = pCert->Generate(key_alg, props);
|
||||
if (!bIsGenerated)
|
||||
{
|
||||
delete pCert;
|
||||
return NULL;
|
||||
}
|
||||
return pCert;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef SUPPORT_OPENSSL
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/conf.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
const EVP_MD* Get_EVP_MD(int nAlg)
|
||||
{
|
||||
switch (nAlg)
|
||||
@ -121,6 +123,148 @@ public:
|
||||
EVP_PKEY_FREE(m_key);
|
||||
}
|
||||
|
||||
bool Generate(const std::string& key_alg, const std::map<std::wstring, std::wstring>& props = std::map<std::wstring, std::wstring>())
|
||||
{
|
||||
EVP_PKEY_CTX* pctx = nullptr;
|
||||
int nRsaKeyLen = 0;
|
||||
|
||||
if (key_alg == "ed25519")
|
||||
{
|
||||
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
|
||||
m_alg = OOXML_HASH_ALG_ED25519;
|
||||
}
|
||||
else if (key_alg == "x25519")
|
||||
{
|
||||
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
|
||||
m_alg = OOXML_HASH_ALG_ED448;
|
||||
}
|
||||
else if (0 == key_alg.find("rsa"))
|
||||
{
|
||||
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
|
||||
std::string sKeyLen = key_alg.substr(3);
|
||||
nRsaKeyLen = 2048;
|
||||
if (!sKeyLen.empty())
|
||||
nRsaKeyLen = std::stoi(sKeyLen);
|
||||
|
||||
m_alg = OOXML_HASH_ALG_SHA256;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
EVP_PKEY_keygen_init(pctx);
|
||||
|
||||
if (0 != nRsaKeyLen && EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, nRsaKeyLen) <= 0)
|
||||
return false;
|
||||
|
||||
EVP_PKEY_keygen(pctx, &m_key);
|
||||
|
||||
m_cert = X509_new();
|
||||
X509_set_version(m_cert, 2);
|
||||
|
||||
ASN1_STRING* serialNumber = X509_get_serialNumber(m_cert);
|
||||
if (serialNumber)
|
||||
{
|
||||
const int nBytesCount = 16;
|
||||
unsigned char pSerialNumber[nBytesCount];
|
||||
RAND_bytes(pSerialNumber, nBytesCount);
|
||||
|
||||
if (1 != ASN1_STRING_set(serialNumber, pSerialNumber, nBytesCount) == 1)
|
||||
ASN1_INTEGER_set(serialNumber, 1);
|
||||
}
|
||||
|
||||
X509_gmtime_adj(X509_get_notBefore(m_cert), 0);
|
||||
X509_gmtime_adj(X509_get_notAfter(m_cert), 31536000L);
|
||||
|
||||
if (X509_set_pubkey(m_cert, m_key) == 0)
|
||||
{
|
||||
if (NULL != m_cert)
|
||||
X509_free(m_cert);
|
||||
m_cert = NULL;
|
||||
|
||||
if (NULL != m_key)
|
||||
EVP_PKEY_free(m_key);
|
||||
m_key = NULL;
|
||||
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
X509_NAME* name_record = X509_get_subject_name(m_cert);
|
||||
|
||||
std::wstring sC = L"US";
|
||||
std::wstring sO = L"Ascensio System SIA";
|
||||
std::wstring sCN = L"AOSign Certificate";
|
||||
|
||||
std::map<std::wstring, std::wstring>::const_iterator iter_prop = props.find(L"C");
|
||||
if (iter_prop != props.end())
|
||||
sC = iter_prop->second;
|
||||
|
||||
iter_prop = props.find(L"O");
|
||||
if (iter_prop != props.end())
|
||||
sO = iter_prop->second;
|
||||
|
||||
iter_prop = props.find(L"CN");
|
||||
if (iter_prop != props.end())
|
||||
sCN = iter_prop->second;
|
||||
|
||||
std::string sC_A = U_TO_UTF8(sC);
|
||||
std::string sO_A = U_TO_UTF8(sO);
|
||||
std::string sCN_A = U_TO_UTF8(sCN);
|
||||
|
||||
X509_NAME_add_entry_by_txt(name_record, "C", MBSTRING_ASC, (unsigned char *)sC_A.c_str(), -1, -1, 0);
|
||||
X509_NAME_add_entry_by_txt(name_record, "O", MBSTRING_ASC, (unsigned char *)sO_A.c_str(), -1, -1, 0);
|
||||
X509_NAME_add_entry_by_txt(name_record, "CN", MBSTRING_ASC, (unsigned char *)sCN_A.c_str(), -1, -1, 0);
|
||||
|
||||
X509_set_issuer_name(m_cert, name_record);
|
||||
|
||||
if (!props.empty())
|
||||
{
|
||||
std::string sAdditions = "";
|
||||
for (std::map<std::wstring, std::wstring>::const_iterator iter = props.begin(); iter != props.end(); iter++)
|
||||
{
|
||||
std::string sKey = U_TO_UTF8(iter->first);
|
||||
std::string sValue = U_TO_UTF8(iter->second);
|
||||
|
||||
string_replace(sKey, ";", ";");
|
||||
string_replace(sKey, "=", "=");
|
||||
string_replace(sValue, ";", ";");
|
||||
|
||||
sAdditions += (sKey + "=" + sValue + ";");
|
||||
}
|
||||
|
||||
if (!sAdditions.empty())
|
||||
{
|
||||
//const int nid_user = OBJ_create("1.2.3", "key", "value");
|
||||
ASN1_OCTET_STRING* oDataAdditions = ASN1_OCTET_STRING_new();
|
||||
int nError = ASN1_OCTET_STRING_set(oDataAdditions, (unsigned const char*)sAdditions.c_str(), (int)sAdditions.length());
|
||||
X509_EXTENSION* ext = X509_EXTENSION_create_by_NID(nullptr, NID_subject_alt_name, false, oDataAdditions);
|
||||
nError = X509_add_ext(m_cert, ext, -1);
|
||||
X509_EXTENSION_free(ext);
|
||||
}
|
||||
}
|
||||
|
||||
const EVP_MD* pDigest = Get_EVP_MD(this->GetHashAlg());
|
||||
if (NULL == pDigest)
|
||||
pDigest = EVP_md_null();
|
||||
|
||||
if (X509_sign(m_cert, m_key, pDigest) == 0)
|
||||
{
|
||||
if (NULL != m_cert)
|
||||
X509_free(m_cert);
|
||||
m_cert = NULL;
|
||||
|
||||
if (NULL != m_key)
|
||||
EVP_PKEY_free(m_key);
|
||||
m_key = NULL;
|
||||
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual int GetType()
|
||||
{
|
||||
return CERTIFICATE_ENGINE_TYPE_OPENSSL;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "../../../common/File.h"
|
||||
#include "../include/XmlCertificate.h"
|
||||
#include "../include/CertificateCommon.h"
|
||||
#include "../include/OOXMLSigner.h"
|
||||
#include "../include/OOXMLVerifier.h"
|
||||
|
||||
@ -12,56 +12,64 @@
|
||||
|
||||
int main()
|
||||
{
|
||||
std::wstring sTestDir = NSFile::GetProcessDirectory() + L"/../../";
|
||||
ICertificate* pCertificate = NULL;
|
||||
std::wstring sTestDir = NSFile::GetProcessDirectory() + L"/../../";
|
||||
|
||||
#ifdef USE_MS_CRYPTO
|
||||
//ICertificate* pCertificate = NSCertificate::FromFiles(sTestDir + L"keys/key.key", "", sTestDir + L"keys/cert.crt", "");
|
||||
|
||||
// TODO: Load sertificate from store
|
||||
std::map<std::wstring, std::wstring> properties;
|
||||
properties.insert(std::make_pair(L"email", L"sign@onlyoffice.com"));
|
||||
properties.insert(std::make_pair(L"phone", L"+00000000000"));
|
||||
std::wstring sNameTest = L"NameTest";
|
||||
std::wstring sValueTest = L"ValueTest";
|
||||
properties.insert(std::make_pair(sNameTest, sValueTest));
|
||||
|
||||
#else
|
||||
//ICertificate* pCertificate = NSCertificate::GenerateByAlg("rsa2048", properties);
|
||||
ICertificate* pCertificate = NSCertificate::GenerateByAlg("ed25519", properties);
|
||||
|
||||
pCertificate = ICertificate::CreateInstance();
|
||||
pCertificate->FromFiles(sTestDir + L"keys/key.key", "", sTestDir + L"keys/cert.crt", "");
|
||||
#endif
|
||||
unsigned char* pSignData = NULL;
|
||||
unsigned int nSignDataLen = 0;
|
||||
std::string sSignData = "Hello world!";
|
||||
bool bRes = pCertificate->SignPKCS7((unsigned char*)sSignData.c_str(), (unsigned int)sSignData.length(), pSignData, nSignDataLen);
|
||||
|
||||
BYTE* pDataDst = NULL;
|
||||
unsigned long nLenDst = 0;
|
||||
RELEASEARRAYOBJECTS(pSignData);
|
||||
|
||||
BYTE* pDataDst = NULL;
|
||||
unsigned long nLenDst = 0;
|
||||
|
||||
#ifdef USE_SIGN
|
||||
#if 0
|
||||
COOXMLSigner oSigner(sTestDir + L"file", pCertificate);
|
||||
oSigner.Sign(pDataDst, nLenDst);
|
||||
COOXMLSigner oSigner(sTestDir + L"file", pCertificate);
|
||||
oSigner.Sign(pDataDst, nLenDst);
|
||||
#else
|
||||
BYTE* pDataSrc = NULL;
|
||||
unsigned long nLenSrc = 0;
|
||||
NSFile::CFileBinary::ReadAllBytes(sTestDir + L"/file.docx", &pDataSrc, nLenSrc);
|
||||
BYTE* pDataSrc = NULL;
|
||||
unsigned long nLenSrc = 0;
|
||||
NSFile::CFileBinary::ReadAllBytes(sTestDir + L"/file.docx", &pDataSrc, nLenSrc);
|
||||
|
||||
COOXMLSigner oSigner(pDataSrc, nLenSrc, pCertificate);
|
||||
oSigner.Sign(pDataDst, nLenDst);
|
||||
RELEASEARRAYOBJECTS(pDataSrc);
|
||||
COOXMLSigner oSigner(pDataSrc, nLenSrc, pCertificate);
|
||||
oSigner.Sign(pDataDst, nLenDst);
|
||||
RELEASEARRAYOBJECTS(pDataSrc);
|
||||
|
||||
NSFile::CFileBinary oFileDst;
|
||||
oFileDst.CreateFileW(sTestDir + L"/file2.docx");
|
||||
oFileDst.WriteFile(pDataDst, nLenDst);
|
||||
oFileDst.CloseFile();
|
||||
NSFile::CFileBinary oFileDst;
|
||||
oFileDst.CreateFileW(sTestDir + L"/file2.docx");
|
||||
oFileDst.WriteFile(pDataDst, nLenDst);
|
||||
oFileDst.CloseFile();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
RELEASEARRAYOBJECTS(pDataDst);
|
||||
RELEASEARRAYOBJECTS(pDataDst);
|
||||
|
||||
#ifdef USE_VERIFY
|
||||
#if 1
|
||||
COOXMLVerifier oVerifier(sTestDir + L"file");
|
||||
int nCount = oVerifier.GetSignatureCount();
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
COOXMLSignature* pSign = oVerifier.GetSignature(i);
|
||||
pSign->Check();
|
||||
}
|
||||
COOXMLVerifier oVerifier(sTestDir + L"file");
|
||||
int nCount = oVerifier.GetSignatureCount();
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
COOXMLSignature* pSign = oVerifier.GetSignature(i);
|
||||
pSign->Check();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
delete pCertificate;
|
||||
return 0;
|
||||
delete pCertificate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user