diff --git a/fuzz/README.md b/fuzz/README.md new file mode 100644 index 00000000000..18cedcdacc8 --- /dev/null +++ b/fuzz/README.md @@ -0,0 +1,25 @@ +# OpenVPN fuzzing harnesses + +## How to build +``` +git clone git@github.com:google/oss-fuzz +cd oss-fuzz +python3 infra_helpers.py build_fuzzers openvpn +ls -l ./build/out/openvpn | grep fuzz +``` + +For more configuration options such as sanitizers and fuzzers, run: ``python3 infra_helpers.py build_fuzzers --help`` + +## Harnesses +- `fuzz_base64.c`: Fuzzes OpenVPN base64 encode/decode functions. +- `fuzz_buffer.c`: Fuzzes buffer and string utility routines. +- `fuzz_crypto.c`: Fuzzes key handling plus OpenVPN encrypt/decrypt paths. +- `fuzz_dhcp.c`: Fuzzes DHCP router option parsing via `dhcp_extract_router_msg`. +- `fuzz_forward.c`: Fuzzes forward path functions for incoming/outgoing tun and link processing. +- `fuzz_list.c`: Fuzzes hash/list utilities (init/add/remove/iterate) in `list.h`. +- `fuzz_misc.c`: Fuzzes env_set management and misc string helpers like `sanitize_control_message`. +- `fuzz_mroute.c`: Fuzzes multicast route parsing/helpers (`mroute_extract_*`, helper init). +- `fuzz_packet_id.c`: Fuzzes packet ID tracking, read/write, and persistence load/save. +- `fuzz_proxy.c`: Fuzzes HTTP proxy auth/setup via `establish_http_proxy_passthru`. +- `fuzz_route.c`: Fuzzes IPv4/IPv6 route option parsing and add/delete routing logic. +- `fuzz_verify_cert.c`: Fuzzes X509 parsing and TLS cert verification (`verify_cert`). diff --git a/fuzz/build.sh b/fuzz/build.sh new file mode 100755 index 00000000000..760a7c6b2ad --- /dev/null +++ b/fuzz/build.sh @@ -0,0 +1,81 @@ +#!/bin/bash -eu +# Copyright 2021 Google LLC +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +OPENVPN_ROOT=${SRC}/openvpn +FUZZ_DIR=${OPENVPN_ROOT}/fuzz +BASE=${OPENVPN_ROOT}/src/openvpn + +apply_sed_changes() { + sed -i 's/read(/fuzz_read(/g' ${BASE}/console_systemd.c + sed -i 's/fgets(/fuzz_fgets(/g' ${BASE}/console_builtin.c + sed -i 's/fgets(/fuzz_fgets(/g' ${BASE}/misc.c + sed -i 's/#include "forward.h"/#include "fuzz_header.h"\n#include "forward.h"/g' ${BASE}/proxy.c + sed -i 's/openvpn_select(/fuzz_select(/g' ${BASE}/proxy.c + sed -i 's/openvpn_send(/fuzz_send(/g' ${BASE}/proxy.c + sed -i 's/recv(/fuzz_recv(/g' ${BASE}/proxy.c + sed -i 's/isatty/fuzz_isatty/g' ${BASE}/console_builtin.c + + sed -i 's/fopen/fuzz_fopen/g' ${BASE}/console_builtin.c + sed -i 's/fclose/fuzz_fclose/g' ${BASE}/console_builtin.c + + sed -i 's/sendto/fuzz_sendto/g' ${BASE}/socket.h + sed -i 's/#include "misc.h"/#include "misc.h"\nextern size_t fuzz_sendto(int sockfd, void *buf, size_t len, int flags, struct sockaddr *dest_addr, socklen_t addrlen);/g' ${BASE}/socket.h + + sed -i 's/fp = (flags/fp = stdout;\n\/\//g' ${BASE}/error.c + + sed -i 's/crypto_msg(M_FATAL/crypto_msg(M_WARN/g' ${BASE}/crypto_openssl.c + sed -i 's/msg(M_FATAL, \"Cipher/return;msg(M_FATAL, \"Cipher/g' ${BASE}/crypto.c + sed -i 's/msg(M_FATAL/msg(M_WARN/g' ${BASE}/crypto.c + + sed -i 's/= write/= fuzz_write/g' ${BASE}/packet_id.c +} + +echo "" >> ${BASE}/openvpn.c +echo "#include \"fake_fuzz_header.h\"" >> ${BASE}/openvpn.c +echo "ssize_t fuzz_get_random_data(void *buf, size_t len) { return 0; }" >> ${BASE}/fake_fuzz_header.h +echo "int fuzz_success;" >> ${BASE}/fake_fuzz_header.h + +# Apply hooking changes +apply_sed_changes + +# Copy corpuses out +zip -r $OUT/fuzz_verify_cert_seed_corpus.zip $SRC/boringssl/fuzz/cert_corpus + +# Build openvpn +autoreconf -ivf +./configure --disable-lz4 --with-crypto-library=openssl OPENSSL_LIBS="-L/usr/local/ssl/ -lssl -lcrypto" OPENSSL_CFLAGS="-I/usr/local/ssl/include/" +make -j$(nproc) + +# Make openvpn object files into a library we can link fuzzers to +cd src/openvpn +rm openvpn.o +ar r libopenvpn.a *.o + +# Compile our fuzz helper +$CXX $CXXFLAGS -g -c ${FUZZ_DIR}/fuzz_randomizer.cpp -o ${FUZZ_DIR}/fuzz_randomizer.o + +# Compile the fuzzers +for fuzzname in dhcp misc base64 proxy buffer route packet_id mroute list verify_cert; do + $CC -DHAVE_CONFIG_H -I. -I../.. -I../../include -I../../src/compat -I/usr/include/libnl3/ \ + -DPLUGIN_LIBDIR=\"/usr/local/lib/openvpn/plugins\" -std=c99 $CFLAGS \ + -c ${FUZZ_DIR}/fuzz_${fuzzname}.c -o ${FUZZ_DIR}/fuzz_${fuzzname}.o + + # Link with CXX + $CXX ${CXXFLAGS} ${LIB_FUZZING_ENGINE} $FUZZ_DIR/fuzz_${fuzzname}.o -o $OUT/fuzz_${fuzzname} $FUZZ_DIR/fuzz_randomizer.o \ + libopenvpn.a ../../src/compat/.libs/libcompat.a /usr/lib/x86_64-linux-gnu/libnsl.a \ + /usr/lib/x86_64-linux-gnu/libresolv.a /usr/lib/x86_64-linux-gnu/liblzo2.a \ + -lssl -lcrypto -ldl -l:libnl-3.a -l:libnl-genl-3.a -lcap-ng -pthread +done diff --git a/fuzz/fuzz.h b/fuzz/fuzz.h new file mode 100644 index 00000000000..10e33c3ee28 --- /dev/null +++ b/fuzz/fuzz.h @@ -0,0 +1,47 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include + +// Returns a NULL-terminated C string that should be freed by the caller. +char *get_modifiable_string(FuzzedDataProvider &provider) { + std::string s1 = provider.ConsumeRandomLengthString(); + char *tmp = (char *)malloc(s1.size() + 1); + memcpy(tmp, s1.c_str(), s1.size()); + tmp[s1.size()] = '\0'; + return tmp; +} + +FuzzedDataProvider *prov = NULL; + + +extern "C" ssize_t fuzz_get_random_data(void *buf, size_t len) { + size_t ret_val; + char *cbuf = (char*)buf; + + if (prov->remaining_bytes() == 0) { + return -1; + } + + double prob = prov->ConsumeProbability(); + if (prob < 0.05) { + return 0; + } + + if (len == 1) { + ret_val = prov->ConsumeData(buf, 1); + return ret_val; + } + ret_val = prov->ConsumeData(buf, len); + return ret_val; +} + diff --git a/fuzz/fuzz_base64.c b/fuzz/fuzz_base64.c new file mode 100644 index 00000000000..c9c45b84b36 --- /dev/null +++ b/fuzz/fuzz_base64.c @@ -0,0 +1,43 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include +#include +#include + +#include "base64.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 500) { + return 0; + } + + char *new_str = (char *)malloc(size + 1); + if (new_str == NULL) { + return 0; + } + memcpy(new_str, data, size); + new_str[size] = '\0'; + + char *str = NULL; + openvpn_base64_encode(data, size, &str); + if(str != NULL) { + free(str); + } + + uint16_t outsize = 10000; + char *output_buf = (char *)malloc(outsize); + openvpn_base64_decode(new_str, output_buf, outsize); + free(output_buf); + + free(new_str); + return 0; +} diff --git a/fuzz/fuzz_buffer.c b/fuzz/fuzz_buffer.c new file mode 100644 index 00000000000..04caf4600fd --- /dev/null +++ b/fuzz/fuzz_buffer.c @@ -0,0 +1,263 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +#include "config.h" +#include "syshead.h" +#include "misc.h" +#include "buffer.h" + +#include "fuzz_randomizer.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + fuzz_random_init(data,size); + + struct gc_arena gc; + struct buffer *bufp; + struct buffer buf, buf2; + struct buffer_list *buflistp = NULL; + ssize_t generic_ssizet, _size; + char *tmp; + char *tmp2; + char match; + + gc = gc_new(); + bufp = NULL; + + int total_to_fuzz = fuzz_randomizer_get_int(1, 20); + for (int i = 0; i < total_to_fuzz; i++) { + if (bufp == NULL) { + generic_ssizet = fuzz_randomizer_get_int(0, 1); + if (generic_ssizet == 0) { + _size = fuzz_randomizer_get_int(0, 100); + buf = alloc_buf_gc(_size, &gc); + bufp = &buf; + } else { + tmp = get_random_string(); + buf = string_alloc_buf(tmp, &gc); + bufp = &buf; + free(tmp); + tmp = NULL; + } + } else { +#define NUM_TARGETS 31 + generic_ssizet = fuzz_randomizer_get_int(0, NUM_TARGETS); + switch (generic_ssizet) { + case 0: + buf_clear(bufp); + break; + case 1: + buf2 = clone_buf(bufp); + free_buf(&buf2); + break; + case 2: + buf_defined(bufp); + break; + case 3: + buf_valid(bufp); + break; + case 4: + buf_bptr(bufp); + break; + case 5: + buf_len(bufp); + break; + case 6: + buf_bend(bufp); + break; + case 7: + buf_blast(bufp); + break; + case 8: + buf_str(bufp); + break; + case 9: + generic_ssizet = fuzz_randomizer_get_int(0, 255); + buf_rmtail(bufp, (uint8_t)generic_ssizet); + break; + case 10: + buf_chomp(bufp); + break; + case 11: + tmp = get_random_string(); + skip_leading_whitespace(tmp); + free(tmp); + tmp = NULL; + break; + case 12: + tmp = get_random_string(); + chomp(tmp); + free(tmp); + tmp = NULL; + break; + case 13: + tmp = get_random_string(); + tmp2 = get_random_string(); + rm_trailing_chars(tmp, tmp2); + free(tmp); + free(tmp2); + tmp = NULL; + tmp2 = NULL; + break; + case 14: + tmp = get_random_string(); + string_clear(tmp); + free(tmp); + tmp = NULL; + break; + case 15: + tmp = get_random_string(); + buf_string_match_head_str(bufp, tmp); + free(tmp); + tmp = NULL; + break; + case 16: + tmp = get_random_string(); + buf_string_compare_advance(bufp, tmp); + free(tmp); + tmp = NULL; + break; + case 17: + generic_ssizet = fuzz_randomizer_get_int(0, 255); + + tmp = get_random_string(); + if (strlen(tmp) > 0) { + buf_parse(bufp, (int)generic_ssizet, tmp, strlen(tmp)); + } + + free(tmp); + tmp = NULL; + break; + case 18: + tmp = get_random_string(); + string_mod(tmp, fuzz_randomizer_get_int(0, 12312), + fuzz_randomizer_get_int(0, 23141234), + (char)fuzz_randomizer_get_int(0, 255)); + + free(tmp); + tmp = NULL; + break; + case 19: + tmp = get_random_string(); + match = (char)fuzz_randomizer_get_int(0, 255); + if (match != 0) { + string_replace_leading(tmp, match, (char)fuzz_randomizer_get_int(0, 255)); + } + + free(tmp); + tmp = NULL; + break; + case 20: + tmp = get_random_string(); + buf_write(bufp, tmp, strlen(tmp)); + + free(tmp); + tmp = NULL; + break; + case 21: + tmp = get_random_string(); + + buf_write_prepend(bufp, tmp, strlen(tmp)); + + free(tmp); + tmp = NULL; + break; + case 22: + buf_write_u8(bufp, fuzz_randomizer_get_int(0, 255)); + break; + case 23: + buf_write_u16(bufp, fuzz_randomizer_get_int(0, 1024)); + break; + case 24: + buf_write_u32(bufp, fuzz_randomizer_get_int(0, 12312)); + break; + case 25: + tmp = get_random_string(); + buf_catrunc(bufp, tmp); + free(tmp); + tmp = NULL; + break; + case 26: + tmp = get_random_string(); + buf_puts(bufp, tmp); + free(tmp); + tmp = NULL; + break; + case 27: + buf_advance(bufp, fuzz_randomizer_get_int(0, 25523)); + break; + case 28: + buf_prepend(bufp, fuzz_randomizer_get_int(0, 251235)); + break; + case 29: + buf_reverse_capacity(bufp); + break; + case 30: + buf_forward_capacity_total(bufp); + break; + case 31: + buf_forward_capacity(bufp); + break; + } + } + + if (buflistp == NULL) { + buflistp = buffer_list_new(); + } else { +#define NUM_LIST_TARGETS 6 + generic_ssizet = fuzz_randomizer_get_int(0, NUM_LIST_TARGETS); + switch (generic_ssizet) { + case 0: + buffer_list_free(buflistp); + buflistp = NULL; + break; + case 1: + buffer_list_defined(buflistp); + break; + case 2: + tmp = get_random_string(); + if (strlen(tmp) < BUF_SIZE_MAX) { + buffer_list_push(buflistp, tmp); + } + free(tmp); + tmp = NULL; + break; + case 3: + buffer_list_peek(buflistp); + break; + case 4: + buffer_list_pop(buflistp); + break; + case 5: + tmp = get_random_string(); + buffer_list_aggregate_separator( + buflistp, fuzz_randomizer_get_int(0, 1024), tmp); + + free(tmp); + tmp = NULL; + break; + case 6: + buffer_list_aggregate(buflistp, + fuzz_randomizer_get_int(0, 1024)); + break; + } + } + } + + // Cleanup + buffer_list_free(buflistp); + gc_free(&gc); + + fuzz_random_destroy(); + + return 0; +} diff --git a/fuzz/fuzz_crypto.c b/fuzz/fuzz_crypto.c new file mode 100644 index 00000000000..2ac25dbaf02 --- /dev/null +++ b/fuzz/fuzz_crypto.c @@ -0,0 +1,258 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +#include "config.h" +#include "syshead.h" + +#include +#include +#include +#include + +#include "fuzz_verify_cert.h" +#include "misc.h" +#include "manage.h" +#include "otime.h" +#include "base64.h" +#include "ssl_verify.h" +#include "ssl_verify_backend.h" + +#include "fuzz_randomizer.h" + +static void key_ctx_update_implicit_iv(struct key_ctx *ctx, uint8_t *key, + size_t key_len) { + //const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt(ctx->cipher); + + cipher_ctx_t *cipher_kt = ctx->cipher; + /* Only use implicit IV in AEAD cipher mode, where HMAC key is not used */ + if (cipher_ctx_mode_aead(cipher_kt)) { + size_t impl_iv_len = 0; + ASSERT(cipher_kt_iv_size(cipher_kt) >= OPENVPN_AEAD_MIN_IV_LEN); + impl_iv_len = cipher_kt_iv_size(cipher_kt) - sizeof(packet_id_type); + ASSERT(impl_iv_len <= OPENVPN_MAX_IV_LENGTH); + ASSERT(impl_iv_len <= key_len); + memcpy(ctx->implicit_iv, key, impl_iv_len); + ctx->implicit_iv_len = impl_iv_len; + } +} + +static int init_frame(struct frame *frame) { + frame->link_mtu = fuzz_randomizer_get_int(100, 1000); + frame->extra_buffer = fuzz_randomizer_get_int(100, 1000); + frame->link_mtu_dynamic = fuzz_randomizer_get_int(100, 1000); + frame->extra_frame = fuzz_randomizer_get_int(100, 1000); + frame->extra_tun = fuzz_randomizer_get_int(100, 1000); + frame->extra_link = fuzz_randomizer_get_int(100, 1000); + frame->align_flags = 0; + frame->align_adjust = 0; + if (TUN_MTU_SIZE(frame) <= 0) { + return -1; + } + return 0; +} + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + OPENSSL_malloc_init(); + SSL_library_init(); + ERR_load_crypto_strings(); + + OpenSSL_add_all_algorithms(); + OpenSSL_add_ssl_algorithms(); + + SSL_load_error_strings(); + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + fuzz_random_init(data, size); + fuzz_success = 1; + bool key_ctx_dec_initialized = false; + bool key_ctx_enc_initialized = false; + struct key_ctx key_ctx_dec; + memset(&key_ctx_dec, 0, sizeof(struct key_ctx)); + struct key_ctx key_ctx_enc; + memset(&key_ctx_enc, 0, sizeof(struct key_ctx)); + + struct gc_arena gc; + struct tls_session *session = NULL; + X509 *x509 = NULL; + gc = gc_new(); + + gb_init(); + + // Read key file + struct key2 key2; + char *keydata = gb_get_random_string(); + read_key_file(&key2, keydata, RKF_INLINE); + + // init key type + struct key_type kt; + memset(&kt, 0, sizeof(struct key_type)); + + char *ciphername = gb_get_random_string(); + char *authname = gb_get_random_string(); + bool key_type_initialized = false; + + if (strcmp(ciphername, "AES-256-GCM") == 0 || + strcmp(ciphername, "AES-128-GCM") == 0 || + strcmp(ciphername, "AES-192-GCM") == 0 || + strcmp(ciphername, "CAMELLIA-128-CFB128") == 0) { + + int v = fuzz_randomizer_get_int(0, 1); + if (v == 0) { + init_key_type(&kt, ciphername, authname, true, 0); + } else { + init_key_type(&kt, ciphername, authname, false, 0); + } + key_type_initialized = true; + } + + if (fuzz_success == 0) { + goto cleanup; + } + + // Generate key. + // Identify which one we should do, read or generate a random key. + int c = fuzz_randomizer_get_int(0, 1); + const uint8_t d[1024]; + int key_read = 0; + struct key key; + if (c == 0) { + if (fuzz_get_random_data(d, 1024) != 1024) { + struct buffer buf = alloc_buf(1024); + buf_write(&buf, d, 1024); + if (read_key(&key, &kt, &buf) == 1) { + key_read = 1; + } + free_buf(&buf); + } + } + else { + if (key_type_initialized == true) { + generate_key_random(&key, &kt); + } + } + + if (fuzz_success == 0) { + goto cleanup; + } + key_read = 1; + + // init decryption context + if (key_type_initialized && key_read) { + init_key_ctx(&key_ctx_dec, &key, &kt, OPENVPN_OP_DECRYPT, "x"); + key_ctx_update_implicit_iv(&key_ctx_dec, &(key.hmac), MAX_HMAC_KEY_LENGTH); + key_ctx_dec_initialized = true; + } + + // init encryption context + if (key_type_initialized && key_read) { + init_key_ctx(&key_ctx_enc, &key, &kt, OPENVPN_OP_DECRYPT, "x"); + key_ctx_update_implicit_iv(&key_ctx_enc, &(key.hmac), MAX_HMAC_KEY_LENGTH); + key_ctx_enc_initialized = true; + } + + // perform encryption + struct frame frame; + memset(&frame, 0, sizeof(struct frame)); + if (key_ctx_enc_initialized == true && key_ctx_dec_initialized == true && + init_frame(&frame) == 0) { + struct crypto_options opt; + memset(&opt, 0, sizeof(opt)); + opt.pid_persist = NULL; + opt.key_ctx_bi.encrypt = key_ctx_enc; + opt.key_ctx_bi.decrypt = key_ctx_dec; + opt.key_ctx_bi.initialized = true; + opt.packet_id.rec.initialized = true; + opt.packet_id.rec.seq_list = NULL; + opt.packet_id.rec.name = NULL; + + void *buf_p; + + struct buffer encrypt_workspace = alloc_buf_gc(BUF_SIZE(&(frame)), &gc); + struct buffer work = alloc_buf_gc(BUF_SIZE(&(frame)), &gc); + struct buffer src = alloc_buf_gc(TUN_MTU_SIZE(&(frame)), &gc); + struct buffer buf = clear_buf(); + + int x = fuzz_randomizer_get_int(1, TUN_MTU_SIZE(&frame)); + + ASSERT(buf_init(&work, FRAME_HEADROOM(&(frame)))); + ASSERT(buf_init(&src, 0)); + src.len = x; + ASSERT(rand_bytes(BPTR(&src), BLEN(&src))); + + buf = work; + buf_p = buf_write_alloc(&buf, BLEN(&src)); + ASSERT(buf_p); + memcpy(buf_p, BPTR(&src), BLEN(&src)); + + ASSERT(buf_init(&encrypt_workspace, FRAME_HEADROOM(&(frame)))); + + openvpn_encrypt(&buf, encrypt_workspace, &opt); + } + + // perform decryption + memset(&frame, 0, sizeof(struct frame)); + if (key_ctx_dec_initialized == true && key_ctx_enc_initialized == true && + init_frame(&frame) == 0) { + struct crypto_options opt; + memset(&opt, 0, sizeof(opt)); + opt.pid_persist = NULL; + opt.key_ctx_bi.encrypt = key_ctx_enc; + opt.key_ctx_bi.decrypt = key_ctx_dec; + opt.key_ctx_bi.initialized = true; + opt.packet_id.rec.initialized = true; + opt.packet_id.rec.seq_list = NULL; + opt.packet_id.rec.name = NULL; + + void *buf_p; + + struct buffer decrypt_workspace = alloc_buf_gc(BUF_SIZE(&(frame)), &gc); + struct buffer work = alloc_buf_gc(BUF_SIZE(&(frame)), &gc); + struct buffer src = alloc_buf_gc(TUN_MTU_SIZE(&(frame)), &gc); + struct buffer buf = clear_buf(); + + int x = fuzz_randomizer_get_int(1, TUN_MTU_SIZE(&frame)); + + ASSERT(buf_init(&work, FRAME_HEADROOM(&(frame)))); + ASSERT(buf_init(&src, 0)); + src.len = x; + ASSERT(rand_bytes(BPTR(&src), BLEN(&src))); + + buf = work; + buf_p = buf_write_alloc(&buf, BLEN(&src)); + ASSERT(buf_p); + memcpy(buf_p, BPTR(&src), BLEN(&src)); + + ASSERT(buf_init(&decrypt_workspace, FRAME_HEADROOM(&(frame)))); + + openvpn_decrypt(&buf, decrypt_workspace, &opt, &frame, BPTR(&buf)); + } + +cleanup: + // cleanup + gc_free(&gc); + + if (key_ctx_dec_initialized == true) { + free_key_ctx(&key_ctx_dec); + } + + if (key_ctx_enc_initialized == true) { + free_key_ctx(&key_ctx_enc); + } + fuzz_random_destroy(); + + gb_cleanup(); + + return 0; +} diff --git a/fuzz/fuzz_dhcp.c b/fuzz/fuzz_dhcp.c new file mode 100644 index 00000000000..1368ac2a138 --- /dev/null +++ b/fuzz/fuzz_dhcp.c @@ -0,0 +1,37 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "config.h" +#include "syshead.h" +#include "dhcp.h" +#include "buffer.h" + +#include "fuzz_randomizer.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + struct buffer ipbuf; + in_addr_t ret; + + fuzz_random_init(data, size); + char *ran_val = get_random_string(); + + ipbuf = alloc_buf(strlen(ran_val)); + if (buf_write(&ipbuf, ran_val, strlen(ran_val)) != false) { + ret = dhcp_extract_router_msg(&ipbuf); + } + free_buf(&ipbuf); + + fuzz_random_destroy(); + free(ran_val); + + return 0; +} diff --git a/fuzz/fuzz_forward.c b/fuzz/fuzz_forward.c new file mode 100644 index 00000000000..dff3e93d3c5 --- /dev/null +++ b/fuzz/fuzz_forward.c @@ -0,0 +1,228 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "config.h" +#include +#include "syshead.h" +#include "interval.h" +#include "init.h" +#include "buffer.h" +#include "forward.h" + +#include "fuzz_randomizer.h" + + +static int init_c2_outgoing_link(struct context_2 *c2, struct gc_arena *gc) { + struct link_socket_actual *to_link_addr = NULL; + struct link_socket *link_socket = NULL; + struct socks_proxy_info *socks_proxy = NULL; + struct buffer buf; + + c2->tun_write_bytes = 0; + ALLOC_ARRAY_GC(link_socket, struct link_socket, 1, gc); + memset(link_socket, 0, sizeof(*link_socket)); + + c2->link_socket = link_socket; + + if (fuzz_randomizer_get_int(0, 2) != 0) { + c2->link_socket->info.proto = PROTO_UDP; + } else { + c2->link_socket->info.proto = PROTO_TCP_SERVER; + } + + ALLOC_ARRAY_GC(socks_proxy, struct socks_proxy_info, 1, gc); + memset(socks_proxy, 0, sizeof(*socks_proxy)); + c2->link_socket->socks_proxy = socks_proxy; + + c2->frame.link_mtu_dynamic = fuzz_randomizer_get_int(0, 0xfffffff); + c2->frame.extra_frame = fuzz_randomizer_get_int(0, 0xfffffff); + c2->frame.extra_tun = fuzz_randomizer_get_int(0, 0xfffffff); + c2->frame.link_mtu = fuzz_randomizer_get_int(0, 0xfffffff); + + ALLOC_ARRAY_GC(to_link_addr, struct link_socket_actual, 1, gc); + memset(to_link_addr, 0, sizeof(*to_link_addr)); + c2->to_link_addr = to_link_addr; + + c2->to_link_addr->dest.addr.sa.sa_family = AF_INET; + c2->to_link_addr->dest.addr.in4.sin_addr.s_addr = 1; + + char *tmp = get_random_string(); + buf = alloc_buf_gc(strlen(tmp), gc); + buf_write(&buf, tmp, strlen(tmp)); + int val = fuzz_randomizer_get_int(0, strlen(tmp)); + buf.offset = val; + free(tmp); + + c2->link_socket->stream_buf.maxlen = BLEN(&buf); + c2->to_link = buf; + + if (buf.offset < 10) { + return -1; + } + return 0; +} + +void fuzz_process_outgoing_link(const uint8_t *data, size_t size) { + struct context ctx; + struct gc_arena gc = gc_new(); + memset(&ctx, 0, sizeof(ctx)); + + if (init_c2_outgoing_link(&ctx.c2, &gc) == 0) { + process_outgoing_link(&ctx); + } + + gc_free(&gc); +} + +static int _init_options(struct options *options, struct client_nat_entry **cne, + struct gc_arena *gc) { + options->passtos = false; + options->mode = MODE_POINT_TO_POINT; + options->allow_recursive_routing = true; + options->client_nat = new_client_nat_list(gc); + + struct client_nat_entry *_cne; + ALLOC_ARRAY_GC(cne[0], struct client_nat_entry, 1, gc); + _cne = cne[0]; + memset(_cne, 0, sizeof(struct client_nat_entry)); + + struct client_nat_option_list clist; + clist.n = 1; + clist.entries[0] = *_cne; + copy_client_nat_option_list(options->client_nat, &clist); + options->route_gateway_via_dhcp = false; + + return 0; +} + +static int init_c2_incoming_tun(struct context_2 *c2, struct gc_arena *gc) { + struct buffer buf; + memset(&buf, 0, sizeof(buf)); + + struct link_socket *link_socket = NULL; + ALLOC_ARRAY_GC(link_socket, struct link_socket, 1, gc); + c2->link_socket = link_socket; + + ALLOC_OBJ_GC(c2->link_socket_info, struct link_socket_info, gc); + ALLOC_OBJ_GC(c2->link_socket_info->lsa, struct link_socket_addr, gc); + c2->link_socket_info->lsa->bind_local = NULL; + c2->link_socket_info->lsa->remote_list = NULL; + c2->link_socket_info->lsa->current_remote = NULL; + c2->link_socket_info->lsa->remote_list = NULL; + c2->es = env_set_create(gc); + + c2->frame.link_mtu_dynamic = 0; + c2->frame.extra_frame = 0; + c2->frame.extra_tun = 0; + c2->to_link_addr = NULL; + + char *tmp = get_random_string(); + buf = alloc_buf(strlen(tmp)); + buf_write(&buf, tmp, strlen(tmp)); + + int retval; + if (strlen(tmp) > 5) { + retval = 0; + } else { + retval = 1; + } + + free(tmp); + + c2->buf = buf; + c2->buffers = init_context_buffers(&c2->frame); + c2->log_rw = false; + + return retval; +} + +int run_process_incoming_tun(const uint8_t *data, size_t size) { + struct gc_arena gc; + struct context ctx; + struct client_nat_entry *cne[MAX_CLIENT_NAT]; + struct route_list route_list; + + memset(&ctx, 0, sizeof(ctx)); + memset(cne, 0, sizeof(cne)); + + gc = gc_new(); + + _init_options(&ctx.options, cne, &gc); + + // Init tuntap + struct tuntap tuntap; + tuntap.type = DEV_TYPE_TAP; + + ctx.c1.tuntap = &tuntap; + + int retval = init_c2_incoming_tun(&ctx.c2, &gc); + ctx.c1.route_list = &route_list; + if (retval == 0) { + process_incoming_tun(&ctx); + } + + free(ctx.c2.buf.data); + free_context_buffers(ctx.c2.buffers); + gc_free(&gc); +} + +static int init_c2_outgoing_tun(struct context_2 *c2, struct gc_arena *gc) { + struct buffer buf; + + c2->tun_write_bytes = 0; + c2->frame.link_mtu_dynamic = fuzz_randomizer_get_int(0, 0xfffffff); + c2->frame.extra_frame = fuzz_randomizer_get_int(0, 0xfffffff); + c2->frame.extra_tun = fuzz_randomizer_get_int(0, 0xfffffff); + + char *tmp = get_random_string(); + buf = alloc_buf_gc(strlen(tmp), gc); + buf_write(&buf, tmp, strlen(tmp)); + free(tmp); + + c2->to_tun = buf; + return 0; +} + +void run_process_outgoing_tun(uint8_t *data, size_t size) { + struct gc_arena gc; + struct context ctx; + struct tuntap tuntap; + + memset(&ctx, 0, sizeof(ctx)); + gc = gc_new(); + + tuntap.type = DEV_TYPE_TAP; + ctx.c1.tuntap = &tuntap; + + init_c2_outgoing_tun(&ctx.c2, &gc); + process_outgoing_tun(&ctx); + + gc_free(&gc); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + fuzz_random_init(data, size); + + int dec = fuzz_randomizer_get_int(0, 2); + if (dec == 0) { + run_process_incoming_tun(data, size); + } + else if (dec == 1) { + run_process_outgoing_tun(data, size); + } + else { + fuzz_process_outgoing_link(data, size); + } + + fuzz_random_destroy(); + return 0; +} diff --git a/fuzz/fuzz_header.h b/fuzz/fuzz_header.h new file mode 100644 index 00000000000..e86b70c62b8 --- /dev/null +++ b/fuzz/fuzz_header.h @@ -0,0 +1,79 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef FUZZ_H +#define FUZZ_H + +#include +#include + +// Forward declared because we want to use FuzzedDataProvider, +// which requires CPP. +extern ssize_t fuzz_get_random_data(void *buf, size_t len); + +ssize_t fuzz_recv(int sockfd, void *buf, size_t len, int flags){ + return fuzz_get_random_data(buf, len); +} + +ssize_t fuzz_read(int sockfd, void *buf, size_t len){ + return fuzz_get_random_data(buf, len); +} + +ssize_t fuzz_write(int fd, const void *buf, size_t count) { + return count; +} + +int fuzz_isatty(int fd) { + return 1; +} + +char *fuzz_fgets(char *s, int size, FILE *stream) { + ssize_t v = fuzz_get_random_data(s, size-1); + // We use fgets to get trusted input. As such, assume we have + // an ascii printable char at the beginning. + printf("Calling into fgets\n"); + if (s[0] <= 0x21 || s[0] >= 0x7f) { + s[0] = 'A'; + } + s[size-1] = '\0'; + return s; +} + +int fuzz_select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout) { + char val; + ssize_t c = fuzz_get_random_data(&val, 1); + return c; +} + +ssize_t fuzz_send(int sockfd, const void *buf, size_t len, int flags) { + return len; +} + +FILE *fp_p = NULL; +FILE *fuzz_fopen(const char *pathname, const char *mode) { + if (mode == NULL) return fp_p; + return fp_p; +} + +int fuzz_fclose(FILE *stream) { + if (stream == NULL) return 1; + return 2; +} + +size_t fuzz_sendto(int sockfd, void *buf, size_t len, int flags, struct sockaddr *dest_addr, socklen_t addrlen) { + if (buf == NULL) { + return len; + } + return len; +} + +#endif diff --git a/fuzz/fuzz_list.c b/fuzz/fuzz_list.c new file mode 100644 index 00000000000..1e8fe621cfe --- /dev/null +++ b/fuzz/fuzz_list.c @@ -0,0 +1,135 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "config.h" +#include "syshead.h" +#include "list.h" + +#include "fuzz_randomizer.h" + +#define KEY_SIZE 23 + +/* Required for hash_init() */ +static uint32_t word_hash_function(const void *key, uint32_t iv) { + return hash_func(key, KEY_SIZE, iv); +} + +/* Required for hash_init() */ +static bool word_compare_function(const void *key1, const void *key2) { + return ((size_t)key1 & 0xFFF) == ((size_t)key1 & 0xFFF); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + struct gc_arena gc; + struct hash *hash = NULL; + ssize_t generic_ssizet, generic_ssizet2, num_loops; + + fuzz_random_init(data, size); + + gc = gc_new(); + + int total_to_fuzz = fuzz_randomizer_get_int(1, 20); + for (int i = 0; i < total_to_fuzz; i++) { + generic_ssizet = fuzz_randomizer_get_int(0, 8); + + switch (generic_ssizet) { + case 0: + if (hash == NULL) { + int n_buckets = fuzz_randomizer_get_int(1, 1000); + uint32_t iv; + + hash = + hash_init(n_buckets, iv, word_hash_function, word_compare_function); + } + break; + case 1: + if (hash) { + hash_free(hash); + hash = NULL; + } + break; + case 2: + if (hash) { + struct hash_iterator hi; + struct hash_element *he; + hash_iterator_init(hash, &hi); + while ((he = hash_iterator_next(&hi))) { + void *w = he->value; + } + hash_iterator_free(&hi); + } + break; + case 3: + if (hash) { + void *key; + void *value; + char arr[KEY_SIZE]; + memset(arr, 0, KEY_SIZE); + fuzz_get_random_data(arr, KEY_SIZE); + key = (void *)arr; + if (!hash_lookup(hash, key)) { + generic_ssizet = fuzz_randomizer_get_int(0, 0xfffffff); + value = (void *)generic_ssizet; + hash_add(hash, key, value, false); + } + } + break; + case 4: + if (hash) { + hash_n_elements(hash); + } + break; + case 5: + if (hash) { + hash_n_buckets(hash); + } + break; + case 6: + if (hash) { + uint32_t hv; + generic_ssizet = fuzz_randomizer_get_int(0, 0xfffffff); + hv = generic_ssizet; + hash_bucket(hash, hv); + } + break; + case 7: + if (hash) { + void *key; + char arr[KEY_SIZE]; + memset(arr, 0, KEY_SIZE); + fuzz_get_random_data(arr, KEY_SIZE); + key = (void *)arr; + hash_remove(hash, key); + } + break; + case 8: + if (hash) { + void *value; + generic_ssizet = fuzz_randomizer_get_int(0, 0xfffffff); + value = (void *)generic_ssizet; + hash_remove_by_value(hash, value); + } + default: + break; + } + } + + if (hash) { + hash_free(hash); + } + + gc_free(&gc); + + fuzz_random_destroy(); + + return 0; +} diff --git a/fuzz/fuzz_misc.c b/fuzz/fuzz_misc.c new file mode 100644 index 00000000000..d4a6667e061 --- /dev/null +++ b/fuzz/fuzz_misc.c @@ -0,0 +1,62 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +#include "config.h" +#include "syshead.h" +#include "misc.h" +#include "buffer.h" + +#include "fuzz_randomizer.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + fuzz_random_init(data, size); + + struct gc_arena gc; + struct env_set *es; + gc = gc_new(); + es = env_set_create(&gc); + + int total_to_fuzz = fuzz_randomizer_get_int(1, 9); + for (int i = 0; i 1 && strlen(tmp2) > 1) { + setenv_str(es, tmp2, tmp1); + } + break; + default: + sanitize_control_message(tmp1, &gc); + } + free(tmp1); + free(tmp2); + } + + env_set_destroy(es); + gc_free(&gc); + + fuzz_random_destroy(); + return 0; +} diff --git a/fuzz/fuzz_mroute.c b/fuzz/fuzz_mroute.c new file mode 100644 index 00000000000..63d0ce23dd5 --- /dev/null +++ b/fuzz/fuzz_mroute.c @@ -0,0 +1,70 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "config.h" +#include "syshead.h" +#include "init.h" +#include "mroute.h" + +#include "fuzz_randomizer.h" + + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + + fuzz_random_init(data, size); + struct buffer buf; + struct gc_arena gc; + + gc = gc_new(); + + char *tmp = get_random_string(); + buf = string_alloc_buf(tmp, &gc); + free(tmp); + + struct mroute_addr src_addr; + struct mroute_addr dst_addr; + mroute_addr_init(&src_addr); + mroute_addr_init(&dst_addr); + unsigned int ret = mroute_extract_addr_ip(&src_addr, &dst_addr, &buf); + + if (ret & MROUTE_EXTRACT_SUCCEEDED) { + mroute_addr_mask_host_bits(&src_addr); + mroute_addr_print(&src_addr, &gc); + mroute_learnable_address(&src_addr, &gc); + } + + uint16_t vid; + struct mroute_addr a1, a2; + mroute_addr_init(&a1); + mroute_addr_init(&a2); + mroute_extract_addr_ether(&a1, &a2, vid, &buf); + + if (size > sizeof(struct openvpn_sockaddr)) { + struct openvpn_sockaddr local_sock; + memcpy(&local_sock, data, sizeof(struct openvpn_sockaddr)); + mroute_extract_openvpn_sockaddr(&a1, &local_sock, true); + mroute_extract_openvpn_sockaddr(&a1, &local_sock, false); + } + + struct mroute_helper *mhelper = NULL; + mhelper = mroute_helper_init(fuzz_randomizer_get_int(0, 0xfffffff)); + if (mhelper != NULL) { + mroute_helper_add_iroute46(mhelper, fuzz_randomizer_get_int(0, MR_HELPER_NET_LEN-1)); + mroute_helper_free(mhelper); + } + + gc_free(&gc); + + fuzz_random_destroy(); + return 0; +} + diff --git a/fuzz/fuzz_packet_id.c b/fuzz/fuzz_packet_id.c new file mode 100644 index 00000000000..9297d0be523 --- /dev/null +++ b/fuzz/fuzz_packet_id.c @@ -0,0 +1,104 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "config.h" +#include "syshead.h" +#include "init.h" +#include "packet_id.h" + +#include "fuzz_randomizer.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + fuzz_random_init(data, size); + + struct packet_id pid; + struct packet_id_net pin; + const int seq_backtrack = 10; + const int time_backtrack = 10; + + packet_id_init(&pid, seq_backtrack, time_backtrack, "name", 0); + + int total_sends = fuzz_randomizer_get_int(0, 10); + for (int i = 0; i < total_sends; i++) { + update_time(); + pin.time = fuzz_randomizer_get_int(0, 0xfffffff); + pin.id = fuzz_randomizer_get_int(0, 0xfffffff); + + packet_id_reap_test(&pid.rec); + bool test = packet_id_test(&pid.rec, &pin); + if (test) { + packet_id_add(&pid.rec, &pin); + } + } + packet_id_free(&pid); + + // packet id send + char *tmp2 = get_random_string(); + if (strlen(tmp2) > sizeof(struct packet_id_send)) { + struct packet_id_send pidsend; + memcmp(&pidsend, tmp2, sizeof(struct packet_id_send)); + + struct timeval tv; + tv.tv_sec = pidsend.time; + tv.tv_usec = 0; + if (localtime(&tv)) { + struct buffer iv_buffer; + buf_set_write(&iv_buffer, tmp2, strlen(tmp2)); + packet_id_write(&pidsend, &iv_buffer, false, false); + packet_id_write(&pidsend, &iv_buffer, false, true); + packet_id_write(&pidsend, &iv_buffer, true, true); + packet_id_write(&pidsend, &iv_buffer, true, false); + } + } + free(tmp2); + + struct gc_arena gc; + gc = gc_new(); + struct buffer buf; + char *tmp = get_random_string(); + buf = string_alloc_buf(tmp, &gc); + free(tmp); + packet_id_read(&pid, &buf, false); + packet_id_read(&pid, &buf, true); + gc_free(&gc); + + char filename[256]; + sprintf(filename, "/tmp/libfuzzer.%d", getpid()); + + FILE *fp = fopen(filename, "wb"); + if (!fp) { + return 0; + } + fwrite(data, size, 1, fp); + fclose(fp); + + struct packet_id_persist p; + memset(&p, 0, sizeof(struct packet_id_persist)); + packet_id_persist_init(&p); + packet_id_persist_load(&p, filename); + //p.time = NULL; + struct timeval tv; + tv.tv_sec = p.time; + tv.tv_usec = 0; + if (localtime(&tv) != NULL) { + gc = gc_new(); + p.id_last_written = fuzz_randomizer_get_int(0, 0xfffffff); + //packet_id_persist_print(&p, &gc); + packet_id_persist_save(&p); + gc_free(&gc); + } + + packet_id_persist_close(&p); + + fuzz_random_destroy(); + return 0; +} diff --git a/fuzz/fuzz_proxy.c b/fuzz/fuzz_proxy.c new file mode 100644 index 00000000000..8aac1bb00c0 --- /dev/null +++ b/fuzz/fuzz_proxy.c @@ -0,0 +1,144 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "config.h" +#include +#include "syshead.h" +#include "interval.h" +#include "proxy.h" +#include +#include +#include "sig.h" + +#include "fuzz_randomizer.h" + +int LLVMFuzzerInitialize(int *argc, char ***argv) +{ + OPENSSL_malloc_init(); + SSL_library_init(); + ERR_load_crypto_strings(); + + OpenSSL_add_all_algorithms(); + OpenSSL_add_ssl_algorithms(); + OpenSSL_add_all_digests(); + + SSL_load_error_strings(); + return 1; +} + + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + + char *tmp = NULL; + char *tmp2 = NULL; + + if (size < 500) { + return 0; + } + fuzz_random_init(data, size); + + struct gc_arena gc = gc_new(); + struct http_proxy_info pi; + ssize_t generic_ssizet; + struct signal_info signal_received = {0}; + // TODO: This coul be randomized + register_signal(&signal_received, SIGUSR1, "remote-exit"); + struct buffer lookahead = alloc_buf(1024); + struct event_timeout evt; + + memset(&evt, 0, sizeof(struct event_timeout)); + memset(&pi, 0, sizeof(struct http_proxy_info)); + memset(&pi, 0, sizeof(pi)); + + generic_ssizet = 0; + char *fuzz_usrnm = fuzz_random_get_string_max_length(USER_PASS_LEN); + strcpy(pi.up.username, fuzz_usrnm); + if (strlen(pi.up.username) == 0) { + gc_free(&gc); + free_buf(&lookahead); + free(fuzz_usrnm); + fuzz_random_destroy(); + return 0; + } + + char *pswd = fuzz_random_get_string_max_length(USER_PASS_LEN); + strcpy(pi.up.password, pswd); + if (strlen(pi.up.password) == 0) { + gc_free(&gc); + free_buf(&lookahead); + + free(pswd); + free(fuzz_usrnm); + fuzz_random_destroy(); + return 0; + } + + generic_ssizet = fuzz_randomizer_get_int(0, 3); + switch (generic_ssizet) { + case 0: + pi.auth_method = HTTP_AUTH_NONE; + break; + case 1: + pi.auth_method = HTTP_AUTH_BASIC; + break; + case 2: + pi.auth_method = HTTP_AUTH_DIGEST; + break; + case 3: + pi.auth_method = HTTP_AUTH_NTLM2; + break; + } + pi.options.http_version = "1.1"; + + generic_ssizet = fuzz_randomizer_get_int(0, 2); + switch (generic_ssizet) { + case 0: + pi.options.auth_retry = PAR_NO; + break; + case 1: + pi.options.auth_retry = PAR_ALL; + break; + case 2: + pi.options.auth_retry = PAR_NCT; + break; + } + + char *tmp_authenticate = get_random_string(); + pi.proxy_authenticate = tmp_authenticate; + + //if (provider.ConsumeProbability() < 0.5) { + //tmp = get_modifiable_string(provider); + tmp = get_random_string(); + pi.options.custom_headers[0].name = tmp; + //if (provider.ConsumeProbability() < 0.5) { + //tmp2 = get_modifiable_string(provider); + tmp2 = get_random_string(); + pi.options.custom_headers[0].content = tmp2; + //} + //} + + establish_http_proxy_passthru(&pi, 0, "1.2.3.4", "777", &evt, &lookahead, + &signal_received); + free(pi.proxy_authenticate); + gc_free(&gc); + free_buf(&lookahead); + + if (tmp != NULL) free(tmp); + if (tmp2 != NULL) free(tmp2); + + free(pswd); + free(fuzz_usrnm); + fuzz_random_destroy(); + + + return 0; +} diff --git a/fuzz/fuzz_randomizer.cpp b/fuzz/fuzz_randomizer.cpp new file mode 100644 index 00000000000..367c55862c1 --- /dev/null +++ b/fuzz/fuzz_randomizer.cpp @@ -0,0 +1,107 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +FuzzedDataProvider *prov = NULL; + +extern "C" void fuzz_random_init(const uint8_t *data, size_t size) { + assert(prov == NULL); + prov = new FuzzedDataProvider(data, size); +} + +extern "C" void fuzz_random_destroy() { + assert(prov != NULL); + delete prov; + prov = NULL; +} + +extern "C" char *get_random_string() { + assert(prov != NULL); + + std::string s1 = prov->ConsumeRandomLengthString(); + char *tmp = (char *)malloc(s1.size() + 1); + memcpy(tmp, s1.c_str(), s1.size()); + tmp[s1.size()] = '\0'; + return tmp; +} + +extern "C" int fuzz_randomizer_get_int(int min, int max) { + assert(prov != NULL); + return prov->ConsumeIntegralInRange(min, max); +} + +extern "C" char *fuzz_random_get_string_max_length(int max_len) { + assert(prov != NULL); + + std::string s1 = prov->ConsumeBytesAsString( + prov->ConsumeIntegralInRange(1, max_len)); + char *tmp123 = (char*)malloc(s1.size()+1); + memcpy(tmp123, s1.c_str(), s1.size()); + tmp123[s1.size()] = '\0'; + + return tmp123; +} + +extern "C" size_t fuzz_get_random_data(void *buf, size_t len) { + assert(prov != NULL); + size_t ret_val; + char *cbuf = (char*)buf; + + if (prov->remaining_bytes() == 0) { + return -1; + } + + double prob = prov->ConsumeProbability(); + if (prob < 0.05) { + return 0; + } + + //if (len == 1) { + // ret_val = prov->ConsumeData(buf, 1); + // return ret_val; + //} + ret_val = prov->ConsumeData(buf, len); + return ret_val; +} + + +// Simple garbage collector +#define GB_SIZE 100 +void *pointer_arr[GB_SIZE]; +static int pointer_idx = 0; + +// If the garbage collector is used then this must be called as first thing +// during a fuzz run. +extern "C" void gb_init() { + pointer_idx = 0; + + for (int i = 0; i < GB_SIZE; i++) { + pointer_arr[i] = NULL; + } +} + +extern "C" void gb_cleanup() { + for(int i = 0; i < GB_SIZE; i++) { + if (pointer_arr[i] != NULL) { + free(pointer_arr[i]); + } + } +} + +extern "C" char *gb_get_random_string() { + char *tmp = get_random_string(); + pointer_arr[pointer_idx++] = (void*)tmp; + return tmp; +} + diff --git a/fuzz/fuzz_randomizer.h b/fuzz/fuzz_randomizer.h new file mode 100644 index 00000000000..a063ecac6b3 --- /dev/null +++ b/fuzz/fuzz_randomizer.h @@ -0,0 +1,27 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +void fuzz_random_init(const uint8_t *data, size_t size); +void fuzz_random_destroy(); +char *get_random_string(); +int fuzz_randomizer_get_int(int min, int max); +size_t fuzz_get_random_data(void *buf, size_t len); +char *fuzz_random_get_string_max_length(int max_len); + +void gb_init(); +void gb_cleanup(); +char *gb_get_random_string(); + +int fuzz_success; diff --git a/fuzz/fuzz_route.c b/fuzz/fuzz_route.c new file mode 100644 index 00000000000..d36096dfac0 --- /dev/null +++ b/fuzz/fuzz_route.c @@ -0,0 +1,207 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "config.h" +#include "syshead.h" +#include "init.h" +#include "proxy.h" +#include "interval.h" +#include "route.h" +#include "buffer.h" + +#include "fuzz_randomizer.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + + fuzz_random_init(data, size); + + gb_init(); + + struct route_option_list *opt; + struct route_list rl; + + int route_list_inited = 0; + int route_list_ipv6_inited = 0; + + struct context c; + memset(&c, 0, sizeof(struct context)); + gc_init(&c.gc); + c.es = env_set_create(&c.gc); + init_options(&c.options, true); + net_ctx_init(&c, &c.net_ctx); + init_verb_mute(&c, IVM_LEVEL_1); + + init_options_dev(&c.options); + + // options_postprocess(&c.options); + pre_setup(&c.options); + + setenv_settings(c.es, &c.options); + + ALLOC_OBJ_CLEAR_GC(c.options.ce.local_list, struct local_list, &c.options.gc); + ALLOC_OBJ_CLEAR_GC(c.options.connection_list, struct connection_list, + &c.options.gc); + context_init_1(&c); + + in_addr_t remote_host; + ssize_t default_metric; + + struct route_ipv6_list rl6; + struct route_ipv6_option_list *opt6; + + memset(&rl, 0, sizeof(rl)); + memset(&rl6, 0, sizeof(rl6)); + memset(&opt, 0, sizeof(opt)); + memset(&opt6, 0, sizeof(opt6)); + + opt6 = new_route_ipv6_option_list(&c.gc); + opt = new_route_option_list(&c.gc); + + int total_to_fuzz = fuzz_randomizer_get_int(1, 20); + for (int i = 0; i < total_to_fuzz; i++) { + int selector = fuzz_randomizer_get_int(0, 13); + switch (selector) { + case 0: + if (route_list_inited == 0) { + const char *remote_endpoint = gb_get_random_string(); + memset(&rl, 0, sizeof(struct route_list)); + rl.flags = fuzz_randomizer_get_int(0, 0xffffff); + + init_route_list(&rl, opt, remote_endpoint, default_metric, remote_host, + c.es, &c); + route_list_inited = 1; + } + break; + case 1: + if (route_list_inited) { + in_addr_t addr; + route_list_add_vpn_gateway(&rl, c.es, addr); + } + break; + case 2: + if (route_list_inited && route_list_ipv6_inited) { + struct tuntap tt; + memset(&tt, 0, sizeof(tt)); + add_routes(&rl, &rl6, &tt, 0, c.es, &c); + } + break; + case 3: + if (route_list_inited) { + setenv_routes(c.es, &rl); + } + break; + case 4: + if (route_list_inited) { + struct route_ipv4 r; + struct route_option ro; + ro.network = gb_get_random_string(); + ro.netmask = gb_get_random_string(); + ro.gateway = gb_get_random_string(); + ro.metric = gb_get_random_string(); + ro.next = NULL; + + memset(&r, 0, sizeof(struct route_ipv4)); + r.option = &ro; + r.flags = RT_DEFINED; + add_route(&r, NULL, 0, NULL, c.es, &c); + } + break; + case 5: + if (route_list_inited) { + char *s1 = get_random_string(); + is_special_addr(s1); + free(s1); + } + break; + case 6: + if (route_list_ipv6_inited == 0) { + const char *remote_endpoint = gb_get_random_string(); + memset(&rl, 0, sizeof(struct route_list)); + struct in6_addr remote_host; + + rl6.rgi6.flags = fuzz_randomizer_get_int(0, 0xffffff); + fuzz_get_random_data(&rl6.rgi6.hwaddr, 6); + + char *t1 = gb_get_random_string(); + if (strlen(t1) > 16) { + memcpy(rl6.rgi6.iface, t1, 16); + } else { + memcpy(rl6.rgi6.iface, t1, strlen(t1)); + } + + init_route_ipv6_list(&rl6, opt6, remote_endpoint, 0, &remote_host, c.es, + &c); + route_list_ipv6_inited = 1; + } + break; + case 7: { + unsigned int flags; + struct route_ipv6 r6; + struct tuntap tt; + memset(&tt, 0, sizeof(tt)); + tt.actual_name = gb_get_random_string(); + r6.iface = gb_get_random_string(); + r6.flags = fuzz_randomizer_get_int(0, 0xfffff); + r6.netbits = fuzz_randomizer_get_int(0, 0xfffff); + r6.metric = fuzz_randomizer_get_int(0, 0xfffff); + + r6.next = NULL; + + add_route_ipv6(&r6, &tt, 0, c.es, &c); + } break; + case 8: + if (route_list_ipv6_inited && route_list_inited) { + delete_routes(&rl, &rl6, NULL, 0, c.es, &c); + route_list_ipv6_inited = 0; + route_list_inited = 0; + } + break; + case 9: + if (route_list_ipv6_inited) { + setenv_routes_ipv6(c.es, &rl6); + } + break; + case 10: { + add_route_ipv6_to_option_list(opt6, + gb_get_random_string(), + gb_get_random_string(), + gb_get_random_string(), + fuzz_randomizer_get_int(0, 100)); + } break; + case 11: { + print_route_options(opt, M_NONFATAL); + } break; + case 12: { + add_route_to_option_list(opt, + gb_get_random_string(), + gb_get_random_string(), + gb_get_random_string(), + gb_get_random_string(), + fuzz_randomizer_get_int(0, 100)); + } break; + default: + break; + } + } + + if (route_list_inited) { + gc_free(&rl.gc); + } + env_set_destroy(c.es); + context_gc_free(&c); + + fuzz_random_destroy(); + + gb_cleanup(); + + return 0; +} diff --git a/fuzz/fuzz_verify_cert.c b/fuzz/fuzz_verify_cert.c new file mode 100644 index 00000000000..c73a6ac828c --- /dev/null +++ b/fuzz/fuzz_verify_cert.c @@ -0,0 +1,167 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "config.h" +#include "syshead.h" + +#include +#include +#include +#include + +#include "fuzz_verify_cert.h" +#include "misc.h" +#include "manage.h" +#include "otime.h" +#include "base64.h" +#include "ssl_verify.h" +#include "ssl_verify_backend.h" + +#include "fuzz_randomizer.h" + + +static int parse_x509(const uint8_t *data, size_t size, X509 **out) { + *out = d2i_X509(NULL, (const unsigned char **)&data, size); + if (*out == NULL) { + return -1; + } + + return 0; +} + + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + OPENSSL_malloc_init(); + SSL_library_init(); + ERR_load_crypto_strings(); + + OpenSSL_add_all_algorithms(); + OpenSSL_add_ssl_algorithms(); + + SSL_load_error_strings(); + return 1; +} + + +static int init_session_opt(struct tls_options **_opt, struct gc_arena *gc) { + ssize_t nid; + ssize_t generic_ssizet; + struct tls_options *opt; + int r; + + ALLOC_OBJ_GC(*_opt, struct tls_options, gc); + if (opt == NULL) { + return -1; + } + + opt = *_opt; + + memset(opt, 0xFE, sizeof(struct tls_options)); + + opt->es = env_set_create(gc); + opt->x509_username_field[0] = NULL; + opt->remote_cert_eku = NULL; + + /* Prevents failure if x509 sha1 hashes do not match */ + opt->verify_hash = NULL; + + /* Prevent attempt to run --tls-verify script */ + opt->verify_command = NULL; + + /* Do not verify against CRL file */ + opt->crl_file = NULL; + + /* Do not run --tls-verify plugins */ + opt->plugins = NULL; + + r = fuzz_randomizer_get_int(0, 1); + if (r == 0) { + opt->x509_username_field[0] = nidstrs[fuzz_randomizer_get_int(0, (sizeof(nidstrs)/sizeof(nidstrs[0])) - 1)]; + } + else { + opt->x509_username_field[0] = "ext:subjectAltName"; + } + opt->x509_username_field[1] = NULL; + + r = fuzz_randomizer_get_int(0, 2); + if (r == 0) + opt->ns_cert_type = NS_CERT_CHECK_CLIENT; + else if (r == 1) + opt->ns_cert_type = NS_CERT_CHECK_SERVER; + else + opt->ns_cert_type = NS_CERT_CHECK_NONE; + + opt->x509_track = NULL; + + r = fuzz_randomizer_get_int(0, 1); + if (r == 0) + opt->remote_cert_eku = NULL; + else + opt->remote_cert_eku = get_random_string(); + + return 0; +} + + +static int init_session(struct tls_session **_session, struct gc_arena *gc) { + struct tls_session *session; + + ALLOC_OBJ_GC(*_session, struct tls_session, gc); + if (*_session == NULL) { + return -1; + } + + session = *_session; + memset(session, 0xFE, sizeof(struct tls_session)); + + /* Accessed in set_common_name() */ + session->common_name = get_random_string();; + + /* Initialize the session->opt structure */ + if (init_session_opt(&(session->opt), gc) == -1) { + free(session->common_name); + return -1; + } + + /* Accessed in server_untrusted() */ + session->untrusted_addr.dest.addr.sa.sa_family = AF_UNSPEC; + + return 0; +} + + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + fuzz_random_init(data, size); + + struct gc_arena gc; + struct tls_session *session = NULL; + X509 *x509 = NULL; + gc = gc_new(); + + if (parse_x509(data, size, &x509) == 0) { + if (init_session(&session, &gc) == 0) { + verify_cert(session, x509, 100); + if (session->opt->remote_cert_eku != NULL) { + free(session->opt->remote_cert_eku); + } + free(session->common_name); + } + + } + + X509_free(x509); + gc_free(&gc); + + fuzz_random_destroy(); + + return 0; +} diff --git a/fuzz/fuzz_verify_cert.h b/fuzz/fuzz_verify_cert.h new file mode 100644 index 00000000000..8a53669b32b --- /dev/null +++ b/fuzz/fuzz_verify_cert.h @@ -0,0 +1,1065 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +static char* nidstrs[] = { +"AD_DVCS", +"AES-128-CBC", +"AES-128-CBC-HMAC-SHA1", +"AES-128-CBC-HMAC-SHA256", +"AES-128-CFB", +"AES-128-CFB1", +"AES-128-CFB8", +"AES-128-CTR", +"AES-128-ECB", +"AES-128-OCB", +"AES-128-OFB", +"AES-128-XTS", +"AES-192-CBC", +"AES-192-CBC-HMAC-SHA1", +"AES-192-CBC-HMAC-SHA256", +"AES-192-CFB", +"AES-192-CFB1", +"AES-192-CFB8", +"AES-192-CTR", +"AES-192-ECB", +"AES-192-OCB", +"AES-192-OFB", +"AES-256-CBC", +"AES-256-CBC-HMAC-SHA1", +"AES-256-CBC-HMAC-SHA256", +"AES-256-CFB", +"AES-256-CFB1", +"AES-256-CFB8", +"AES-256-CTR", +"AES-256-ECB", +"AES-256-OCB", +"AES-256-OFB", +"AES-256-XTS", +"AuthDSS", +"AuthECDSA", +"AuthGOST01", +"AuthGOST12", +"AuthNULL", +"AuthPSK", +"AuthRSA", +"AuthSRP", +"BF-CBC", +"BF-CFB", +"BF-ECB", +"BF-OFB", +"BLAKE2b512", +"BLAKE2s256", +"C", +"CAMELLIA-128-CBC", +"CAMELLIA-128-CCM", +"CAMELLIA-128-CFB", +"CAMELLIA-128-CFB1", +"CAMELLIA-128-CFB8", +"CAMELLIA-128-CMAC", +"CAMELLIA-128-CTR", +"CAMELLIA-128-ECB", +"CAMELLIA-128-GCM", +"CAMELLIA-128-OFB", +"CAMELLIA-192-CBC", +"CAMELLIA-192-CCM", +"CAMELLIA-192-CFB", +"CAMELLIA-192-CFB1", +"CAMELLIA-192-CFB8", +"CAMELLIA-192-CMAC", +"CAMELLIA-192-CTR", +"CAMELLIA-192-ECB", +"CAMELLIA-192-GCM", +"CAMELLIA-192-OFB", +"CAMELLIA-256-CBC", +"CAMELLIA-256-CCM", +"CAMELLIA-256-CFB", +"CAMELLIA-256-CFB1", +"CAMELLIA-256-CFB8", +"CAMELLIA-256-CMAC", +"CAMELLIA-256-CTR", +"CAMELLIA-256-ECB", +"CAMELLIA-256-GCM", +"CAMELLIA-256-OFB", +"CAST5-CBC", +"CAST5-CFB", +"CAST5-ECB", +"CAST5-OFB", +"CMAC", +"CN", +"CRLReason", +"CSPName", +"ChaCha20", +"ChaCha20-Poly1305", +"CrlID", +"DC", +"DES-CBC", +"DES-CDMF", +"DES-CFB", +"DES-CFB1", +"DES-CFB8", +"DES-ECB", +"DES-EDE", +"DES-EDE-CBC", +"DES-EDE-CFB", +"DES-EDE-OFB", +"DES-EDE3", +"DES-EDE3-CBC", +"DES-EDE3-CFB", +"DES-EDE3-CFB1", +"DES-EDE3-CFB8", +"DES-EDE3-OFB", +"DES-OFB", +"DESX-CBC", +"DOD", +"DSA", +"DSA-SHA", +"DSA-SHA1", +"DSA-SHA1-old", +"DSA-old", +"DVCS", +"GN", +"HKDF", +"HMAC", +"HMAC-MD5", +"HMAC-SHA1", +"IANA", +"IDEA-CBC", +"IDEA-CFB", +"IDEA-ECB", +"IDEA-OFB", +"INN", +"ISO", +"ISO-US", +"ITU-T", +"JOINT-ISO-ITU-T", +"KISA", +"KxDHE", +"KxDHE-PSK", +"KxECDHE", +"KxECDHE-PSK", +"KxGOST", +"KxPSK", +"KxRSA", +"KxRSA_PSK", +"KxSRP", +"L", +"LocalKeySet", +"MD2", +"MD4", +"MD5", +"MD5-SHA1", +"MDC2", +"MGF1", +"Mail", +"NULL", +"Netscape", +"Nonce", +"O", +"OCSP", +"OCSPSigning", +"OGRN", +"ORG", +"OU", +"Oakley-EC2N-3", +"Oakley-EC2N-4", +"PBE-MD2-DES", +"PBE-MD2-RC2-64", +"PBE-MD5-DES", +"PBE-MD5-RC2-64", +"PBE-SHA1-2DES", +"PBE-SHA1-3DES", +"PBE-SHA1-DES", +"PBE-SHA1-RC2-128", +"PBE-SHA1-RC2-40", +"PBE-SHA1-RC2-64", +"PBE-SHA1-RC4-128", +"PBE-SHA1-RC4-40", +"PBES2", +"PBKDF2", +"PBMAC1", +"PKIX", +"PSPECIFIED", +"RC2-40-CBC", +"RC2-64-CBC", +"RC2-CBC", +"RC2-CFB", +"RC2-ECB", +"RC2-OFB", +"RC4", +"RC4-40", +"RC4-HMAC-MD5", +"RC5-CBC", +"RC5-CFB", +"RC5-ECB", +"RC5-OFB", +"RIPEMD160", +"RSA", +"RSA-MD2", +"RSA-MD4", +"RSA-MD5", +"RSA-MDC2", +"RSA-NP-MD5", +"RSA-RIPEMD160", +"RSA-SHA", +"RSA-SHA1", +"RSA-SHA1-2", +"RSA-SHA224", +"RSA-SHA256", +"RSA-SHA384", +"RSA-SHA512", +"RSAES-OAEP", +"RSASSA-PSS", +"SEED-CBC", +"SEED-CFB", +"SEED-ECB", +"SEED-OFB", +"SHA", +"SHA1", +"SHA224", +"SHA256", +"SHA384", +"SHA512", +"SMIME", +"SMIME-CAPS", +"SN", +"SNILS", +"ST", +"SXNetID", +"TLS1-PRF", +"UID", +"UNDEF", +"X25519", +"X448", +"X500", +"X500algorithms", +"X509", +"X9-57", +"X9cm", +"ZLIB", +"aRecord", +"aaControls", +"ac-auditEntity", +"ac-proxying", +"ac-targeting", +"acceptableResponses", +"account", +"ad_timestamping", +"algorithm", +"ansi-X9-62", +"anyExtendedKeyUsage", +"anyPolicy", +"archiveCutoff", +"associatedDomain", +"associatedName", +"audio", +"authorityInfoAccess", +"authorityKeyIdentifier", +"authorityRevocationList", +"basicConstraints", +"basicOCSPResponse", +"biometricInfo", +"brainpoolP160r1", +"brainpoolP160t1", +"brainpoolP192r1", +"brainpoolP192t1", +"brainpoolP224r1", +"brainpoolP224t1", +"brainpoolP256r1", +"brainpoolP256t1", +"brainpoolP320r1", +"brainpoolP320t1", +"brainpoolP384r1", +"brainpoolP384t1", +"brainpoolP512r1", +"brainpoolP512t1", +"buildingName", +"businessCategory", +"c2onb191v4", +"c2onb191v5", +"c2onb239v4", +"c2onb239v5", +"c2pnb163v1", +"c2pnb163v2", +"c2pnb163v3", +"c2pnb176v1", +"c2pnb208w1", +"c2pnb272w1", +"c2pnb304w1", +"c2pnb368w1", +"c2tnb191v1", +"c2tnb191v2", +"c2tnb191v3", +"c2tnb239v1", +"c2tnb239v2", +"c2tnb239v3", +"c2tnb359v1", +"c2tnb431r1", +"cACertificate", +"cNAMERecord", +"caIssuers", +"caRepository", +"capwapAC", +"capwapWTP", +"caseIgnoreIA5StringSyntax", +"certBag", +"certicom-arc", +"certificateIssuer", +"certificatePolicies", +"certificateRevocationList", +"challengePassword", +"characteristic-two-field", +"clearance", +"clientAuth", +"codeSigning", +"contentType", +"countersignature", +"crlBag", +"crlDistributionPoints", +"crlNumber", +"crossCertificatePair", +"cryptocom", +"cryptopro", +"ct_cert_scts", +"ct_precert_poison", +"ct_precert_scts", +"ct_precert_signer", +"dITRedirect", +"dNSDomain", +"dSAQuality", +"data", +"dcobject", +"deltaCRL", +"deltaRevocationList", +"description", +"destinationIndicator", +"dh-cofactor-kdf", +"dh-std-kdf", +"dhKeyAgreement", +"dhSinglePass-cofactorDH-sha1kdf-scheme", +"dhSinglePass-cofactorDH-sha224kdf-scheme", +"dhSinglePass-cofactorDH-sha256kdf-scheme", +"dhSinglePass-cofactorDH-sha384kdf-scheme", +"dhSinglePass-cofactorDH-sha512kdf-scheme", +"dhSinglePass-stdDH-sha1kdf-scheme", +"dhSinglePass-stdDH-sha224kdf-scheme", +"dhSinglePass-stdDH-sha256kdf-scheme", +"dhSinglePass-stdDH-sha384kdf-scheme", +"dhSinglePass-stdDH-sha512kdf-scheme", +"dhpublicnumber", +"directory", +"distinguishedName", +"dmdName", +"dnQualifier", +"document", +"documentAuthor", +"documentIdentifier", +"documentLocation", +"documentPublisher", +"documentSeries", +"documentTitle", +"documentVersion", +"domain", +"domainRelatedObject", +"dsa_with_SHA224", +"dsa_with_SHA256", +"ecdsa-with-Recommended", +"ecdsa-with-SHA1", +"ecdsa-with-SHA224", +"ecdsa-with-SHA256", +"ecdsa-with-SHA384", +"ecdsa-with-SHA512", +"ecdsa-with-Specified", +"emailAddress", +"emailProtection", +"enhancedSearchGuide", +"enterprises", +"experimental", +"extReq", +"extendedCertificateAttributes", +"extendedKeyUsage", +"extendedStatus", +"facsimileTelephoneNumber", +"favouriteDrink", +"freshestCRL", +"friendlyCountry", +"friendlyCountryName", +"friendlyName", +"generationQualifier", +"gost-mac", +"gost-mac-12", +"gost2001", +"gost2001cc", +"gost2012_256", +"gost2012_512", +"gost89", +"gost89-cbc", +"gost89-cnt", +"gost89-cnt-12", +"gost89-ctr", +"gost89-ecb", +"gost94", +"gost94cc", +"grasshopper-cbc", +"grasshopper-cfb", +"grasshopper-ctr", +"grasshopper-ecb", +"grasshopper-mac", +"grasshopper-ofb", +"hmacWithMD5", +"hmacWithSHA1", +"hmacWithSHA224", +"hmacWithSHA256", +"hmacWithSHA384", +"hmacWithSHA512", +"holdInstructionCallIssuer", +"holdInstructionCode", +"holdInstructionNone", +"holdInstructionReject", +"homePostalAddress", +"homeTelephoneNumber", +"host", +"houseIdentifier", +"iA5StringSyntax", +"id-DHBasedMac", +"id-Gost28147-89-CryptoPro-A-ParamSet", +"id-Gost28147-89-CryptoPro-B-ParamSet", +"id-Gost28147-89-CryptoPro-C-ParamSet", +"id-Gost28147-89-CryptoPro-D-ParamSet", +"id-Gost28147-89-CryptoPro-KeyMeshing", +"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", +"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", +"id-Gost28147-89-CryptoPro-RIC-1-ParamSet", +"id-Gost28147-89-None-KeyMeshing", +"id-Gost28147-89-TestParamSet", +"id-Gost28147-89-cc", +"id-GostR3410-2001-CryptoPro-A-ParamSet", +"id-GostR3410-2001-CryptoPro-B-ParamSet", +"id-GostR3410-2001-CryptoPro-C-ParamSet", +"id-GostR3410-2001-CryptoPro-XchA-ParamSet", +"id-GostR3410-2001-CryptoPro-XchB-ParamSet", +"id-GostR3410-2001-ParamSet-cc", +"id-GostR3410-2001-TestParamSet", +"id-GostR3410-2001DH", +"id-GostR3410-94-CryptoPro-A-ParamSet", +"id-GostR3410-94-CryptoPro-B-ParamSet", +"id-GostR3410-94-CryptoPro-C-ParamSet", +"id-GostR3410-94-CryptoPro-D-ParamSet", +"id-GostR3410-94-CryptoPro-XchA-ParamSet", +"id-GostR3410-94-CryptoPro-XchB-ParamSet", +"id-GostR3410-94-CryptoPro-XchC-ParamSet", +"id-GostR3410-94-TestParamSet", +"id-GostR3410-94-a", +"id-GostR3410-94-aBis", +"id-GostR3410-94-b", +"id-GostR3410-94-bBis", +"id-GostR3410-94DH", +"id-GostR3411-94-CryptoProParamSet", +"id-GostR3411-94-TestParamSet", +"id-GostR3411-94-with-GostR3410-2001", +"id-GostR3411-94-with-GostR3410-2001-cc", +"id-GostR3411-94-with-GostR3410-94", +"id-GostR3411-94-with-GostR3410-94-cc", +"id-HMACGostR3411-94", +"id-PasswordBasedMAC", +"id-aca", +"id-aca-accessIdentity", +"id-aca-authenticationInfo", +"id-aca-chargingIdentity", +"id-aca-encAttrs", +"id-aca-group", +"id-aca-role", +"id-ad", +"id-aes128-CCM", +"id-aes128-GCM", +"id-aes128-wrap", +"id-aes128-wrap-pad", +"id-aes192-CCM", +"id-aes192-GCM", +"id-aes192-wrap", +"id-aes192-wrap-pad", +"id-aes256-CCM", +"id-aes256-GCM", +"id-aes256-wrap", +"id-aes256-wrap-pad", +"id-alg", +"id-alg-PWRI-KEK", +"id-alg-des40", +"id-alg-dh-pop", +"id-alg-dh-sig-hmac-sha1", +"id-alg-noSignature", +"id-camellia128-wrap", +"id-camellia192-wrap", +"id-camellia256-wrap", +"id-cct", +"id-cct-PKIData", +"id-cct-PKIResponse", +"id-cct-crs", +"id-ce", +"id-characteristic-two-basis", +"id-cmc", +"id-cmc-addExtensions", +"id-cmc-confirmCertAcceptance", +"id-cmc-dataReturn", +"id-cmc-decryptedPOP", +"id-cmc-encryptedPOP", +"id-cmc-getCRL", +"id-cmc-getCert", +"id-cmc-identification", +"id-cmc-identityProof", +"id-cmc-lraPOPWitness", +"id-cmc-popLinkRandom", +"id-cmc-popLinkWitness", +"id-cmc-queryPending", +"id-cmc-recipientNonce", +"id-cmc-regInfo", +"id-cmc-responseInfo", +"id-cmc-revokeRequest", +"id-cmc-senderNonce", +"id-cmc-statusInfo", +"id-cmc-transactionId", +"id-ct-asciiTextWithCRLF", +"id-ct-xml", +"id-ecPublicKey", +"id-hex-multipart-message", +"id-hex-partial-message", +"id-it", +"id-it-caKeyUpdateInfo", +"id-it-caProtEncCert", +"id-it-confirmWaitTime", +"id-it-currentCRL", +"id-it-encKeyPairTypes", +"id-it-implicitConfirm", +"id-it-keyPairParamRep", +"id-it-keyPairParamReq", +"id-it-origPKIMessage", +"id-it-preferredSymmAlg", +"id-it-revPassphrase", +"id-it-signKeyPairTypes", +"id-it-subscriptionRequest", +"id-it-subscriptionResponse", +"id-it-suppLangTags", +"id-it-unsupportedOIDs", +"id-kp", +"id-mod-attribute-cert", +"id-mod-cmc", +"id-mod-cmp", +"id-mod-cmp2000", +"id-mod-crmf", +"id-mod-dvcs", +"id-mod-kea-profile-88", +"id-mod-kea-profile-93", +"id-mod-ocsp", +"id-mod-qualified-cert-88", +"id-mod-qualified-cert-93", +"id-mod-timestamp-protocol", +"id-on", +"id-on-permanentIdentifier", +"id-on-personalData", +"id-pda", +"id-pda-countryOfCitizenship", +"id-pda-countryOfResidence", +"id-pda-dateOfBirth", +"id-pda-gender", +"id-pda-placeOfBirth", +"id-pe", +"id-pkinit", +"id-pkip", +"id-pkix-mod", +"id-pkix1-explicit-88", +"id-pkix1-explicit-93", +"id-pkix1-implicit-88", +"id-pkix1-implicit-93", +"id-ppl", +"id-ppl-anyLanguage", +"id-ppl-independent", +"id-ppl-inheritAll", +"id-qcs", +"id-qcs-pkixQCSyntax-v1", +"id-qt", +"id-qt-cps", +"id-qt-unotice", +"id-regCtrl", +"id-regCtrl-authenticator", +"id-regCtrl-oldCertID", +"id-regCtrl-pkiArchiveOptions", +"id-regCtrl-pkiPublicationInfo", +"id-regCtrl-protocolEncrKey", +"id-regCtrl-regToken", +"id-regInfo", +"id-regInfo-certReq", +"id-regInfo-utf8Pairs", +"id-scrypt", +"id-set", +"id-smime-aa", +"id-smime-aa-contentHint", +"id-smime-aa-contentIdentifier", +"id-smime-aa-contentReference", +"id-smime-aa-dvcs-dvc", +"id-smime-aa-encapContentType", +"id-smime-aa-encrypKeyPref", +"id-smime-aa-equivalentLabels", +"id-smime-aa-ets-CertificateRefs", +"id-smime-aa-ets-RevocationRefs", +"id-smime-aa-ets-archiveTimeStamp", +"id-smime-aa-ets-certCRLTimestamp", +"id-smime-aa-ets-certValues", +"id-smime-aa-ets-commitmentType", +"id-smime-aa-ets-contentTimestamp", +"id-smime-aa-ets-escTimeStamp", +"id-smime-aa-ets-otherSigCert", +"id-smime-aa-ets-revocationValues", +"id-smime-aa-ets-sigPolicyId", +"id-smime-aa-ets-signerAttr", +"id-smime-aa-ets-signerLocation", +"id-smime-aa-macValue", +"id-smime-aa-mlExpandHistory", +"id-smime-aa-msgSigDigest", +"id-smime-aa-receiptRequest", +"id-smime-aa-securityLabel", +"id-smime-aa-signatureType", +"id-smime-aa-signingCertificate", +"id-smime-aa-smimeEncryptCerts", +"id-smime-aa-timeStampToken", +"id-smime-alg", +"id-smime-alg-3DESwrap", +"id-smime-alg-CMS3DESwrap", +"id-smime-alg-CMSRC2wrap", +"id-smime-alg-ESDH", +"id-smime-alg-ESDHwith3DES", +"id-smime-alg-ESDHwithRC2", +"id-smime-alg-RC2wrap", +"id-smime-cd", +"id-smime-cd-ldap", +"id-smime-ct", +"id-smime-ct-DVCSRequestData", +"id-smime-ct-DVCSResponseData", +"id-smime-ct-TDTInfo", +"id-smime-ct-TSTInfo", +"id-smime-ct-authData", +"id-smime-ct-authEnvelopedData", +"id-smime-ct-compressedData", +"id-smime-ct-contentCollection", +"id-smime-ct-contentInfo", +"id-smime-ct-publishCert", +"id-smime-ct-receipt", +"id-smime-cti", +"id-smime-cti-ets-proofOfApproval", +"id-smime-cti-ets-proofOfCreation", +"id-smime-cti-ets-proofOfDelivery", +"id-smime-cti-ets-proofOfOrigin", +"id-smime-cti-ets-proofOfReceipt", +"id-smime-cti-ets-proofOfSender", +"id-smime-mod", +"id-smime-mod-cms", +"id-smime-mod-ess", +"id-smime-mod-ets-eSigPolicy-88", +"id-smime-mod-ets-eSigPolicy-97", +"id-smime-mod-ets-eSignature-88", +"id-smime-mod-ets-eSignature-97", +"id-smime-mod-msg-v3", +"id-smime-mod-oid", +"id-smime-spq", +"id-smime-spq-ets-sqt-unotice", +"id-smime-spq-ets-sqt-uri", +"id-tc26", +"id-tc26-agreement", +"id-tc26-agreement-gost-3410-2012-256", +"id-tc26-agreement-gost-3410-2012-512", +"id-tc26-algorithms", +"id-tc26-cipher", +"id-tc26-cipher-constants", +"id-tc26-constants", +"id-tc26-digest", +"id-tc26-digest-constants", +"id-tc26-gost-28147-constants", +"id-tc26-gost-28147-param-Z", +"id-tc26-gost-3410-2012-512-constants", +"id-tc26-gost-3410-2012-512-paramSetA", +"id-tc26-gost-3410-2012-512-paramSetB", +"id-tc26-gost-3410-2012-512-paramSetTest", +"id-tc26-hmac-gost-3411-2012-256", +"id-tc26-hmac-gost-3411-2012-512", +"id-tc26-mac", +"id-tc26-sign", +"id-tc26-sign-constants", +"id-tc26-signwithdigest", +"id-tc26-signwithdigest-gost3410-2012-256", +"id-tc26-signwithdigest-gost3410-2012-512", +"identified-organization", +"info", +"inhibitAnyPolicy", +"initials", +"international-organizations", +"internationaliSDNNumber", +"invalidityDate", +"ipsecEndSystem", +"ipsecIKE", +"ipsecTunnel", +"ipsecUser", +"issuerAltName", +"issuerSignTool", +"issuingDistributionPoint", +"janetMailbox", +"jurisdictionC", +"jurisdictionL", +"jurisdictionST", +"keyBag", +"keyUsage", +"lastModifiedBy", +"lastModifiedTime", +"localKeyID", +"mXRecord", +"mail", +"mailPreferenceOption", +"manager", +"md_gost12_256", +"md_gost12_512", +"md_gost94", +"member", +"member-body", +"messageDigest", +"mgmt", +"mime-mhs", +"mime-mhs-bodies", +"mime-mhs-headings", +"mobileTelephoneNumber", +"msCTLSign", +"msCodeCom", +"msCodeInd", +"msEFS", +"msExtReq", +"msSGC", +"msSmartcardLogin", +"msUPN", +"nSRecord", +"name", +"nameConstraints", +"noCheck", +"noRevAvail", +"nsBaseUrl", +"nsCaPolicyUrl", +"nsCaRevocationUrl", +"nsCertExt", +"nsCertSequence", +"nsCertType", +"nsComment", +"nsDataType", +"nsRenewalUrl", +"nsRevocationUrl", +"nsSGC", +"nsSslServerName", +"onBasis", +"organizationalStatus", +"otherMailbox", +"owner", +"pagerTelephoneNumber", +"path", +"pbeWithMD5AndCast5CBC", +"personalSignature", +"personalTitle", +"photo", +"physicalDeliveryOfficeName", +"pilot", +"pilotAttributeSyntax", +"pilotAttributeType", +"pilotAttributeType27", +"pilotDSA", +"pilotGroups", +"pilotObject", +"pilotObjectClass", +"pilotOrganization", +"pilotPerson", +"pkInitClientAuth", +"pkInitKDC", +"pkcs", +"pkcs1", +"pkcs3", +"pkcs5", +"pkcs7", +"pkcs7-data", +"pkcs7-digestData", +"pkcs7-encryptedData", +"pkcs7-envelopedData", +"pkcs7-signedAndEnvelopedData", +"pkcs7-signedData", +"pkcs8ShroudedKeyBag", +"pkcs9", +"policyConstraints", +"policyMappings", +"postOfficeBox", +"postalAddress", +"postalCode", +"ppBasis", +"preferredDeliveryMethod", +"presentationAddress", +"prf-gostr3411-94", +"prime-field", +"prime192v1", +"prime192v2", +"prime192v3", +"prime239v1", +"prime239v2", +"prime239v3", +"prime256v1", +"private", +"privateKeyUsagePeriod", +"protocolInformation", +"proxyCertInfo", +"pseudonym", +"pss", +"qcStatements", +"qualityLabelledData", +"rFC822localPart", +"registeredAddress", +"role", +"roleOccupant", +"room", +"roomNumber", +"rsaEncryption", +"rsaOAEPEncryptionSET", +"rsaSignature", +"rsadsi", +"sOARecord", +"safeContentsBag", +"sbgp-autonomousSysNum", +"sbgp-ipAddrBlock", +"sbgp-routerIdentifier", +"sdsiCertificate", +"searchGuide", +"secp112r1", +"secp112r2", +"secp128r1", +"secp128r2", +"secp160k1", +"secp160r1", +"secp160r2", +"secp192k1", +"secp224k1", +"secp224r1", +"secp256k1", +"secp384r1", +"secp521r1", +"secretBag", +"secretary", +"sect113r1", +"sect113r2", +"sect131r1", +"sect131r2", +"sect163k1", +"sect163r1", +"sect163r2", +"sect193r1", +"sect193r2", +"sect233k1", +"sect233r1", +"sect239k1", +"sect283k1", +"sect283r1", +"sect409k1", +"sect409r1", +"sect571k1", +"sect571r1", +"secureShellClient", +"secureShellServer", +"security", +"seeAlso", +"selected-attribute-types", +"sendOwner", +"sendProxiedOwner", +"sendProxiedRouter", +"sendRouter", +"serialNumber", +"serverAuth", +"serviceLocator", +"set-addPolicy", +"set-attr", +"set-brand", +"set-brand-AmericanExpress", +"set-brand-Diners", +"set-brand-IATA-ATA", +"set-brand-JCB", +"set-brand-MasterCard", +"set-brand-Novus", +"set-brand-Visa", +"set-certExt", +"set-ctype", +"set-msgExt", +"set-policy", +"set-policy-root", +"set-rootKeyThumb", +"setAttr-Cert", +"setAttr-GenCryptgrm", +"setAttr-IssCap", +"setAttr-IssCap-CVM", +"setAttr-IssCap-Sig", +"setAttr-IssCap-T2", +"setAttr-PGWYcap", +"setAttr-SecDevSig", +"setAttr-T2Enc", +"setAttr-T2cleartxt", +"setAttr-TokICCsig", +"setAttr-Token-B0Prime", +"setAttr-Token-EMV", +"setAttr-TokenType", +"setCext-IssuerCapabilities", +"setCext-PGWYcapabilities", +"setCext-TokenIdentifier", +"setCext-TokenType", +"setCext-Track2Data", +"setCext-cCertRequired", +"setCext-certType", +"setCext-hashedRoot", +"setCext-merchData", +"setCext-setExt", +"setCext-setQualf", +"setCext-tunneling", +"setct-AcqCardCodeMsg", +"setct-AcqCardCodeMsgTBE", +"setct-AuthReqTBE", +"setct-AuthReqTBS", +"setct-AuthResBaggage", +"setct-AuthResTBE", +"setct-AuthResTBEX", +"setct-AuthResTBS", +"setct-AuthResTBSX", +"setct-AuthRevReqBaggage", +"setct-AuthRevReqTBE", +"setct-AuthRevReqTBS", +"setct-AuthRevResBaggage", +"setct-AuthRevResData", +"setct-AuthRevResTBE", +"setct-AuthRevResTBEB", +"setct-AuthRevResTBS", +"setct-AuthTokenTBE", +"setct-AuthTokenTBS", +"setct-BCIDistributionTBS", +"setct-BatchAdminReqData", +"setct-BatchAdminReqTBE", +"setct-BatchAdminResData", +"setct-BatchAdminResTBE", +"setct-CRLNotificationResTBS", +"setct-CRLNotificationTBS", +"setct-CapReqTBE", +"setct-CapReqTBEX", +"setct-CapReqTBS", +"setct-CapReqTBSX", +"setct-CapResData", +"setct-CapResTBE", +"setct-CapRevReqTBE", +"setct-CapRevReqTBEX", +"setct-CapRevReqTBS", +"setct-CapRevReqTBSX", +"setct-CapRevResData", +"setct-CapRevResTBE", +"setct-CapTokenData", +"setct-CapTokenSeq", +"setct-CapTokenTBE", +"setct-CapTokenTBEX", +"setct-CapTokenTBS", +"setct-CardCInitResTBS", +"setct-CertInqReqTBS", +"setct-CertReqData", +"setct-CertReqTBE", +"setct-CertReqTBEX", +"setct-CertReqTBS", +"setct-CertResData", +"setct-CertResTBE", +"setct-CredReqTBE", +"setct-CredReqTBEX", +"setct-CredReqTBS", +"setct-CredReqTBSX", +"setct-CredResData", +"setct-CredResTBE", +"setct-CredRevReqTBE", +"setct-CredRevReqTBEX", +"setct-CredRevReqTBS", +"setct-CredRevReqTBSX", +"setct-CredRevResData", +"setct-CredRevResTBE", +"setct-ErrorTBS", +"setct-HODInput", +"setct-MeAqCInitResTBS", +"setct-OIData", +"setct-PANData", +"setct-PANOnly", +"setct-PANToken", +"setct-PCertReqData", +"setct-PCertResTBS", +"setct-PI", +"setct-PI-TBS", +"setct-PIData", +"setct-PIDataUnsigned", +"setct-PIDualSignedTBE", +"setct-PIUnsignedTBE", +"setct-PInitResData", +"setct-PResData", +"setct-RegFormReqTBE", +"setct-RegFormResTBS", +"setext-cv", +"setext-genCrypt", +"setext-miAuth", +"setext-pinAny", +"setext-pinSecure", +"setext-track2", +"signingTime", +"simpleSecurityObject", +"singleLevelQuality", +"snmpv2", +"street", +"subjectAltName", +"subjectDirectoryAttributes", +"subjectInfoAccess", +"subjectKeyIdentifier", +"subjectSignTool", +"subtreeMaximumQuality", +"subtreeMinimumQuality", +"supportedAlgorithms", +"supportedApplicationContext", +"targetInformation", +"telephoneNumber", +"teletexTerminalIdentifier", +"telexNumber", +"textEncodedORAddress", +"textNotice", +"timeStamping", +"title", +"tlsfeature", +"tpBasis", +"trustRoot", +"ucl", +"uid", +"uniqueMember", +"unstructuredAddress", +"unstructuredName", +"userCertificate", +"userClass", +"userPassword", +"valid", +"wap", +"wap-wsg", +"wap-wsg-idm-ecid-wtls1", +"wap-wsg-idm-ecid-wtls10", +"wap-wsg-idm-ecid-wtls11", +"wap-wsg-idm-ecid-wtls12", +"wap-wsg-idm-ecid-wtls3", +"wap-wsg-idm-ecid-wtls4", +"wap-wsg-idm-ecid-wtls5", +"wap-wsg-idm-ecid-wtls6", +"wap-wsg-idm-ecid-wtls7", +"wap-wsg-idm-ecid-wtls8", +"wap-wsg-idm-ecid-wtls9", +"whirlpool", +"x121Address", +"x500UniqueIdentifier", +"x509Certificate", +"x509Crl", +};