Add support for utf-8 characters in subject

This changes the format produced by OpenSSL from being separated by / to ,
This commit is contained in:
Pascal Bach 2019-12-17 12:09:41 +01:00
parent 7c177b6f89
commit 69a7f53b02
3 changed files with 78 additions and 20 deletions

View File

@ -38,7 +38,6 @@
namespace Poco {
namespace Crypto {
X509Certificate::X509Certificate(std::istream& istr):
_pCert(0)
{
@ -200,13 +199,21 @@ void X509Certificate::save(const std::string& path) const
}
std::string _X509_NAME_oneline_utf8(X509_NAME *name)
{
BIO * bio_out = BIO_new(BIO_s_mem());
X509_NAME_print_ex(bio_out, name, 0, (ASN1_STRFLGS_RFC2253 | XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_FN_SN | XN_FLAG_DUMP_UNKNOWN_FIELDS) & ~ASN1_STRFLGS_ESC_MSB);
BUF_MEM *bio_buf;
BIO_get_mem_ptr(bio_out, &bio_buf);
std::string line = std::string(bio_buf->data, bio_buf->length);
BIO_free(bio_out);
return line;
}
void X509Certificate::init()
{
char buffer[NAME_BUFFER_SIZE];
X509_NAME_oneline(X509_get_issuer_name(_pCert), buffer, sizeof(buffer));
_issuerName = buffer;
X509_NAME_oneline(X509_get_subject_name(_pCert), buffer, sizeof(buffer));
_subjectName = buffer;
_issuerName = _X509_NAME_oneline_utf8(X509_get_issuer_name(_pCert));
_subjectName = _X509_NAME_oneline_utf8(X509_get_subject_name(_pCert));
BIGNUM* pBN = ASN1_INTEGER_to_BN(X509_get_serialNumber(const_cast<X509*>(_pCert)), 0);
if (pBN)
{

View File

@ -54,6 +54,27 @@ static const std::string APPINF_PEM(
"-----END CERTIFICATE-----\n"
);
static const std::string UTF8_PEM(
"-----BEGIN CERTIFICATE-----\n"
"MIIDEzCCArigAwIBAgIQAKegojl/YLNUPqTyCnQ4LzAKBggqhkjOPQQDAjB0MQsw\n"
"CQYDVQQGEwJDSDEQMA4GA1UECgwHU2llbWVuczEUMBIGA1UECwwLQlQgRGl2aXNp\n"
"b24xPTA7BgNVBAMMNEt1cnpSUzFNUDIyc3ByaW50NTlwcmVWVlMgcHJvamVjdCBp\n"
"bnRlcm1lZGlhdGUgQ0EgRUMwHhcNMTkxMTI3MDAwMDAwWhcNMjQxMTI4MTkzMzQw\n"
"WjCCAQMxJDAiBgNVBAUTG1BJRDpQWEM1LkUwMDMgU046MTQwMDA0RDhFMjELMAkG\n"
"A1UEBhMCQ0gxEDAOBgNVBAoMB1NpZW1lbnMxFzAVBgNVBAsMDlNJIEJQIERpdmlz\n"
"aW9uMQwwCgYDVQQIDANadWcxHjAcBgNVBAcMFVrDpGhsZXJ3ZWcgNyBSb29tIDU0\n"
"NDEnMCUGCSqGSIb3DQEJARYYcmljaGFyZC5rdXJ6QHNpZW1lbnMuY29tMRgwFgYD\n"
"VQQLDA9TU0wgQ2VydGlmaWNhdGUxMjAwBgNVBAMMKUt1cnpSUzFNUDIyc3ByaW50\n"
"NTlwcmVWVlMuS3VyUFhDNUJOUjM3NjUyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n"
"QgAEJjy+wx/mN9FbW3/IoOAOXdbfQvF1gF8wNasHUeLdn1UsCABnaAZTytqX7gMD\n"
"Y5HS32SIvdULYwsy6Dn3CO5tVKOBmjCBlzAOBgNVHQ8BAf8EBAMCA6gwIAYDVR0l\n"
"AQH/BBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0O\n"
"BBYEFIbtuXQJoVh7FlYiWZeWT2ooEQRNMB8GA1UdIwQYMBaAFOtUSuT1OYK7bNS4\n"
"Mqz0UGPoGavuMBUGA1UdEQQOMAyHBAqqt7SHBMCo/AEwCgYIKoZIzj0EAwIDSQAw\n"
"RgIhANBQnB1HFLHp7t8oZbLYsm8nWI0hshmVQupXV9oFwb4qAiEAg5UqSDnvAax3\n"
"LWWgnAZJkUS0AEQXu4Rx9ZiP7wBdFtA=\n"
"-----END CERTIFICATE-----\n"
);
CryptoTest::CryptoTest(const std::string& name): CppUnit::TestCase(name)
{
@ -327,7 +348,7 @@ void CryptoTest::testCertificate()
std::string organizationName(cert.subjectName(X509Certificate::NID_ORGANIZATION_NAME));
std::string organizationUnitName(cert.subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME));
assertTrue (subjectName == "/CN=appinf.com/O=Applied Informatics Software Engineering GmbH/OU=Development/ST=Carinthia/C=AT/L=St. Jakob im Rosental/emailAddress=guenter.obiltschnig@appinf.com");
assertTrue (subjectName == "CN=appinf.com,O=Applied Informatics Software Engineering GmbH,OU=Development,ST=Carinthia,C=AT,L=St. Jakob im Rosental,emailAddress=guenter.obiltschnig@appinf.com");
assertTrue (issuerName == subjectName);
assertTrue (commonName == "appinf.com");
assertTrue (country == "AT");
@ -337,7 +358,7 @@ void CryptoTest::testCertificate()
assertTrue (organizationUnitName == "Development");
// fails with recent OpenSSL versions:
// assertTrue (cert.issuedBy(cert));
// assert (cert.issuedBy(cert));
std::istringstream otherCertStream(APPINF_PEM);
X509Certificate otherCert(otherCertStream);
@ -345,6 +366,34 @@ void CryptoTest::testCertificate()
assertTrue (cert.equals(otherCert));
}
void CryptoTest::testCertificateUTF8()
{
std::istringstream certStream(UTF8_PEM);
X509Certificate cert(certStream);
std::string subjectName(cert.subjectName());
std::string issuerName(cert.issuerName());
std::string commonName(cert.commonName());
std::string country(cert.subjectName(X509Certificate::NID_COUNTRY));
std::string localityName(cert.subjectName(X509Certificate::NID_LOCALITY_NAME));
std::string stateOrProvince(cert.subjectName(X509Certificate::NID_STATE_OR_PROVINCE));
std::string organizationName(cert.subjectName(X509Certificate::NID_ORGANIZATION_NAME));
std::string organizationUnitName(cert.subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME));
assertTrue (subjectName == "serialNumber=PID:PXC5.E003 SN:140004D8E2,C=CH,O=Siemens,OU=SI BP Division,ST=Zug,L=Zählerweg 7 Room 544,emailAddress=richard.kurz@siemens.com,OU=SSL Certificate,CN=KurzRS1MP22sprint59preVVS.KurPXC5BNR37652");
assertTrue (commonName == "KurzRS1MP22sprint59preVVS.KurPXC5BNR37652");
assertTrue (country == "CH");
assertTrue (localityName == "Zählerweg 7 Room 544");
assertTrue (stateOrProvince == "Zug");
assertTrue (organizationName == "Siemens");
assertTrue (organizationUnitName == "SI BP Division");
std::istringstream otherCertStream(UTF8_PEM);
X509Certificate otherCert(otherCertStream);
assertTrue (cert.equals(otherCert));
}
void CryptoTest::setUp()
{
@ -371,6 +420,7 @@ CppUnit::Test* CryptoTest::suite()
CppUnit_addTest(pSuite, CryptoTest, testDecryptInterop);
CppUnit_addTest(pSuite, CryptoTest, testStreams);
CppUnit_addTest(pSuite, CryptoTest, testCertificate);
CppUnit_addTest(pSuite, CryptoTest, testCertificateUTF8);
return pSuite;
}

View File

@ -40,6 +40,7 @@ public:
void testEncryptInterop();
void testDecryptInterop();
void testCertificate();
void testCertificateUTF8();
void setUp();
void tearDown();