Ring Daemon 16.0.0
Loading...
Searching...
No Matches
sdes_negotiator.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2025 Savoir-faire Linux Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#include "sdes_negotiator.h"
19
20#include <iostream>
21#include <sstream>
22#include <algorithm>
23#include <stdexcept>
24#include <regex>
25
26#include <cstdio>
27
28namespace jami {
29
30std::vector<CryptoAttribute>
31SdesNegotiator::parse(const std::vector<std::string>& attributes)
32{
33 // The patterns below try to follow
34 // the ABNF grammar rules described in
35 // RFC4568 section 9.2 with the general
36 // syntax :
37 // a=crypto:tag 1*WSP crypto-suite 1*WSP key-params *(1*WSP session-param)
38
39 // used to match white space (which are used as separator)
40
41 static const std::regex generalSyntaxPattern {"[\x20\x09]+"};
42
43 static const std::regex tagPattern {"^([0-9]{1,9})"};
44
45 static const std::regex cryptoSuitePattern {"(AES_CM_128_HMAC_SHA1_80|"
46 "AES_CM_128_HMAC_SHA1_32|"
47 "F8_128_HMAC_SHA1_80|"
48 "[A-Za-z0-9_]+)"}; // srtp-crypto-suite-ext
49
50 static const std::regex keyParamsPattern {"(inline|[A-Za-z0-9_]+)\\:"
51 "([A-Za-z0-9\x2B\x2F\x3D]+)"
52 "((\\|2\\^)([0-9]+)\\|"
53 "([0-9]+)\\:"
54 "([0-9]{1,3})\\;?)?"};
55
56 // Take each line from the vector
57 // and parse its content
58
59 std::vector<CryptoAttribute> cryptoAttributeVector;
60
61 for (const auto& item : attributes) {
62 // Split the line into its component that we will analyze further down.
63 // Additional white space is added to better split the content
64 // Result is stored in the sdsLine
65
66 std::vector<std::string> sdesLine;
67 std::smatch sm_generalSyntaxPattern;
68
69 std::sregex_token_iterator iter(item.begin(), item.end(), generalSyntaxPattern, -1), end;
70 for (; iter != end; ++iter)
71 sdesLine.push_back(*iter);
72
73 if (sdesLine.size() < 3) {
74 throw ParseError("Missing components in SDES line");
75 }
76
77 // Check if the attribute starts with a=crypto
78 // and get the tag for this line
79
80 std::string tag;
81 std::smatch sm_tagPattern;
82
84 tag = sm_tagPattern[1];
85
86 } else {
87 throw ParseError("No Matching Found in Tag Attribute");
88 }
89
90 // Check if the crypto suite is valid and retrieve
91 // its value.
92
93 std::string cryptoSuite;
94 std::smatch sm_cryptoSuitePattern;
95
98
99 } else {
100 throw ParseError("No Matching Found in CryptoSuite Attribute");
101 }
102
103 // Parse one or more key-params field.
104 // Group number is used to locate different paras
105
106 std::string srtpKeyInfo;
107 std::string srtpKeyMethod;
108 std::string lifetime;
109 std::string mkiLength;
110 std::string mkiValue;
111 std::smatch sm_keyParamsPattern;
112
119
120 } else {
121 throw ParseError("No Matching Found in Key-params Attribute");
122 }
123
124 // Add the new CryptoAttribute to the vector
125 cryptoAttributeVector.emplace_back(std::move(tag),
126 std::move(cryptoSuite),
127 std::move(srtpKeyMethod),
128 std::move(srtpKeyInfo),
129 std::move(lifetime),
130 std::move(mkiValue),
131 std::move(mkiLength));
132 }
134}
135
136CryptoAttribute
137SdesNegotiator::negotiate(const std::vector<std::string>& attributes)
138{
139 try {
141 for (const auto& iter_offer : cryptoAttributeVector) {
142 for (const auto& iter_local : CryptoSuites) {
143 if (iter_offer.getCryptoSuite() == iter_local.name)
144 return iter_offer;
145 }
146 }
147 } catch (const ParseError& exception) {
148 }
149 return {};
150}
151
152} // namespace jami
General exception object that is thrown when an error occurred with a regular expression operation.
static CryptoAttribute negotiate(const std::vector< std::string > &attributes)
void emitSignal(Args... args)
Definition ring_signal.h:64
static std::vector< CryptoSuiteDefinition > CryptoSuites
List of accepted Crypto-Suites as defined in RFC4568 (6.2)
bool regex_search(string_view sv, svmatch &m, const regex &e, regex_constants::match_flag_type flags=regex_constants::match_default)