Remove proxy tests. Add verify callback tests.
[openssl.git] / test / ssl_test_ctx.c
1 /*
2  * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL licenses, (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * https://www.openssl.org/source/license.html
8  * or in the file LICENSE in the source distribution.
9  */
10
11 #include <string.h>
12
13 #include <openssl/e_os2.h>
14 #include <openssl/crypto.h>
15
16 #include "e_os.h"
17 #include "ssl_test_ctx.h"
18
19 /* True enums and other test configuration values that map to an int. */
20 typedef struct {
21     const char *name;
22     int value;
23 } test_enum;
24
25
26 __owur static int parse_enum(const test_enum *enums, size_t num_enums,
27                              int *value, const char *name)
28 {
29     size_t i;
30     for (i = 0; i < num_enums; i++) {
31         if (strcmp(enums[i].name, name) == 0) {
32             *value = enums[i].value;
33             return 1;
34         }
35     }
36     return 0;
37 }
38
39 static const char *enum_name(const test_enum *enums, size_t num_enums,
40                              int value)
41 {
42     size_t i;
43     for (i = 0; i < num_enums; i++) {
44         if (enums[i].value == value) {
45             return enums[i].name;
46         }
47     }
48     return "InvalidValue";
49 }
50
51
52 /*******************/
53 /* ExpectedResult. */
54 /*******************/
55
56 static const test_enum ssl_test_results[] = {
57     {"Success", SSL_TEST_SUCCESS},
58     {"ServerFail", SSL_TEST_SERVER_FAIL},
59     {"ClientFail", SSL_TEST_CLIENT_FAIL},
60     {"InternalError", SSL_TEST_INTERNAL_ERROR},
61 };
62
63 __owur static int parse_expected_result(SSL_TEST_CTX *test_ctx, const char *value)
64 {
65     int ret_value;
66     if (!parse_enum(ssl_test_results, OSSL_NELEM(ssl_test_results),
67                     &ret_value, value)) {
68         return 0;
69     }
70     test_ctx->expected_result = ret_value;
71     return 1;
72 }
73
74 const char *ssl_test_result_name(ssl_test_result_t result)
75 {
76     return enum_name(ssl_test_results, OSSL_NELEM(ssl_test_results), result);
77 }
78
79 /******************************/
80 /* ClientAlert / ServerAlert. */
81 /******************************/
82
83 static const test_enum ssl_alerts[] = {
84     {"UnknownCA", SSL_AD_UNKNOWN_CA},
85     {"HandshakeFailure", SSL_AD_HANDSHAKE_FAILURE},
86 };
87
88 __owur static int parse_alert(int *alert, const char *value)
89 {
90     return parse_enum(ssl_alerts, OSSL_NELEM(ssl_alerts), alert, value);
91 }
92
93 __owur static int parse_client_alert(SSL_TEST_CTX *test_ctx, const char *value)
94 {
95     return parse_alert(&test_ctx->client_alert, value);
96 }
97
98 __owur static int parse_server_alert(SSL_TEST_CTX *test_ctx, const char *value)
99 {
100     return parse_alert(&test_ctx->server_alert, value);
101 }
102
103 const char *ssl_alert_name(int alert)
104 {
105     return enum_name(ssl_alerts, OSSL_NELEM(ssl_alerts), alert);
106 }
107
108 /************/
109 /* Protocol */
110 /************/
111
112 static const test_enum ssl_protocols[] = {
113      {"TLSv1.2", TLS1_2_VERSION},
114      {"TLSv1.1", TLS1_1_VERSION},
115      {"TLSv1", TLS1_VERSION},
116      {"SSLv3", SSL3_VERSION},
117 };
118
119 __owur static int parse_protocol(SSL_TEST_CTX *test_ctx, const char *value)
120 {
121     return parse_enum(ssl_protocols, OSSL_NELEM(ssl_protocols),
122                       &test_ctx->protocol, value);
123 }
124
125 const char *ssl_protocol_name(int protocol)
126 {
127     return enum_name(ssl_protocols, OSSL_NELEM(ssl_protocols), protocol);
128 }
129
130 /***********************/
131 /* CertVerifyCallback. */
132 /***********************/
133
134 static const test_enum ssl_verify_callbacks[] = {
135     {"None", SSL_TEST_VERIFY_NONE},
136     {"AcceptAll", SSL_TEST_VERIFY_ACCEPT_ALL},
137     {"RejectAll", SSL_TEST_VERIFY_REJECT_ALL},
138 };
139
140 __owur static int parse_client_verify_callback(SSL_TEST_CTX *test_ctx,
141                                               const char *value)
142 {
143     int ret_value;
144     if (!parse_enum(ssl_verify_callbacks, OSSL_NELEM(ssl_verify_callbacks),
145                     &ret_value, value)) {
146         return 0;
147     }
148     test_ctx->client_verify_callback = ret_value;
149     return 1;
150 }
151
152 const char *ssl_verify_callback_name(ssl_verify_callback_t callback)
153 {
154     return enum_name(ssl_verify_callbacks, OSSL_NELEM(ssl_verify_callbacks),
155                      callback);
156 }
157
158
159 /*************************************************************/
160 /* Known test options and their corresponding parse methods. */
161 /*************************************************************/
162
163 typedef struct {
164     const char *name;
165     int (*parse)(SSL_TEST_CTX *test_ctx, const char *value);
166 } ssl_test_ctx_option;
167
168 static const ssl_test_ctx_option ssl_test_ctx_options[] = {
169     { "ExpectedResult", &parse_expected_result },
170     { "ClientAlert", &parse_client_alert },
171     { "ServerAlert", &parse_server_alert },
172     { "Protocol", &parse_protocol },
173     { "ClientVerifyCallback", &parse_client_verify_callback },
174 };
175
176
177 /*
178  * Since these methods are used to create tests, we use OPENSSL_assert liberally
179  * for malloc failures and other internal errors.
180  */
181 SSL_TEST_CTX *SSL_TEST_CTX_new()
182 {
183     SSL_TEST_CTX *ret;
184     ret = OPENSSL_zalloc(sizeof(*ret));
185     OPENSSL_assert(ret != NULL);
186     return ret;
187 }
188
189 void SSL_TEST_CTX_free(SSL_TEST_CTX *ctx)
190 {
191     OPENSSL_free(ctx);
192 }
193
194 SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section)
195 {
196     STACK_OF(CONF_VALUE) *sk_conf;
197     SSL_TEST_CTX *ctx;
198     int i;
199     size_t j;
200
201     sk_conf = NCONF_get_section(conf, test_section);
202     OPENSSL_assert(sk_conf != NULL);
203
204     ctx = SSL_TEST_CTX_new();
205     OPENSSL_assert(ctx != NULL);
206
207     for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
208         int found = 0;
209         const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i);
210         for (j = 0; j < OSSL_NELEM(ssl_test_ctx_options); j++) {
211             if (strcmp(option->name, ssl_test_ctx_options[j].name) == 0) {
212                 if (!ssl_test_ctx_options[j].parse(ctx, option->value)) {
213                     fprintf(stderr, "Bad value %s for option %s\n",
214                             option->value, option->name);
215                     goto err;
216                 }
217                 found = 1;
218                 break;
219             }
220         }
221         if (!found) {
222             fprintf(stderr, "Unknown test option: %s\n", option->name);
223             goto err;
224         }
225     }
226
227     goto done;
228
229  err:
230     SSL_TEST_CTX_free(ctx);
231     ctx = NULL;
232  done:
233     return ctx;
234 }