add X509 version, serialNumber and signatureAlgorithm

This commit is contained in:
Alex Fabijanic 2017-09-29 13:45:56 -05:00
parent 767853a44a
commit 6121d55819
4 changed files with 82 additions and 10 deletions

View File

@ -83,6 +83,13 @@ public:
~X509Certificate();
/// Destroys the X509Certificate.
long version() const;
/// Returns the version of the certificate.
const std::string& serialNumber() const;
/// Returns the certificate serial number as a
/// string in decimal encoding.
const std::string& issuerName() const;
/// Returns the certificate issuer's distinguished name.
@ -144,6 +151,9 @@ public:
const X509* certificate() const;
/// Returns the underlying OpenSSL certificate.
std::string signatureAlgorithm() const;
/// Returns the certificate signature algorithm long name.
void print(std::ostream& out) const;
/// Prints the certificate information to ostream.
@ -177,6 +187,7 @@ private:
std::string _issuerName;
std::string _subjectName;
std::string _serialNumber;
X509* _pCert;
OpenSSLInitializer _openSSLInitializer;
};
@ -185,6 +196,21 @@ private:
//
// inlines
//
inline long X509Certificate::version() const
{
// This is defined by standards (X.509 et al) to be
// one less than the certificate version.
// So, eg. a version 3 certificate will return 2.
return X509_get_version(_pCert) + 1;
}
inline const std::string& X509Certificate::serialNumber() const
{
return _serialNumber;
}
inline const std::string& X509Certificate::issuerName() const
{
return _issuerName;

View File

@ -194,7 +194,7 @@ std::string ECKeyImpl::getCurveName(int nid)
}
if (-1 == nid) nid = pCurves[0].nid;
int bufLen = 128;
const int bufLen = 128;
char buf[bufLen];
std::memset(buf, 0, bufLen);
OBJ_obj2txt(buf, bufLen, OBJ_nid2obj(nid), 0);

View File

@ -77,6 +77,7 @@ X509Certificate::X509Certificate(X509* pCert, bool shared):
X509Certificate::X509Certificate(const X509Certificate& cert):
_issuerName(cert._issuerName),
_subjectName(cert._subjectName),
_serialNumber(cert._serialNumber),
_pCert(cert._pCert)
{
_pCert = X509_dup(_pCert);
@ -96,6 +97,7 @@ void X509Certificate::swap(X509Certificate& cert)
using std::swap;
swap(cert._issuerName, _issuerName);
swap(cert._subjectName, _subjectName);
swap(cert._serialNumber, _serialNumber);
swap(cert._pCert, _pCert);
}
@ -199,6 +201,17 @@ void X509Certificate::init()
_issuerName = buffer;
X509_NAME_oneline(X509_get_subject_name(_pCert), buffer, sizeof(buffer));
_subjectName = buffer;
BIGNUM* pBN = ASN1_INTEGER_to_BN(X509_get_serialNumber(const_cast<X509*>(_pCert)), 0);
if (pBN)
{
char* pSN = BN_bn2hex(pBN);
if (pSN)
{
_serialNumber = pSN;
OPENSSL_free(pSN);
}
BN_free(pBN);
}
}
@ -296,6 +309,23 @@ bool X509Certificate::equals(const X509Certificate& otherCertificate) const
}
std::string X509Certificate::signatureAlgorithm() const
{
int sigNID = X509_get_signature_nid(_pCert);
if (sigNID != NID_undef)
{
const char* pAlgName = OBJ_nid2ln(sigNID);
if (pAlgName) return std::string(pAlgName);
else throw OpenSSLException(Poco::format("X509Certificate::"
"signatureAlgorithm(): OBJ_nid2ln(%d)", sigNID));
}
else
throw NotFoundException("X509Certificate::signatureAlgorithm()");
return "";
}
X509Certificate::List X509Certificate::readPEM(const std::string& pemFileName)
{
List caCertList;

View File

@ -100,7 +100,7 @@ void PKCS12ContainerTest::fullCert(const X509Certificate& x509)
std::string organizationName(x509.subjectName(X509Certificate::NID_ORGANIZATION_NAME));
std::string organizationUnitName(x509.subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME));
std::string emailAddress(x509.subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS));
std::string serialNumber(x509.subjectName(X509Certificate::NID_SERIAL_NUMBER));
std::string serialNumber(x509.serialNumber());
assert (subjectName == "/C=CH/ST=Zug/O=Crypto Vally/CN=CV Server");
assert (issuerName == "/C=CH/ST=Zug/O=Crypto Vally/CN=CV Intermediate CA v3");
@ -111,7 +111,9 @@ void PKCS12ContainerTest::fullCert(const X509Certificate& x509)
assert (organizationName == "Crypto Vally");
assert (organizationUnitName.empty());
assert (emailAddress.empty());
assert (serialNumber.empty());
assert (serialNumber == "1000");
assert (x509.version() == 3);
assert (x509.signatureAlgorithm() == "sha256WithRSAEncryption");
}
@ -136,7 +138,9 @@ void PKCS12ContainerTest::fullList(const PKCS12Container::CAList& caList,
assert (caList[certOrder[0]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Crypto Vally");
assert (caList[certOrder[0]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty());
assert (caList[certOrder[0]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty());
assert (caList[certOrder[0]].subjectName(X509Certificate::NID_SERIAL_NUMBER).empty());
assert (caList[certOrder[0]].serialNumber() == "C3ECA1FCEAA16055");
assert (caList[certOrder[0]].version() == 3);
assert (caList[certOrder[0]].signatureAlgorithm() == "sha256WithRSAEncryption");
assert (caList[certOrder[1]].subjectName() == "/C=CH/ST=Zug/O=Crypto Vally/CN=CV Intermediate CA v3");
assert (caList[certOrder[1]].issuerName() == "/C=CH/ST=Zug/O=Crypto Vally/CN=CV Root CA v3");
@ -147,7 +151,9 @@ void PKCS12ContainerTest::fullList(const PKCS12Container::CAList& caList,
assert (caList[certOrder[1]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Crypto Vally");
assert (caList[certOrder[1]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty());
assert (caList[certOrder[1]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty());
assert (caList[certOrder[1]].subjectName(X509Certificate::NID_SERIAL_NUMBER).empty());
assert (caList[certOrder[1]].serialNumber() == "1000");
assert (caList[certOrder[1]].version() == 3);
assert (caList[certOrder[1]].signatureAlgorithm() == "sha256WithRSAEncryption");
}
@ -205,7 +211,9 @@ void PKCS12ContainerTest::certsOnlyList(const PKCS12Container::CAList& caList,
assert (caList[certOrder[0]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Let's Encrypt");
assert (caList[certOrder[0]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty());
assert (caList[certOrder[0]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty());
assert (caList[certOrder[0]].subjectName(X509Certificate::NID_SERIAL_NUMBER).empty());
assert (caList[certOrder[0]].serialNumber() == "D3B17226342332DCF40528512AEC9C6A");
assert (caList[certOrder[0]].version() == 3);
assert (caList[certOrder[0]].signatureAlgorithm() == "sha256WithRSAEncryption");
assert (caList[certOrder[1]].subjectName() == "/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3");
assert (caList[certOrder[1]].issuerName() == "/O=Digital Signature Trust Co./CN=DST Root CA X3");
@ -216,7 +224,9 @@ void PKCS12ContainerTest::certsOnlyList(const PKCS12Container::CAList& caList,
assert (caList[certOrder[1]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Let's Encrypt");
assert (caList[certOrder[1]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty());
assert (caList[certOrder[1]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty());
assert (caList[certOrder[1]].subjectName(X509Certificate::NID_SERIAL_NUMBER).empty());
assert (caList[certOrder[1]].serialNumber() == "0A0141420000015385736A0B85ECA708");
assert (caList[certOrder[1]].version() == 3);
assert (caList[certOrder[1]].signatureAlgorithm() == "sha256WithRSAEncryption");
assert (caList[certOrder[2]].subjectName() == "/C=US/O=Internet Security Research Group/CN=ISRG Root X1");
assert (caList[certOrder[2]].issuerName() == "/C=US/O=Internet Security Research Group/CN=ISRG Root X1");
@ -227,7 +237,9 @@ void PKCS12ContainerTest::certsOnlyList(const PKCS12Container::CAList& caList,
assert (caList[certOrder[2]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Internet Security Research Group");
assert (caList[certOrder[2]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty());
assert (caList[certOrder[2]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty());
assert (caList[certOrder[2]].subjectName(X509Certificate::NID_SERIAL_NUMBER).empty());
assert (caList[certOrder[2]].serialNumber() == "8210CFB0D240E3594463E0BB63828B00");
assert (caList[certOrder[2]].version() == 3);
assert (caList[certOrder[2]].signatureAlgorithm() == "sha256WithRSAEncryption");
assert (caList[certOrder[3]].subjectName() == "/C=CH/ST=Zug/O=Crypto Vally/CN=CV Root CA v3");
assert (caList[certOrder[3]].issuerName() == "/C=CH/ST=Zug/O=Crypto Vally/CN=CV Root CA v3");
@ -238,7 +250,9 @@ void PKCS12ContainerTest::certsOnlyList(const PKCS12Container::CAList& caList,
assert (caList[certOrder[3]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Crypto Vally");
assert (caList[certOrder[3]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty());
assert (caList[certOrder[3]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty());
assert (caList[certOrder[3]].subjectName(X509Certificate::NID_SERIAL_NUMBER).empty());
assert (caList[certOrder[3]].serialNumber() == "C3ECA1FCEAA16055");
assert (caList[certOrder[3]].version() == 3);
assert (caList[certOrder[3]].signatureAlgorithm() == "sha256WithRSAEncryption");
assert (caList[certOrder[4]].subjectName() == "/C=CH/ST=Zug/O=Crypto Vally/CN=CV Intermediate CA v3");
assert (caList[certOrder[4]].issuerName() == "/C=CH/ST=Zug/O=Crypto Vally/CN=CV Root CA v3");
@ -249,7 +263,9 @@ void PKCS12ContainerTest::certsOnlyList(const PKCS12Container::CAList& caList,
assert (caList[certOrder[4]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Crypto Vally");
assert (caList[certOrder[4]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty());
assert (caList[certOrder[4]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty());
assert (caList[certOrder[4]].subjectName(X509Certificate::NID_SERIAL_NUMBER).empty());
assert (caList[certOrder[4]].serialNumber()== "1000");
assert (caList[certOrder[4]].version() == 3);
assert (caList[certOrder[4]].signatureAlgorithm() == "sha256WithRSAEncryption");
}