1 /*
2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "rtc_base/sslstreamadapter.h"
12 
13 #include "rtc_base/opensslstreamadapter.h"
14 
15 ///////////////////////////////////////////////////////////////////////////////
16 
17 namespace rtc {
18 
19 // TODO(guoweis): Move this to SDP layer and use int form internally.
20 // webrtc:5043.
21 const char CS_AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80";
22 const char CS_AES_CM_128_HMAC_SHA1_32[] = "AES_CM_128_HMAC_SHA1_32";
23 const char CS_AEAD_AES_128_GCM[] = "AEAD_AES_128_GCM";
24 const char CS_AEAD_AES_256_GCM[] = "AEAD_AES_256_GCM";
25 
SrtpCryptoSuiteToName(int crypto_suite)26 std::string SrtpCryptoSuiteToName(int crypto_suite) {
27   switch (crypto_suite) {
28   case SRTP_AES128_CM_SHA1_32:
29     return CS_AES_CM_128_HMAC_SHA1_32;
30   case SRTP_AES128_CM_SHA1_80:
31     return CS_AES_CM_128_HMAC_SHA1_80;
32   case SRTP_AEAD_AES_128_GCM:
33     return CS_AEAD_AES_128_GCM;
34   case SRTP_AEAD_AES_256_GCM:
35     return CS_AEAD_AES_256_GCM;
36   default:
37     return std::string();
38   }
39 }
40 
SrtpCryptoSuiteFromName(const std::string & crypto_suite)41 int SrtpCryptoSuiteFromName(const std::string& crypto_suite) {
42   if (crypto_suite == CS_AES_CM_128_HMAC_SHA1_32)
43     return SRTP_AES128_CM_SHA1_32;
44   if (crypto_suite == CS_AES_CM_128_HMAC_SHA1_80)
45     return SRTP_AES128_CM_SHA1_80;
46   if (crypto_suite == CS_AEAD_AES_128_GCM)
47     return SRTP_AEAD_AES_128_GCM;
48   if (crypto_suite == CS_AEAD_AES_256_GCM)
49     return SRTP_AEAD_AES_256_GCM;
50   return SRTP_INVALID_CRYPTO_SUITE;
51 }
52 
GetSrtpKeyAndSaltLengths(int crypto_suite,int * key_length,int * salt_length)53 bool GetSrtpKeyAndSaltLengths(int crypto_suite, int *key_length,
54     int *salt_length) {
55   switch (crypto_suite) {
56   case SRTP_AES128_CM_SHA1_32:
57   case SRTP_AES128_CM_SHA1_80:
58     // SRTP_AES128_CM_HMAC_SHA1_32 and SRTP_AES128_CM_HMAC_SHA1_80 are defined
59     // in RFC 5764 to use a 128 bits key and 112 bits salt for the cipher.
60     *key_length = 16;
61     *salt_length = 14;
62     break;
63   case SRTP_AEAD_AES_128_GCM:
64     // SRTP_AEAD_AES_128_GCM is defined in RFC 7714 to use a 128 bits key and
65     // a 96 bits salt for the cipher.
66     *key_length = 16;
67     *salt_length = 12;
68     break;
69   case SRTP_AEAD_AES_256_GCM:
70     // SRTP_AEAD_AES_256_GCM is defined in RFC 7714 to use a 256 bits key and
71     // a 96 bits salt for the cipher.
72     *key_length = 32;
73     *salt_length = 12;
74     break;
75   default:
76     return false;
77   }
78   return true;
79 }
80 
IsGcmCryptoSuite(int crypto_suite)81 bool IsGcmCryptoSuite(int crypto_suite) {
82   return (crypto_suite == SRTP_AEAD_AES_256_GCM ||
83           crypto_suite == SRTP_AEAD_AES_128_GCM);
84 }
85 
IsGcmCryptoSuiteName(const std::string & crypto_suite)86 bool IsGcmCryptoSuiteName(const std::string& crypto_suite) {
87   return (crypto_suite == CS_AEAD_AES_256_GCM ||
88           crypto_suite == CS_AEAD_AES_128_GCM);
89 }
90 
91 // static
NoGcm()92 CryptoOptions CryptoOptions::NoGcm() {
93   CryptoOptions options;
94   options.enable_gcm_crypto_suites = false;
95   return options;
96 }
97 
GetSupportedDtlsSrtpCryptoSuites(const rtc::CryptoOptions & crypto_options)98 std::vector<int> GetSupportedDtlsSrtpCryptoSuites(
99     const rtc::CryptoOptions& crypto_options) {
100   std::vector<int> crypto_suites;
101   if (crypto_options.enable_gcm_crypto_suites) {
102     crypto_suites.push_back(rtc::SRTP_AEAD_AES_256_GCM);
103     crypto_suites.push_back(rtc::SRTP_AEAD_AES_128_GCM);
104   }
105   // Note: SRTP_AES128_CM_SHA1_80 is what is required to be supported (by
106   // draft-ietf-rtcweb-security-arch), but SRTP_AES128_CM_SHA1_32 is allowed as
107   // well, and saves a few bytes per packet if it ends up selected.
108   crypto_suites.push_back(rtc::SRTP_AES128_CM_SHA1_32);
109   crypto_suites.push_back(rtc::SRTP_AES128_CM_SHA1_80);
110   return crypto_suites;
111 }
112 
Create(StreamInterface * stream)113 SSLStreamAdapter* SSLStreamAdapter::Create(StreamInterface* stream) {
114   return new OpenSSLStreamAdapter(stream);
115 }
116 
SSLStreamAdapter(StreamInterface * stream)117 SSLStreamAdapter::SSLStreamAdapter(StreamInterface* stream)
118     : StreamAdapterInterface(stream),
119       ignore_bad_cert_(false),
120       client_auth_enabled_(true) {}
121 
~SSLStreamAdapter()122 SSLStreamAdapter::~SSLStreamAdapter() {}
123 
GetSslCipherSuite(int * cipher_suite)124 bool SSLStreamAdapter::GetSslCipherSuite(int* cipher_suite) {
125   return false;
126 }
127 
ExportKeyingMaterial(const std::string & label,const uint8_t * context,size_t context_len,bool use_context,uint8_t * result,size_t result_len)128 bool SSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
129                                             const uint8_t* context,
130                                             size_t context_len,
131                                             bool use_context,
132                                             uint8_t* result,
133                                             size_t result_len) {
134   return false;  // Default is unsupported
135 }
136 
SetDtlsSrtpCryptoSuites(const std::vector<int> & crypto_suites)137 bool SSLStreamAdapter::SetDtlsSrtpCryptoSuites(
138     const std::vector<int>& crypto_suites) {
139   return false;
140 }
141 
GetDtlsSrtpCryptoSuite(int * crypto_suite)142 bool SSLStreamAdapter::GetDtlsSrtpCryptoSuite(int* crypto_suite) {
143   return false;
144 }
145 
IsBoringSsl()146 bool SSLStreamAdapter::IsBoringSsl() {
147   return OpenSSLStreamAdapter::IsBoringSsl();
148 }
IsAcceptableCipher(int cipher,KeyType key_type)149 bool SSLStreamAdapter::IsAcceptableCipher(int cipher, KeyType key_type) {
150   return OpenSSLStreamAdapter::IsAcceptableCipher(cipher, key_type);
151 }
IsAcceptableCipher(const std::string & cipher,KeyType key_type)152 bool SSLStreamAdapter::IsAcceptableCipher(const std::string& cipher,
153                                           KeyType key_type) {
154   return OpenSSLStreamAdapter::IsAcceptableCipher(cipher, key_type);
155 }
SslCipherSuiteToName(int cipher_suite)156 std::string SSLStreamAdapter::SslCipherSuiteToName(int cipher_suite) {
157   return OpenSSLStreamAdapter::SslCipherSuiteToName(cipher_suite);
158 }
enable_time_callback_for_testing()159 void SSLStreamAdapter::enable_time_callback_for_testing() {
160   OpenSSLStreamAdapter::enable_time_callback_for_testing();
161 }
162 
163 ///////////////////////////////////////////////////////////////////////////////
164 
165 }  // namespace rtc
166