Skip to content

Commit 6849e2c

Browse files
authored
Add rules for stdlib, rustls, and stdio (#183)
This mainly adds translation rules for rustls_ffi. I needed to do a few modifications in `cpp2rust/` to be able to add translation rules for typedef'ed integers, for example rustls_ffi::rustls_result (`typedef uint32_t rustls_result`): * add support in cpp-rule-preprocessor to define rule types as `typedef` in C and `using` in C++. rustls.h uses C specific features, hence the source rules must be put in a src.c file. For example in rustls.h uses the following which is valid C but invalid C++: ```c enum rustls_result { ... } typedef uint32_t rustls_result; // same name as the enum ``` * zero-initialize rust enums using the enum default value, not using 0, in getIntegerLiteral, for example: `rustls_result r = 0` * install rustls.h into rules/rustls using the cargo installation instead of copy-pasting the vendored rustls.h file. `rules/build.rs` takes care of this
1 parent c48eecc commit 6849e2c

9 files changed

Lines changed: 770 additions & 11 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ build/
44
# Cargo
55
target/
66
Cargo.lock
7+
rules/rustls/rustls.h
78

89
# Python
910
*.pyc

CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ add_custom_target("check"
135135

136136
set(RULES_IR_DIR "${CMAKE_BINARY_DIR}/rules")
137137

138+
set(RUSTLS_HEADER "${PROJECT_SOURCE_DIR}/rules/rustls/rustls.h")
139+
138140
file(GLOB rule_subdirs ${PROJECT_SOURCE_DIR}/rules/*)
139141
set(cpp_rules_ir_outputs)
140142
set(rust_rules_ir_outputs)
@@ -151,7 +153,7 @@ foreach(_rule_dir IN LISTS rule_subdirs)
151153
OUTPUT ${_out}
152154
COMMAND ${CMAKE_COMMAND} -E make_directory ${_out_dir}
153155
COMMAND $<TARGET_FILE:cpp-rule-preprocessor> --dir ${_rule_dir} --out ${_out}
154-
DEPENDS ${_srcs} ${PROJECT_SOURCE_DIR}/cpp2rust/cpp_rule_preprocessor.cpp
156+
DEPENDS ${_srcs} ${PROJECT_SOURCE_DIR}/cpp2rust/cpp_rule_preprocessor.cpp ${RUSTLS_HEADER}
155157
VERBATIM
156158
)
157159
list(APPEND cpp_rules_ir_outputs ${_out})
@@ -171,7 +173,7 @@ file(GLOB_RECURSE rule_preprocessor_sources
171173
${PROJECT_SOURCE_DIR}/rule-preprocessor/src/*.rs)
172174

173175
add_custom_command(
174-
OUTPUT ${rust_rules_ir_outputs}
176+
OUTPUT ${rust_rules_ir_outputs} ${RUSTLS_HEADER}
175177
COMMAND cargo +${RUST_STABLE_VERSION} build --release --manifest-path "${PROJECT_SOURCE_DIR}/rules/Cargo.toml"
176178
COMMAND ${CMAKE_COMMAND} -E env
177179
CARGO_TARGET_DIR=${CMAKE_BINARY_DIR}/target_preprocessor

cpp2rust/converter/converter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,11 @@ std::string Converter::getIntegerLiteral(clang::IntegerLiteral *expr,
18091809
auto type_as_string = GetUnsafeTypeAsString(ty);
18101810

18111811
if (ty->isFloatingType() || incl_type) {
1812+
if (expr->getValue().isZero()) {
1813+
if (auto init = Mapper::MapInitializer(ty); !init.empty()) {
1814+
return init;
1815+
}
1816+
}
18121817
return std::format("{}_{}", num_as_string.c_str(), type_as_string);
18131818
}
18141819

cpp2rust/cpp_rule_preprocessor.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <string>
3030

3131
#include "compat/platform_flags.h"
32+
#include "converter/converter_lib.h"
3233
#include "converter/mapper.h"
3334

3435
namespace fs = std::filesystem;
@@ -109,14 +110,15 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
109110
}
110111
return;
111112
}
112-
if (auto var = R.Nodes.getNodeAs<clang::TypeAliasDecl>("tvar")) {
113-
clang::QualType type;
114-
if (auto *tdecl = var->getDescribedAliasTemplate()) {
115-
type = lookupType(tdecl);
116-
} else {
117-
type = var->getUnderlyingType();
113+
if (auto var = R.Nodes.getNodeAs<clang::TypedefNameDecl>("tvar")) {
114+
clang::QualType type = var->getUnderlyingType();
115+
if (auto *alias = llvm::dyn_cast<clang::TypeAliasDecl>(var)) {
116+
if (auto *tdecl = alias->getDescribedAliasTemplate()) {
117+
type = lookupType(tdecl);
118+
}
118119
}
119-
out_.try_emplace(var->getQualifiedNameAsString(), Mapper::ToString(type));
120+
auto src = Mapper::ToString(type, Mapper::ScalarSugar::kPreserve);
121+
out_.try_emplace(var->getQualifiedNameAsString(), std::move(src));
120122
return;
121123
}
122124

@@ -707,7 +709,7 @@ class ActionFactory : public clang::tooling::FrontendActionFactory {
707709
&cb_);
708710

709711
finder_.addMatcher(
710-
typeAliasDecl(matchesName("(^|::)t[0-9]+$"), isExpansionInMainFile())
712+
typedefNameDecl(matchesName("(^|::)t[0-9]+$"), isExpansionInMainFile())
711713
.bind("tvar"),
712714
&cb_);
713715

rule-preprocessor/src/semantic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ fn build_rustc_args(crate_root: &Path) -> Vec<String> {
4646
args.push("-L".to_string());
4747
args.push(format!("dependency={}", deps.display()));
4848

49-
for dep in &["libcc2rs", "libc", "brotli_sys"] {
49+
for dep in &["libcc2rs", "libc", "brotli_sys", "rustls_ffi"] {
5050
if let Some(rlib) = find_rlib(deps.as_path(), dep) {
5151
args.push("--extern".to_string());
5252
args.push(format!("{}={}", dep, rlib.display()));

rules/build.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ fn main() {
3030
println!("cargo:rerun-if-changed=build.rs");
3131
println!("cargo:rerun-if-changed=Cargo.toml");
3232

33+
println!("cargo:rerun-if-env-changed=DEP_RUSTLS_FFI_INCLUDE");
34+
let inc = env::var("DEP_RUSTLS_FFI_INCLUDE")
35+
.expect("rustls-ffi did not export its include dir (DEP_RUSTLS_FFI_INCLUDE)");
36+
let src = Path::new(&inc).join("rustls.h");
37+
let dst = crate_root.join("rustls").join("rustls.h");
38+
fs::copy(&src, &dst)
39+
.unwrap_or_else(|e| panic!("failed to copy {} to {}: {e}", src.display(), dst.display()));
40+
3341
// Generate modules that include absolute paths
3442
let mut buf = String::new();
3543
for f in files {

rules/rustls/src.c

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
#include "rustls.h"
5+
6+
typedef rustls_connection *t1;
7+
typedef const rustls_connection *t2;
8+
typedef const rustls_certificate *t3;
9+
typedef rustls_str t4;
10+
typedef rustls_result t5;
11+
typedef rustls_io_result t6;
12+
typedef rustls_tls_version t7;
13+
14+
rustls_result f1() { return RUSTLS_RESULT_OK; }
15+
rustls_result f2() { return RUSTLS_RESULT_NULL_PARAMETER; }
16+
rustls_result f3() { return RUSTLS_RESULT_PLAINTEXT_EMPTY; }
17+
rustls_result f4() { return RUSTLS_RESULT_UNEXPECTED_EOF; }
18+
19+
rustls_tls_version f5() { return RUSTLS_TLS_VERSION_TLSV1_2; }
20+
rustls_tls_version f6() { return RUSTLS_TLS_VERSION_TLSV1_3; }
21+
22+
rustls_result f7(rustls_connection *conn, uint8_t *buf, size_t count,
23+
size_t *out_n) {
24+
return rustls_connection_read(conn, buf, count, out_n);
25+
}
26+
rustls_result f8(rustls_connection *conn, const uint8_t *buf, size_t count,
27+
size_t *out_n) {
28+
return rustls_connection_write(conn, buf, count, out_n);
29+
}
30+
rustls_result f9(rustls_connection *conn) {
31+
return rustls_connection_process_new_packets(conn);
32+
}
33+
bool f10(const rustls_connection *conn) {
34+
return rustls_connection_wants_read(conn);
35+
}
36+
bool f11(const rustls_connection *conn) {
37+
return rustls_connection_wants_write(conn);
38+
}
39+
bool f12(const rustls_connection *conn) {
40+
return rustls_connection_is_handshaking(conn);
41+
}
42+
void f13(rustls_connection *conn) {
43+
return rustls_connection_send_close_notify(conn);
44+
}
45+
void f14(rustls_connection *conn, void *userdata) {
46+
return rustls_connection_set_userdata(conn, userdata);
47+
}
48+
void f15(const rustls_connection *conn, const uint8_t **protocol_out,
49+
size_t *protocol_out_len) {
50+
return rustls_connection_get_alpn_protocol(conn, protocol_out,
51+
protocol_out_len);
52+
}
53+
uint16_t f16(const rustls_connection *conn) {
54+
return rustls_connection_get_protocol_version(conn);
55+
}
56+
rustls_str f17(const rustls_connection *conn) {
57+
return rustls_connection_get_negotiated_ciphersuite_name(conn);
58+
}
59+
rustls_str f18(const rustls_connection *conn) {
60+
return rustls_connection_get_negotiated_key_exchange_group_name(conn);
61+
}
62+
const rustls_certificate *f19(const rustls_connection *conn, size_t i) {
63+
return rustls_connection_get_peer_certificate(conn, i);
64+
}
65+
void f20(rustls_connection *conn) { return rustls_connection_free(conn); }
66+
67+
typedef rustls_client_config *t8;
68+
typedef const rustls_client_config *t9;
69+
typedef rustls_client_config_builder *t10;
70+
typedef const rustls_client_config_builder *t11;
71+
typedef rustls_certified_key *t12;
72+
typedef const rustls_certified_key *t13;
73+
typedef rustls_crypto_provider *t14;
74+
typedef const rustls_crypto_provider *t15;
75+
typedef rustls_crypto_provider_builder *t16;
76+
typedef const rustls_crypto_provider_builder *t17;
77+
typedef rustls_root_cert_store *t18;
78+
typedef const rustls_root_cert_store *t19;
79+
typedef rustls_root_cert_store_builder *t20;
80+
typedef const rustls_root_cert_store_builder *t21;
81+
typedef rustls_server_cert_verifier *t22;
82+
typedef const rustls_server_cert_verifier *t23;
83+
typedef rustls_web_pki_server_cert_verifier_builder *t24;
84+
typedef const rustls_web_pki_server_cert_verifier_builder *t25;
85+
typedef rustls_supported_ciphersuite *t26;
86+
typedef const rustls_supported_ciphersuite *t27;
87+
typedef rustls_slice_bytes t28;
88+
typedef rustls_verify_server_cert_params t29;
89+
90+
rustls_result f21(rustls_client_config_builder *builder,
91+
const rustls_client_config **config_out) {
92+
return rustls_client_config_builder_build(builder, config_out);
93+
}
94+
void f22(rustls_client_config_builder *config) {
95+
return rustls_client_config_builder_free(config);
96+
}
97+
rustls_result f23(const rustls_crypto_provider *provider,
98+
const uint16_t *tls_versions, size_t tls_versions_len,
99+
rustls_client_config_builder **builder_out) {
100+
return rustls_client_config_builder_new_custom(provider, tls_versions,
101+
tls_versions_len, builder_out);
102+
}
103+
rustls_result f24(rustls_client_config_builder *builder,
104+
const rustls_slice_bytes *protocols, size_t len) {
105+
return rustls_client_config_builder_set_alpn_protocols(builder, protocols,
106+
len);
107+
}
108+
rustls_result f25(rustls_client_config_builder *builder,
109+
const rustls_certified_key *const *certified_keys,
110+
size_t certified_keys_len) {
111+
return rustls_client_config_builder_set_certified_key(builder, certified_keys,
112+
certified_keys_len);
113+
}
114+
void f26(rustls_client_config_builder *builder,
115+
const rustls_server_cert_verifier *verifier) {
116+
return rustls_client_config_builder_set_server_verifier(builder, verifier);
117+
}
118+
void f27(const rustls_client_config *config) {
119+
return rustls_client_config_free(config);
120+
}
121+
rustls_result f28(const rustls_client_config *config, const char *server_name,
122+
rustls_connection **conn_out) {
123+
return rustls_client_connection_new(config, server_name, conn_out);
124+
}
125+
126+
rustls_result f29(const rustls_certificate *cert, const uint8_t **out_der_data,
127+
size_t *out_der_len) {
128+
return rustls_certificate_get_der(cert, out_der_data, out_der_len);
129+
}
130+
rustls_result f30(const uint8_t *cert_chain, size_t cert_chain_len,
131+
const uint8_t *private_key, size_t private_key_len,
132+
const rustls_certified_key **certified_key_out) {
133+
return rustls_certified_key_build(cert_chain, cert_chain_len, private_key,
134+
private_key_len, certified_key_out);
135+
}
136+
void f31(const rustls_certified_key *key) {
137+
return rustls_certified_key_free(key);
138+
}
139+
rustls_result f32(const rustls_certified_key *key) {
140+
return rustls_certified_key_keys_match(key);
141+
}
142+
rustls_result f33(rustls_root_cert_store_builder *builder, const uint8_t *pem,
143+
size_t pem_len, bool strict) {
144+
return rustls_root_cert_store_builder_add_pem(builder, pem, pem_len, strict);
145+
}
146+
rustls_result f34(rustls_root_cert_store_builder *builder,
147+
const rustls_root_cert_store **root_cert_store_out) {
148+
return rustls_root_cert_store_builder_build(builder, root_cert_store_out);
149+
}
150+
void f35(rustls_root_cert_store_builder *builder) {
151+
return rustls_root_cert_store_builder_free(builder);
152+
}
153+
rustls_result f36(rustls_root_cert_store_builder *builder, const char *filename,
154+
bool strict) {
155+
return rustls_root_cert_store_builder_load_roots_from_file(builder, filename,
156+
strict);
157+
}
158+
rustls_root_cert_store_builder *f37() {
159+
return rustls_root_cert_store_builder_new();
160+
}
161+
void f38(const rustls_root_cert_store *store) {
162+
return rustls_root_cert_store_free(store);
163+
}
164+
165+
rustls_result f39(rustls_crypto_provider_builder *builder,
166+
const rustls_crypto_provider **provider_out) {
167+
return rustls_crypto_provider_builder_build(builder, provider_out);
168+
}
169+
void f40(rustls_crypto_provider_builder *builder) {
170+
return rustls_crypto_provider_builder_free(builder);
171+
}
172+
rustls_result f41(rustls_crypto_provider_builder **builder_out) {
173+
return rustls_crypto_provider_builder_new_from_default(builder_out);
174+
}
175+
rustls_result f42(rustls_crypto_provider_builder *builder,
176+
const rustls_supported_ciphersuite *const *cipher_suites,
177+
size_t cipher_suites_len) {
178+
return rustls_crypto_provider_builder_set_cipher_suites(builder, cipher_suites,
179+
cipher_suites_len);
180+
}
181+
void f43(const rustls_crypto_provider *provider) {
182+
return rustls_crypto_provider_free(provider);
183+
}
184+
const rustls_supported_ciphersuite *f44(size_t index) {
185+
return rustls_default_crypto_provider_ciphersuites_get(index);
186+
}
187+
size_t f45() { return rustls_default_crypto_provider_ciphersuites_len(); }
188+
rustls_result f46(uint8_t *buff, size_t len) {
189+
return rustls_default_crypto_provider_random(buff, len);
190+
}
191+
192+
rustls_result f47(rustls_server_cert_verifier **verifier_out) {
193+
return rustls_platform_server_cert_verifier(verifier_out);
194+
}
195+
void f48(rustls_server_cert_verifier *verifier) {
196+
return rustls_server_cert_verifier_free(verifier);
197+
}
198+
rustls_result f49(rustls_web_pki_server_cert_verifier_builder *builder,
199+
const uint8_t *crl_pem, size_t crl_pem_len) {
200+
return rustls_web_pki_server_cert_verifier_builder_add_crl(builder, crl_pem,
201+
crl_pem_len);
202+
}
203+
rustls_result f50(rustls_web_pki_server_cert_verifier_builder *builder,
204+
rustls_server_cert_verifier **verifier_out) {
205+
return rustls_web_pki_server_cert_verifier_builder_build(builder,
206+
verifier_out);
207+
}
208+
void f51(rustls_web_pki_server_cert_verifier_builder *builder) {
209+
return rustls_web_pki_server_cert_verifier_builder_free(builder);
210+
}
211+
rustls_web_pki_server_cert_verifier_builder *
212+
f52(const rustls_root_cert_store *store) {
213+
return rustls_web_pki_server_cert_verifier_builder_new(store);
214+
}
215+
216+
uint16_t f53(const rustls_supported_ciphersuite *supported_ciphersuite) {
217+
return rustls_supported_ciphersuite_get_suite(supported_ciphersuite);
218+
}
219+
rustls_tls_version
220+
f54(const rustls_supported_ciphersuite *supported_ciphersuite) {
221+
return rustls_supported_ciphersuite_protocol_version(supported_ciphersuite);
222+
}
223+
224+
rustls_str f55() { return rustls_version(); }
225+
226+
void f56(unsigned int result, char *buf, size_t len, size_t *out_n) {
227+
return rustls_error(result, buf, len, out_n);
228+
}
229+
bool f57(unsigned int result) { return rustls_result_is_cert_error(result); }
230+
231+
rustls_io_result f58(rustls_connection *conn, rustls_read_callback callback,
232+
void *userdata, size_t *out_n) {
233+
return rustls_connection_read_tls(conn, callback, userdata, out_n);
234+
}
235+
rustls_io_result f59(rustls_connection *conn, rustls_write_callback callback,
236+
void *userdata, size_t *out_n) {
237+
return rustls_connection_write_tls(conn, callback, userdata, out_n);
238+
}
239+
rustls_result f60(rustls_client_config_builder *builder,
240+
rustls_keylog_log_callback log_cb,
241+
rustls_keylog_will_log_callback will_log_cb) {
242+
return rustls_client_config_builder_set_key_log(builder, log_cb, will_log_cb);
243+
}
244+
rustls_result f61(rustls_client_config_builder *config_builder,
245+
rustls_verify_server_cert_callback callback) {
246+
return rustls_client_config_builder_dangerous_set_certificate_verifier(
247+
config_builder, callback);
248+
}

0 commit comments

Comments
 (0)