/* * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ /* DTLS code by Eric Rescorla Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. */ #include #include #include #include #include "internal.h" using namespace bssl; static const SRTP_PROTECTION_PROFILE kSRTPProfiles[] = { {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80}, {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32}, {"SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM}, {"SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM}, {0, 0}, }; static int find_profile_by_name(const char *profile_name, const SRTP_PROTECTION_PROFILE **pptr, size_t len) { const SRTP_PROTECTION_PROFILE *p = kSRTPProfiles; while (p->name) { if (len == strlen(p->name) && !strncmp(p->name, profile_name, len)) { *pptr = p; return 1; } p++; } return 0; } static int ssl_ctx_make_profiles( const char *profiles_string, UniquePtr *out) { UniquePtr profiles( sk_SRTP_PROTECTION_PROFILE_new_null()); if (profiles == nullptr) { OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); return 0; } const char *col; const char *ptr = profiles_string; do { col = strchr(ptr, ':'); const SRTP_PROTECTION_PROFILE *profile; if (!find_profile_by_name(ptr, &profile, col ? (size_t)(col - ptr) : strlen(ptr))) { OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); return 0; } if (!sk_SRTP_PROTECTION_PROFILE_push(profiles.get(), profile)) { return 0; } if (col) { ptr = col + 1; } } while (col); *out = std::move(profiles); return 1; } int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, const char *profiles) { return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles); } int SSL_set_srtp_profiles(SSL *ssl, const char *profiles) { return ssl->config != nullptr && ssl_ctx_make_profiles(profiles, &ssl->config->srtp_profiles); } const STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(const SSL *ssl) { if (ssl == nullptr) { return nullptr; } if (ssl->config == nullptr) { assert(0); return nullptr; } return ssl->config->srtp_profiles != nullptr ? ssl->config->srtp_profiles.get() : ssl->ctx->srtp_profiles.get(); } const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *ssl) { return ssl->s3->srtp_profile; } int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) { // This API inverts its return value. return !SSL_CTX_set_srtp_profiles(ctx, profiles); } int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles) { // This API inverts its return value. return !SSL_set_srtp_profiles(ssl, profiles); }