mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-14 02:57:45 +01:00
add PKCS12 CA-cert friendly names extraction
This commit is contained in:
parent
09b229df2c
commit
4c4de6b7fb
@ -39,6 +39,7 @@ class Crypto_API PKCS12Container
|
||||
{
|
||||
public:
|
||||
typedef X509Certificate::List CAList;
|
||||
typedef std::vector<std::string> CANameList;
|
||||
|
||||
explicit PKCS12Container(std::istream& istr, const std::string& password = "");
|
||||
/// Creates the PKCS12Container object from a stream.
|
||||
@ -84,8 +85,12 @@ public:
|
||||
const std::string& getFriendlyName() const;
|
||||
/// Returns the friendly name of the certificate bag.
|
||||
|
||||
const CANameList& getFriendlyNamesCA() const;
|
||||
/// Returns a list of CA certificates friendly names.
|
||||
|
||||
private:
|
||||
void load(PKCS12* pPKCS12, const std::string& password = "");
|
||||
std::string extractFriendlyName(X509* pCert);
|
||||
|
||||
#ifdef POCO_ENABLE_CPP11
|
||||
typedef std::unique_ptr<X509Certificate> CertPtr;
|
||||
@ -97,7 +102,8 @@ private:
|
||||
EVP_PKEY* _pKey;
|
||||
CertPtr _pX509Cert;
|
||||
CAList _caCertList;
|
||||
std::string _pkcsFriendlyname;
|
||||
CANameList _caCertNames;
|
||||
std::string _pkcsFriendlyName;
|
||||
};
|
||||
|
||||
|
||||
@ -121,7 +127,7 @@ inline const X509Certificate& PKCS12Container::getX509Certificate() const
|
||||
|
||||
inline const std::string& PKCS12Container::getFriendlyName() const
|
||||
{
|
||||
return _pkcsFriendlyname;
|
||||
return _pkcsFriendlyName;
|
||||
}
|
||||
|
||||
|
||||
@ -131,6 +137,12 @@ inline const PKCS12Container::CAList& PKCS12Container::getCACerts() const
|
||||
}
|
||||
|
||||
|
||||
inline const PKCS12Container::CANameList& PKCS12Container::getFriendlyNamesCA() const
|
||||
{
|
||||
return _caCertNames;
|
||||
}
|
||||
|
||||
|
||||
inline bool PKCS12Container::hasKey() const
|
||||
{
|
||||
return _pKey != 0;
|
||||
|
@ -67,7 +67,8 @@ PKCS12Container::PKCS12Container(const PKCS12Container& other):
|
||||
_pKey(EVPPKey::duplicate(other._pKey, &_pKey)),
|
||||
_pX509Cert(new X509Certificate(*other._pX509Cert)),
|
||||
_caCertList(other._caCertList),
|
||||
_pkcsFriendlyname(other._pkcsFriendlyname)
|
||||
_caCertNames(other._caCertNames),
|
||||
_pkcsFriendlyName(other._pkcsFriendlyName)
|
||||
{
|
||||
}
|
||||
|
||||
@ -80,7 +81,8 @@ PKCS12Container& PKCS12Container::operator = (const PKCS12Container& other)
|
||||
_pKey = EVPPKey::duplicate(other._pKey, &_pKey);
|
||||
_pX509Cert.reset(new X509Certificate(*other._pX509Cert));
|
||||
_caCertList = other._caCertList;
|
||||
_pkcsFriendlyname = other._pkcsFriendlyname;
|
||||
_caCertNames = other._caCertNames;
|
||||
_pkcsFriendlyName = other._pkcsFriendlyName;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -93,7 +95,8 @@ PKCS12Container::PKCS12Container(PKCS12Container&& other):
|
||||
_pKey(other._pKey),
|
||||
_pX509Cert(std::move(other._pX509Cert)),
|
||||
_caCertList(std::move(other._caCertList)),
|
||||
_pkcsFriendlyname(std::move(other._pkcsFriendlyname))
|
||||
_caCertNames(std::move(other._caCertNames)),
|
||||
_pkcsFriendlyName(std::move(other._pkcsFriendlyName))
|
||||
{
|
||||
other._pKey = 0;
|
||||
}
|
||||
@ -107,7 +110,8 @@ PKCS12Container& PKCS12Container::operator = (PKCS12Container&& other)
|
||||
_pKey = other._pKey; other._pKey = 0;
|
||||
_pX509Cert = std::move(other._pX509Cert);
|
||||
_caCertList = std::move(other._caCertList);
|
||||
_pkcsFriendlyname = std::move(other._pkcsFriendlyname);
|
||||
_caCertNames = std::move(other._caCertNames);
|
||||
_pkcsFriendlyName = std::move(other._pkcsFriendlyName);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -122,6 +126,31 @@ PKCS12Container::~PKCS12Container()
|
||||
}
|
||||
|
||||
|
||||
std::string PKCS12Container::extractFriendlyName(X509* pCert)
|
||||
{
|
||||
std::string friendlyName;
|
||||
if(pCert)
|
||||
{
|
||||
STACK_OF(PKCS12_SAFEBAG)*pBags = 0;
|
||||
PKCS12_SAFEBAG*pBag = PKCS12_add_cert(&pBags, pCert);
|
||||
if(pBag)
|
||||
{
|
||||
char* pBuffer = PKCS12_get_friendlyname(pBag);
|
||||
if(pBuffer)
|
||||
{
|
||||
friendlyName = pBuffer;
|
||||
OPENSSL_free(pBuffer);
|
||||
}
|
||||
if(pBags) sk_PKCS12_SAFEBAG_pop_free(pBags, PKCS12_SAFEBAG_free);
|
||||
}
|
||||
else throw OpenSSLException("PKCS12Container::extractFriendlyName()");
|
||||
}
|
||||
else throw NullPointerException("PKCS12Container::extractFriendlyName()");
|
||||
|
||||
return friendlyName;
|
||||
}
|
||||
|
||||
|
||||
void PKCS12Container::load(PKCS12* pPKCS12, const std::string& password)
|
||||
{
|
||||
if (pPKCS12)
|
||||
@ -132,30 +161,25 @@ void PKCS12Container::load(PKCS12* pPKCS12, const std::string& password)
|
||||
{
|
||||
if (pCert)
|
||||
{
|
||||
STACK_OF(PKCS12_SAFEBAG)* pBags = 0;
|
||||
_pX509Cert.reset(new X509Certificate(pCert, true));
|
||||
PKCS12_SAFEBAG* pBag = PKCS12_add_cert(&pBags, pCert);
|
||||
if (pBag)
|
||||
{
|
||||
char* pBuffer = PKCS12_get_friendlyname(pBag);
|
||||
if(pBuffer)
|
||||
{
|
||||
_pkcsFriendlyname = pBuffer;
|
||||
OPENSSL_free(pBuffer);
|
||||
}else _pkcsFriendlyname.clear();
|
||||
if(pBags) sk_PKCS12_SAFEBAG_pop_free(pBags, PKCS12_SAFEBAG_free);
|
||||
}
|
||||
else throw OpenSSLException();
|
||||
_pkcsFriendlyName = extractFriendlyName(pCert);
|
||||
}
|
||||
else _pX509Cert.reset();
|
||||
|
||||
_caCertList.clear();
|
||||
_caCertNames.clear();
|
||||
if (pCA)
|
||||
{
|
||||
int certCount = sk_X509_num(pCA);
|
||||
for (int i = 0; i < certCount; ++i)
|
||||
{
|
||||
_caCertList.push_back(X509Certificate(sk_X509_value(pCA, i), true));
|
||||
X509* pX509 = sk_X509_value(pCA, i);
|
||||
if (pX509)
|
||||
{
|
||||
_caCertList.push_back(X509Certificate(pX509, true));
|
||||
_caCertNames.push_back(extractFriendlyName(pX509));
|
||||
}
|
||||
else throw OpenSSLException("PKCS12Container::load()");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,7 +189,8 @@ void PKCS12Container::load(PKCS12* pPKCS12, const std::string& password)
|
||||
}
|
||||
PKCS12_free(pPKCS12);
|
||||
sk_X509_pop_free(pCA, X509_free);
|
||||
X509_free(pCert);
|
||||
if (pCert) X509_free(pCert);
|
||||
poco_assert_dbg (_caCertList.size() == _caCertNames.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -87,7 +87,7 @@ void PKCS12ContainerTest::full(const PKCS12Container& pkcs12)
|
||||
|
||||
std::vector<int> certOrder;
|
||||
for (int i = 0; i < 2; ++i) certOrder.push_back(i);
|
||||
fullList(pkcs12.getCACerts(), certOrder);
|
||||
fullList(pkcs12.getCACerts(), pkcs12.getFriendlyNamesCA(), certOrder);
|
||||
}
|
||||
|
||||
|
||||
@ -117,9 +117,18 @@ void PKCS12ContainerTest::fullCert(const X509Certificate& x509)
|
||||
}
|
||||
|
||||
|
||||
void PKCS12ContainerTest::fullList(const PKCS12Container::CAList& caList, const std::vector<int>& certOrder)
|
||||
void PKCS12ContainerTest::fullList(const PKCS12Container::CAList& caList,
|
||||
const PKCS12Container::CANameList& caNamesList,
|
||||
const std::vector<int>& certOrder)
|
||||
{
|
||||
assert (certOrder.size() == caList.size());
|
||||
assert ((0 == caNamesList.size()) || (certOrder.size() == caNamesList.size()));
|
||||
|
||||
if (caNamesList.size())
|
||||
{
|
||||
assert (caNamesList[certOrder[0]].empty());
|
||||
assert (caNamesList[certOrder[1]].empty());
|
||||
}
|
||||
|
||||
assert (caList[certOrder[0]].subjectName() == "/C=CH/ST=Zug/O=Crypto Vally/CN=CV Root CA v3");
|
||||
assert (caList[certOrder[0]].issuerName() == "/C=CH/ST=Zug/O=Crypto Vally/CN=CV Root CA v3");
|
||||
@ -167,16 +176,28 @@ void PKCS12ContainerTest::certsOnly(const PKCS12Container& pkcs12)
|
||||
{
|
||||
assert (!pkcs12.hasKey());
|
||||
assert (!pkcs12.hasX509Certificate());
|
||||
assert (pkcs12.getFriendlyName().empty());
|
||||
|
||||
std::vector<int> certOrder;
|
||||
for (int i = 0; i < 5; ++i) certOrder.push_back(i);
|
||||
certsOnlyList(pkcs12.getCACerts(), certOrder);
|
||||
certsOnlyList(pkcs12.getCACerts(), pkcs12.getFriendlyNamesCA(), certOrder);
|
||||
}
|
||||
|
||||
|
||||
void PKCS12ContainerTest::certsOnlyList(const PKCS12Container::CAList& caList, const std::vector<int>& certOrder)
|
||||
void PKCS12ContainerTest::certsOnlyList(const PKCS12Container::CAList& caList,
|
||||
const PKCS12Container::CANameList& caNamesList, const std::vector<int>& certOrder)
|
||||
{
|
||||
assert (certOrder.size() == caList.size());
|
||||
assert ((0 == caNamesList.size()) || (certOrder.size() == caNamesList.size()));
|
||||
|
||||
if (caNamesList.size())
|
||||
{
|
||||
assert (caNamesList[certOrder[0]].empty());
|
||||
assert (caNamesList[certOrder[1]].empty());
|
||||
assert (caNamesList[certOrder[2]].empty());
|
||||
assert (caNamesList[certOrder[3]] == "vally-ca");
|
||||
assert (caNamesList[certOrder[4]] == "vally-ca");
|
||||
}
|
||||
|
||||
assert (caList[certOrder[0]].subjectName() == "/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3");
|
||||
assert (caList[certOrder[0]].issuerName() == "/C=US/O=Internet Security Research Group/CN=ISRG Root X1");
|
||||
@ -245,14 +266,14 @@ void PKCS12ContainerTest::testPEMReadWrite()
|
||||
// PEM is written by openssl in reverse order from p12
|
||||
std::vector<int> certOrder;
|
||||
for(int i = (int)certsOnly.size() - 1; i >= 0; --i) certOrder.push_back(i);
|
||||
certsOnlyList(certsOnly, certOrder);
|
||||
certsOnlyList(certsOnly, PKCS12Container::CANameList(), certOrder);
|
||||
|
||||
TemporaryFile tmpFile;
|
||||
X509Certificate::writePEM(tmpFile.path(), certsOnly);
|
||||
|
||||
certsOnly.clear();
|
||||
certsOnly = X509Certificate::readPEM(tmpFile.path());
|
||||
certsOnlyList(certsOnly, certOrder);
|
||||
certsOnlyList(certsOnly, PKCS12Container::CANameList(), certOrder);
|
||||
|
||||
file = getTestFilesPath("full", "pem");
|
||||
X509Certificate::List full = X509Certificate::readPEM(file);
|
||||
@ -263,14 +284,14 @@ void PKCS12ContainerTest::testPEMReadWrite()
|
||||
|
||||
certOrder.clear();
|
||||
for(int i = (int)full.size() - 1; i >= 0; --i) certOrder.push_back(i);
|
||||
fullList(full, certOrder);
|
||||
fullList(full, PKCS12Container::CANameList(), certOrder);
|
||||
|
||||
TemporaryFile tmpFile2;
|
||||
X509Certificate::writePEM(tmpFile2.path(), full);
|
||||
|
||||
full.clear();
|
||||
full = X509Certificate::readPEM(tmpFile2.path());
|
||||
fullList(full, certOrder);
|
||||
fullList(full, PKCS12Container::CANameList(), certOrder);
|
||||
}
|
||||
catch (Poco::Exception& ex)
|
||||
{
|
||||
|
@ -39,10 +39,14 @@ private:
|
||||
std::string getTestFilesPath(const std::string& name,
|
||||
const std::string& ext = "p12");
|
||||
void certsOnly(const Poco::Crypto::PKCS12Container& pkcs12);
|
||||
void certsOnlyList(const Poco::Crypto::PKCS12Container::CAList& caList, const std::vector<int>& certOrder);
|
||||
void certsOnlyList(const Poco::Crypto::PKCS12Container::CAList& caList,
|
||||
const Poco::Crypto::PKCS12Container::CANameList& caNamesList,
|
||||
const std::vector<int>& certOrder);
|
||||
void full(const Poco::Crypto::PKCS12Container& pkcs12);
|
||||
void fullCert(const Poco::Crypto::X509Certificate& x509);
|
||||
void fullList(const Poco::Crypto::PKCS12Container::CAList& caList, const std::vector<int>& certOrder);
|
||||
void fullList(const Poco::Crypto::PKCS12Container::CAList& caList,
|
||||
const Poco::Crypto::PKCS12Container::CANameList& caNamesList,
|
||||
const std::vector<int>& certOrder);
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user