diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 224 |
1 files changed, 223 insertions, 1 deletions
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index 405882c0e9..2438b90d04 100644 --- a/src/lib/libssl/ssl_tlsext.c +++ b/src/lib/libssl/ssl_tlsext.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_tlsext.c,v 1.11 2017/08/26 20:23:46 doug Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.12 2017/08/27 02:58:04 doug Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
| 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> | 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
| @@ -704,6 +704,7 @@ tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert) | |||
| 704 | return 1; | 704 | return 1; |
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | |||
| 707 | /* | 708 | /* |
| 708 | *Certificate Status Request - RFC 6066 section 8. | 709 | *Certificate Status Request - RFC 6066 section 8. |
| 709 | */ | 710 | */ |
| @@ -983,6 +984,216 @@ tlsext_sessionticket_serverhello_parse(SSL *s, CBS *cbs, int *alert) | |||
| 983 | return 1; | 984 | return 1; |
| 984 | } | 985 | } |
| 985 | 986 | ||
| 987 | /* | ||
| 988 | * DTLS extension for SRTP key establishment - RFC 5764 | ||
| 989 | */ | ||
| 990 | |||
| 991 | #ifndef OPENSSL_NO_SRTP | ||
| 992 | |||
| 993 | int | ||
| 994 | tlsext_srtp_clienthello_needs(SSL *s) | ||
| 995 | { | ||
| 996 | return SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s) != NULL; | ||
| 997 | } | ||
| 998 | |||
| 999 | int | ||
| 1000 | tlsext_srtp_clienthello_build(SSL *s, CBB *cbb) | ||
| 1001 | { | ||
| 1002 | CBB profiles, mki; | ||
| 1003 | int ct, i; | ||
| 1004 | STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = NULL; | ||
| 1005 | SRTP_PROTECTION_PROFILE *prof; | ||
| 1006 | |||
| 1007 | if ((clnt = SSL_get_srtp_profiles(s)) == NULL) { | ||
| 1008 | SSLerror(s, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); | ||
| 1009 | return 0; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | if ((ct = sk_SRTP_PROTECTION_PROFILE_num(clnt)) < 1) { | ||
| 1013 | SSLerror(s, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); | ||
| 1014 | return 0; | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | if (!CBB_add_u16_length_prefixed(cbb, &profiles)) | ||
| 1018 | return 0; | ||
| 1019 | |||
| 1020 | for (i = 0; i < ct; i++) { | ||
| 1021 | if ((prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i)) == NULL) | ||
| 1022 | return 0; | ||
| 1023 | if (!CBB_add_u16(&profiles, prof->id)) | ||
| 1024 | return 0; | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | if (!CBB_add_u8_length_prefixed(cbb, &mki)) | ||
| 1028 | return 0; | ||
| 1029 | |||
| 1030 | if (!CBB_flush(cbb)) | ||
| 1031 | return 0; | ||
| 1032 | |||
| 1033 | return 1; | ||
| 1034 | } | ||
| 1035 | |||
| 1036 | int | ||
| 1037 | tlsext_srtp_clienthello_parse(SSL *s, CBS *cbs, int *alert) | ||
| 1038 | { | ||
| 1039 | SRTP_PROTECTION_PROFILE *cprof, *sprof; | ||
| 1040 | STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = NULL, *srvr; | ||
| 1041 | int i, j; | ||
| 1042 | int ret; | ||
| 1043 | uint16_t id; | ||
| 1044 | CBS profiles, mki; | ||
| 1045 | |||
| 1046 | ret = 0; | ||
| 1047 | |||
| 1048 | if (!CBS_get_u16_length_prefixed(cbs, &profiles)) | ||
| 1049 | goto err; | ||
| 1050 | if (CBS_len(&profiles) == 0 || CBS_len(&profiles) % 2 != 0) | ||
| 1051 | goto err; | ||
| 1052 | |||
| 1053 | if ((clnt = sk_SRTP_PROTECTION_PROFILE_new_null()) == NULL) | ||
| 1054 | goto err; | ||
| 1055 | |||
| 1056 | while (CBS_len(&profiles) > 0) { | ||
| 1057 | if (!CBS_get_u16(&profiles, &id)) | ||
| 1058 | goto err; | ||
| 1059 | |||
| 1060 | if (!srtp_find_profile_by_num(id, &cprof)) { | ||
| 1061 | if (!sk_SRTP_PROTECTION_PROFILE_push(clnt, cprof)) | ||
| 1062 | goto err; | ||
| 1063 | } | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | if (!CBS_get_u8_length_prefixed(cbs, &mki) || CBS_len(&mki) != 0) { | ||
| 1067 | SSLerror(s, SSL_R_BAD_SRTP_MKI_VALUE); | ||
| 1068 | *alert = SSL_AD_DECODE_ERROR; | ||
| 1069 | goto done; | ||
| 1070 | } | ||
| 1071 | if (CBS_len(cbs) != 0) | ||
| 1072 | goto err; | ||
| 1073 | |||
| 1074 | /* | ||
| 1075 | * Per RFC 5764 section 4.1.1 | ||
| 1076 | * | ||
| 1077 | * Find the server preferred profile using the client's list. | ||
| 1078 | * | ||
| 1079 | * The server MUST send a profile if it sends the use_srtp | ||
| 1080 | * extension. If one is not found, it should fall back to the | ||
| 1081 | * negotiated DTLS cipher suite or return a DTLS alert. | ||
| 1082 | */ | ||
| 1083 | if ((srvr = SSL_get_srtp_profiles(s)) == NULL) | ||
| 1084 | goto err; | ||
| 1085 | for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(srvr); i++) { | ||
| 1086 | if ((sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i)) | ||
| 1087 | == NULL) | ||
| 1088 | goto err; | ||
| 1089 | |||
| 1090 | for (j = 0; j < sk_SRTP_PROTECTION_PROFILE_num(clnt); j++) { | ||
| 1091 | if ((cprof = sk_SRTP_PROTECTION_PROFILE_value(clnt, j)) | ||
| 1092 | == NULL) | ||
| 1093 | goto err; | ||
| 1094 | |||
| 1095 | if (cprof->id == sprof->id) { | ||
| 1096 | s->internal->srtp_profile = sprof; | ||
| 1097 | ret = 1; | ||
| 1098 | goto done; | ||
| 1099 | } | ||
| 1100 | } | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | /* If we didn't find anything, fall back to the negotiated */ | ||
| 1104 | ret = 1; | ||
| 1105 | goto done; | ||
| 1106 | |||
| 1107 | err: | ||
| 1108 | SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); | ||
| 1109 | *alert = SSL_AD_DECODE_ERROR; | ||
| 1110 | |||
| 1111 | done: | ||
| 1112 | sk_SRTP_PROTECTION_PROFILE_free(clnt); | ||
| 1113 | return ret; | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | int | ||
| 1117 | tlsext_srtp_serverhello_needs(SSL *s) | ||
| 1118 | { | ||
| 1119 | return SSL_IS_DTLS(s) && SSL_get_selected_srtp_profile(s) != NULL; | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | int | ||
| 1123 | tlsext_srtp_serverhello_build(SSL *s, CBB *cbb) | ||
| 1124 | { | ||
| 1125 | SRTP_PROTECTION_PROFILE *profile; | ||
| 1126 | CBB srtp, mki; | ||
| 1127 | |||
| 1128 | if (!CBB_add_u16_length_prefixed(cbb, &srtp)) | ||
| 1129 | return 0; | ||
| 1130 | |||
| 1131 | if ((profile = SSL_get_selected_srtp_profile(s)) == NULL) | ||
| 1132 | return 0; | ||
| 1133 | |||
| 1134 | if (!CBB_add_u16(&srtp, profile->id)) | ||
| 1135 | return 0; | ||
| 1136 | |||
| 1137 | if (!CBB_add_u8_length_prefixed(cbb, &mki)) | ||
| 1138 | return 0; | ||
| 1139 | |||
| 1140 | if (!CBB_flush(cbb)) | ||
| 1141 | return 0; | ||
| 1142 | |||
| 1143 | return 1; | ||
| 1144 | } | ||
| 1145 | |||
| 1146 | int | ||
| 1147 | tlsext_srtp_serverhello_parse(SSL *s, CBS *cbs, int *alert) | ||
| 1148 | { | ||
| 1149 | STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; | ||
| 1150 | SRTP_PROTECTION_PROFILE *prof; | ||
| 1151 | int i; | ||
| 1152 | uint16_t id; | ||
| 1153 | CBS profile_ids, mki; | ||
| 1154 | |||
| 1155 | if (!CBS_get_u16_length_prefixed(cbs, &profile_ids)) { | ||
| 1156 | SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); | ||
| 1157 | goto err; | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | if (!CBS_get_u16(&profile_ids, &id) || CBS_len(&profile_ids) != 0) { | ||
| 1161 | SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); | ||
| 1162 | goto err; | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | if (!CBS_get_u8_length_prefixed(cbs, &mki) || CBS_len(&mki) != 0) { | ||
| 1166 | SSLerror(s, SSL_R_BAD_SRTP_MKI_VALUE); | ||
| 1167 | *alert = SSL_AD_ILLEGAL_PARAMETER; | ||
| 1168 | return 0; | ||
| 1169 | } | ||
| 1170 | |||
| 1171 | if ((clnt = SSL_get_srtp_profiles(s)) == NULL) { | ||
| 1172 | SSLerror(s, SSL_R_NO_SRTP_PROFILES); | ||
| 1173 | goto err; | ||
| 1174 | } | ||
| 1175 | |||
| 1176 | for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) { | ||
| 1177 | if ((prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i)) | ||
| 1178 | == NULL) { | ||
| 1179 | SSLerror(s, SSL_R_NO_SRTP_PROFILES); | ||
| 1180 | goto err; | ||
| 1181 | } | ||
| 1182 | |||
| 1183 | if (prof->id == id) { | ||
| 1184 | s->internal->srtp_profile = prof; | ||
| 1185 | return 1; | ||
| 1186 | } | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); | ||
| 1190 | err: | ||
| 1191 | *alert = SSL_AD_DECODE_ERROR; | ||
| 1192 | return 0; | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | #endif /* OPENSSL_NO_SRTP */ | ||
| 1196 | |||
| 986 | struct tls_extension { | 1197 | struct tls_extension { |
| 987 | uint16_t type; | 1198 | uint16_t type; |
| 988 | int (*clienthello_needs)(SSL *s); | 1199 | int (*clienthello_needs)(SSL *s); |
| @@ -1066,6 +1277,17 @@ static struct tls_extension tls_extensions[] = { | |||
| 1066 | .serverhello_build = tlsext_alpn_serverhello_build, | 1277 | .serverhello_build = tlsext_alpn_serverhello_build, |
| 1067 | .serverhello_parse = tlsext_alpn_serverhello_parse, | 1278 | .serverhello_parse = tlsext_alpn_serverhello_parse, |
| 1068 | }, | 1279 | }, |
| 1280 | #ifndef OPENSSL_NO_SRTP | ||
| 1281 | { | ||
| 1282 | .type = TLSEXT_TYPE_use_srtp, | ||
| 1283 | .clienthello_needs = tlsext_srtp_clienthello_needs, | ||
| 1284 | .clienthello_build = tlsext_srtp_clienthello_build, | ||
| 1285 | .clienthello_parse = tlsext_srtp_clienthello_parse, | ||
| 1286 | .serverhello_needs = tlsext_srtp_serverhello_needs, | ||
| 1287 | .serverhello_build = tlsext_srtp_serverhello_build, | ||
| 1288 | .serverhello_parse = tlsext_srtp_serverhello_parse, | ||
| 1289 | } | ||
| 1290 | #endif /* OPENSSL_NO_SRTP */ | ||
| 1069 | }; | 1291 | }; |
| 1070 | 1292 | ||
| 1071 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) | 1293 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) |
