Skip to content
Snippets Groups Projects
Commit 9b2f1ef7 authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files

Merge branch 'master' of...

parents 7b0f48c0 d551f336
No related branches found
No related tags found
No related merge requests found
......@@ -18,7 +18,7 @@
#include "SdesNegotiator.h"
#include "regex.h"
#include "Regex.h"
#include <iostream>
#include <sstream>
......@@ -34,134 +34,119 @@ namespace sfl {
std::string sessionParams;
};
SdesNegotiator::SdesNegotiator(const std::vector<CryptoSuiteDefinition>& localCapabilites, const std::vector<std::string>& remoteAttribute) :
SdesNegotiator::SdesNegotiator(const std::vector<CryptoSuiteDefinition>& localCapabilites,
const std::vector<std::string>& remoteAttribute) :
_remoteAttribute(remoteAttribute),
_localCapabilities(localCapabilites)
{
}
void SdesNegotiator::parse(void)
{
// The patterns below try to follow
// the ABNF grammar rules described in
// RFC4568 section 9.2 with the general
// syntax :
//a=crypto:tag 1*WSP crypto-suite 1*WSP key-params *(1*WSP session-param)
CryptoAttribute * SdesNegotiator::tokenize(const std::string& attributeLine)
{
// Split the line into at most
// 4 components corresponding to
// a=crypto:<tag> <crypto-suite> <key-params> [<session-params>]
size_t pos;
const char WSP = ' ';
std::string line(attributeLine);
pos = line.rfind(WSP);
std::string token;
std::vector<std::string> lineSplitted;
Regex tagPattern, cryptoSuitePattern, keyParamsPattern, sessionParamPattern;
while (pos != std::string::npos && lineSplitted.size() != 4) {
try {
tagPattern = "^a=crypto:(?P<tag>[0-9]{1,9})";
token = line.substr(pos+1);
lineSplitted.push_back(token);
cryptoSuitePattern = "[\x20\x09]+(?P<cryptoSuite>AES_CM_128_HMAC_SHA1_80|" \
"AES_CM_128_HMAC_SHA1_32|" \
"F8_128_HMAC_SHA1_80|" \
"[A-Za-z0-9_]+)"; // srtp-crypto-suite-ext
token = line.substr(0, pos);
line = token;
pos = line.rfind(WSP);
keyParamsPattern = "[\x20\x09]+(?P<srtpKeyMethod>inline|[A-Za-z0-9_]+)\\:" \
"(?P<srtpKeyInfo>[A-Za-z0-9\x2B\x2F\x3D]+)\\|" \
"2\\^(?P<lifetime>[0-9]+)\\|" \
"(?P<mkiValue>[0-9]+)\\:" \
"(?P<mkiLength>[0-9]{1,3})\\;?";
sessionParamPattern = "[\x20\x09]+(?P<sessionParam>(kdr\\=[0-9]{1,2}|" \
"UNENCRYPTED_SRTP|" \
"UNENCRYPTED_SRTCP|" \
"UNAUTHENTICATED_SRTP|" \
"FEC_ORDER=(?P<fecOrder>FEC_SRTP|SRTP_FEC)|" \
"FEC_KEY=(?P<fecKey>" + keyParamsPattern.getPattern() + ")|" \
"WSH=(?P<wsh>[0-9]{1,2})|" \
"(?<!\\-)[[:graph:]]+))*"; // srtp-session-extension
} catch(compile_error& exception) {
throw parse_error("A compile exception occured on a pattern.");
}
lineSplitted.push_back(line);
// Take each line from the vector
// and parse its content
std::vector<std::string>::iterator iter;
for (iter = _remoteAttribute.begin(); iter != _remoteAttribute.end(); iter++) {
CryptoAttribute * cryptoLine;
// Build up the new CryptoAttribute
try {
cryptoLine = new CryptoAttribute();
} catch (std::bad_alloc&) {
std::cerr << "Failed create new CryptoLine" << std::endl;
throw;
}
std::reverse(lineSplitted.begin(), lineSplitted.end());
cryptoLine->tag = lineSplitted.at(0);
cryptoLine->cryptoSuite = lineSplitted.at(1);
cryptoLine->keyParams = lineSplitted.at(2);
if (lineSplitted.size() == 4) {
cryptoLine->sessionParams = lineSplitted.at(3);
}
return cryptoLine;
}
bool SdesNegotiator::parse(void)
{
std::vector<std::string>::iterator iter;
for (iter = _remoteAttribute.begin(); iter != _remoteAttribute.end(); iter++) {
// Split the line into components
// and build up a CryptoAttribute
// structure.
CryptoAttribute * cryptoLine;
std::cout << (*iter) << std::endl;
// Check if the attribute
// starts with a=crypto
// and get the tag for this line
tagPattern << (*iter);
try {
cryptoLine = tokenize((*iter));
} catch (...) {
std::cerr << "An exception occured" << std::endl;
}
// Check if we have the right kind of attribute
if (cryptoLine->tag.find("a=crypto:") != 0) {
std::cout << cryptoLine->tag << std::endl;
throw std::runtime_error("Bad syntax");
}
// Find index
size_t tagPos;
tagPos = cryptoLine->tag.find(":");
if (tagPos == std::string::npos) {
throw std::runtime_error("Bad syntax");
std::string tag = tagPattern.group("tag");
std::cout << "tag = " << tag << std::endl;
} catch (match_error& exception) {
throw parse_error("Error while parsing the tag field");
}
std::string index;
index = cryptoLine->tag.substr(tagPos+1);
std::cout << "index:" << index << std::endl;
// Make sure its less than 9 digit long
if (index.length() > 9) {
throw std::runtime_error("Index too long.");
// Check if the crypto
// suite is valid and retreive
// its value.
cryptoSuitePattern << (*iter);
try {
std::string cryptoSuite = cryptoSuitePattern.group("cryptoSuite");
std::cout << "crypto-suite = " << cryptoSuite << std::endl;
} catch (match_error& exception) {
throw parse_error("Error while parsing the crypto-suite field");
}
int tagIndex;
std::istringstream ss(index);
ss >> tagIndex;
if (ss.fail()) {
throw std::runtime_error("Bad conversion");
// Parse one or more key-params
// field.
keyParamsPattern << (*iter);
try {
std::string srtpKeyMethod = keyParamsPattern.group("srtpKeyMethod");
std::cout << "srtp-key-method = " << srtpKeyMethod << std::endl;
std::string srtpKeyInfo = keyParamsPattern.group("srtpKeyInfo");
std::cout << "srtp-key-info = " << srtpKeyInfo << std::endl;
std::string lifetime = keyParamsPattern.group("lifetime");
std::cout << "lifetime = " << lifetime << std::endl;
std::string mkiValue = keyParamsPattern.group("mkiValue");
std::cout << "mkiValue = " << mkiValue << std::endl;
std::string mkiLength = keyParamsPattern.group("mkiLength");
std::cout << "mkiLength = " << mkiLength << std::endl;
} catch (match_error& exception) {
throw parse_error("Error while parsing the key-params field");
}
// Check if the given crypto-suite is valid
// by looking in our list.
// Extension: 1*(ALPHA / DIGIT / "_")
int i;
for (i = 0; i < 3; i++) {
if (cryptoLine->cryptoSuite.compare(CryptoSuites[i].name) == 0) {
break;
}
}
// Parse the optional session-param
// field
sessionParamPattern << (*iter);
try {
std::string sessionParam = sessionParamPattern.group("sessionParam");
std::cout << "srtp-session-param = " << sessionParam << std::endl;
} catch (not_found& exception){
// Thats totally find, do nothing
} catch (match_error& exception) {
throw parse_error("Error while parsing the crypto-suite field");
}
if (i == 3) {
std::cout << "This is an unhandled extension\n" << std::endl;
}
// Parse the key-params
// Check it starts with a valid key-method
if (cryptoLine->keyParams.find("inline:") != 0) {
throw std::runtime_error("Unsupported key-method\n");
}
KeyMethod method = Inline;
// Find concatenated key and salt values
}
}
}
......
......@@ -18,10 +18,23 @@
#ifndef __SFL_SDES_NEGOTIATOR_H__
#define __SFL_SDES_NEGOTIATOR_H__
#include <vector>
#include <stdexcept>
#include <string>
#include <vector>
namespace sfl {
/**
* General exception object that is thrown when
* an error occured with a regular expression
* operation.
*/
class parse_error : public std::invalid_argument
{
public:
explicit parse_error(const std::string& error) :
std::invalid_argument(error) {}
};
enum CipherMode {
AESCounterMode,
......@@ -99,7 +112,7 @@ namespace sfl {
private:
bool parse(void);
void parse(void);
CryptoAttribute * tokenize(const std::string& attributeLine);
};
}
......
#include "SdesNegotiator.h"
#include <vector>
#include <iostream>
int main(void)
{
std::vector<sfl::CryptoSuiteDefinition> localCapabilities;
std::vector<std::string> remoteOffer;
remoteOffer.push_back("a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32");
remoteOffer.push_back("a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32");
sfl::SdesNegotiator sdesNegotiator(localCapabilities, remoteOffer);
sdesNegotiator.negotiate();
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment