xref: /src/crypto/openssl/ssl/d1_srtp.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
1 /*
2  * Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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. Copyright (C) 2011, RTFM, Inc.
14  */
15 
16 #include <stdio.h>
17 #include <openssl/objects.h>
18 #include "ssl_local.h"
19 #include "internal/ssl_unwrap.h"
20 
21 #ifndef OPENSSL_NO_SRTP
22 
23 static const SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
24     {
25         "SRTP_AES128_CM_SHA1_80",
26         SRTP_AES128_CM_SHA1_80,
27     },
28     {
29         "SRTP_AES128_CM_SHA1_32",
30         SRTP_AES128_CM_SHA1_32,
31     },
32     {
33         "SRTP_AEAD_AES_128_GCM",
34         SRTP_AEAD_AES_128_GCM,
35     },
36     {
37         "SRTP_AEAD_AES_256_GCM",
38         SRTP_AEAD_AES_256_GCM,
39     },
40     {
41         "SRTP_DOUBLE_AEAD_AES_128_GCM_AEAD_AES_128_GCM",
42         SRTP_DOUBLE_AEAD_AES_128_GCM_AEAD_AES_128_GCM,
43     },
44     {
45         "SRTP_DOUBLE_AEAD_AES_256_GCM_AEAD_AES_256_GCM",
46         SRTP_DOUBLE_AEAD_AES_256_GCM_AEAD_AES_256_GCM,
47     },
48     {
49         "SRTP_ARIA_128_CTR_HMAC_SHA1_80",
50         SRTP_ARIA_128_CTR_HMAC_SHA1_80,
51     },
52     {
53         "SRTP_ARIA_128_CTR_HMAC_SHA1_32",
54         SRTP_ARIA_128_CTR_HMAC_SHA1_32,
55     },
56     {
57         "SRTP_ARIA_256_CTR_HMAC_SHA1_80",
58         SRTP_ARIA_256_CTR_HMAC_SHA1_80,
59     },
60     {
61         "SRTP_ARIA_256_CTR_HMAC_SHA1_32",
62         SRTP_ARIA_256_CTR_HMAC_SHA1_32,
63     },
64     {
65         "SRTP_AEAD_ARIA_128_GCM",
66         SRTP_AEAD_ARIA_128_GCM,
67     },
68     {
69         "SRTP_AEAD_ARIA_256_GCM",
70         SRTP_AEAD_ARIA_256_GCM,
71     },
72     { 0 }
73 };
74 
find_profile_by_name(char * profile_name,const SRTP_PROTECTION_PROFILE ** pptr,size_t len)75 static int find_profile_by_name(char *profile_name,
76     const SRTP_PROTECTION_PROFILE **pptr, size_t len)
77 {
78     const SRTP_PROTECTION_PROFILE *p;
79 
80     p = srtp_known_profiles;
81     while (p->name) {
82         if ((len == strlen(p->name))
83             && strncmp(p->name, profile_name, len) == 0) {
84             *pptr = p;
85             return 0;
86         }
87 
88         p++;
89     }
90 
91     return 1;
92 }
93 
ssl_ctx_make_profiles(const char * profiles_string,STACK_OF (SRTP_PROTECTION_PROFILE)** out)94 static int ssl_ctx_make_profiles(const char *profiles_string,
95     STACK_OF(SRTP_PROTECTION_PROFILE) **out)
96 {
97     STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
98 
99     char *col;
100     char *ptr = (char *)profiles_string;
101     const SRTP_PROTECTION_PROFILE *p;
102 
103     if ((profiles = sk_SRTP_PROTECTION_PROFILE_new_null()) == NULL) {
104         ERR_raise(ERR_LIB_SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
105         return 1;
106     }
107 
108     do {
109         col = strchr(ptr, ':');
110 
111         if (!find_profile_by_name(ptr, &p, col ? (size_t)(col - ptr) : strlen(ptr))) {
112             if (sk_SRTP_PROTECTION_PROFILE_find(profiles,
113                     (SRTP_PROTECTION_PROFILE *)p)
114                 >= 0) {
115                 ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
116                 goto err;
117             }
118 
119             if (!sk_SRTP_PROTECTION_PROFILE_push(profiles,
120                     (SRTP_PROTECTION_PROFILE *)p)) {
121                 ERR_raise(ERR_LIB_SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
122                 goto err;
123             }
124         } else {
125             ERR_raise(ERR_LIB_SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
126             goto err;
127         }
128 
129         if (col)
130             ptr = col + 1;
131     } while (col);
132 
133     sk_SRTP_PROTECTION_PROFILE_free(*out);
134 
135     *out = profiles;
136 
137     return 0;
138 err:
139     sk_SRTP_PROTECTION_PROFILE_free(profiles);
140     return 1;
141 }
142 
SSL_CTX_set_tlsext_use_srtp(SSL_CTX * ctx,const char * profiles)143 int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles)
144 {
145     if (IS_QUIC_METHOD(ctx->method))
146         return 1;
147 
148     return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles);
149 }
150 
SSL_set_tlsext_use_srtp(SSL * s,const char * profiles)151 int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles)
152 {
153     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
154 
155     if (sc == NULL)
156         return 1;
157 
158     return ssl_ctx_make_profiles(profiles, &sc->srtp_profiles);
159 }
160 
STACK_OF(SRTP_PROTECTION_PROFILE)161 STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s)
162 {
163     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
164 
165     if (sc != NULL) {
166         if (sc->srtp_profiles != NULL) {
167             return sc->srtp_profiles;
168         } else if ((s->ctx != NULL) && (s->ctx->srtp_profiles != NULL)) {
169             return s->ctx->srtp_profiles;
170         }
171     }
172 
173     return NULL;
174 }
175 
SSL_get_selected_srtp_profile(SSL * s)176 SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s)
177 {
178     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
179 
180     if (sc == NULL)
181         return 0;
182 
183     return sc->srtp_profile;
184 }
185 #endif
186