Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- std::vector<std::string> fetchCertChain(const std::string& host, int port) {
- std::vector<std::string> certPaths;
- SSL_library_init();
- SSL_load_error_strings();
- SSL_CTX* ctx = nullptr;
- SSL* ssl = nullptr;
- BIO* bio = nullptr;
- auto cleanup = [&]() {
- if (bio)
- BIO_free_all(bio);
- if (ctx)
- SSL_CTX_free(ctx);
- };
- const SSL_METHOD* method = TLS_client_method();
- ctx = SSL_CTX_new(method);
- bio = BIO_new_ssl_connect(ctx);
- BIO_get_ssl(bio, &ssl);
- SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
- std::string target = host + ":" + std::to_string(port);
- const auto pos = target.find("://");
- if (pos != std::string::npos) {
- target.erase(0, pos + 3);
- }
- BIO_set_conn_hostname(bio, target.c_str());
- if (BIO_do_connect(bio) <= 0) {
- std::cerr << "Connection failed\n";
- cleanup();
- return certPaths;
- }
- STACK_OF(X509)* certs = SSL_get_peer_cert_chain(ssl);
- if (!certs) {
- std::cerr << "No cert chain received.\n";
- cleanup();
- return certPaths;
- }
- for (int i = 0; i < sk_X509_num(certs); ++i) {
- X509* cert = sk_X509_value(certs, i);
- // X509_NAME* subj = X509_get_subject_name(cert);
- const std::string name = getCertSha1(cert);
- // std::string name = getSubjectField(cert, NID_commonName);
- // if (name.empty())
- // name = getCertSha1(cert);
- // std::cout << "name: " << name << "\n";
- // const std::string name = "cert_" + std::to_string(i) + ".pem";
- //// const std::string name = "cert_" + std::to_string(i) + ".pem";
- const fs::path certPath = getPath() / name;
- // fs::path derPath{certPath};
- // derPath.replace_extension(".der");
- FILE* fp = fopen(certPath.c_str(), "w");
- if (fp) {
- PEM_write_X509(fp, cert);
- fclose(fp);
- certPaths.push_back(certPath);
- // ::convertPemToDer(pemPath, derPath);
- std::cout << "Saved: " << certPath << "\n";
- }
- }
- // BIO_free_all(bio);
- // SSL_CTX_free(ctx);
- cleanup();
- return certPaths;
- }
Advertisement
Add Comment
Please, Sign In to add comment