int tls_parse_stoc_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al) { unsigned int id, ct, mki; int i; STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; SRTP_PROTECTION_PROFILE *prof; if (!PACKET_get_net_2(pkt, &ct) || ct != 2 || !PACKET_get_net_2(pkt, &id) || !PACKET_get_1(pkt, &mki) || PACKET_remaining(pkt) != 0) { SSLerr(SSL_F_TLS_PARSE_STOC_USE_SRTP, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); *al = SSL_AD_DECODE_ERROR; return 0; } if (mki != 0) { /* Must be no MKI, since we never offer one */ SSLerr(SSL_F_TLS_PARSE_STOC_USE_SRTP, SSL_R_BAD_SRTP_MKI_VALUE); *al = SSL_AD_ILLEGAL_PARAMETER; return 0; } /* Throw an error if the server gave us an unsolicited extension */ clnt = SSL_get_srtp_profiles(s); if (clnt == NULL) { SSLerr(SSL_F_TLS_PARSE_STOC_USE_SRTP, SSL_R_NO_SRTP_PROFILES); *al = SSL_AD_DECODE_ERROR; return 0; } /* * Check to see if the server gave us something we support (and * presumably offered) */ for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) { prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); if (prof->id == id) { s->srtp_profile = prof; *al = 0; return 1; } } SSLerr(SSL_F_TLS_PARSE_STOC_USE_SRTP, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); *al = SSL_AD_DECODE_ERROR; return 0; }
int tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al) { STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(s); int i, end; if (clnt == NULL) return 1; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp) /* Sub-packet for SRTP extension */ || !WPACKET_start_sub_packet_u16(pkt) /* Sub-packet for the protection profile list */ || !WPACKET_start_sub_packet_u16(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP, ERR_R_INTERNAL_ERROR); return 0; } end = sk_SRTP_PROTECTION_PROFILE_num(clnt); for (i = 0; i < end; i++) { const SRTP_PROTECTION_PROFILE *prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); if (prof == NULL || !WPACKET_put_bytes_u16(pkt, prof->id)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP, ERR_R_INTERNAL_ERROR); return 0; } } if (!WPACKET_close(pkt) /* Add an empty use_mki value */ || !WPACKET_put_bytes_u8(pkt, 0) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP, ERR_R_INTERNAL_ERROR); return 0; } return 1; }
int tls_parse_ctos_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al) { STACK_OF(SRTP_PROTECTION_PROFILE) *srvr; unsigned int ct, mki_len, id; int i, srtp_pref; PACKET subpkt; /* Ignore this if we have no SRTP profiles */ if (SSL_get_srtp_profiles(s) == NULL) return 1; /* Pull off the length of the cipher suite list and check it is even */ if (!PACKET_get_net_2(pkt, &ct) || (ct & 1) != 0 || !PACKET_get_sub_packet(pkt, &subpkt, ct)) { SSLerr(SSL_F_TLS_PARSE_CTOS_USE_SRTP, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); *al = SSL_AD_DECODE_ERROR; return 0; } srvr = SSL_get_srtp_profiles(s); s->srtp_profile = NULL; /* Search all profiles for a match initially */ srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr); while (PACKET_remaining(&subpkt)) { if (!PACKET_get_net_2(&subpkt, &id)) { SSLerr(SSL_F_TLS_PARSE_CTOS_USE_SRTP, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); *al = SSL_AD_DECODE_ERROR; return 0; } /* * Only look for match in profiles of higher preference than * current match. * If no profiles have been have been configured then this * does nothing. */ for (i = 0; i < srtp_pref; i++) { SRTP_PROTECTION_PROFILE *sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i); if (sprof->id == id) { s->srtp_profile = sprof; srtp_pref = i; break; } } } /* Now extract the MKI value as a sanity check, but discard it for now */ if (!PACKET_get_1(pkt, &mki_len)) { SSLerr(SSL_F_TLS_PARSE_CTOS_USE_SRTP, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); *al = SSL_AD_DECODE_ERROR; return 0; } if (!PACKET_forward(pkt, mki_len) || PACKET_remaining(pkt)) { SSLerr(SSL_F_TLS_PARSE_CTOS_USE_SRTP, SSL_R_BAD_SRTP_MKI_VALUE); *al = SSL_AD_DECODE_ERROR; return 0; } return 1; }