diff options
Diffstat (limited to 'src/regress/lib')
| -rw-r--r-- | src/regress/lib/libssl/tlsext/tlsexttest.c | 338 |
1 files changed, 337 insertions, 1 deletions
diff --git a/src/regress/lib/libssl/tlsext/tlsexttest.c b/src/regress/lib/libssl/tlsext/tlsexttest.c index 5a7a34c56c..4f9e6e29e2 100644 --- a/src/regress/lib/libssl/tlsext/tlsexttest.c +++ b/src/regress/lib/libssl/tlsext/tlsexttest.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tlsexttest.c,v 1.4 2017/08/11 05:06:34 doug Exp $ */ | 1 | /* $OpenBSD: tlsexttest.c,v 1.5 2017/08/11 20:14:13 doug Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2017 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -34,6 +34,17 @@ hexdump(const unsigned char *buf, size_t len) | |||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | static void | 36 | static void |
| 37 | hexdump2(const uint16_t *buf, size_t len) | ||
| 38 | { | ||
| 39 | size_t i; | ||
| 40 | |||
| 41 | for (i = 1; i <= len / 2; i++) | ||
| 42 | fprintf(stderr, " 0x%04hx,%s", buf[i - 1], i % 8 ? "" : "\n"); | ||
| 43 | |||
| 44 | fprintf(stderr, "\n"); | ||
| 45 | } | ||
| 46 | |||
| 47 | static void | ||
| 37 | compare_data(const uint8_t *recv, size_t recv_len, const uint8_t *expect, | 48 | compare_data(const uint8_t *recv, size_t recv_len, const uint8_t *expect, |
| 38 | size_t expect_len) | 49 | size_t expect_len) |
| 39 | { | 50 | { |
| @@ -44,6 +55,17 @@ compare_data(const uint8_t *recv, size_t recv_len, const uint8_t *expect, | |||
| 44 | hexdump(expect, expect_len); | 55 | hexdump(expect, expect_len); |
| 45 | } | 56 | } |
| 46 | 57 | ||
| 58 | static void | ||
| 59 | compare_data2(const uint16_t *recv, size_t recv_len, const uint16_t *expect, | ||
| 60 | size_t expect_len) | ||
| 61 | { | ||
| 62 | fprintf(stderr, "received:\n"); | ||
| 63 | hexdump2(recv, recv_len); | ||
| 64 | |||
| 65 | fprintf(stderr, "test data:\n"); | ||
| 66 | hexdump2(expect, expect_len); | ||
| 67 | } | ||
| 68 | |||
| 47 | #define FAIL(msg, ...) \ | 69 | #define FAIL(msg, ...) \ |
| 48 | do { \ | 70 | do { \ |
| 49 | fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \ | 71 | fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \ |
| @@ -988,6 +1010,317 @@ test_tlsext_ecpf_serverhello(void) | |||
| 988 | return (failure); | 1010 | return (failure); |
| 989 | } | 1011 | } |
| 990 | 1012 | ||
| 1013 | /* | ||
| 1014 | * ellliptic_curves - RFC 4492 section 5.1.1 (Supported Elliptic Curves). | ||
| 1015 | * | ||
| 1016 | * This extension is only used by the client. | ||
| 1017 | */ | ||
| 1018 | |||
| 1019 | static uint8_t tlsext_ec_clienthello_default[] = { | ||
| 1020 | 0x00, 0x06, | ||
| 1021 | 0x00, 0x1d, /* X25519 (29) */ | ||
| 1022 | 0x00, 0x17, /* secp256r1 (23) */ | ||
| 1023 | 0x00, 0x18 /* secp384r1 (24) */ | ||
| 1024 | }; | ||
| 1025 | |||
| 1026 | static uint16_t tlsext_ec_clienthello_secp384r1_val[] = { | ||
| 1027 | 0x0018 /* tls1_ec_nid2curve_id(NID_secp384r1) */ | ||
| 1028 | }; | ||
| 1029 | static uint8_t tlsext_ec_clienthello_secp384r1[] = { | ||
| 1030 | 0x00, 0x02, | ||
| 1031 | 0x00, 0x18 /* secp384r1 (24) */ | ||
| 1032 | }; | ||
| 1033 | |||
| 1034 | /* Example from RFC 4492 section 5.1.1 */ | ||
| 1035 | static uint16_t tlsext_ec_clienthello_nistp192and224_val[] = { | ||
| 1036 | 0x0013, /* tls1_ec_nid2curve_id(NID_X9_62_prime192v1) */ | ||
| 1037 | 0x0015 /* tls1_ec_nid2curve_id(NID_secp224r1) */ | ||
| 1038 | }; | ||
| 1039 | static uint8_t tlsext_ec_clienthello_nistp192and224[] = { | ||
| 1040 | 0x00, 0x04, | ||
| 1041 | 0x00, 0x13, /* secp192r1 aka NIST P-192 */ | ||
| 1042 | 0x00, 0x15 /* secp224r1 aka NIST P-224 */ | ||
| 1043 | }; | ||
| 1044 | |||
| 1045 | static int | ||
| 1046 | test_tlsext_ec_clienthello(void) | ||
| 1047 | { | ||
| 1048 | unsigned char *data = NULL; | ||
| 1049 | SSL_CTX *ssl_ctx = NULL; | ||
| 1050 | SSL *ssl = NULL; | ||
| 1051 | size_t dlen; | ||
| 1052 | int failure, alert; | ||
| 1053 | CBB cbb; | ||
| 1054 | CBS cbs; | ||
| 1055 | |||
| 1056 | failure = 1; | ||
| 1057 | |||
| 1058 | CBB_init(&cbb, 0); | ||
| 1059 | |||
| 1060 | if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) | ||
| 1061 | errx(1, "failed to create SSL_CTX"); | ||
| 1062 | if ((ssl = SSL_new(ssl_ctx)) == NULL) | ||
| 1063 | errx(1, "failed to create SSL"); | ||
| 1064 | |||
| 1065 | /* | ||
| 1066 | * Default ciphers include EC so we need it by default. | ||
| 1067 | */ | ||
| 1068 | if (!tlsext_ec_clienthello_needs(ssl)) { | ||
| 1069 | FAIL("clienthello should need Ellipticcurves for default " | ||
| 1070 | "ciphers\n"); | ||
| 1071 | goto err; | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | /* | ||
| 1075 | * Exclude cipher suites so we can test not including it. | ||
| 1076 | */ | ||
| 1077 | if (!SSL_set_cipher_list(ssl, "TLSv1.2:!ECDHE:!ECDSA")) { | ||
| 1078 | FAIL("clienthello should be able to set cipher list\n"); | ||
| 1079 | goto err; | ||
| 1080 | } | ||
| 1081 | if (tlsext_ec_clienthello_needs(ssl)) { | ||
| 1082 | FAIL("clienthello should not need Ellipticcurves\n"); | ||
| 1083 | goto err; | ||
| 1084 | } | ||
| 1085 | |||
| 1086 | /* | ||
| 1087 | * Use libtls default for the rest of the testing | ||
| 1088 | */ | ||
| 1089 | if (!SSL_set_cipher_list(ssl, "TLSv1.2+AEAD+ECDHE")) { | ||
| 1090 | FAIL("clienthello should be able to set cipher list\n"); | ||
| 1091 | goto err; | ||
| 1092 | } | ||
| 1093 | if (!tlsext_ec_clienthello_needs(ssl)) { | ||
| 1094 | FAIL("clienthello should need Ellipticcurves\n"); | ||
| 1095 | goto err; | ||
| 1096 | } | ||
| 1097 | |||
| 1098 | /* | ||
| 1099 | * Test with a session secp384r1. The default is used instead. | ||
| 1100 | */ | ||
| 1101 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 1102 | errx(1, "failed to create session"); | ||
| 1103 | |||
| 1104 | if ((SSI(ssl)->tlsext_supportedgroups = malloc(sizeof(uint16_t))) | ||
| 1105 | == NULL) { | ||
| 1106 | FAIL("client could not malloc\n"); | ||
| 1107 | goto err; | ||
| 1108 | } | ||
| 1109 | SSI(ssl)->tlsext_supportedgroups[0] = tls1_ec_nid2curve_id(NID_secp384r1); | ||
| 1110 | SSI(ssl)->tlsext_supportedgroups_length = 1; | ||
| 1111 | |||
| 1112 | if (!tlsext_ec_clienthello_needs(ssl)) { | ||
| 1113 | FAIL("clienthello should need Ellipticcurves\n"); | ||
| 1114 | goto err; | ||
| 1115 | } | ||
| 1116 | |||
| 1117 | if (!tlsext_ec_clienthello_build(ssl, &cbb)) { | ||
| 1118 | FAIL("clienthello failed to build Ellipticcurves\n"); | ||
| 1119 | goto err; | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | if (!CBB_finish(&cbb, &data, &dlen)) | ||
| 1123 | errx(1, "failed to finish CBB"); | ||
| 1124 | |||
| 1125 | if (dlen != sizeof(tlsext_ec_clienthello_default)) { | ||
| 1126 | FAIL("got clienthello Ellipticcurves with length %zu, " | ||
| 1127 | "want length %zu\n", dlen, | ||
| 1128 | sizeof(tlsext_ec_clienthello_default)); | ||
| 1129 | compare_data(data, dlen, tlsext_ec_clienthello_default, | ||
| 1130 | sizeof(tlsext_ec_clienthello_default)); | ||
| 1131 | goto err; | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | if (memcmp(data, tlsext_ec_clienthello_default, dlen) != 0) { | ||
| 1135 | FAIL("clienthello Ellipticcurves differs:\n"); | ||
| 1136 | compare_data(data, dlen, tlsext_ec_clienthello_default, | ||
| 1137 | sizeof(tlsext_ec_clienthello_default)); | ||
| 1138 | goto err; | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | /* | ||
| 1142 | * Test parsing secp384r1 | ||
| 1143 | */ | ||
| 1144 | CBB_cleanup(&cbb); | ||
| 1145 | CBB_init(&cbb, 0); | ||
| 1146 | free(data); | ||
| 1147 | data = NULL; | ||
| 1148 | |||
| 1149 | SSL_SESSION_free(ssl->session); | ||
| 1150 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 1151 | errx(1, "failed to create session"); | ||
| 1152 | |||
| 1153 | CBS_init(&cbs, tlsext_ec_clienthello_secp384r1, | ||
| 1154 | sizeof(tlsext_ec_clienthello_secp384r1)); | ||
| 1155 | if (!tlsext_ec_clienthello_parse(ssl, &cbs, &alert)) { | ||
| 1156 | FAIL("failed to parse clienthello Ellipticcurves\n"); | ||
| 1157 | goto err; | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | if (SSI(ssl)->tlsext_supportedgroups_length != | ||
| 1161 | sizeof(tlsext_ec_clienthello_secp384r1_val) / sizeof(uint16_t)) { | ||
| 1162 | FAIL("no tlsext_ellipticcurves from clienthello " | ||
| 1163 | "Ellipticcurves\n"); | ||
| 1164 | goto err; | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | if (memcmp(SSI(ssl)->tlsext_supportedgroups, | ||
| 1168 | tlsext_ec_clienthello_secp384r1_val, | ||
| 1169 | sizeof(tlsext_ec_clienthello_secp384r1_val)) != 0) { | ||
| 1170 | FAIL("clienthello had an incorrect Ellipticcurves " | ||
| 1171 | "entry\n"); | ||
| 1172 | compare_data2(SSI(ssl)->tlsext_supportedgroups, | ||
| 1173 | SSI(ssl)->tlsext_supportedgroups_length * 2, | ||
| 1174 | tlsext_ec_clienthello_secp384r1_val, | ||
| 1175 | sizeof(tlsext_ec_clienthello_secp384r1_val)); | ||
| 1176 | goto err; | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | /* | ||
| 1180 | * Use a custom order. | ||
| 1181 | */ | ||
| 1182 | CBB_cleanup(&cbb); | ||
| 1183 | CBB_init(&cbb, 0); | ||
| 1184 | |||
| 1185 | SSL_SESSION_free(ssl->session); | ||
| 1186 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 1187 | errx(1, "failed to create session"); | ||
| 1188 | |||
| 1189 | if ((ssl->internal->tlsext_supportedgroups = malloc(sizeof(uint16_t) * 2)) == NULL) { | ||
| 1190 | FAIL("client could not malloc\n"); | ||
| 1191 | goto err; | ||
| 1192 | } | ||
| 1193 | ssl->internal->tlsext_supportedgroups[0] = tls1_ec_nid2curve_id(NID_X9_62_prime192v1); | ||
| 1194 | ssl->internal->tlsext_supportedgroups[1] = tls1_ec_nid2curve_id(NID_secp224r1); | ||
| 1195 | ssl->internal->tlsext_supportedgroups_length = 2; | ||
| 1196 | |||
| 1197 | if (!tlsext_ec_clienthello_needs(ssl)) { | ||
| 1198 | FAIL("clienthello should need Ellipticcurves\n"); | ||
| 1199 | goto err; | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | if (!tlsext_ec_clienthello_build(ssl, &cbb)) { | ||
| 1203 | FAIL("clienthello failed to build Ellipticcurves\n"); | ||
| 1204 | goto err; | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | if (!CBB_finish(&cbb, &data, &dlen)) | ||
| 1208 | errx(1, "failed to finish CBB"); | ||
| 1209 | |||
| 1210 | if (dlen != sizeof(tlsext_ec_clienthello_nistp192and224)) { | ||
| 1211 | FAIL("got clienthello Ellipticcurves with length %zu, " | ||
| 1212 | "want length %zu\n", dlen, | ||
| 1213 | sizeof(tlsext_ec_clienthello_nistp192and224)); | ||
| 1214 | fprintf(stderr, "received:\n"); | ||
| 1215 | hexdump(data, dlen); | ||
| 1216 | fprintf(stderr, "test data:\n"); | ||
| 1217 | hexdump(tlsext_ec_clienthello_nistp192and224, | ||
| 1218 | sizeof(tlsext_ec_clienthello_nistp192and224)); | ||
| 1219 | goto err; | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | if (memcmp(data, tlsext_ec_clienthello_nistp192and224, dlen) != 0) { | ||
| 1223 | FAIL("clienthello Ellipticcurves differs:\n"); | ||
| 1224 | fprintf(stderr, "received:\n"); | ||
| 1225 | hexdump(data, dlen); | ||
| 1226 | fprintf(stderr, "test data:\n"); | ||
| 1227 | hexdump(tlsext_ec_clienthello_nistp192and224, | ||
| 1228 | sizeof(tlsext_ec_clienthello_nistp192and224)); | ||
| 1229 | goto err; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | /* | ||
| 1233 | * Parse non-default curves to session. | ||
| 1234 | */ | ||
| 1235 | CBB_cleanup(&cbb); | ||
| 1236 | CBB_init(&cbb, 0); | ||
| 1237 | free(data); | ||
| 1238 | data = NULL; | ||
| 1239 | |||
| 1240 | SSL_SESSION_free(ssl->session); | ||
| 1241 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 1242 | errx(1, "failed to create session"); | ||
| 1243 | |||
| 1244 | /* Reset back to the default list. */ | ||
| 1245 | free(ssl->internal->tlsext_supportedgroups); | ||
| 1246 | ssl->internal->tlsext_supportedgroups = NULL; | ||
| 1247 | ssl->internal->tlsext_supportedgroups_length = 0; | ||
| 1248 | |||
| 1249 | CBS_init(&cbs, tlsext_ec_clienthello_nistp192and224, | ||
| 1250 | sizeof(tlsext_ec_clienthello_nistp192and224)); | ||
| 1251 | if (!tlsext_ec_clienthello_parse(ssl, &cbs, &alert)) { | ||
| 1252 | FAIL("failed to parse clienthello Ellipticcurves\n"); | ||
| 1253 | goto err; | ||
| 1254 | } | ||
| 1255 | |||
| 1256 | if (SSI(ssl)->tlsext_supportedgroups_length != | ||
| 1257 | sizeof(tlsext_ec_clienthello_nistp192and224_val) / sizeof(uint16_t)) { | ||
| 1258 | FAIL("no tlsext_ellipticcurves from clienthello " | ||
| 1259 | "Ellipticcurves\n"); | ||
| 1260 | goto err; | ||
| 1261 | } | ||
| 1262 | |||
| 1263 | if (memcmp(SSI(ssl)->tlsext_supportedgroups, | ||
| 1264 | tlsext_ec_clienthello_nistp192and224_val, | ||
| 1265 | sizeof(tlsext_ec_clienthello_nistp192and224_val)) != 0) { | ||
| 1266 | FAIL("clienthello had an incorrect Ellipticcurves entry\n"); | ||
| 1267 | compare_data2(SSI(ssl)->tlsext_supportedgroups, | ||
| 1268 | SSI(ssl)->tlsext_supportedgroups_length * 2, | ||
| 1269 | tlsext_ec_clienthello_nistp192and224_val, | ||
| 1270 | sizeof(tlsext_ec_clienthello_nistp192and224_val)); | ||
| 1271 | goto err; | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | failure = 0; | ||
| 1275 | |||
| 1276 | err: | ||
| 1277 | CBB_cleanup(&cbb); | ||
| 1278 | SSL_CTX_free(ssl_ctx); | ||
| 1279 | SSL_free(ssl); | ||
| 1280 | free(data); | ||
| 1281 | |||
| 1282 | return (failure); | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | |||
| 1286 | /* elliptic_curves is only used by the client so this doesn't test much. */ | ||
| 1287 | static int | ||
| 1288 | test_tlsext_ec_serverhello(void) | ||
| 1289 | { | ||
| 1290 | SSL_CTX *ssl_ctx = NULL; | ||
| 1291 | SSL *ssl = NULL; | ||
| 1292 | int failure; | ||
| 1293 | |||
| 1294 | failure = 1; | ||
| 1295 | |||
| 1296 | if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) | ||
| 1297 | errx(1, "failed to create SSL_CTX"); | ||
| 1298 | if ((ssl = SSL_new(ssl_ctx)) == NULL) | ||
| 1299 | errx(1, "failed to create SSL"); | ||
| 1300 | |||
| 1301 | if (tlsext_ec_serverhello_needs(ssl)) { | ||
| 1302 | FAIL("serverhello should not need elliptic_curves\n"); | ||
| 1303 | goto err; | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 1307 | errx(1, "failed to create session"); | ||
| 1308 | |||
| 1309 | if (tlsext_ec_serverhello_needs(ssl)) { | ||
| 1310 | FAIL("serverhello should not need elliptic_curves\n"); | ||
| 1311 | goto err; | ||
| 1312 | } | ||
| 1313 | |||
| 1314 | failure = 0; | ||
| 1315 | |||
| 1316 | err: | ||
| 1317 | SSL_CTX_free(ssl_ctx); | ||
| 1318 | SSL_free(ssl); | ||
| 1319 | |||
| 1320 | return (failure); | ||
| 1321 | |||
| 1322 | } | ||
| 1323 | |||
| 991 | int | 1324 | int |
| 992 | main(int argc, char **argv) | 1325 | main(int argc, char **argv) |
| 993 | { | 1326 | { |
| @@ -1004,5 +1337,8 @@ main(int argc, char **argv) | |||
| 1004 | failed |= test_tlsext_ecpf_clienthello(); | 1337 | failed |= test_tlsext_ecpf_clienthello(); |
| 1005 | failed |= test_tlsext_ecpf_serverhello(); | 1338 | failed |= test_tlsext_ecpf_serverhello(); |
| 1006 | 1339 | ||
| 1340 | failed |= test_tlsext_ec_clienthello(); | ||
| 1341 | failed |= test_tlsext_ec_serverhello(); | ||
| 1342 | |||
| 1007 | return (failed); | 1343 | return (failed); |
| 1008 | } | 1344 | } |
