Import multiple certificates withing a single stream

This commit is contained in:
Xavier Guérin 2018-05-30 22:07:41 -04:00
parent 6ad4c1a0d5
commit df8051d8db
3 changed files with 100 additions and 0 deletions

View File

@ -85,6 +85,23 @@ public:
*/
static shared_ptr <X509Certificate> import(const byte_t* data, const size_t length);
/** Imports a DER or PEM encoded X.509 certificate.
*
* @param is input stream to read data from
* @param certs the resulting list of certificates
*/
static void import(utility::inputStream& is,
std::vector <shared_ptr <X509Certificate> >& certs);
/** Imports a DER or PEM encoded X.509 certificate.
*
* @param data points to raw data
* @param length size of data
* @param certs the resulting list of certificates
*/
static void import(const byte_t* data, const size_t length,
std::vector <shared_ptr <X509Certificate> >& certs);
/** Exports this X.509 certificate to the specified format.
*
* @param os output stream into which write data

View File

@ -56,6 +56,11 @@ struct GnuTLSX509CertificateInternalData
gnutls_x509_crt_deinit(cert);
}
void swap(gnutls_x509_crt_t to) {
gnutls_x509_crt_deinit(cert);
cert = to;
}
gnutls_x509_crt_t cert;
};
@ -128,6 +133,49 @@ shared_ptr <X509Certificate> X509Certificate::import
}
// static
void X509Certificate::import(utility::inputStream& is,
std::vector <shared_ptr <X509Certificate> >& certs)
{
byteArray bytes;
byte_t chunk[4096];
while (!is.eof())
{
const size_t len = is.read(chunk, sizeof(chunk));
bytes.insert(bytes.end(), chunk, chunk + len);
}
import(&bytes[0], bytes.size(), certs);
}
// static
void X509Certificate::import(const byte_t* data, const size_t length,
std::vector <shared_ptr <X509Certificate> >& certs)
{
gnutls_datum_t buffer;
buffer.data = const_cast <byte_t*>(data);
buffer.size = static_cast <unsigned int>(length);
unsigned int size = 1024;
gnutls_x509_crt_t x509[1024];
// Try DER format
if (gnutls_x509_crt_list_import(x509, &size, &buffer, GNUTLS_X509_FMT_DER, 0) < 0)
// Try PEM format
if (gnutls_x509_crt_list_import(x509, &size, &buffer, GNUTLS_X509_FMT_PEM, 0) < 0)
return;
for (unsigned int i = 0; i < size; i += 1) {
auto c = make_shared <X509Certificate_GnuTLS>();
c->m_data->swap(x509[i]);
certs.push_back(c);
}
}
void X509Certificate_GnuTLS::write
(utility::outputStream& os, const Format format) const
{

View File

@ -218,6 +218,41 @@ shared_ptr <X509Certificate> X509Certificate::import
}
// static
void X509Certificate::import(utility::inputStream& is,
std::vector <shared_ptr <X509Certificate> >& certs)
{
byteArray bytes;
byte_t chunk[4096];
while (!is.eof())
{
const size_t len = is.read(chunk, sizeof(chunk));
bytes.insert(bytes.end(), chunk, chunk + len);
}
import(&bytes[0], bytes.size(), certs);
}
// static
void X509Certificate::import(const byte_t* data, const size_t length,
std::vector <shared_ptr <X509Certificate> >& certs)
{
BIO* membio = BIO_new_mem_buf(const_cast <byte_t*>(data), static_cast <int>(length));
shared_ptr <X509Certificate_OpenSSL> cert = null;
while (true) {
cert = make_shared <X509Certificate_OpenSSL>();
if (!PEM_read_bio_X509(membio, &(cert->m_data->cert), 0, 0)) break;
certs.push_back(cert);
}
BIO_vfree(membio);
}
void X509Certificate_OpenSSL::write
(utility::outputStream& os, const Format format) const
{