Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
savoirfairelinux
jami-daemon
Commits
bebe12d4
Commit
bebe12d4
authored
May 14, 2014
by
Vittorio Giovara
Committed by
Tristan Matthews
May 15, 2014
Browse files
Rewrite audio srtp key generation and base64 functions internally
Change-Id: I81e4c27599c8e41d79d6d96d35798db0047f2922 Refs: #47142
parent
cf8f7b7b
Changes
4
Hide whitespace changes
Inline
Side-by-side
daemon/src/audio/audiortp/Makefile.am
View file @
bebe12d4
...
...
@@ -19,4 +19,5 @@ libaudiortp_la_SOURCES = \
audio_rtp_stream.h
\
audio_rtp_factory.h
\
audio_symmetric_rtp_session.h
\
audio_srtp_session.h
audio_srtp_session.h
\
base64.c base64.h
daemon/src/audio/audiortp/audio_srtp_session.cpp
View file @
bebe12d4
...
...
@@ -30,15 +30,10 @@
#include
"audio_srtp_session.h"
#include
"logger.h"
#include
"array_size.h"
#include
"base64.h"
#include
<algorithm>
#include
<openssl/sha.h>
#include
<openssl/hmac.h>
#include
<openssl/evp.h>
#include
<openssl/bio.h>
#include
<openssl/buffer.h>
#include
<openssl/rand.h>
#include
<random>
#include
<cstdio>
#include
<cstring>
...
...
@@ -51,53 +46,27 @@
namespace
sfl
{
namespace
{
std
::
string
encodeBase64
(
unsigned
char
*
input
,
int
length
)
{
// init decoder
BIO
*
b64
=
BIO_new
(
BIO_f_base64
());
BIO_set_flags
(
b64
,
BIO_FLAGS_BASE64_NO_NL
);
// init internal buffer
BIO
*
bmem
=
BIO_new
(
BIO_s_mem
());
// create decoder chain
b64
=
BIO_push
(
b64
,
bmem
);
BIO_write
(
b64
,
input
,
length
);
// BIO_flush (b64);
// get pointer to data
BUF_MEM
*
bptr
=
0
;
BIO_get_mem_ptr
(
b64
,
&
bptr
);
std
::
string
output
(
bptr
->
data
,
bptr
->
length
);
BIO_free_all
(
bmem
);
std
::
string
encodeBase64
(
unsigned
char
*
input
,
int
length
)
{
size_t
output_length
;
uint8_t
*
encoded_str
=
base64_encode
(
input
,
length
,
&
output_length
);
if
(
!
encoded_str
)
THROW_ERROR
(
AudioSrtpException
,
"Out of memory for base64 operation"
);
std
::
string
output
((
const
char
*
)
encoded_str
,
output_length
);
free
(
encoded_str
);
return
output
;
}
std
::
vector
<
char
>
decodeBase64
(
unsigned
char
*
input
,
int
length
)
std
::
string
decodeBase64
(
unsigned
char
*
input
,
int
length
)
{
BIO
*
b64
,
*
bmem
;
// init decoder and read-only BIO buffer
b64
=
BIO_new
(
BIO_f_base64
());
BIO_set_flags
(
b64
,
BIO_FLAGS_BASE64_NO_NL
);
// init internal buffer
bmem
=
BIO_new_mem_buf
(
input
,
length
);
// create encoder chain
bmem
=
BIO_push
(
b64
,
bmem
);
std
::
vector
<
char
>
buffer
(
length
,
0
);
BIO_read
(
bmem
,
buffer
.
data
(),
length
);
BIO_free_all
(
bmem
);
return
buffer
;
size_t
output_length
;
uint8_t
*
decoded_str
=
base64_decode
(
input
,
length
,
&
output_length
);
if
(
!
decoded_str
)
THROW_ERROR
(
AudioSrtpException
,
"Out of memory for base64 operation"
);
std
::
string
output
((
const
char
*
)
decoded_str
,
output_length
);
free
(
decoded_str
);
return
output
;
}
// Fills the array dest with length random bytes
...
...
@@ -105,12 +74,16 @@ void bufferFillMasterKey(std::vector<uint8>& dest)
{
DEBUG
(
"Init local master key"
);
// Prepare pseudo random generationusing Mersenne Twister
std
::
mt19937
eng
;
std
::
uniform_int_distribution
<
uint8_t
>
dist
(
0
,
255
);
// Allocate memory for key
std
::
vector
<
unsigned
char
>
random_key
(
dest
.
size
());
//
Generate ryptographically strong pseudo-random bytes
if
(
RAND_bytes
(
random_key
.
data
(),
dest
.
size
()
)
!=
1
)
DEBUG
(
"Error occured while generating cryptographically strong pseudo-random key"
);
//
Fill the key
for
(
int
i
=
0
;
i
<
dest
.
size
()
;
i
++
)
random_key
[
i
]
=
dist
(
eng
);
std
::
copy
(
random_key
.
begin
(),
random_key
.
end
(),
dest
.
begin
());
}
...
...
@@ -118,14 +91,18 @@ void bufferFillMasterKey(std::vector<uint8>& dest)
// Fills the array dest with length random bytes
void
bufferFillMasterSalt
(
std
::
vector
<
uint8
>&
dest
)
{
DEBUG
(
"Init local master key"
);
DEBUG
(
"Init local master salt"
);
// Prepare pseudo random generation using Mersenne Twister
std
::
mt19937
eng
;
std
::
uniform_int_distribution
<
uint8_t
>
dist
(
0
,
255
);
// Allocate memory for key
std
::
vector
<
unsigned
char
>
random_key
(
dest
.
size
());
//
Generate ryptographically strong pseudo-random bytes
if
(
RAND_bytes
(
random_key
.
data
(),
dest
.
size
()
)
!=
1
)
DEBUG
(
"Error occured while generating cryptographically strong pseudo-random key"
);
//
Fill the key
for
(
int
i
=
0
;
i
<
dest
.
size
()
;
i
++
)
random_key
[
i
]
=
dist
(
eng
);
std
::
copy
(
random_key
.
begin
(),
random_key
.
end
(),
dest
.
begin
());
}
...
...
@@ -276,14 +253,11 @@ void AudioSrtpSession::unBase64ConcatenatedKeys(std::string base64keys)
remoteMasterKey_
.
resize
(
sfl
::
CryptoSuites
[
remoteCryptoSuite_
].
masterKeyLength
/
BITS_PER_BYTE
);
remoteMasterSalt_
.
resize
(
sfl
::
CryptoSuites
[
remoteCryptoSuite_
].
masterSaltLength
/
BITS_PER_BYTE
);
// pointer to binary data
char
*
dataptr
=
(
char
*
)
base64keys
.
data
();
// decode concatenated binary keys
std
::
vector
<
char
>
output
(
decodeBase64
((
u
nsigned
char
*
)
dataptr
,
strlen
(
dataptr
)));
std
::
string
output
(
decodeBase64
((
u
int8_t
*
)
base64keys
.
data
(),
base64keys
.
size
(
)));
// copy master and slt respectively
const
std
::
vector
<
char
>
::
iterator
key_end
=
output
.
begin
()
+
remoteMasterKey_
.
size
();
const
std
::
string
::
iterator
key_end
=
output
.
begin
()
+
remoteMasterKey_
.
size
();
if
(
key_end
>
output
.
end
()
or
(
size_t
)
std
::
distance
(
key_end
,
output
.
end
())
>
remoteMasterSalt_
.
size
())
...
...
daemon/src/audio/audiortp/base64.c
0 → 100644
View file @
bebe12d4
/*
* Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#include
<stdint.h>
#include
<stdlib.h>
/* Mainly based on the following stackoverflow question:
* http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
*/
static
const
uint8_t
encoding_table
[]
=
{
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
,
'G'
,
'H'
,
'I'
,
'J'
,
'K'
,
'L'
,
'M'
,
'N'
,
'O'
,
'P'
,
'Q'
,
'R'
,
'S'
,
'T'
,
'U'
,
'V'
,
'W'
,
'X'
,
'Y'
,
'Z'
,
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
,
'g'
,
'h'
,
'i'
,
'j'
,
'k'
,
'l'
,
'm'
,
'n'
,
'o'
,
'p'
,
'q'
,
'r'
,
's'
,
't'
,
'u'
,
'v'
,
'w'
,
'x'
,
'y'
,
'z'
,
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'+'
,
'/'
};
static
const
int
mod_table
[]
=
{
0
,
2
,
1
};
uint8_t
*
base64_encode
(
const
uint8_t
*
data
,
size_t
input_length
,
size_t
*
output_length
)
{
int
i
,
j
;
uint8_t
*
encoded_data
;
*
output_length
=
4
*
((
input_length
+
2
)
/
3
);
encoded_data
=
(
uint8_t
*
)
malloc
(
*
output_length
);
if
(
encoded_data
==
NULL
)
return
NULL
;
for
(
i
=
0
,
j
=
0
;
i
<
input_length
;
)
{
uint8_t
octet_a
=
i
<
input_length
?
data
[
i
++
]
:
0
;
uint8_t
octet_b
=
i
<
input_length
?
data
[
i
++
]
:
0
;
uint8_t
octet_c
=
i
<
input_length
?
data
[
i
++
]
:
0
;
uint32_t
triple
=
(
octet_a
<<
0x10
)
+
(
octet_b
<<
0x08
)
+
octet_c
;
encoded_data
[
j
++
]
=
encoding_table
[(
triple
>>
3
*
6
)
&
0x3F
];
encoded_data
[
j
++
]
=
encoding_table
[(
triple
>>
2
*
6
)
&
0x3F
];
encoded_data
[
j
++
]
=
encoding_table
[(
triple
>>
1
*
6
)
&
0x3F
];
encoded_data
[
j
++
]
=
encoding_table
[(
triple
>>
0
*
6
)
&
0x3F
];
}
for
(
i
=
0
;
i
<
mod_table
[
input_length
%
3
];
i
++
)
encoded_data
[
*
output_length
-
1
-
i
]
=
'='
;
return
encoded_data
;
}
uint8_t
*
base64_decode
(
const
uint8_t
*
data
,
size_t
input_length
,
size_t
*
output_length
)
{
int
i
,
j
;
uint8_t
decoding_table
[
256
];
unsigned
char
*
decoded_data
;
for
(
i
=
0
;
i
<
64
;
i
++
)
decoding_table
[(
uint8_t
)
encoding_table
[
i
]]
=
i
;
if
(
input_length
%
4
!=
0
)
return
NULL
;
*
output_length
=
input_length
/
4
*
3
;
if
(
data
[
input_length
-
1
]
==
'='
)
(
*
output_length
)
--
;
if
(
data
[
input_length
-
2
]
==
'='
)
(
*
output_length
)
--
;
decoded_data
=
(
unsigned
char
*
)
malloc
(
*
output_length
);
if
(
decoded_data
==
NULL
)
return
NULL
;
for
(
i
=
0
,
j
=
0
;
i
<
input_length
;)
{
uint8_t
sextet_a
=
data
[
i
]
==
'='
?
0
&
i
++
:
decoding_table
[
data
[
i
++
]];
uint8_t
sextet_b
=
data
[
i
]
==
'='
?
0
&
i
++
:
decoding_table
[
data
[
i
++
]];
uint8_t
sextet_c
=
data
[
i
]
==
'='
?
0
&
i
++
:
decoding_table
[
data
[
i
++
]];
uint8_t
sextet_d
=
data
[
i
]
==
'='
?
0
&
i
++
:
decoding_table
[
data
[
i
++
]];
uint32_t
triple
=
(
sextet_a
<<
3
*
6
)
+
(
sextet_b
<<
2
*
6
)
+
(
sextet_c
<<
1
*
6
)
+
(
sextet_d
<<
0
*
6
);
if
(
j
<
*
output_length
)
decoded_data
[
j
++
]
=
(
triple
>>
2
*
8
)
&
0xFF
;
if
(
j
<
*
output_length
)
decoded_data
[
j
++
]
=
(
triple
>>
1
*
8
)
&
0xFF
;
if
(
j
<
*
output_length
)
decoded_data
[
j
++
]
=
(
triple
>>
0
*
8
)
&
0xFF
;
}
return
decoded_data
;
}
daemon/src/audio/audiortp/base64.h
0 → 100644
View file @
bebe12d4
/*
* Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#ifndef H_BASE64
#define H_BASE64
#ifdef __cplusplus
extern
"C"
{
#endif
#include
"stdint.h"
/**
* Encode a buffer in base64.
*
* @param data the input buffer
* @param input_length the input length
* @param output_length the resulting output length
* @return a base64-encoded buffer
*
* @note callers should free the returned memory
*/
uint8_t
*
base64_encode
(
const
uint8_t
*
data
,
size_t
input_length
,
size_t
*
output_length
);
/**
* Decode a base64 buffer.
*
* @param data the input buffer
* @param input_length the input length
* @param output_length the resulting output length
* @return a buffer
*
* @note callers should free the returned memory
*/
uint8_t
*
base64_decode
(
const
uint8_t
*
data
,
size_t
input_length
,
size_t
*
output_length
);
#ifdef __cplusplus
}
#endif
#endif // H_BASE64
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment