9
9
#include " certificate.hpp"
10
10
#include " threadpool.hpp"
11
11
12
+ #include < algorithm>
12
13
#include < cassert>
13
14
#include < chrono>
14
15
#include < iomanip>
@@ -384,9 +385,16 @@ Certificate Certificate::FromString(string crt_pem, string key_pem) {
384
385
BIO *bio = BIO_new (BIO_s_mem ());
385
386
BIO_write (bio, crt_pem.data (), int (crt_pem.size ()));
386
387
auto x509 = shared_ptr<X509>(PEM_read_bio_X509 (bio, nullptr , nullptr , nullptr ), X509_free);
387
- BIO_free (bio);
388
- if (!x509)
388
+ if (!x509) {
389
+ BIO_free (bio);
389
390
throw std::invalid_argument (" Unable to import PEM certificate" );
391
+ }
392
+ std::vector<shared_ptr<X509>> chain;
393
+ while (auto extra =
394
+ shared_ptr<X509>(PEM_read_bio_X509 (bio, nullptr , nullptr , nullptr ), X509_free)) {
395
+ chain.push_back (std::move (extra));
396
+ }
397
+ BIO_free (bio);
390
398
391
399
bio = BIO_new (BIO_s_mem ());
392
400
BIO_write (bio, key_pem.data (), int (key_pem.size ()));
@@ -396,7 +404,7 @@ Certificate Certificate::FromString(string crt_pem, string key_pem) {
396
404
if (!pkey)
397
405
throw std::invalid_argument (" Unable to import PEM key" );
398
406
399
- return Certificate (x509, pkey);
407
+ return Certificate (x509, pkey, std::move (chain) );
400
408
}
401
409
402
410
Certificate Certificate::FromFile (const string &crt_pem_file, const string &key_pem_file,
@@ -408,9 +416,16 @@ Certificate Certificate::FromFile(const string &crt_pem_file, const string &key_
408
416
throw std::invalid_argument (" Unable to open PEM certificate file" );
409
417
410
418
auto x509 = shared_ptr<X509>(PEM_read_bio_X509 (bio, nullptr , nullptr , nullptr ), X509_free);
411
- BIO_free (bio);
412
- if (!x509)
419
+ if (!x509) {
420
+ BIO_free (bio);
413
421
throw std::invalid_argument (" Unable to import PEM certificate from file" );
422
+ }
423
+ std::vector<shared_ptr<X509>> chain;
424
+ while (auto extra =
425
+ shared_ptr<X509>(PEM_read_bio_X509 (bio, nullptr , nullptr , nullptr ), X509_free)) {
426
+ chain.push_back (std::move (extra));
427
+ }
428
+ BIO_free (bio);
414
429
415
430
bio = openssl::BIO_new_from_file (key_pem_file);
416
431
if (!bio)
@@ -423,7 +438,7 @@ Certificate Certificate::FromFile(const string &crt_pem_file, const string &key_
423
438
if (!pkey)
424
439
throw std::invalid_argument (" Unable to import PEM key from file" );
425
440
426
- return Certificate (x509, pkey);
441
+ return Certificate (x509, pkey, std::move (chain) );
427
442
}
428
443
429
444
Certificate Certificate::Generate (CertificateType type, const string &commonName) {
@@ -514,14 +529,23 @@ Certificate Certificate::Generate(CertificateType type, const string &commonName
514
529
return Certificate (x509, pkey);
515
530
}
516
531
517
- Certificate::Certificate (shared_ptr<X509> x509, shared_ptr<EVP_PKEY> pkey)
518
- : mX509(std::move(x509)), mPKey(std::move(pkey)),
532
+ Certificate::Certificate (shared_ptr<X509> x509, shared_ptr<EVP_PKEY> pkey,
533
+ std::vector<shared_ptr<X509>> chain)
534
+ : mX509(std::move(x509)), mPKey(std::move(pkey)), mChain(std::move(chain)),
519
535
mFingerprint(make_fingerprint(mX509 .get(), CertificateFingerprint::Algorithm::Sha256)) {}
520
536
521
537
std::tuple<X509 *, EVP_PKEY *> Certificate::credentials () const {
522
538
return {mX509 .get (), mPKey .get ()};
523
539
}
524
540
541
+ std::vector<X509 *> Certificate::chain () const {
542
+ std::vector<X509 *> v;
543
+ v.reserve (mChain .size ());
544
+ std::transform (mChain .begin (), mChain .end (), std::back_inserter (v),
545
+ [](const auto &c) { return c.get (); });
546
+ return v;
547
+ }
548
+
525
549
string make_fingerprint (X509 *x509, CertificateFingerprint::Algorithm fingerprintAlgorithm) {
526
550
size_t size = CertificateFingerprint::AlgorithmSize (fingerprintAlgorithm);
527
551
std::vector<unsigned char > buffer (size);
0 commit comments