diff options
Diffstat (limited to 'src/lib/libssl/ssl_tlsext.c')
-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)) |