1e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz/*
2e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz * Copyright (C) 2017 The Android Open Source Project
3e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz *
4e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz * Licensed under the Apache License, Version 2.0 (the "License");
5e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz * you may not use this file except in compliance with the License.
6e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz * You may obtain a copy of the License at
7e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz *
8e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz *      http://www.apache.org/licenses/LICENSE-2.0
9e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz *
10e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz * Unless required by applicable law or agreed to in writing, software
11e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz * distributed under the License is distributed on an "AS IS" BASIS,
12e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz * See the License for the specific language governing permissions and
14e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz * limitations under the License.
15e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz */
16e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
17e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include "dns_tls_frontend.h"
18e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
19e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <netdb.h>
20e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <stdio.h>
21e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <unistd.h>
22e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <sys/poll.h>
23e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <sys/socket.h>
24e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <sys/types.h>
25e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <arpa/inet.h>
26e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <openssl/err.h>
27e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <openssl/evp.h>
28e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <openssl/ssl.h>
29e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
30e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#define LOG_TAG "DnsTlsFrontend"
31e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <log/log.h>
32e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
33e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#include <unistd.h>
34e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
35e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartznamespace {
36e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
37e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartzconst int SHA256_SIZE = 32;
38e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
39e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz// Copied from DnsTlsTransport.
40e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartzbool getSPKIDigest(const X509* cert, std::vector<uint8_t>* out) {
41e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    int spki_len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
42e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    unsigned char spki[spki_len];
43e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    unsigned char* temp = spki;
44e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (spki_len != i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp)) {
45e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("SPKI length mismatch");
46e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
47e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
48e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    out->resize(SHA256_SIZE);
49e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    unsigned int digest_len = 0;
50e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    int ret = EVP_Digest(spki, spki_len, out->data(), &digest_len, EVP_sha256(), NULL);
51e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (ret != 1) {
52e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("Server cert digest extraction failed");
53e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
54e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
55e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (digest_len != out->size()) {
56e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("Wrong digest length: %d", digest_len);
57e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
58e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
59e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    return true;
60e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}
61e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
62e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartzstd::string errno2str() {
63e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    char error_msg[512] = { 0 };
64e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (strerror_r(errno, error_msg, sizeof(error_msg)))
65e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return std::string();
66e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    return std::string(error_msg);
67e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}
68e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
69e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz#define APLOGI(fmt, ...) ALOGI(fmt ": [%d] %s", __VA_ARGS__, errno, errno2str().c_str())
70e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
71e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartzstd::string addr2str(const sockaddr* sa, socklen_t sa_len) {
72e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    char host_str[NI_MAXHOST] = { 0 };
73e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    int rv = getnameinfo(sa, sa_len, host_str, sizeof(host_str), nullptr, 0,
74e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz                         NI_NUMERICHOST);
75e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (rv == 0) return std::string(host_str);
76e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    return std::string();
77e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}
78e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
791ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartzbssl::UniquePtr<EVP_PKEY> make_private_key() {
801ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    bssl::UniquePtr<BIGNUM> e(BN_new());
81e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (!e) {
82e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("BN_new failed");
83e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return nullptr;
84e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
851ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    if (!BN_set_word(e.get(), RSA_F4)) {
86e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("BN_set_word failed");
87e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return nullptr;
88e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
89e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
901ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    bssl::UniquePtr<RSA> rsa(RSA_new());
91e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (!rsa) {
92e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("RSA_new failed");
93e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return nullptr;
94e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
951ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    if (!RSA_generate_key_ex(rsa.get(), 2048, e.get(), NULL)) {
96e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("RSA_generate_key_ex failed");
97e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return nullptr;
98e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
99e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
1001ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    bssl::UniquePtr<EVP_PKEY> privkey(EVP_PKEY_new());
101e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (!privkey) {
102e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("EVP_PKEY_new failed");
103e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return nullptr;
104e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
1051ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    if(!EVP_PKEY_assign_RSA(privkey.get(), rsa.get())) {
106e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("EVP_PKEY_assign_RSA failed");
107e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return nullptr;
108e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
109e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
110e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    // |rsa| is now owned by |privkey|, so no need to free it.
1111ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    rsa.release();
112e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    return privkey;
113e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}
114e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
1151ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartzbssl::UniquePtr<X509> make_cert(EVP_PKEY* privkey) {
1161ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    bssl::UniquePtr<X509> cert(X509_new());
117e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (!cert) {
118e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("X509_new failed");
119e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return nullptr;
120e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
121e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
1221ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    ASN1_INTEGER_set(X509_get_serialNumber(cert.get()), 1);
123e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
124e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    // Set one hour expiration.
1251ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    X509_gmtime_adj(X509_get_notBefore(cert.get()), 0);
1261ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    X509_gmtime_adj(X509_get_notAfter(cert.get()), 60 * 60);
127e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
1281ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    X509_set_pubkey(cert.get(), privkey);
129e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
1301ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    if (!X509_sign(cert.get(), privkey, EVP_sha256())) {
131e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("X509_sign failed");
132e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return nullptr;
133e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
134e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
135e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    return cert;
136e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}
137e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
138e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}
139e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
140e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartznamespace test {
141e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
142e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartzbool DnsTlsFrontend::startServer() {
143e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    SSL_load_error_strings();
144e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    OpenSSL_add_ssl_algorithms();
145e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
1461ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    ctx_.reset(SSL_CTX_new(TLS_server_method()));
147e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (!ctx_) {
148e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("SSL context creation failed");
149e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
150e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
151e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
1521ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    SSL_CTX_set_ecdh_auto(ctx_.get(), 1);
153e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
1541ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    bssl::UniquePtr<EVP_PKEY> key(make_private_key());
1551ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    bssl::UniquePtr<X509> cert(make_cert(key.get()));
1561ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    if (SSL_CTX_use_certificate(ctx_.get(), cert.get()) <= 0) {
157e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("SSL_CTX_use_certificate failed");
158e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
159e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
160e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
1611ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    if (!getSPKIDigest(cert.get(), &fingerprint_)) {
162e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("getSPKIDigest failed");
163e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
164e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
165e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
1661ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    if (SSL_CTX_use_PrivateKey(ctx_.get(), key.get()) <= 0 ) {
167e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("SSL_CTX_use_PrivateKey failed");
168e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
169e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
170e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
171e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    // Set up TCP server socket for clients.
172e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    addrinfo frontend_ai_hints{
173e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        .ai_family = AF_UNSPEC,
174e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        .ai_socktype = SOCK_STREAM,
175e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        .ai_flags = AI_PASSIVE
176e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    };
177e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    addrinfo* frontend_ai_res;
178e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    int rv = getaddrinfo(listen_address_.c_str(), listen_service_.c_str(),
179e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz                         &frontend_ai_hints, &frontend_ai_res);
180e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (rv) {
181e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("frontend getaddrinfo(%s, %s) failed: %s", listen_address_.c_str(),
182e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            listen_service_.c_str(), gai_strerror(rv));
183e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
184e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
185e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
186e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    int s = -1;
187e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    for (const addrinfo* ai = frontend_ai_res ; ai ; ai = ai->ai_next) {
188e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
189e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        if (s < 0) continue;
190e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        const int one = 1;
191e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
192e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        if (bind(s, ai->ai_addr, ai->ai_addrlen)) {
193e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            APLOGI("bind failed for socket %d", s);
194e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            close(s);
195e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            s = -1;
196e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            continue;
197e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        }
198e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        std::string host_str = addr2str(ai->ai_addr, ai->ai_addrlen);
199e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGI("bound to TCP %s:%s", host_str.c_str(), listen_service_.c_str());
200e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        break;
201e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
202e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    freeaddrinfo(frontend_ai_res);
203e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (s < 0) {
204e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("server socket creation failed");
205e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
206e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
207e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
208e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (listen(s, 1) < 0) {
209e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("listen failed");
210e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
211e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
212e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
213e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    socket_ = s;
214e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
215e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    // Set up UDP client socket to backend.
216e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    addrinfo backend_ai_hints{
217e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        .ai_family = AF_UNSPEC,
218e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        .ai_socktype = SOCK_DGRAM
219e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    };
220e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    addrinfo* backend_ai_res;
221e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    rv = getaddrinfo(backend_address_.c_str(), backend_service_.c_str(),
222e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz                         &backend_ai_hints, &backend_ai_res);
223e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (rv) {
224e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("backend getaddrinfo(%s, %s) failed: %s", listen_address_.c_str(),
225e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            listen_service_.c_str(), gai_strerror(rv));
226e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
227e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
228e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    backend_socket_ = socket(backend_ai_res->ai_family, backend_ai_res->ai_socktype,
229e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        backend_ai_res->ai_protocol);
230e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (backend_socket_ < 0) {
231e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGE("backend socket creation failed");
232e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
233e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
234e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    connect(backend_socket_, backend_ai_res->ai_addr, backend_ai_res->ai_addrlen);
235e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    freeaddrinfo(backend_ai_res);
236e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
237e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    {
238e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        std::lock_guard<std::mutex> lock(update_mutex_);
239e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        handler_thread_ = std::thread(&DnsTlsFrontend::requestHandler, this);
240e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
241e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    ALOGI("server started successfully");
242e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    return true;
243e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}
244e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
245e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartzvoid DnsTlsFrontend::requestHandler() {
246e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    ALOGD("Request handler started");
247e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    struct pollfd fds[1] = {{ .fd = socket_, .events = POLLIN }};
248e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
249e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    while (!terminate_) {
250e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        int poll_code = poll(fds, 1, 10 /* ms */);
251e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        if (poll_code == 0) {
252e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            // Timeout.  Poll again.
253e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            continue;
254e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        } else if (poll_code < 0) {
255e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            ALOGW("Poll failed with error %d", poll_code);
256e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            // Error.
257e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            break;
258e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        }
259e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        sockaddr_storage addr;
260e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        socklen_t len = sizeof(addr);
261e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
262e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGD("Trying to accept a client");
263e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        int client = accept(socket_, reinterpret_cast<sockaddr*>(&addr), &len);
264e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGD("Got client socket %d", client);
265e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        if (client < 0) {
266e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            // Stop
267e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            break;
268e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        }
269e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
2701ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz        bssl::UniquePtr<SSL> ssl(SSL_new(ctx_.get()));
2711ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz        SSL_set_fd(ssl.get(), client);
272e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
273e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGD("Doing SSL handshake");
274e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        bool success = false;
2751ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz        if (SSL_accept(ssl.get()) <= 0) {
276e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            ALOGI("SSL negotiation failure");
277e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        } else {
278e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            ALOGD("SSL handshake complete");
2791ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz            success = handleOneRequest(ssl.get());
280e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        }
281e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
282e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        close(client);
283e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
284e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        if (success) {
285e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            // Increment queries_ as late as possible, because it represents
286e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            // a query that is fully processed, and the response returned to the
287e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            // client, including cleanup actions.
288e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            ++queries_;
289e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        }
290e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
291e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    ALOGD("Request handler terminating");
292e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}
293e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
294e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartzbool DnsTlsFrontend::handleOneRequest(SSL* ssl) {
295e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    uint8_t queryHeader[2];
296e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (SSL_read(ssl, &queryHeader, 2) != 2) {
297e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGI("Not enough header bytes");
298e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
299e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
300e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    const uint16_t qlen = (queryHeader[0] << 8) | queryHeader[1];
301e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    uint8_t query[qlen];
302e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (SSL_read(ssl, &query, qlen) != qlen) {
303e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGI("Not enough query bytes");
304e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
305e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
306e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    int sent = send(backend_socket_, query, qlen, 0);
307e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (sent != qlen) {
308e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGI("Failed to send query");
309e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
310e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
311e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    const int max_size = 4096;
312e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    uint8_t recv_buffer[max_size];
313e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    int rlen = recv(backend_socket_, recv_buffer, max_size, 0);
314e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (rlen <= 0) {
315e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGI("Failed to receive response");
316e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
317e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
318e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    uint8_t responseHeader[2];
319e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    responseHeader[0] = rlen >> 8;
320e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    responseHeader[1] = rlen;
321e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (SSL_write(ssl, responseHeader, 2) != 2) {
322e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGI("Failed to write response header");
323e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
324e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
325e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (SSL_write(ssl, recv_buffer, rlen) != rlen) {
326e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGI("Failed to write response body");
327e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
328e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
329e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    return true;
330e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}
331e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
332e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartzbool DnsTlsFrontend::stopServer() {
333e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    std::lock_guard<std::mutex> lock(update_mutex_);
334e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (!running()) {
335e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGI("server not running");
336e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
337e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
338e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    if (terminate_) {
339e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        ALOGI("LOGIC ERROR");
340e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        return false;
341e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
342e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    ALOGI("stopping frontend");
343e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    terminate_ = true;
344e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    handler_thread_.join();
345e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    close(socket_);
346e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    close(backend_socket_);
347e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    terminate_ = false;
348e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    socket_ = -1;
349e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    backend_socket_ = -1;
3501ba8b75513d7502b419ec1ee6f5f406bc6eb490cBen Schwartz    ctx_.reset();
351e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    fingerprint_.clear();
352e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    ALOGI("frontend stopped successfully");
353e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    return true;
354e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}
355e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
356e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartzbool DnsTlsFrontend::waitForQueries(int number, int timeoutMs) const {
357e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    constexpr int intervalMs = 20;
358e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    int limit = timeoutMs / intervalMs;
359e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    for (int count = 0; count <= limit; ++count) {
360e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        bool done = queries_ >= number;
361e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        // Always sleep at least one more interval after we are done, to wait for
362e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        // any immediate post-query actions that the client may take (such as
363e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        // marking this server as reachable during validation).
364e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        usleep(intervalMs * 1000);
365e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        if (done) {
366e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            // For ensuring that calls have sufficient headroom for slow machines
367e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            ALOGD("Query arrived in %d/%d of allotted time", count, limit);
368e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz            return true;
369e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz        }
370e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    }
371e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz    return false;
372e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}
373e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz
374e760181ff41a5f4526e4f543f3838eb05690e2aaBen Schwartz}  // namespace test
375