Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include <stdio.h>
35 : #include <string.h>
36 :
37 : #include "src/core/security/security_connector.h"
38 : #include "src/core/security/security_context.h"
39 : #include "src/core/tsi/ssl_transport_security.h"
40 : #include "src/core/tsi/transport_security.h"
41 : #include "test/core/util/test_config.h"
42 :
43 : #include <grpc/grpc_security.h>
44 :
45 : #include <grpc/support/alloc.h>
46 : #include <grpc/support/log.h>
47 : #include <grpc/support/useful.h>
48 :
49 5 : static int check_transport_security_type(const grpc_auth_context *ctx) {
50 5 : grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name(
51 : ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME);
52 5 : const grpc_auth_property *prop = grpc_auth_property_iterator_next(&it);
53 5 : if (prop == NULL) return 0;
54 5 : if (strncmp(prop->value, GRPC_SSL_TRANSPORT_SECURITY_TYPE,
55 : prop->value_length) != 0) {
56 0 : return 0;
57 : }
58 : /* Check that we have only one property with this name. */
59 5 : if (grpc_auth_property_iterator_next(&it) != NULL) return 0;
60 5 : return 1;
61 : }
62 :
63 1 : static void test_unauthenticated_ssl_peer(void) {
64 : tsi_peer peer;
65 : grpc_auth_context *ctx;
66 1 : GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK);
67 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
68 : TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
69 : &peer.properties[0]) == TSI_OK);
70 1 : ctx = tsi_ssl_peer_to_auth_context(&peer);
71 1 : GPR_ASSERT(ctx != NULL);
72 1 : GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx));
73 1 : GPR_ASSERT(check_transport_security_type(ctx));
74 :
75 1 : tsi_peer_destruct(&peer);
76 1 : GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
77 1 : }
78 :
79 4 : static int check_identity(const grpc_auth_context *ctx,
80 : const char *expected_property_name,
81 : const char **expected_identities,
82 : size_t num_identities) {
83 : grpc_auth_property_iterator it;
84 : const grpc_auth_property *prop;
85 : size_t i;
86 4 : GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
87 4 : it = grpc_auth_context_peer_identity(ctx);
88 12 : for (i = 0; i < num_identities; i++) {
89 8 : prop = grpc_auth_property_iterator_next(&it);
90 8 : if (prop == NULL) {
91 0 : gpr_log(GPR_ERROR, "Expected identity value %s not found.",
92 0 : expected_identities[i]);
93 0 : return 0;
94 : }
95 8 : if (strcmp(prop->name, expected_property_name) != 0) {
96 0 : gpr_log(GPR_ERROR, "Expected peer identity property name %s and got %s.",
97 : expected_property_name, prop->name);
98 0 : return 0;
99 : }
100 8 : if (strncmp(prop->value, expected_identities[i], prop->value_length) != 0) {
101 0 : gpr_log(GPR_ERROR, "Expected peer identity %s and got %s.",
102 0 : expected_identities[i], prop->value);
103 0 : return 0;
104 : }
105 : }
106 4 : return 1;
107 : }
108 :
109 4 : static int check_x509_cn(const grpc_auth_context *ctx,
110 : const char *expected_cn) {
111 4 : grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name(
112 : ctx, GRPC_X509_CN_PROPERTY_NAME);
113 4 : const grpc_auth_property *prop = grpc_auth_property_iterator_next(&it);
114 4 : if (prop == NULL) {
115 0 : gpr_log(GPR_ERROR, "CN property not found.");
116 0 : return 0;
117 : }
118 4 : if (strncmp(prop->value, expected_cn, prop->value_length) != 0) {
119 0 : gpr_log(GPR_ERROR, "Expected CN %s and got %s", expected_cn, prop->value);
120 0 : return 0;
121 : }
122 4 : if (grpc_auth_property_iterator_next(&it) != NULL) {
123 0 : gpr_log(GPR_ERROR, "Expected only one property for CN.");
124 0 : return 0;
125 : }
126 4 : return 1;
127 : }
128 :
129 1 : static void test_cn_only_ssl_peer_to_auth_context(void) {
130 : tsi_peer peer;
131 : grpc_auth_context *ctx;
132 1 : const char *expected_cn = "cn1";
133 1 : GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
134 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
135 : TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
136 : &peer.properties[0]) == TSI_OK);
137 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
138 : TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn,
139 : &peer.properties[1]) == TSI_OK);
140 1 : ctx = tsi_ssl_peer_to_auth_context(&peer);
141 1 : GPR_ASSERT(ctx != NULL);
142 1 : GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
143 1 : GPR_ASSERT(check_identity(ctx, GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1));
144 1 : GPR_ASSERT(check_transport_security_type(ctx));
145 1 : GPR_ASSERT(check_x509_cn(ctx, expected_cn));
146 :
147 1 : tsi_peer_destruct(&peer);
148 1 : GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
149 1 : }
150 :
151 1 : static void test_cn_and_one_san_ssl_peer_to_auth_context(void) {
152 : tsi_peer peer;
153 : grpc_auth_context *ctx;
154 1 : const char *expected_cn = "cn1";
155 1 : const char *expected_san = "san1";
156 1 : GPR_ASSERT(tsi_construct_peer(3, &peer) == TSI_OK);
157 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
158 : TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
159 : &peer.properties[0]) == TSI_OK);
160 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
161 : TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn,
162 : &peer.properties[1]) == TSI_OK);
163 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
164 : TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_san,
165 : &peer.properties[2]) == TSI_OK);
166 1 : ctx = tsi_ssl_peer_to_auth_context(&peer);
167 1 : GPR_ASSERT(ctx != NULL);
168 1 : GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
169 1 : GPR_ASSERT(
170 : check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, &expected_san, 1));
171 1 : GPR_ASSERT(check_transport_security_type(ctx));
172 1 : GPR_ASSERT(check_x509_cn(ctx, expected_cn));
173 :
174 1 : tsi_peer_destruct(&peer);
175 1 : GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
176 1 : }
177 :
178 1 : static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) {
179 : tsi_peer peer;
180 : grpc_auth_context *ctx;
181 1 : const char *expected_cn = "cn1";
182 1 : const char *expected_sans[] = {"san1", "san2", "san3"};
183 : size_t i;
184 1 : GPR_ASSERT(tsi_construct_peer(2 + GPR_ARRAY_SIZE(expected_sans), &peer) ==
185 : TSI_OK);
186 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
187 : TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
188 : &peer.properties[0]) == TSI_OK);
189 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
190 : TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn,
191 : &peer.properties[1]) == TSI_OK);
192 4 : for (i = 0; i < GPR_ARRAY_SIZE(expected_sans); i++) {
193 3 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
194 : TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY,
195 : expected_sans[i], &peer.properties[2 + i]) == TSI_OK);
196 : }
197 1 : ctx = tsi_ssl_peer_to_auth_context(&peer);
198 1 : GPR_ASSERT(ctx != NULL);
199 1 : GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
200 1 : GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans,
201 : GPR_ARRAY_SIZE(expected_sans)));
202 1 : GPR_ASSERT(check_transport_security_type(ctx));
203 1 : GPR_ASSERT(check_x509_cn(ctx, expected_cn));
204 :
205 1 : tsi_peer_destruct(&peer);
206 1 : GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
207 1 : }
208 :
209 1 : static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(
210 : void) {
211 : tsi_peer peer;
212 : grpc_auth_context *ctx;
213 1 : const char *expected_cn = "cn1";
214 1 : const char *expected_sans[] = {"san1", "san2", "san3"};
215 : size_t i;
216 1 : GPR_ASSERT(tsi_construct_peer(4 + GPR_ARRAY_SIZE(expected_sans), &peer) ==
217 : TSI_OK);
218 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
219 : TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
220 : &peer.properties[0]) == TSI_OK);
221 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
222 : "foo", "bar", &peer.properties[1]) == TSI_OK);
223 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
224 : TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn,
225 : &peer.properties[2]) == TSI_OK);
226 1 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
227 : "chapi", "chapo", &peer.properties[3]) == TSI_OK);
228 4 : for (i = 0; i < GPR_ARRAY_SIZE(expected_sans); i++) {
229 3 : GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
230 : TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY,
231 : expected_sans[i], &peer.properties[4 + i]) == TSI_OK);
232 : }
233 1 : ctx = tsi_ssl_peer_to_auth_context(&peer);
234 1 : GPR_ASSERT(ctx != NULL);
235 1 : GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
236 1 : GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans,
237 : GPR_ARRAY_SIZE(expected_sans)));
238 1 : GPR_ASSERT(check_transport_security_type(ctx));
239 1 : GPR_ASSERT(check_x509_cn(ctx, expected_cn));
240 :
241 1 : tsi_peer_destruct(&peer);
242 1 : GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
243 1 : }
244 :
245 1 : int main(int argc, char **argv) {
246 1 : grpc_test_init(argc, argv);
247 1 : grpc_init();
248 :
249 1 : test_unauthenticated_ssl_peer();
250 1 : test_cn_only_ssl_peer_to_auth_context();
251 1 : test_cn_and_one_san_ssl_peer_to_auth_context();
252 1 : test_cn_and_multiple_sans_ssl_peer_to_auth_context();
253 1 : test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context();
254 :
255 1 : grpc_shutdown();
256 1 : return 0;
257 : }
|