struct s2n_config *s2n_config_new(void) { struct s2n_blob allocator; struct s2n_config *new_config; GUARD_PTR(s2n_alloc(&allocator, sizeof(struct s2n_config))); new_config = (struct s2n_config *)(void *)allocator.data; new_config->cert_and_key_pairs = NULL; new_config->dhparams = NULL; new_config->application_protocols.data = NULL; new_config->application_protocols.size = 0; new_config->status_request_type = S2N_STATUS_REQUEST_NONE; new_config->nanoseconds_since_epoch = get_nanoseconds_since_epoch; GUARD_PTR(s2n_config_set_cipher_preferences(new_config, "default")); return new_config; }
static void setup_s2n_config(struct s2n_config *config, const char *cipher_prefs, s2n_status_request_type type, struct verify_data *unsafe_verify_data, const char *host, const char *alpn_protocols, uint16_t mfl_value) { if (config == NULL) { print_s2n_error("Error getting new config"); exit(1); } GUARD_EXIT(s2n_config_set_cipher_preferences(config, cipher_prefs), "Error setting cipher prefs"); GUARD_EXIT(s2n_config_set_status_request_type(config, type), "OCSP validation is not supported by the linked libCrypto implementation. It cannot be set."); if (s2n_config_set_verify_host_callback(config, unsafe_verify_host, unsafe_verify_data) < 0) { print_s2n_error("Error setting host name verification function."); } if (type == S2N_STATUS_REQUEST_OCSP) { if(s2n_config_set_check_stapled_ocsp_response(config, 1)) { print_s2n_error("OCSP validation is not supported by the linked libCrypto implementation. It cannot be set."); } } unsafe_verify_data->trusted_host = host; if (alpn_protocols) { /* Count the number of commas, this tells us how many protocols there are in the list */ const char *ptr = alpn_protocols; int protocol_count = 1; while (*ptr) { if (*ptr == ',') { protocol_count++; } ptr++; } char **protocols = malloc(sizeof(char *) * protocol_count); if (!protocols) { fprintf(stderr, "Error allocating memory\n"); exit(1); } const char *next = alpn_protocols; int idx = 0; int length = 0; ptr = alpn_protocols; while (*ptr) { if (*ptr == ',') { protocols[idx] = malloc(length + 1); if (!protocols[idx]) { fprintf(stderr, "Error allocating memory\n"); exit(1); } memcpy(protocols[idx], next, length); protocols[idx][length] = '\0'; length = 0; idx++; ptr++; next = ptr; } else { length++; ptr++; } } if (ptr != next) { protocols[idx] = malloc(length + 1); if (!protocols[idx]) { fprintf(stderr, "Error allocating memory\n"); exit(1); } memcpy(protocols[idx], next, length); protocols[idx][length] = '\0'; } GUARD_EXIT(s2n_config_set_protocol_preferences(config, (const char *const *)protocols, protocol_count), "Failed to set protocol preferences"); while (protocol_count) { protocol_count--; free(protocols[protocol_count]); } free(protocols); } uint8_t mfl_code = 0; if (mfl_value > 0) { switch(mfl_value) { case 512: mfl_code = S2N_TLS_MAX_FRAG_LEN_512; break; case 1024: mfl_code = S2N_TLS_MAX_FRAG_LEN_1024; break; case 2048: mfl_code = S2N_TLS_MAX_FRAG_LEN_2048; break; case 4096: mfl_code = S2N_TLS_MAX_FRAG_LEN_4096; break; default: fprintf(stderr, "Invalid maximum fragment length value\n"); exit(1); } } GUARD_EXIT(s2n_config_send_max_fragment_length(config, mfl_code), "Error setting maximum fragment length"); }