Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 1 | /* |
| 2 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 3 | * Copyright 2015 gRPC authors. |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 4 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | * you may not use this file except in compliance with the License. |
| 7 | * You may obtain a copy of the License at |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 8 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 10 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 16 | * |
| 17 | */ |
| 18 | |
| 19 | #include <stdio.h> |
| 20 | #include <string.h> |
| 21 | |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 22 | #include <grpc/grpc_security.h> |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 23 | #include <grpc/support/alloc.h> |
| 24 | #include <grpc/support/log.h> |
Julien Boeuf | aaebf7a | 2016-01-28 17:04:42 -0800 | [diff] [blame] | 25 | #include <grpc/support/string_util.h> |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 26 | |
Mark D. Roth | dbdf495 | 2018-01-18 11:21:12 -0800 | [diff] [blame] | 27 | #include "src/core/lib/gpr/env.h" |
| 28 | #include "src/core/lib/gpr/string.h" |
| 29 | #include "src/core/lib/gpr/tmpfile.h" |
Julien Boeuf | 8ca294e | 2016-05-02 14:56:30 -0700 | [diff] [blame] | 30 | #include "src/core/lib/security/context/security_context.h" |
Yihua Zhang | 75f0a9f | 2018-02-20 10:09:47 -0800 | [diff] [blame] | 31 | #include "src/core/lib/security/security_connector/security_connector.h" |
Craig Tiller | e4222b4 | 2016-10-26 17:15:30 -0700 | [diff] [blame] | 32 | #include "src/core/lib/slice/slice_string_helpers.h" |
Craig Tiller | b29f1fe | 2017-03-28 15:49:23 -0700 | [diff] [blame] | 33 | #include "src/core/tsi/ssl_transport_security.h" |
| 34 | #include "src/core/tsi/transport_security.h" |
Craig Tiller | 732a875 | 2016-02-22 15:59:19 -0800 | [diff] [blame] | 35 | #include "test/core/util/test_config.h" |
| 36 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 37 | static int check_transport_security_type(const grpc_auth_context* ctx) { |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 38 | grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name( |
| 39 | ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME); |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 40 | const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it); |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 41 | if (prop == nullptr) return 0; |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 42 | if (strncmp(prop->value, GRPC_SSL_TRANSPORT_SECURITY_TYPE, |
| 43 | prop->value_length) != 0) { |
| 44 | return 0; |
| 45 | } |
| 46 | /* Check that we have only one property with this name. */ |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 47 | if (grpc_auth_property_iterator_next(&it) != nullptr) return 0; |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 48 | return 1; |
| 49 | } |
| 50 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 51 | static int check_peer_property(const tsi_peer* peer, |
| 52 | const tsi_peer_property* expected) { |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 53 | size_t i; |
| 54 | for (i = 0; i < peer->property_count; i++) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 55 | const tsi_peer_property* prop = &peer->properties[i]; |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 56 | if ((strcmp(prop->name, expected->name) == 0) && |
| 57 | (prop->value.length == expected->value.length) && |
| 58 | (memcmp(prop->value.data, expected->value.data, |
| 59 | expected->value.length) == 0)) { |
| 60 | return 1; |
| 61 | } |
| 62 | } |
| 63 | return 0; /* Not found... */ |
| 64 | } |
| 65 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 66 | static int check_ssl_peer_equivalence(const tsi_peer* original, |
| 67 | const tsi_peer* reconstructed) { |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 68 | /* The reconstructed peer only has CN, SAN and pem cert properties. */ |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 69 | size_t i; |
| 70 | for (i = 0; i < original->property_count; i++) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 71 | const tsi_peer_property* prop = &original->properties[i]; |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 72 | if ((strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) || |
| 73 | (strcmp(prop->name, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 74 | 0) || |
| 75 | (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0)) { |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 76 | if (!check_peer_property(reconstructed, prop)) return 0; |
| 77 | } |
| 78 | } |
| 79 | return 1; |
| 80 | } |
| 81 | |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 82 | static void test_unauthenticated_ssl_peer(void) { |
| 83 | tsi_peer peer; |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 84 | tsi_peer rpeer; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 85 | grpc_auth_context* ctx; |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 86 | GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); |
| 87 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 88 | TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, |
| 89 | &peer.properties[0]) == TSI_OK); |
| 90 | ctx = tsi_ssl_peer_to_auth_context(&peer); |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 91 | GPR_ASSERT(ctx != nullptr); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 92 | GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx)); |
| 93 | GPR_ASSERT(check_transport_security_type(ctx)); |
| 94 | |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 95 | rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx); |
| 96 | GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); |
| 97 | |
| 98 | tsi_shallow_peer_destruct(&rpeer); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 99 | tsi_peer_destruct(&peer); |
Craig Tiller | 991edad | 2015-06-30 11:40:41 -0700 | [diff] [blame] | 100 | GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 101 | } |
| 102 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 103 | static int check_identity(const grpc_auth_context* ctx, |
| 104 | const char* expected_property_name, |
| 105 | const char** expected_identities, |
Craig Tiller | d6c98df | 2015-08-18 09:33:44 -0700 | [diff] [blame] | 106 | size_t num_identities) { |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 107 | grpc_auth_property_iterator it; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 108 | const grpc_auth_property* prop; |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 109 | size_t i; |
| 110 | GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); |
| 111 | it = grpc_auth_context_peer_identity(ctx); |
| 112 | for (i = 0; i < num_identities; i++) { |
| 113 | prop = grpc_auth_property_iterator_next(&it); |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 114 | if (prop == nullptr) { |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 115 | gpr_log(GPR_ERROR, "Expected identity value %s not found.", |
| 116 | expected_identities[i]); |
| 117 | return 0; |
| 118 | } |
| 119 | if (strcmp(prop->name, expected_property_name) != 0) { |
| 120 | gpr_log(GPR_ERROR, "Expected peer identity property name %s and got %s.", |
| 121 | expected_property_name, prop->name); |
| 122 | return 0; |
| 123 | } |
| 124 | if (strncmp(prop->value, expected_identities[i], prop->value_length) != 0) { |
| 125 | gpr_log(GPR_ERROR, "Expected peer identity %s and got %s.", |
| 126 | expected_identities[i], prop->value); |
| 127 | return 0; |
| 128 | } |
| 129 | } |
| 130 | return 1; |
| 131 | } |
| 132 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 133 | static int check_x509_cn(const grpc_auth_context* ctx, |
| 134 | const char* expected_cn) { |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 135 | grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name( |
| 136 | ctx, GRPC_X509_CN_PROPERTY_NAME); |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 137 | const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it); |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 138 | if (prop == nullptr) { |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 139 | gpr_log(GPR_ERROR, "CN property not found."); |
| 140 | return 0; |
| 141 | } |
| 142 | if (strncmp(prop->value, expected_cn, prop->value_length) != 0) { |
| 143 | gpr_log(GPR_ERROR, "Expected CN %s and got %s", expected_cn, prop->value); |
| 144 | return 0; |
| 145 | } |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 146 | if (grpc_auth_property_iterator_next(&it) != nullptr) { |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 147 | gpr_log(GPR_ERROR, "Expected only one property for CN."); |
| 148 | return 0; |
| 149 | } |
| 150 | return 1; |
| 151 | } |
| 152 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 153 | static int check_x509_pem_cert(const grpc_auth_context* ctx, |
| 154 | const char* expected_pem_cert) { |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 155 | grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name( |
| 156 | ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME); |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 157 | const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it); |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 158 | if (prop == nullptr) { |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 159 | gpr_log(GPR_ERROR, "Pem certificate property not found."); |
| 160 | return 0; |
| 161 | } |
| 162 | if (strncmp(prop->value, expected_pem_cert, prop->value_length) != 0) { |
| 163 | gpr_log(GPR_ERROR, "Expected pem cert %s and got %s", expected_pem_cert, |
| 164 | prop->value); |
| 165 | return 0; |
| 166 | } |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 167 | if (grpc_auth_property_iterator_next(&it) != nullptr) { |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 168 | gpr_log(GPR_ERROR, "Expected only one property for pem cert."); |
| 169 | return 0; |
| 170 | } |
| 171 | return 1; |
| 172 | } |
| 173 | |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 174 | static void test_cn_only_ssl_peer_to_auth_context(void) { |
| 175 | tsi_peer peer; |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 176 | tsi_peer rpeer; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 177 | grpc_auth_context* ctx; |
| 178 | const char* expected_cn = "cn1"; |
| 179 | const char* expected_pem_cert = "pem_cert1"; |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 180 | GPR_ASSERT(tsi_construct_peer(3, &peer) == TSI_OK); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 181 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 182 | TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, |
| 183 | &peer.properties[0]) == TSI_OK); |
| 184 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 185 | TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn, |
| 186 | &peer.properties[1]) == TSI_OK); |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 187 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 188 | TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, |
| 189 | &peer.properties[2]) == TSI_OK); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 190 | ctx = tsi_ssl_peer_to_auth_context(&peer); |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 191 | GPR_ASSERT(ctx != nullptr); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 192 | GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); |
| 193 | GPR_ASSERT(check_identity(ctx, GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1)); |
| 194 | GPR_ASSERT(check_transport_security_type(ctx)); |
| 195 | GPR_ASSERT(check_x509_cn(ctx, expected_cn)); |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 196 | GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 197 | |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 198 | rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx); |
| 199 | GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); |
| 200 | |
| 201 | tsi_shallow_peer_destruct(&rpeer); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 202 | tsi_peer_destruct(&peer); |
Craig Tiller | 991edad | 2015-06-30 11:40:41 -0700 | [diff] [blame] | 203 | GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 204 | } |
| 205 | |
| 206 | static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { |
| 207 | tsi_peer peer; |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 208 | tsi_peer rpeer; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 209 | grpc_auth_context* ctx; |
| 210 | const char* expected_cn = "cn1"; |
| 211 | const char* expected_san = "san1"; |
| 212 | const char* expected_pem_cert = "pem_cert1"; |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 213 | GPR_ASSERT(tsi_construct_peer(4, &peer) == TSI_OK); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 214 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 215 | TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, |
| 216 | &peer.properties[0]) == TSI_OK); |
| 217 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 218 | TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn, |
| 219 | &peer.properties[1]) == TSI_OK); |
| 220 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 221 | TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_san, |
| 222 | &peer.properties[2]) == TSI_OK); |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 223 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 224 | TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, |
| 225 | &peer.properties[3]) == TSI_OK); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 226 | ctx = tsi_ssl_peer_to_auth_context(&peer); |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 227 | GPR_ASSERT(ctx != nullptr); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 228 | GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); |
Craig Tiller | d6c98df | 2015-08-18 09:33:44 -0700 | [diff] [blame] | 229 | GPR_ASSERT( |
| 230 | check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, &expected_san, 1)); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 231 | GPR_ASSERT(check_transport_security_type(ctx)); |
| 232 | GPR_ASSERT(check_x509_cn(ctx, expected_cn)); |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 233 | GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 234 | |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 235 | rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx); |
| 236 | GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); |
| 237 | |
| 238 | tsi_shallow_peer_destruct(&rpeer); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 239 | tsi_peer_destruct(&peer); |
Craig Tiller | 991edad | 2015-06-30 11:40:41 -0700 | [diff] [blame] | 240 | GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 241 | } |
| 242 | |
| 243 | static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { |
| 244 | tsi_peer peer; |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 245 | tsi_peer rpeer; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 246 | grpc_auth_context* ctx; |
| 247 | const char* expected_cn = "cn1"; |
| 248 | const char* expected_sans[] = {"san1", "san2", "san3"}; |
| 249 | const char* expected_pem_cert = "pem_cert1"; |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 250 | size_t i; |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 251 | GPR_ASSERT(tsi_construct_peer(3 + GPR_ARRAY_SIZE(expected_sans), &peer) == |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 252 | TSI_OK); |
| 253 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 254 | TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, |
| 255 | &peer.properties[0]) == TSI_OK); |
| 256 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 257 | TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn, |
| 258 | &peer.properties[1]) == TSI_OK); |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 259 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 260 | TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, |
| 261 | &peer.properties[2]) == TSI_OK); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 262 | for (i = 0; i < GPR_ARRAY_SIZE(expected_sans); i++) { |
| 263 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 264 | TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 265 | expected_sans[i], &peer.properties[3 + i]) == TSI_OK); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 266 | } |
| 267 | ctx = tsi_ssl_peer_to_auth_context(&peer); |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 268 | GPR_ASSERT(ctx != nullptr); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 269 | GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); |
| 270 | GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans, |
| 271 | GPR_ARRAY_SIZE(expected_sans))); |
| 272 | GPR_ASSERT(check_transport_security_type(ctx)); |
| 273 | GPR_ASSERT(check_x509_cn(ctx, expected_cn)); |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 274 | GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 275 | |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 276 | rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx); |
| 277 | GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); |
| 278 | |
| 279 | tsi_shallow_peer_destruct(&rpeer); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 280 | tsi_peer_destruct(&peer); |
Craig Tiller | 991edad | 2015-06-30 11:40:41 -0700 | [diff] [blame] | 281 | GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 282 | } |
| 283 | |
| 284 | static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( |
| 285 | void) { |
| 286 | tsi_peer peer; |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 287 | tsi_peer rpeer; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 288 | grpc_auth_context* ctx; |
| 289 | const char* expected_cn = "cn1"; |
| 290 | const char* expected_pem_cert = "pem_cert1"; |
| 291 | const char* expected_sans[] = {"san1", "san2", "san3"}; |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 292 | size_t i; |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 293 | GPR_ASSERT(tsi_construct_peer(5 + GPR_ARRAY_SIZE(expected_sans), &peer) == |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 294 | TSI_OK); |
| 295 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 296 | TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, |
| 297 | &peer.properties[0]) == TSI_OK); |
| 298 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 299 | "foo", "bar", &peer.properties[1]) == TSI_OK); |
| 300 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 301 | TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn, |
| 302 | &peer.properties[2]) == TSI_OK); |
| 303 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 304 | "chapi", "chapo", &peer.properties[3]) == TSI_OK); |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 305 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 306 | TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, |
| 307 | &peer.properties[4]) == TSI_OK); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 308 | for (i = 0; i < GPR_ARRAY_SIZE(expected_sans); i++) { |
| 309 | GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( |
| 310 | TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 311 | expected_sans[i], &peer.properties[5 + i]) == TSI_OK); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 312 | } |
| 313 | ctx = tsi_ssl_peer_to_auth_context(&peer); |
Craig Tiller | 4ac2b8e | 2017-11-10 14:14:17 -0800 | [diff] [blame] | 314 | GPR_ASSERT(ctx != nullptr); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 315 | GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); |
| 316 | GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans, |
| 317 | GPR_ARRAY_SIZE(expected_sans))); |
| 318 | GPR_ASSERT(check_transport_security_type(ctx)); |
| 319 | GPR_ASSERT(check_x509_cn(ctx, expected_cn)); |
Deepak Lukose | e61cbe3 | 2016-03-14 14:10:44 -0700 | [diff] [blame] | 320 | GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 321 | |
Julien Boeuf | ee9d78b | 2015-12-18 09:50:34 -0800 | [diff] [blame] | 322 | rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx); |
| 323 | GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); |
| 324 | |
| 325 | tsi_shallow_peer_destruct(&rpeer); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 326 | tsi_peer_destruct(&peer); |
Craig Tiller | 991edad | 2015-06-30 11:40:41 -0700 | [diff] [blame] | 327 | GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 328 | } |
| 329 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 330 | static const char* roots_for_override_api = "roots for override api"; |
Julien Boeuf | aaebf7a | 2016-01-28 17:04:42 -0800 | [diff] [blame] | 331 | |
| 332 | static grpc_ssl_roots_override_result override_roots_success( |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 333 | char** pem_root_certs) { |
Julien Boeuf | aaebf7a | 2016-01-28 17:04:42 -0800 | [diff] [blame] | 334 | *pem_root_certs = gpr_strdup(roots_for_override_api); |
| 335 | return GRPC_SSL_ROOTS_OVERRIDE_OK; |
| 336 | } |
| 337 | |
| 338 | static grpc_ssl_roots_override_result override_roots_permanent_failure( |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 339 | char** pem_root_certs) { |
Julien Boeuf | aaebf7a | 2016-01-28 17:04:42 -0800 | [diff] [blame] | 340 | return GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY; |
| 341 | } |
| 342 | |
jiangtaoli2016 | 144f555 | 2018-03-23 11:28:48 -0700 | [diff] [blame^] | 343 | namespace grpc_core { |
| 344 | namespace { |
| 345 | |
| 346 | class TestDefafaultSllRootStore : public DefaultSslRootStore { |
| 347 | public: |
| 348 | static grpc_slice ComputePemRootCertsForTesting() { |
| 349 | return ComputePemRootCerts(); |
| 350 | } |
| 351 | }; |
| 352 | |
| 353 | } // namespace |
| 354 | } // namespace grpc_core |
| 355 | |
| 356 | // TODO: Convert this test to C++ test when security_connector implementation |
| 357 | // is converted to C++. |
Julien Boeuf | 373debd | 2016-01-27 15:41:12 -0800 | [diff] [blame] | 358 | static void test_default_ssl_roots(void) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 359 | const char* roots_for_env_var = "roots for env var"; |
Julien Boeuf | 373debd | 2016-01-27 15:41:12 -0800 | [diff] [blame] | 360 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 361 | char* roots_env_var_file_path; |
| 362 | FILE* roots_env_var_file = |
Julien Boeuf | 373debd | 2016-01-27 15:41:12 -0800 | [diff] [blame] | 363 | gpr_tmpfile("test_roots_for_env_var", &roots_env_var_file_path); |
| 364 | fwrite(roots_for_env_var, 1, strlen(roots_for_env_var), roots_env_var_file); |
| 365 | fclose(roots_env_var_file); |
| 366 | |
Julien Boeuf | 2757fa8 | 2016-01-29 22:13:24 -0800 | [diff] [blame] | 367 | /* First let's get the root through the override: set the env to an invalid |
| 368 | value. */ |
| 369 | gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, ""); |
Julien Boeuf | aaebf7a | 2016-01-28 17:04:42 -0800 | [diff] [blame] | 370 | grpc_set_ssl_roots_override_callback(override_roots_success); |
jiangtaoli2016 | 144f555 | 2018-03-23 11:28:48 -0700 | [diff] [blame^] | 371 | grpc_slice roots = |
| 372 | grpc_core::TestDefafaultSllRootStore::ComputePemRootCertsForTesting(); |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 373 | char* roots_contents = grpc_slice_to_c_string(roots); |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 374 | grpc_slice_unref(roots); |
Julien Boeuf | 373debd | 2016-01-27 15:41:12 -0800 | [diff] [blame] | 375 | GPR_ASSERT(strcmp(roots_contents, roots_for_override_api) == 0); |
| 376 | gpr_free(roots_contents); |
| 377 | |
| 378 | /* Now let's set the env var: We should get the contents pointed value |
| 379 | instead. */ |
| 380 | gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_env_var_file_path); |
jiangtaoli2016 | 144f555 | 2018-03-23 11:28:48 -0700 | [diff] [blame^] | 381 | roots = grpc_core::TestDefafaultSllRootStore::ComputePemRootCertsForTesting(); |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 382 | roots_contents = grpc_slice_to_c_string(roots); |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 383 | grpc_slice_unref(roots); |
Julien Boeuf | 373debd | 2016-01-27 15:41:12 -0800 | [diff] [blame] | 384 | GPR_ASSERT(strcmp(roots_contents, roots_for_env_var) == 0); |
| 385 | gpr_free(roots_contents); |
| 386 | |
| 387 | /* Now reset the env var. We should fall back to the value overridden using |
| 388 | the api. */ |
| 389 | gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, ""); |
jiangtaoli2016 | 144f555 | 2018-03-23 11:28:48 -0700 | [diff] [blame^] | 390 | roots = grpc_core::TestDefafaultSllRootStore::ComputePemRootCertsForTesting(); |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 391 | roots_contents = grpc_slice_to_c_string(roots); |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 392 | grpc_slice_unref(roots); |
Julien Boeuf | 373debd | 2016-01-27 15:41:12 -0800 | [diff] [blame] | 393 | GPR_ASSERT(strcmp(roots_contents, roots_for_override_api) == 0); |
| 394 | gpr_free(roots_contents); |
| 395 | |
Julien Boeuf | aaebf7a | 2016-01-28 17:04:42 -0800 | [diff] [blame] | 396 | /* Now setup a permanent failure for the overridden roots and we should get |
| 397 | an empty slice. */ |
| 398 | grpc_set_ssl_roots_override_callback(override_roots_permanent_failure); |
jiangtaoli2016 | 144f555 | 2018-03-23 11:28:48 -0700 | [diff] [blame^] | 399 | roots = grpc_core::TestDefafaultSllRootStore::ComputePemRootCertsForTesting(); |
Craig Tiller | 618e67d | 2016-10-26 21:08:10 -0700 | [diff] [blame] | 400 | GPR_ASSERT(GRPC_SLICE_IS_EMPTY(roots)); |
jiangtaoli2016 | 144f555 | 2018-03-23 11:28:48 -0700 | [diff] [blame^] | 401 | const tsi_ssl_root_certs_store* root_store = |
| 402 | grpc_core::TestDefafaultSllRootStore::GetRootStore(); |
| 403 | GPR_ASSERT(root_store == nullptr); |
Julien Boeuf | aaebf7a | 2016-01-28 17:04:42 -0800 | [diff] [blame] | 404 | |
Julien Boeuf | 373debd | 2016-01-27 15:41:12 -0800 | [diff] [blame] | 405 | /* Cleanup. */ |
Julien Boeuf | 373debd | 2016-01-27 15:41:12 -0800 | [diff] [blame] | 406 | remove(roots_env_var_file_path); |
Julien Boeuf | 373debd | 2016-01-27 15:41:12 -0800 | [diff] [blame] | 407 | gpr_free(roots_env_var_file_path); |
Julien Boeuf | 373debd | 2016-01-27 15:41:12 -0800 | [diff] [blame] | 408 | } |
| 409 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 410 | int main(int argc, char** argv) { |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 411 | grpc_test_init(argc, argv); |
| 412 | grpc_init(); |
| 413 | |
| 414 | test_unauthenticated_ssl_peer(); |
| 415 | test_cn_only_ssl_peer_to_auth_context(); |
| 416 | test_cn_and_one_san_ssl_peer_to_auth_context(); |
| 417 | test_cn_and_multiple_sans_ssl_peer_to_auth_context(); |
| 418 | test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(); |
Julien Boeuf | 373debd | 2016-01-27 15:41:12 -0800 | [diff] [blame] | 419 | test_default_ssl_roots(); |
Julien Boeuf | a701ade | 2015-06-18 15:23:40 +0200 | [diff] [blame] | 420 | |
| 421 | grpc_shutdown(); |
| 422 | return 0; |
| 423 | } |