aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.cpp
blob: 9a2548d7e99225a20043d8e7f5c7ba9e79862475 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "make_tls_options_for_testing.h"
#include "peer_policy_utils.h"
#include <vespa/vespalib/crypto/private_key.h>
#include <vespa/vespalib/crypto/x509_certificate.h>

namespace {

using namespace vespalib::crypto;
using namespace vespalib::net::tls;

struct TransientCryptoCredentials {
    CertKeyWrapper root_ca;
    CertKeyWrapper host_creds;
    vespalib::net::tls::TransportSecurityOptions cached_transport_options;
    vespalib::net::tls::TransportSecurityOptions cached_constrained_transport_options;

    TransientCryptoCredentials();
    ~TransientCryptoCredentials();

    static CertKeyWrapper make_root_ca() {
        auto dn = X509Certificate::DistinguishedName()
                .country("US").state("CA").locality("Sunnyvale")
                .organization("ACME, Inc.")
                .organizational_unit("ACME Root CA")
                .add_common_name("acme.example.com");
        auto subject = X509Certificate::SubjectInfo(std::move(dn));
        auto key = PrivateKey::generate_p256_ec_key();
        auto params = X509Certificate::Params::self_signed(std::move(subject), key);
        auto cert = X509Certificate::generate_from(std::move(params));
        return {std::move(cert), std::move(key)};
    }

    static CertKeyWrapper make_host_creds(const CertKeyWrapper& root_ca_creds,
                                          const vespalib::string& extra_san_entry) {
        auto dn = X509Certificate::DistinguishedName()
                .country("US").state("CA").locality("Sunnyvale")
                .organization("Wile E. Coyote, Ltd.")
                .organizational_unit("Unit Testing and Anvil Dropping Division")
                .add_common_name("localhost"); // Should technically not be needed, but including it anyway.
        auto subject = X509Certificate::SubjectInfo(std::move(dn));
        subject.add_subject_alt_name("DNS:localhost")
               .add_subject_alt_name(extra_san_entry);
        auto key = PrivateKey::generate_p256_ec_key();
        auto params = X509Certificate::Params::issued_by(std::move(subject), key, root_ca_creds.cert, root_ca_creds.key);
        params.valid_for = std::chrono::hours(1);
        auto cert = X509Certificate::generate_from(std::move(params));
        return {std::move(cert), std::move(key)};
    }

    static const TransientCryptoCredentials& instance();
};

TransientCryptoCredentials::TransientCryptoCredentials()
    : root_ca(make_root_ca()),
      host_creds(make_host_creds(root_ca, "DNS:anvils.example")),
      cached_transport_options(vespalib::net::tls::TransportSecurityOptions::Params().
            ca_certs_pem(root_ca.cert->to_pem()).
            cert_chain_pem(host_creds.cert->to_pem()).
            private_key_pem(host_creds.key->private_to_pem()).
            authorized_peers(vespalib::net::tls::AuthorizedPeers::allow_all_authenticated())),
      cached_constrained_transport_options(vespalib::net::tls::TransportSecurityOptions::Params().
            ca_certs_pem(root_ca.cert->to_pem()).
            cert_chain_pem(host_creds.cert->to_pem()).
            private_key_pem(host_creds.key->private_to_pem()).
            authorized_peers(authorized_peers({policy_with({required_san_dns("anvils.example")},
                                                           CapabilitySet::telemetry())})))
{}

TransientCryptoCredentials::~TransientCryptoCredentials() = default;

const TransientCryptoCredentials& TransientCryptoCredentials::instance() {
    static TransientCryptoCredentials test_creds;
    return test_creds;
}

}

namespace vespalib::test {

SocketSpec make_local_spec() {
    return SocketSpec("tcp/localhost:123");
}

vespalib::net::tls::TransportSecurityOptions make_tls_options_for_testing() {
    return TransientCryptoCredentials::instance().cached_transport_options;
}

vespalib::net::tls::TransportSecurityOptions make_telemetry_only_capability_tls_options_for_testing() {
    return TransientCryptoCredentials::instance().cached_constrained_transport_options;
}

} // namespace vespalib::test