• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 /*
11   DTLS code by Eric Rescorla <ekr@rtfm.com>
12 
13   Copyright (C) 2006, Network Resonance, Inc.
14   Copyright (C) 2011, RTFM, Inc.
15 */
16 
17 #include <openssl/ssl.h>
18 
19 #include <string.h>
20 
21 #include <openssl/bytestring.h>
22 #include <openssl/err.h>
23 
24 #include "internal.h"
25 
26 
27 using namespace bssl;
28 
29 static const SRTP_PROTECTION_PROFILE kSRTPProfiles[] = {
30     {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80},
31     {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32},
32     {"SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM},
33     {"SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM},
34     {0, 0},
35 };
36 
find_profile_by_name(const char * profile_name,const SRTP_PROTECTION_PROFILE ** pptr,size_t len)37 static int find_profile_by_name(const char *profile_name,
38                                 const SRTP_PROTECTION_PROFILE **pptr,
39                                 size_t len) {
40   const SRTP_PROTECTION_PROFILE *p = kSRTPProfiles;
41   while (p->name) {
42     if (len == strlen(p->name) && !strncmp(p->name, profile_name, len)) {
43       *pptr = p;
44       return 1;
45     }
46 
47     p++;
48   }
49 
50   return 0;
51 }
52 
ssl_ctx_make_profiles(const char * profiles_string,UniquePtr<STACK_OF (SRTP_PROTECTION_PROFILE)> * out)53 static int ssl_ctx_make_profiles(
54     const char *profiles_string,
55     UniquePtr<STACK_OF(SRTP_PROTECTION_PROFILE)> *out) {
56   UniquePtr<STACK_OF(SRTP_PROTECTION_PROFILE)> profiles(
57       sk_SRTP_PROTECTION_PROFILE_new_null());
58   if (profiles == nullptr) {
59     OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
60     return 0;
61   }
62 
63   const char *col;
64   const char *ptr = profiles_string;
65   do {
66     col = strchr(ptr, ':');
67 
68     const SRTP_PROTECTION_PROFILE *profile;
69     if (!find_profile_by_name(ptr, &profile,
70                               col ? (size_t)(col - ptr) : strlen(ptr))) {
71       OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
72       return 0;
73     }
74 
75     if (!sk_SRTP_PROTECTION_PROFILE_push(profiles.get(), profile)) {
76       return 0;
77     }
78 
79     if (col) {
80       ptr = col + 1;
81     }
82   } while (col);
83 
84   *out = std::move(profiles);
85   return 1;
86 }
87 
SSL_CTX_set_srtp_profiles(SSL_CTX * ctx,const char * profiles)88 int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, const char *profiles) {
89   return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles);
90 }
91 
SSL_set_srtp_profiles(SSL * ssl,const char * profiles)92 int SSL_set_srtp_profiles(SSL *ssl, const char *profiles) {
93   return ssl->config != nullptr &&
94          ssl_ctx_make_profiles(profiles, &ssl->config->srtp_profiles);
95 }
96 
STACK_OF(SRTP_PROTECTION_PROFILE)97 const STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(const SSL *ssl) {
98   if (ssl == nullptr) {
99     return nullptr;
100   }
101 
102   if (ssl->config == nullptr) {
103     assert(0);
104     return nullptr;
105   }
106 
107   return ssl->config->srtp_profiles != nullptr
108              ? ssl->config->srtp_profiles.get()
109              : ssl->ctx->srtp_profiles.get();
110 }
111 
SSL_get_selected_srtp_profile(SSL * ssl)112 const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *ssl) {
113   return ssl->s3->srtp_profile;
114 }
115 
SSL_CTX_set_tlsext_use_srtp(SSL_CTX * ctx,const char * profiles)116 int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) {
117   // This API inverts its return value.
118   return !SSL_CTX_set_srtp_profiles(ctx, profiles);
119 }
120 
SSL_set_tlsext_use_srtp(SSL * ssl,const char * profiles)121 int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles) {
122   // This API inverts its return value.
123   return !SSL_set_srtp_profiles(ssl, profiles);
124 }
125