Skip to content

Commit

Permalink
ca
Browse files Browse the repository at this point in the history
  • Loading branch information
dayu521 committed Feb 9, 2024
1 parent fc51f51 commit 7340259
Show file tree
Hide file tree
Showing 14 changed files with 334 additions and 80 deletions.
21 changes: 13 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

[harddns](https://github.com/stealth/harddns)

[openssl-sign-by-ca](https://github.com/zozs/openssl-sign-by-ca/)

### 编译

需要c++20,使用xmake构建
Expand All @@ -30,16 +32,19 @@ windows使用最新编译器
xmake run hcpp
```

#### 例子

当前测试了三个主机,`github.com`,`gitee.com`,`www.baidu.com`.这三者由mitm代理.使用下面的自签名的`ca证书`,签名了服务的证书.服务的证书包含了上述三个主机名
#### 运行

其余主机都是正常的http proxy或者http tunnel代理
当前会在配置文件指定的目录(例如 ~/.config/hcpp/)下生成自签名的ca密钥和ca证书

[ca证书](doc/cert/ca.crt),可以导入浏览器
浏览器需要信任该ca证书

下面的证书和密钥需要放到程序运行目录
使用curl直接进行测试

- 使用的[证书](doc/cert/server.crt.pem),由密钥生成,被ca签名
```shell
curl -i -x http://localhost:55555 -v --cacert ~/.config/hcpp/ca.cert.pem 'https://gitee.com'
```

- 使用的[密钥](doc/cert/server.key.pem)
或者
```shell
curl -i -x http://localhost:55555 -vk 'https://gitee.com'
```
2 changes: 1 addition & 1 deletion action_xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ target("hcpp")
add_packages("lsf",{public = true})

add_includedirs("src",{public = true})
add_files("src/*.cpp","src/https/*.cpp","src/http/*.cpp","src/dns/*.cc")
add_files("src/*.cpp","src/https/*.cpp","src/http/*.cpp","src/dns/*.cc","src/certificate/*.cpp")
add_files("main.cpp")

set_policy("build.c++.modules", true)
Expand Down
4 changes: 3 additions & 1 deletion main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ int main(int argc, char **argv)

hcpp::httpserver hs;
hcpp::mimt_https_server mhs;
c->config_to(mhs);
if(!c->config_to(mhs)){
return -1;
}

hs.attach_tunnel([&mhs](auto &&c, auto h, auto s)
{
Expand Down
92 changes: 66 additions & 26 deletions src/certificate/cert.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "cert.h"

#include <cstring>
#include <stdexcept>

#include <openssl/bio.h>

// X509_new
namespace hcpp
Expand Down Expand Up @@ -77,9 +80,8 @@ namespace hcpp

// Issuer
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.4
void add_issuer(X509 *cert, std::string_view name2)
void set_issuer(X509 *cert, const std::vector<name_entry> &ne)
{
// auto issuer = X509_NAME_new();
// * country,
// * organization,
// * organizational unit,
Expand All @@ -89,24 +91,10 @@ namespace hcpp
// x serial number.

// * locality
struct name_entry
{
int nid_;
const char *nid_val_;
int nid_val_len_;
};
name_entry issuer[] = {
{NID_countryName, "CN", sizeof("CN") - 1},
{NID_organizationName, "NoBody", sizeof("NoBody") - 1},
{NID_organizationalUnitName, "XX", sizeof("XX") - 1},
{NID_stateOrProvinceName, "JS", sizeof("JS") - 1},
{NID_commonName, "SelfCA", sizeof("SelfCA") - 1},
{NID_localityName, "SQ", sizeof("SQ") - 1},
};

auto name = X509_NAME_new();

for (auto &&i : issuer)
for (auto &&i : ne)
{
X509_NAME_add_entry_by_NID(name, i.nid_, MBSTRING_ASC, (const unsigned char *)i.nid_val_, i.nid_val_len_, -1, 0);
}
Expand All @@ -132,10 +120,18 @@ namespace hcpp

// Subject
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.6
void set_subject(X509 *cert)
void set_subject(X509 *cert, const std::vector<name_entry> &ne)
{
auto name = X509_NAME_new();

for (auto &&i : ne)
{
X509_NAME_add_entry_by_NID(name, i.nid_, MBSTRING_ASC, (const unsigned char *)i.nid_val_, i.nid_val_len_, -1, 0);
}
X509_set_subject_name(cert, name);
X509_NAME_free(name);
// X509_set_subject_name get X509_NAME hashes or get and set issuer or subject names
X509_set_subject_name(cert, X509_get_issuer_name(cert));
// X509_set_subject_name(cert, X509_get_issuer_name(cert));
}

// Subject Public Key Info
Expand Down Expand Up @@ -207,15 +203,22 @@ namespace hcpp

// Subject Alternative Name
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.6
void add_DNS_SAN(X509 *caCert, std::string_view dns_name)
void add_DNS_SAN(X509 *caCert, const std::vector<std::string> &dns_names)
{
if (dns_names.empty())
{
return;
}
GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null();

GENERAL_NAME *gen_dns = GENERAL_NAME_new();
ASN1_IA5STRING *ia5 = ASN1_IA5STRING_new();
ASN1_STRING_set(ia5, dns_name.data(), dns_name.length());
GENERAL_NAME_set0_value(gen_dns, GEN_DNS, ia5);
sk_GENERAL_NAME_push(gens, gen_dns);
for (auto &dns_name : dns_names)
{
GENERAL_NAME *gen_dns = GENERAL_NAME_new();
ASN1_IA5STRING *ia5 = ASN1_IA5STRING_new();
ASN1_STRING_set(ia5, dns_name.data(), dns_name.length());
GENERAL_NAME_set0_value(gen_dns, GEN_DNS, ia5);
sk_GENERAL_NAME_push(gens, gen_dns);
}

// in_addr_t ipv4 = inet_addr("10.0.0.1");
// GENERAL_NAME *gen_ip = GENERAL_NAME_new();
Expand Down Expand Up @@ -272,14 +275,51 @@ namespace hcpp
return pkey_array;
}

X509 *make_x509(const std::string_view cert)
{
auto bp = BIO_new_mem_buf(cert.data(), cert.size());
if (bp == nullptr)
{
throw std::runtime_error("bio 打开失败");
}
auto c = PEM_read_bio_X509(bp, NULL, 0, NULL);
if (c == nullptr)
{
throw std::runtime_error("make_x509 failed");
}
BIO_free(bp);
return c;
}

EVP_PKEY *make_pkey(const std::string_view pkey)
{
auto bp = BIO_new_mem_buf(pkey.data(), pkey.size());
if (bp == nullptr)
{
throw std::runtime_error("bio 打开失败");
}
auto p = PEM_read_bio_PrivateKey(bp, nullptr, nullptr, nullptr);
if (p == nullptr)
{
throw std::runtime_error("读取密钥错误");
}
BIO_free(bp);
return p;
}

void add_issuer(X509 *cert, X509 *ca_cert)
{
X509_set_issuer_name(cert, X509_get_subject_name(ca_cert));
}

void test()
{

auto cert = X509_new();

auto pkey = generate_pkey();
// if (pkey == NULL)
// CHECK(false);
// CHECK(false);
// print_key(pkey);

// set_version(cert);
Expand Down
39 changes: 33 additions & 6 deletions src/certificate/cert.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,53 @@
#include <openssl/rand.h>

#include <string>
#include <vector>

namespace hcpp
{
X509 * make_x509();
EVP_PKEY * make_pkey();
struct name_entry
{
int nid_;
const char *nid_val_;
int nid_val_len_;
};

X509 *make_x509();
EVP_PKEY *make_pkey();
void set_version(X509 *cert);
void set_serialNumber(X509 *cert);
void add_issuer(X509 *cert,std::string_view name);
void set_validity(X509 *cert,std::size_t days=365*10);
void set_subject(X509 *cert);
void set_issuer(X509 *cert, const std::vector<name_entry> &ne = {
{NID_countryName, "CN", sizeof("CN") - 1},
{NID_organizationName, "NoBody", sizeof("NoBody") - 1},
{NID_organizationalUnitName, "JS", sizeof("JS") - 1},
{NID_stateOrProvinceName, "JS", sizeof("JS") - 1},
{NID_commonName, "SQ", sizeof("SQ") - 1},
{NID_localityName, "SQ", sizeof("SQ") - 1},
});
void set_validity(X509 *cert, std::size_t days = 365 * 10);
void set_subject(X509 *cert, const std::vector<name_entry> &ne = {
{NID_countryName, "CN", sizeof("CN") - 1},
{NID_organizationName, "NoBody", sizeof("NoBody") - 1},
{NID_organizationalUnitName, "JS", sizeof("JS") - 1},
{NID_stateOrProvinceName, "JS", sizeof("JS") - 1},
{NID_commonName, "SQ", sizeof("SQ") - 1},
{NID_localityName, "SQ", sizeof("SQ") - 1},
});
void set_pubkey(X509 *cert, EVP_PKEY *pkey);
void add_ca_key_usage(X509 *cert);
void add_SKI(X509 *cert);
void add_AKI(X509 *cert);
void add_DNS_SAN(X509 *cert, std::string_view dns_name);
void add_DNS_SAN(X509 *cert, const std::vector<std::string> &dns_names);
void add_ca_BS(X509 *cert);
void sign(X509 *cert, EVP_PKEY *pkey);

std::string make_pem_str(X509 *cert);
std::string make_pem_str(EVP_PKEY *pkey);

X509 *make_x509(const std::string_view cert);
EVP_PKEY *make_pkey(const std::string_view pkey);

void add_issuer(X509 *cert, X509 *ca_cert);
} // namespace hcpp

#endif /* SRC_CERTIFICATE_CERT */
Loading

0 comments on commit 7340259

Please sign in to comment.