Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 16 additions & 74 deletions bin/policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,10 @@

#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>

#include "api/s2n.h"
#include "tls/s2n_security_policies.h"
#include "tls/s2n_security_rules.h"

#define BOOL_STR(b) ((b) ? "yes" : "no")

extern const struct s2n_security_rule security_rule_definitions[S2N_SECURITY_RULES_COUNT];

const char *version_strs[] = {
[S2N_SSLv2] = "SSLv2",
[S2N_SSLv3] = "SSLv3",
[S2N_TLS10] = "TLS1.0",
[S2N_TLS11] = "TLS1.1",
[S2N_TLS12] = "TLS1.2",
[S2N_TLS13] = "TLS1.3",
};
#include "tls/policy/s2n_policy_feature.h"

static int usage()
{
Expand All @@ -47,72 +34,27 @@ int main(int argc, char *const *argv)
exit(1);
}

const char *policy_name = argv[1];
const struct s2n_security_policy *policy = NULL;
if (s2n_find_security_policy_from_version(policy_name, &policy) != S2N_SUCCESS) {
usage();
if (s2n_init() != S2N_SUCCESS) {
fprintf(stderr, "Error: Failed to initialize s2n\n");
exit(1);
}

printf("name: %s\n", policy_name);

const char *version_str = version_strs[policy->minimum_protocol_version];
printf("min version: %s\n", version_str ? version_str : "None");

printf("rules:\n");
for (size_t i = 0; i < S2N_SECURITY_RULES_COUNT; i++) {
printf("- %s: %s\n", security_rule_definitions[i].name, BOOL_STR(policy->rules[i]));
}

printf("cipher suites:\n");
if (policy->cipher_preferences->allow_chacha20_boosting) {
printf("- chacha20 boosting enabled\n");
}
for (size_t i = 0; i < policy->cipher_preferences->count; i++) {
printf("- %s\n", policy->cipher_preferences->suites[i]->iana_name);
}

printf("signature schemes:\n");
for (size_t i = 0; i < policy->signature_preferences->count; i++) {
printf("- %s\n", policy->signature_preferences->signature_schemes[i]->name);
}

printf("curves:\n");
for (size_t i = 0; i < policy->ecc_preferences->count; i++) {
printf("- %s\n", policy->ecc_preferences->ecc_curves[i]->name);
}

if (policy->certificate_signature_preferences) {
if (policy->certificate_preferences_apply_locally) {
printf("certificate preferences apply locally\n");
}
printf("certificate signature schemes:\n");
for (size_t i = 0; i < policy->certificate_signature_preferences->count; i++) {
printf("- %s\n", policy->certificate_signature_preferences->signature_schemes[i]->name);
}
const char *policy_name = argv[1];
struct s2n_security_policy_builder *builder = s2n_security_policy_builder_from_version(policy_name);
if (!builder) {
fprintf(stderr, "Error: Failed to create policy builder\n");
s2n_cleanup();
exit(1);
}

if (policy->certificate_key_preferences) {
printf("certificate keys:\n");
for (size_t i = 0; i < policy->certificate_key_preferences->count; i++) {
printf("- %s\n", policy->certificate_key_preferences->certificate_keys[i]->name);
}
if (s2n_policy_builder_write_verbose(builder, S2N_POLICY_FORMAT_V1, STDOUT_FILENO) != S2N_SUCCESS) {
s2n_security_policy_builder_free(&builder);
s2n_cleanup();
exit(1);
}

if (policy->kem_preferences && policy->kem_preferences != &kem_preferences_null) {
printf("pq:\n");
printf("- revision: %i\n", policy->kem_preferences->tls13_pq_hybrid_draft_revision);
if (policy->kem_preferences->kem_count > 0) {
printf("- kems:\n");
for (size_t i = 0; i < policy->kem_preferences->kem_count; i++) {
printf("-- %s\n", policy->kem_preferences->kems[i]->name);
}
}
printf("- kem groups:\n");
for (size_t i = 0; i < policy->kem_preferences->tls13_kem_group_count; i++) {
printf("-- %s\n", policy->kem_preferences->tls13_kem_groups[i]->name);
}
}
s2n_security_policy_builder_free(&builder);
s2n_cleanup();

return 0;
}
2 changes: 1 addition & 1 deletion tests/policy_snapshot/snapshots/20240501
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 20240501
name: default
min version: TLS1.2
rules:
- Perfect Forward Secrecy: yes
Expand Down
2 changes: 1 addition & 1 deletion tests/policy_snapshot/snapshots/20240502
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 20240502
name: default_fips
min version: TLS1.2
rules:
- Perfect Forward Secrecy: yes
Expand Down
2 changes: 1 addition & 1 deletion tests/policy_snapshot/snapshots/20240503
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 20240503
name: default_tls13
min version: TLS1.2
rules:
- Perfect Forward Secrecy: yes
Expand Down
2 changes: 1 addition & 1 deletion tests/policy_snapshot/snapshots/20250721
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 20250721
name: default_pq
min version: TLS1.2
rules:
- Perfect Forward Secrecy: yes
Expand Down
2 changes: 1 addition & 1 deletion tests/policy_snapshot/snapshots/ELBSecurityPolicy-2016-08
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: ELBSecurityPolicy-2016-08
name: ELBSecurityPolicy-TLS-1-0-2015-05
min version: TLS1.0
rules:
- Perfect Forward Secrecy: no
Expand Down
2 changes: 1 addition & 1 deletion tests/policy_snapshot/snapshots/rfc9151
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: rfc9151
name: 20250429
min version: TLS1.2
rules:
- Perfect Forward Secrecy: no
Expand Down
142 changes: 142 additions & 0 deletions tests/unit/s2n_policy_builder_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,55 @@
* permissions and limitations under the License.
*/

#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#include "s2n_test.h"
#include "testlib/s2n_testlib.h"
#include "tls/policy/s2n_policy_feature.h"

static S2N_RESULT s2n_verify_format_v1_output(const char *output, const char *policy_name)
{
RESULT_ENSURE_REF(output);
RESULT_ENSURE_REF(policy_name);

/* Required sections are present */
RESULT_ENSURE(strstr(output, "name: ") != NULL, S2N_ERR_TEST_ASSERTION);
RESULT_ENSURE(strstr(output, "min version: ") != NULL, S2N_ERR_TEST_ASSERTION);
RESULT_ENSURE(strstr(output, "rules:\n") != NULL, S2N_ERR_TEST_ASSERTION);
RESULT_ENSURE(strstr(output, "cipher suites:\n") != NULL, S2N_ERR_TEST_ASSERTION);
RESULT_ENSURE(strstr(output, "signature schemes:\n") != NULL, S2N_ERR_TEST_ASSERTION);
RESULT_ENSURE(strstr(output, "curves:\n") != NULL, S2N_ERR_TEST_ASSERTION);

/* Policy name matches */
RESULT_ENSURE(strstr(output, policy_name) != NULL, S2N_ERR_TEST_ASSERTION);

return S2N_RESULT_OK;
}

static S2N_RESULT s2n_capture_output_to_buffer(struct s2n_security_policy_builder *builder,
s2n_policy_format format,
char *buffer,
size_t buffer_size)
{
RESULT_ENSURE_REF(builder);
RESULT_ENSURE_REF(buffer);
RESULT_ENSURE(buffer_size > 0, S2N_ERR_INVALID_ARGUMENT);

/* Use a pipe for capturing output */
int pipe_fds[2];
RESULT_ENSURE(pipe(pipe_fds) == 0, S2N_ERR_IO);
int write_result = s2n_policy_builder_write_verbose(builder, format, pipe_fds[1]);
close(pipe_fds[1]);
RESULT_GUARD_POSIX(write_result);
ssize_t bytes_read = read(pipe_fds[0], buffer, buffer_size - 1);
close(pipe_fds[0]);
RESULT_ENSURE(bytes_read > 0, S2N_ERR_IO);

return S2N_RESULT_OK;
}

static S2N_RESULT s2n_security_policies_assert_match(
const struct s2n_security_policy *a, const struct s2n_security_policy *b)
{
Expand Down Expand Up @@ -229,5 +274,102 @@ int main(int argc, char **argv)
};
}

/* Test: s2n_policy_builder_write_verbose */
{
/* Test: safety - NULL builder */
{
EXPECT_FAILURE_WITH_ERRNO(
s2n_policy_builder_write_verbose(NULL, S2N_POLICY_FORMAT_V1, STDOUT_FILENO),
S2N_ERR_NULL);
};

/* Test: safety - invalid format */
{
DEFER_CLEANUP(struct s2n_security_policy_builder *builder =
s2n_security_policy_builder_from_version("default"),
s2n_security_policy_builder_free);
EXPECT_NOT_NULL(builder);

EXPECT_FAILURE_WITH_ERRNO(
s2n_policy_builder_write_verbose(builder, 999, STDOUT_FILENO),
S2N_ERR_INVALID_ARGUMENT);
};

/* Test: safety - invalid file descriptor */
{
DEFER_CLEANUP(struct s2n_security_policy_builder *builder =
s2n_security_policy_builder_from_version("default"),
s2n_security_policy_builder_free);
EXPECT_NOT_NULL(builder);

EXPECT_FAILURE_WITH_ERRNO(
s2n_policy_builder_write_verbose(builder, S2N_POLICY_FORMAT_V1, -1),
S2N_ERR_INVALID_ARGUMENT);
};

/* Test: s2n_policy_builder_write_verbose - FORMAT_V1 structure verification */
{
/* Pick a few named policies for sanity checking. Snapshot tests verify the exact content. */
const char *test_policies[] = {
"default",
"default_fips",
"default_tls13",
"default_pq",
NULL
};

for (size_t i = 0; test_policies[i] != NULL; i++) {
const char *policy_version = test_policies[i];

DEFER_CLEANUP(struct s2n_security_policy_builder *builder =
s2n_security_policy_builder_from_version(policy_version),
s2n_security_policy_builder_free);
EXPECT_NOT_NULL(builder);

char buffer[8192];
EXPECT_OK(s2n_capture_output_to_buffer(builder, S2N_POLICY_FORMAT_V1, buffer, sizeof(buffer)));
EXPECT_OK(s2n_verify_format_v1_output(buffer, policy_version));
}
};

/* Test: write to stdout */
{
DEFER_CLEANUP(struct s2n_security_policy_builder *builder =
s2n_security_policy_builder_from_version("default"),
s2n_security_policy_builder_free);
EXPECT_NOT_NULL(builder);
EXPECT_SUCCESS(s2n_policy_builder_write_verbose(builder, S2N_POLICY_FORMAT_V1, STDOUT_FILENO));
};

/* Test: write to file and verify content */
{
DEFER_CLEANUP(struct s2n_security_policy_builder *builder =
s2n_security_policy_builder_from_version("default_tls13"),
s2n_security_policy_builder_free);
EXPECT_NOT_NULL(builder);

/* Create a temp file */
char temp_filename[] = "/tmp/s2n_policy_test_XXXXXX";
int temp_fd = mkstemp(temp_filename);
EXPECT_TRUE(temp_fd >= 0);

/* Write policy to file */
EXPECT_SUCCESS(s2n_policy_builder_write_verbose(builder, S2N_POLICY_FORMAT_V1, temp_fd));
EXPECT_SUCCESS(close(temp_fd));

/* Read file content back */
FILE *file = fopen(temp_filename, "r");
EXPECT_NOT_NULL(file);
char file_buffer[8192];
size_t bytes_read = fread(file_buffer, 1, sizeof(file_buffer) - 1, file);
EXPECT_TRUE(bytes_read > 0);
fclose(file);

EXPECT_OK(s2n_verify_format_v1_output(file_buffer, "default_tls13"));

EXPECT_SUCCESS(unlink(temp_filename));
};
};

END_TEST();
}
Loading
Loading