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