pax_global_header 0000666 0000000 0000000 00000000064 13641445014 0014514 g ustar 00root root 0000000 0000000 52 comment=9e63125e8715c6198ca1185d4e0acb6e1ab0c7ff
bzrtp-4.4.13/ 0000775 0000000 0000000 00000000000 13641445014 0012746 5 ustar 00root root 0000000 0000000 bzrtp-4.4.13/.gitignore 0000664 0000000 0000000 00000000500 13641445014 0014731 0 ustar 00root root 0000000 0000000 Makefile
Makefile.in
aclocal.m4
autom4te.cache
compile
config.guess
config.h
config.h.in
config.log
config.status
config.sub
configure
depcomp
install-sh
intltool-extract
intltool-merge
intltool-update
libtool
ltmain.sh
missing
mkinstalldirs
stamp-h1
*.o
*.exe
*.zip
*~
*.lo
*.la
*.swp
.deps
.libs
INSTALL
m4
bzrtp.spec
bzrtp-4.4.13/Android.mk 0000664 0000000 0000000 00000001435 13641445014 0014662 0 ustar 00root root 0000000 0000000 LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -DHAVE_LIBXML2
LOCAL_MODULE := libbzrtp
LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES = \
src/bzrtp.c \
src/cryptoUtils.c \
src/packetParser.c \
src/stateMachine.c \
src/zidCache.c \
src/pgpwords.c
LOCAL_STATIC_LIBRARIES += liblpxml2
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/../externals/libxml2/include \
$(LOCAL_PATH)/../externals/build/libxml2
ifeq ($(BUILD_BCTOOLBOX_MBEDTLS),1)
LOCAL_SRC_FILES += src/cryptoMbedtls.c
LOCAL_STATIC_LIBRARIES += mbedtls
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../externals/mbedtls/include
else
LOCAL_SRC_FILES += src/cryptoPolarssl.c
LOCAL_STATIC_LIBRARIES += polarssl
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../externals/polarssl/include
endif
include $(BUILD_STATIC_LIBRARY)
bzrtp-4.4.13/CHANGELOG.md 0000664 0000000 0000000 00000000537 13641445014 0014564 0 ustar 00root root 0000000 0000000 # Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.0.0] - 2015-03-15
### Added
- Initial release.
### Changed
### Removed
bzrtp-4.4.13/CMakeLists.txt 0000664 0000000 0000000 00000011252 13641445014 0015507 0 ustar 00root root 0000000 0000000 ############################################################################
# CMakeLists.txt
# Copyright (C) 2010-2019 Belledonne Communications, Grenoble France
#
############################################################################
#
# 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 2
# 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.
#
############################################################################
cmake_minimum_required(VERSION 3.1)
project(bzrtp VERSION 4.4.0 LANGUAGES C CXX)
option(ENABLE_SHARED "Build shared library." YES)
option(ENABLE_STATIC "Build static library." YES)
option(ENABLE_ZIDCACHE "Turn on compilation of ZID cache, request sqlite" YES)
option(ENABLE_STRICT "Build with strict compile options." YES)
option(ENABLE_TESTS "Enable compilation of unit tests." NO)
option(ENABLE_EXPORTEDKEY_V1_0_RETROCOMPATIBILITY "Enable support for Limev1 with older version of bzrtp(before v1.06)" YES)
option(ENABLE_PACKAGE_SOURCE "Create 'package_source' target for source archive making (CMake >= 3.11)" OFF)
if(NOT CMAKE_INSTALL_RPATH AND CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR})
message(STATUS "Setting install rpath to ${CMAKE_INSTALL_RPATH}")
endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(MSVC_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/MSVC")
if(MSVC)
list(APPEND CMAKE_REQUIRED_INCLUDES ${MSVC_INCLUDE_DIR})
endif()
include(GNUInstallDirs)
include(CheckLibraryExists)
check_library_exists("m" "sqrt" "" HAVE_SQRT)
find_package(bctoolbox 0.0.3 REQUIRED OPTIONAL_COMPONENTS tester CONFIG)
if(ENABLE_ZIDCACHE)
find_package(Sqlite3 REQUIRED)
# Also check if we have libxml2, as we need it for migration purpose
find_package(XML2)
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/config.h PROPERTIES GENERATED ON)
add_definitions("-DHAVE_CONFIG_H")
set(STRICT_OPTIONS_CPP )
if(NOT MSVC)
list(APPEND STRICT_OPTIONS_CPP "-Wall")
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
list(APPEND STRICT_OPTIONS_CPP "-Qunused-arguments")
endif()
if(ENABLE_STRICT)
list(APPEND STRICT_OPTIONS_CPP "-Werror" "-Wextra" "-Wno-unused-parameter" "-Wno-missing-field-initializers")
endif()
endif()
if(STRICT_OPTIONS_CPP)
list(REMOVE_DUPLICATES STRICT_OPTIONS_CPP)
string(REPLACE ";" " " STRICT_OPTIONS_CPP "${STRICT_OPTIONS_CPP}")
endif()
set(BZRTP_CPPFLAGS ${BCTOOLBOX_CPPFLAGS})
if(ENABLE_STATIC)
list(APPEND BZRTP_CPPFLAGS "-DBZRTP_STATIC")
endif()
if(BZRTP_CPPFLAGS)
list(REMOVE_DUPLICATES BZRTP_CPPFLAGS)
add_definitions(${BZRTP_CPPFLAGS})
endif()
include_directories(
include
${CMAKE_CURRENT_BINARY_DIR}
)
if(MSVC)
include_directories(${MSVC_INCLUDE_DIR})
endif()
if(ENABLE_ZIDCACHE)
add_definitions("-DZIDCACHE_ENABLED")
if(XML2_FOUND)
add_definitions("-DHAVE_LIBXML2")
endif()
endif()
if (ENABLE_EXPORTEDKEY_V1_0_RETROCOMPATIBILITY)
add_definitions("-DSUPPORT_EXPORTEDKEY_V010000")
endif()
set(EXPORT_TARGETS_NAME "bzrtp")
add_subdirectory(include)
add_subdirectory(src)
if(ENABLE_TESTS)
enable_testing()
add_subdirectory(test)
endif()
include(CMakePackageConfigHelpers)
set(CONFIG_PACKAGE_LOCATION "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/cmake")
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_TARGETS_NAME}ConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
export(EXPORT ${EXPORT_TARGETS_NAME}Targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_TARGETS_NAME}Targets.cmake"
)
configure_package_config_file(cmake/BZRTPConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_TARGETS_NAME}Config.cmake"
INSTALL_DESTINATION ${CONFIG_PACKAGE_LOCATION}
NO_SET_AND_CHECK_MACRO
)
install(EXPORT ${EXPORT_TARGETS_NAME}Targets
FILE ${EXPORT_TARGETS_NAME}Targets.cmake
DESTINATION ${CONFIG_PACKAGE_LOCATION}
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_TARGETS_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_TARGETS_NAME}ConfigVersion.cmake"
DESTINATION ${CONFIG_PACKAGE_LOCATION}
)
if (ENABLE_PACKAGE_SOURCE)
add_subdirectory(build)
endif()
bzrtp-4.4.13/LICENSE.txt 0000664 0000000 0000000 00000077331 13641445014 0014604 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
bzrtp-4.4.13/Makefile.am 0000664 0000000 0000000 00000000521 13641445014 0015000 0 ustar 00root root 0000000 0000000 ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src include test
EXTRA_DIST= \
CMakeLists.txt \
cmake/BZRTPConfig.cmake.in \
cmake/FindXML2.cmake \
config.h.cmake \
include/CMakeLists.txt \
src/CMakeLists.txt \
test/CMakeLists.txt \
README.md
test:
cd test && $(MAKE) test
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libbzrtp.pc
bzrtp-4.4.13/README.md 0000664 0000000 0000000 00000005611 13641445014 0014230 0 ustar 00root root 0000000 0000000 [](https://gitlab.linphone.org/BC/public/bzrtp/commits/master)
BZRTP
=====
What's BZRTP
------------
BZRTP is an opensource implementation of ZRTP keys exchange protocol.
The library written in C 89 is fully portable and can be executed on many platforms including both ARM processor and x86.
Licensing: The source code is licensed under GPLv2.
License
--------
BZRTP library is dual-licensed and can be distributed either under a GNU GPLv3 license (open source, see *LICENSE.txt*) or under a proprietary
license (closed source).
Copyright © Belledonne Communications SARL
Johan Pascal is the original author of BZRTP.
Compatibility with RFC6189 - ZRTP: Media Path Key Agreement for Unicast Secure RTP
----------------------------------------------------------------------------------
### Mandatory but NOT implemented
* Sas Relay mechanism (section 7.3)
* Error message generation, emission or reception(which doesn't imply any security problem, they are mostly for debug purpose)
### Optional and implementd
* multistream mode
* cacheless implementation
* zrtp-hash attribute in SDP
### Optional and NOT implemented
* Go Clear/Clear ACK messages
* SAS signing
### Supported Algorithms
* Hash : SHA-256, SHA-384
* Cipher : AES-128, AES-256
* SAS rendering: B32, B256(PGP word list)
* Auth Tag : HS32, HS80
* Key Agreement : DH-2048, DH-3072, X25519, X448
*Note*: X25519 and X448 Key agreements(RFC7748) are not part of RFC6189 and supported only when *bctoolbox[1]* is linking *libdecaf[2]*
Dependencies
------------
- *bctoolbox[1]*: portability layer and crypto function abstraction
Build BZRTP
-----------
cmake . -DCMAKE_INSTALL_PREFIX= -DCMAKE_PREFIX_PATH=
make
make install
Build options
-------------
* `CMAKE_INSTALL_PREFIX=` : install prefix
* `CMAKE_PREFIX_PATH=` : column-separated list of prefixes where to search for dependencies
* `ENABLE_SHARED=NO` : do not build the shared library
* `ENABLE_STATIC=NO` : do not build the static library
* `ENABLE_STRICT=NO` : build without the strict compilation flags
* `ENABLE_TESTS=YES` : build non-regression tests
Notes for packagers
-------------------
Our CMake scripts may automatically add some paths into research paths of generated binaries.
To ensure that the installed binaries are striped of any rpath, use `-DCMAKE_SKIP_INSTALL_RPATH=ON`
while you invoke cmake.
Rpm packaging
bzrtp can be generated with cmake3 using the following command:
mkdir WORK
cd WORK
cmake3 ../
make package_source
rpmbuild -ta --clean --rmsource --rmspec bzrtp--.tar.gz
----------------------------------
* [1] git://git.linphone.org/bctoolbox.git or
* [2]
bzrtp-4.4.13/autogen.sh 0000775 0000000 0000000 00000002730 13641445014 0014751 0 ustar 00root root 0000000 0000000 #!/bin/sh
##
## Copyright (c) 2014-2019 Belledonne Communications SARL.
##
## This file is part of bzrtp.
##
## 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, see .
##
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
THEDIR=`pwd`
cd $srcdir
#AM_VERSION="1.11"
if ! type aclocal-$AM_VERSION 1>/dev/null 2>&1; then
AUTOMAKE=automake
ACLOCAL=aclocal
else
ACLOCAL=aclocal-${AM_VERSION}
AUTOMAKE=automake-${AM_VERSION}
fi
if test -f /opt/local/bin/glibtoolize ; then
# darwin
LIBTOOLIZE=/opt/local/bin/glibtoolize
else
LIBTOOLIZE=libtoolize
fi
if test -d /opt/local/share/aclocal ; then
ACLOCAL_ARGS="-I /opt/local/share/aclocal"
fi
if test -d /share/aclocal ; then
ACLOCAL_ARGS="-I /share/aclocal"
fi
echo "Generating build scripts for BZRtp: ZRTP engine"
set -x
$LIBTOOLIZE --copy --force
$ACLOCAL $ACLOCAL_ARGS
#autoheader
$AUTOMAKE --force-missing --add-missing --copy
autoconf
cd $THEDIR
bzrtp-4.4.13/build/ 0000775 0000000 0000000 00000000000 13641445014 0014045 5 ustar 00root root 0000000 0000000 bzrtp-4.4.13/build/CMakeLists.txt 0000664 0000000 0000000 00000002465 13641445014 0016614 0 ustar 00root root 0000000 0000000 ############################################################################
# CMakeLists.txt
# Copyright (C) 2010-2019 Belledonne Communications, Grenoble France
#
############################################################################
#
# 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 2
# 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.
#
############################################################################
cmake_minimum_required(VERSION 3.11) # we need CMake 3.11 for defining 'package_source' target as custom target
if(NOT CPACK_PACKAGE_NAME)
set(CPACK_PACKAGE_NAME "bzrtp")
ENDIF()
set(CPACK_SOURCE_IGNORE_FILES
"${CMAKE_BINARY_DIR}"
"^${PROJECT_SOURCE_DIR}/.git*"
)
bc_make_package_source_target()
bzrtp-4.4.13/build/rpm/ 0000775 0000000 0000000 00000000000 13641445014 0014643 5 ustar 00root root 0000000 0000000 bzrtp-4.4.13/build/rpm/bzrtp.spec.cmake 0000775 0000000 0000000 00000005537 13641445014 0017754 0 ustar 00root root 0000000 0000000 # -*- rpm-spec -*-
%define _prefix @CMAKE_INSTALL_PREFIX@
%define pkg_prefix @BC_PACKAGE_NAME_PREFIX@
%define package_name @CPACK_PACKAGE_NAME@-${FULL_VERSION}
# re-define some directories for older RPMBuild versions which don't. This messes up the doc/ dir
# taken from https://fedoraproject.org/wiki/Packaging:RPMMacros?rd=Packaging/RPMMacros
%define _datarootdir %{_prefix}/share
%define _datadir %{_datarootdir}
%define _docdir %{_datadir}/doc
Name: @CPACK_PACKAGE_NAME@
Version: ${RPM_VERSION}
Release: ${RPM_RELEASE}%{?dist}
Summary: BZRTP is an opensource implementation of ZRTP keys exchange protocol.
Group: Applications/Communications
License: GPL
URL: http://www.linphone.org
Source0: %{package_name}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
Requires: %{pkg_prefix}bctoolbox
%description
BZRTP is an opensource implementation of ZRTP keys exchange protocol.
The library written in C 89 is fully portable and can be executed on many platforms including both ARM processor and x86.
Licensing: The source code is licensed under GPLv2.
%package devel
Summary: Development libraries for bzrtp
Group: Development/Libraries
Requires: %{name} = %{version}-%{release}
%description devel
Libraries and headers required to develop software with bzrtp
%if 0%{?rhel} && 0%{?rhel} <= 7
%global cmake_name cmake3
%define ctest_name ctest3
%else
%global cmake_name cmake
%define ctest_name ctest
%endif
# This is for debian builds where debug_package has to be manually specified, whereas in centos it does not
%define custom_debug_package %{!?_enable_debug_packages:%debug_package}%{?_enable_debug_package:%{nil}}
%custom_debug_package
%prep
%setup -n %{package_name}
%build
%{expand:%%%cmake_name} . -DCMAKE_BUILD_TYPE=@CMAKE_BUILD_TYPE@ -DCMAKE_PREFIX_PATH:PATH=%{_prefix} @RPM_ALL_CMAKE_OPTIONS@
make %{?_smp_mflags}
%install
make install DESTDIR=%{buildroot}
# Dirty workaround to give exec rights for all shared libraries. Debian packaging needs this
# TODO : set CMAKE_INSTALL_SO_NO_EXE for a cleaner workaround
chmod +x `find %{buildroot} *.so.*`
%check
%{ctest_name} -V %{?_smp_mflags}
%clean
rm -rf $RPM_BUILD_ROOT
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr(-,root,root)
%doc CHANGELOG.md LICENSE.txt README.md
%{_libdir}/*.so.*
%files devel
%defattr(-,root,root)
%{_includedir}/bzrtp
%if @ENABLE_STATIC@
%{_libdir}/libbzrtp.a
%endif
%if @ENABLE_SHARED@
%{_libdir}/libbzrtp.so
%endif
%{_datadir}/bzrtp/cmake/BZRTPConfig*.cmake
%{_datadir}/bzrtp/cmake/BZRTPTargets*.cmake
%changelog
* Tue Nov 27 2018 ronan.abhamon
- Do not set CMAKE_INSTALL_LIBDIR and never with _libdir!
* Wed Jul 19 2017 jehan.monnier
- Initial RPM release.
bzrtp-4.4.13/cmake/ 0000775 0000000 0000000 00000000000 13641445014 0014026 5 ustar 00root root 0000000 0000000 bzrtp-4.4.13/cmake/BZRTPConfig.cmake.in 0000664 0000000 0000000 00000003627 13641445014 0017474 0 ustar 00root root 0000000 0000000 ############################################################################
# BZRTPConfig.cmake
# Copyright (C) 2015 Belledonne Communications, Grenoble France
#
############################################################################
#
# 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 2
# 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.
#
############################################################################
#
# Config file for the bzrtp package.
# It defines the following variables:
#
# BZRTP_FOUND - system has bzrtp
# BZRTP_INCLUDE_DIRS - the bzrtp include directory
# BZRTP_LIBRARIES - The libraries needed to use bzrtp
# BZRTP_CPPFLAGS - The compilation flags needed to use bzrtp
@PACKAGE_INIT@
set(BZRTP_TARGETNAME bzrtp)
include("${CMAKE_CURRENT_LIST_DIR}/${BZRTP_TARGETNAME}Targets.cmake")
if(@ENABLE_SHARED@)
set(BZRTP_LIBRARIES ${BZRTP_TARGETNAME})
else()
if(TARGET ${BZRTP_TARGETNAME})
get_target_property(BZRTP_LIBRARIES ${BZRTP_TARGETNAME} LOCATION)
get_target_property(BZRTP_LINK_LIBRARIES ${BZRTP_TARGETNAME} INTERFACE_LINK_LIBRARIES)
if(BZRTP_LINK_LIBRARIES)
list(APPEND BZRTP_LIBRARIES ${BZRTP_LINK_LIBRARIES})
endif()
endif()
endif()
get_target_property(BZRTP_INCLUDE_DIRS ${BZRTP_TARGETNAME} INTERFACE_INCLUDE_DIRECTORIES)
set(BZRTP_CPPFLAGS @BZRTP_CPPFLAGS@)
set(BZRTP_FOUND 1)
bzrtp-4.4.13/cmake/FindSqlite3.cmake 0000664 0000000 0000000 00000003453 13641445014 0017162 0 ustar 00root root 0000000 0000000 ############################################################################
# FindSqlite3.cmake
# Copyright (C) 2014 Belledonne Communications, Grenoble France
#
############################################################################
#
# 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 2
# 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.
#
############################################################################
#
# - Find the sqlite3 include file and library
#
# SQLITE3_FOUND - system has sqlite3
# SQLITE3_INCLUDE_DIRS - the sqlite3 include directory
# SQLITE3_LIBRARIES - The libraries needed to use sqlite3
if(APPLE AND NOT IOS)
set(SQLITE3_HINTS "/usr")
endif()
if(SQLITE3_HINTS)
set(SQLITE3_LIBRARIES_HINTS "${SQLITE3_HINTS}/lib")
endif()
find_path(SQLITE3_INCLUDE_DIRS
NAMES sqlite3.h
HINTS "${SQLITE3_HINTS}"
PATH_SUFFIXES include
)
if(SQLITE3_INCLUDE_DIRS)
set(HAVE_SQLITE3_H 1)
endif()
find_library(SQLITE3_LIBRARIES
NAMES sqlite3
HINTS "${SQLITE3_LIBRARIES_HINTS}"
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Sqlite3
DEFAULT_MSG
SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES HAVE_SQLITE3_H
)
mark_as_advanced(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES HAVE_SQLITE3_H)
bzrtp-4.4.13/cmake/FindXML2.cmake 0000664 0000000 0000000 00000003354 13641445014 0016360 0 ustar 00root root 0000000 0000000 ############################################################################
# FindXML2.txt
# Copyright (C) 2015 Belledonne Communications, Grenoble France
#
############################################################################
#
# 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 2
# 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.
#
############################################################################
#
# - Find the libxml2 include file and library
#
# XML2_FOUND - system has libxml2
# XML2_INCLUDE_DIRS - the libxml2 include directory
# XML2_LIBRARIES - The libraries needed to use libxml2
if(APPLE AND NOT IOS)
set(XML2_HINTS "/usr")
endif()
if(XML2_HINTS)
set(XML2_LIBRARIES_HINTS "${XML2_HINTS}/lib")
endif()
find_path(XML2_INCLUDE_DIRS
NAMES libxml/xmlreader.h
HINTS "${XML2_HINTS}"
PATH_SUFFIXES include/libxml2
)
if(XML2_INCLUDE_DIRS)
set(HAVE_LIBXML_XMLREADER_H 1)
endif()
find_library(XML2_LIBRARIES
NAMES xml2
HINTS "${XML2_LIBRARIES_HINTS}"
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(XML2
DEFAULT_MSG
XML2_INCLUDE_DIRS XML2_LIBRARIES
)
mark_as_advanced(XML2_INCLUDE_DIRS XML2_LIBRARIES)
bzrtp-4.4.13/config.h.cmake 0000664 0000000 0000000 00000002226 13641445014 0015445 0 ustar 00root root 0000000 0000000 /***************************************************************************
* config.h.cmake
* Copyright (C) 2014 Belledonne Communications, Grenoble France
*
****************************************************************************
*
* 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 2
* 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.
*
****************************************************************************/
#cmakedefine HAVE_CU_ADD_SUITE
#cmakedefine HAVE_CU_GET_SUITE
#cmakedefine HAVE_CU_CURSES
#cmakedefine ZIDCACHE_ENABLED
#cmakedefine HAVE_LIBXML2
bzrtp-4.4.13/configure.ac 0000664 0000000 0000000 00000004750 13641445014 0015242 0 ustar 00root root 0000000 0000000 # -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_INIT([bzrtp],[1.0.5])
AC_PREREQ(2.63)
AC_CONFIG_SRCDIR([src/bzrtp.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([tar-ustar --warnings=no-portability foreign])
AC_PROG_CC(["xcrun clang" gcc])
LT_INIT(win32-dll shared disable-static)
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AC_ARG_ENABLE(strict,
[ --enable-strict Enable error on compilation warning [default=yes]],
[wall_werror=$enableval],
[wall_werror=yes]
)
# configure option to disable the tests
PKG_CHECK_MODULES(BCTOOLBOXTESTER, bctoolbox-tester, [found_pkg_config_bctoolboxtester=yes],[found_pkg_config_bctoolboxtester=no])
if test "$found_pkg_config_bctoolboxtester" = "no" ; then
AC_MSG_WARN([Could not find bctoolbox-tester wrapper, tests are not compiled.])
fi
dnl check bctoolbox
PKG_CHECK_MODULES(BCTOOLBOX, [bctoolbox] ,[bctoolbox_found=yes] ,foo=bar)
if test "$bctoolbox_found" != "yes" ; then
AC_MSG_ERROR([bctoolbox not found, aborting. ])
fi
dnl check for sqlite
PKG_CHECK_MODULES(SQLITE3,[sqlite3 >= 3.6.0],[found_sqlite=yes],[found_sqlite=no])
if test "$found_sqlite" != "yes" ; then
AC_MSG_WARN([sqlite3 not found. Disabling cache.])
else
AC_DEFINE(ZIDCACHE_ENABLED,1,[defined when libxml2 is available])
fi
dnl check libxml2
PKG_CHECK_MODULES(LIBXML2, [libxml-2.0] ,[libxml2_found=yes] ,foo=bar)
if test "$libxml2_found$found_sqlite" != "yesyes" ; then
AC_MSG_WARN([libxml2 not found. Disabling cache.])
else
AC_DEFINE(HAVE_LIBXML2,1,[defined when libxml2 is available])
fi
AC_ARG_ENABLE(tests,
[AS_HELP_STRING([--disable-tests], [Disable compilation of tests])],
[case "${enableval}" in
yes) tests_enabled=true ;;
no) tests_enabled=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --disable-tests) ;;
esac],
[tests_enabled=yes]
)
AM_CONDITIONAL(ENABLE_TESTS, test x$tests_enabled = xyes && test x$found_pkg_config_bctoolboxtester = xyes)
CFLAGS="$CFLAGS -Wall"
case $CC in
*clang*)
CFLAGS="$CFLAGS -Qunused-arguments"
;;
esac
if test $GCC = yes && test $wall_werror = yes; then
CFLAGS="$CFLAGS -Werror -Wextra -Wno-unused-parameter -Wno-missing-field-initializers "
fi
# Create the following files from their .in counterparts
AC_CONFIG_FILES([
Makefile
src/Makefile
include/Makefile
include/bzrtp/Makefile
test/Makefile
libbzrtp.pc
])
AC_OUTPUT
bzrtp-4.4.13/include/ 0000775 0000000 0000000 00000000000 13641445014 0014371 5 ustar 00root root 0000000 0000000 bzrtp-4.4.13/include/CMakeLists.txt 0000664 0000000 0000000 00000002211 13641445014 0017125 0 ustar 00root root 0000000 0000000 ############################################################################
# CMakeLists.txt
# Copyright (C) 2014 Belledonne Communications, Grenoble France
#
############################################################################
#
# 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 2
# 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.
#
############################################################################
install(FILES bzrtp/bzrtp.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/bzrtp
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
)
bzrtp-4.4.13/include/MSVC/ 0000775 0000000 0000000 00000000000 13641445014 0015141 5 ustar 00root root 0000000 0000000 bzrtp-4.4.13/include/MSVC/stdint.h 0000664 0000000 0000000 00000017060 13641445014 0016623 0 ustar 00root root 0000000 0000000 // ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
extern "C" {
#endif
# include
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]
bzrtp-4.4.13/include/Makefile.am 0000664 0000000 0000000 00000000136 13641445014 0016425 0 ustar 00root root 0000000 0000000 SUBDIRS = bzrtp
EXTRA_DIST=cryptoUtils.h packetParser.h stateMachine.h typedef.h zidCache.h
bzrtp-4.4.13/include/bzrtp/ 0000775 0000000 0000000 00000000000 13641445014 0015532 5 ustar 00root root 0000000 0000000 bzrtp-4.4.13/include/bzrtp/Makefile.am 0000664 0000000 0000000 00000000152 13641445014 0017564 0 ustar 00root root 0000000 0000000 bzrtp_includedir=$(includedir)/bzrtp
bzrtp_include_HEADERS= bzrtp.h
EXTRA_DIST=$(bzrtp_include_HEADERS)
bzrtp-4.4.13/include/bzrtp/bzrtp.h 0000664 0000000 0000000 00000077423 13641445014 0017061 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2014-2019 Belledonne Communications SARL.
*
* This file is part of bzrtp.
*
* 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, see .
*/
#ifndef BZRTP_H
#define BZRTP_H
#include
#include "bctoolbox/crypto.h"
#include "bctoolbox/port.h"
#ifdef _MSC_VER
#ifdef BZRTP_STATIC
#define BZRTP_EXPORT
#else /* BZRTP_STATIC */
#ifdef BZRTP_EXPORTS
#define BZRTP_EXPORT __declspec(dllexport)
#else /* BZRTP_EXPORTS */
#define BZRTP_EXPORT __declspec(dllimport)
#endif /* BZRTP_EXPORTS */
#endif /* BZRTP_STATIC */
#ifndef BZRTP_DEPRECATED
#define BZRTP_DEPRECATED __declspec(deprecated)
#endif /* BZRTP_DEPRECATED */
#else /* _MSC_VER*/
#define BZRTP_EXPORT __attribute__ ((visibility ("default")))
#ifndef BZRTP_DEPRECATED
#define BZRTP_DEPRECATED __attribute__ ((deprecated))
#endif /* BZRTP_DEPRECATED */
#endif /* _MSC_VER*/
/**
* Define different types of crypto functions */
#define ZRTP_HASH_TYPE 0x01
#define ZRTP_CIPHERBLOCK_TYPE 0x02
#define ZRTP_AUTHTAG_TYPE 0x04
#define ZRTP_KEYAGREEMENT_TYPE 0x08
#define ZRTP_SAS_TYPE 0x10
/**
* map the differents algorithm (some may not be available) to integer */
#define ZRTP_UNSET_ALGO 0x00
#define ZRTP_HASH_S256 0x11
#define ZRTP_HASH_S384 0x12
#define ZRTP_HASH_N256 0x13
#define ZRTP_HASH_N384 0x14
#define ZRTP_CIPHER_AES1 0x21
#define ZRTP_CIPHER_AES2 0x22
#define ZRTP_CIPHER_AES3 0x23
#define ZRTP_CIPHER_2FS1 0x24
#define ZRTP_CIPHER_2FS2 0x25
#define ZRTP_CIPHER_2FS3 0x26
#define ZRTP_AUTHTAG_HS32 0x31
#define ZRTP_AUTHTAG_HS80 0x32
#define ZRTP_AUTHTAG_SK32 0x33
#define ZRTP_AUTHTAG_SK64 0x34
/**
* WARNING : it is very important to keep the key agreement defined in that order
* as it is used to easily sort them from faster(DH2k) to slower(EC52)
*/
#define ZRTP_KEYAGREEMENT_DH2k 0x41
#define ZRTP_KEYAGREEMENT_X255 0x42
#define ZRTP_KEYAGREEMENT_EC25 0x43
#define ZRTP_KEYAGREEMENT_X448 0x44
#define ZRTP_KEYAGREEMENT_DH3k 0x45
#define ZRTP_KEYAGREEMENT_EC38 0x46
#define ZRTP_KEYAGREEMENT_EC52 0x47
#define ZRTP_KEYAGREEMENT_Prsh 0x4e
#define ZRTP_KEYAGREEMENT_Mult 0x4f
#define ZRTP_SAS_B32 0x51
#define ZRTP_SAS_B256 0x52
/**
* Define to give client indication on which srtp secrets are valid when given
*/
#define ZRTP_SRTP_SECRETS_FOR_SENDER 0x01
#define ZRTP_SRTP_SECRETS_FOR_RECEIVER 0x02
/**
* brief The data structure containing the keys and algorithms to be used by srtp
* Also stores SAS and informations about the crypto algorithms selected during ZRTP negotiation */
typedef struct bzrtpSrtpSecrets_struct {
uint8_t *selfSrtpKey; /**< The key used by local part to encrypt */
uint8_t selfSrtpKeyLength; /**< The length in byte of the key */
uint8_t *selfSrtpSalt; /**< The salt used by local part to encrypt */
uint8_t selfSrtpSaltLength; /**< The length in byte of the salt */
uint8_t *peerSrtpKey; /**< The key used by local part to decrypt */
uint8_t peerSrtpKeyLength; /**< The length in byte of the key */
uint8_t *peerSrtpSalt; /**< The salt used by local part to decrypt */
uint8_t peerSrtpSaltLength; /**< The length in byte of the salt */
uint8_t cipherAlgo; /**< The cipher block algorithm selected durign ZRTP negotiation and used by srtp */
uint8_t cipherKeyLength; /**< The key length in bytes for the cipher block algorithm used by srtp */
uint8_t authTagAlgo; /**< srtp authentication tag algorithm agreed on after Hello packet exchange */
char *sas; /**< a null terminated char containing the Short Authentication String */
uint8_t sasLength; /**< The length of sas, including the termination character */
uint8_t hashAlgo; /**< The hash algo selected during ZRTP negotiation */
uint8_t keyAgreementAlgo; /**< The key agreement algo selected during ZRTP negotiation */
uint8_t sasAlgo; /**< The SAS rendering algo selected during ZRTP negotiation */
uint8_t cacheMismatch; /**< Flag set to 1 in case of ZRTP cache mismatch, may occurs only on first channel(the one computing SAS) */
uint8_t auxSecretMismatch; /**< Flag set to BZRTP_AUXSECRET_MATCH, BZRTP_AUXSECRET_MISMATCH or BZRTP_AUXSECRET_UNSET, may occurs only on first channel(the one computing SAS), in case of mismatch it may be ignored and we can still validate the SAS */
} bzrtpSrtpSecrets_t;
/* define auxSecretMismatch flag codes */
#define BZRTP_AUXSECRET_MATCH 0x00
#define BZRTP_AUXSECRET_MISMATCH 0x01
#define BZRTP_AUXSECRET_UNSET 0x02
/* define message levels */
#define BZRTP_MESSAGE_ERROR 0x00
#define BZRTP_MESSAGE_WARNING 0x01
#define BZRTP_MESSAGE_LOG 0x02
#define BZRTP_MESSAGE_DEBUG 0x03
/* define message codes */
#define BZRTP_MESSAGE_CACHEMISMATCH 0x01
#define BZRTP_MESSAGE_PEERVERSIONOBSOLETE 0x02
#define BZRTP_MESSAGE_PEERNOTBZRTP 0x03
/**
* Function pointer used by bzrtp to free memory allocated by callbacks.
**/
typedef void (*zrtpFreeBuffer_callback)(void *);
/**
* @brief All the callback functions provided by the client needed by the ZRTP engine
*/
typedef struct bzrtpCallbacks_struct {
/* messaging status and warnings */
int (* bzrtp_statusMessage)(void *clientData, const uint8_t messageLevel, const uint8_t messageId, const char *messageString); /**< Sending messages to caller: error, warnings, logs, the messageString can be NULL or a NULL terminated string */
int bzrtp_messageLevel; /**< Filter calls to this callback to levels inferiors to this setting (BZRTP_MESSAGE_ERROR, BZRTP_MESSAGE_WARNING, BZRTP_MESSAGE_LOG, BZRTP_MESSAGE_DEBUG )*/
/* sending packets */
int (* bzrtp_sendData)(void *clientData, const uint8_t *packetString, uint16_t packetLength); /**< Send a ZRTP packet to peer. Shall return 0 on success */
/* dealing with SRTP session */
int (* bzrtp_srtpSecretsAvailable)(void *clientData, const bzrtpSrtpSecrets_t *srtpSecrets, uint8_t part); /**< Send the srtp secrets to the client, for either sender, receiver or both according to the part parameter value. Client may wait for the end of ZRTP process before using it */
int (* bzrtp_startSrtpSession)(void *clientData, const bzrtpSrtpSecrets_t *srtpSecrets, int32_t verified); /**< ZRTP process ended well, client is given the SAS and informations about the crypto algo used during ZRTP negotiation. He may start his SRTP session if not done when calling srtpSecretsAvailable */
/* ready for exported keys */
int (* bzrtp_contextReadyForExportedKeys)(void *clientData, int zuid, uint8_t role); /**< Tell the client that this is the time to create any exported keys, s0 is erased just after the call to this callback. Callback is given the peerZID and zuid to adress the correct node in cache and current role which is needed to set a pair of keys for IM encryption */
} bzrtpCallbacks_t;
#define ZRTP_MAGIC_COOKIE 0x5a525450
#define ZRTP_VERSION "1.10"
/* error code definition */
#define BZRTP_ERROR_INVALIDCALLBACKID 0x0001
#define BZRTP_ERROR_CONTEXTNOTREADY 0x0002
#define BZRTP_ERROR_INVALIDCONTEXT 0x0004
#define BZRTP_ERROR_MULTICHANNELNOTSUPPORTEDBYPEER 0x0008
#define BZRTP_ERROR_UNABLETOADDCHANNEL 0x0010
#define BZRTP_ERROR_UNABLETOSTARTCHANNEL 0x0020
#define BZRTP_ERROR_OUTPUTBUFFER_LENGTH 0x0040
#define BZRTP_ERROR_HELLOHASH_MISMATCH 0x0080
#define BZRTP_ERROR_CHANNELALREADYSTARTED 0x0100
#define BZRTP_ERROR_CACHEDISABLED 0x0200
#define BZRTP_ERROR_CACHEMIGRATIONFAILED 0x0400
#define BZRTP_ERROR_CACHE_PEERNOTFOUND 0x0800
/* channel status definition */
#define BZRTP_CHANNEL_NOTFOUND 0x1000
#define BZRTP_CHANNEL_INITIALISED 0x1001
#define BZRTP_CHANNEL_ONGOING 0x1002
#define BZRTP_CHANNEL_SECURE 0x1004
#define BZRTP_CHANNEL_ERROR 0x1008
/* role mapping */
#define BZRTP_ROLE_INITIATOR 0
#define BZRTP_ROLE_RESPONDER 1
/* cache related value */
#define BZRTP_CACHE_SETUP 0x2000
#define BZRTP_CACHE_UPDATE 0x2001
#define BZRTP_CACHE_DATA_NOTFOUND 0x2002
#define BZRTP_CACHE_PEER_STATUS_UNKNOWN 0x2010
#define BZRTP_CACHE_PEER_STATUS_VALID 0x2011
#define BZRTP_CACHE_PEER_STATUS_INVALID 0x2012
/* cache function error codes */
#define BZRTP_ZIDCACHE_INVALID_CONTEXT 0x2101
#define BZRTP_ZIDCACHE_INVALID_CACHE 0x2102
#define BZRTP_ZIDCACHE_UNABLETOUPDATE 0x2103
#define BZRTP_ZIDCACHE_UNABLETOREAD 0x2104
#define BZRTP_ZIDCACHE_BADINPUTDATA 0x2105
#define BZRTP_ZIDCACHE_RUNTIME_CACHELESS 0x2110
/**
* @brief bzrtpContext_t The ZRTP engine context
* Store current state, timers, HMAC and encryption keys
*/
typedef struct bzrtpContext_struct bzrtpContext_t;
#ifdef __cplusplus
extern "C" {
#endif
/**
* Create context structure and initialise it
*
* @return The ZRTP engine context data
*
*/
BZRTP_EXPORT bzrtpContext_t *bzrtp_createBzrtpContext(void);
/**
* @brief Perform initialisation which can't be done without ZIDcache acces
* - get ZID and create the first channel context
*
* @param[in] context The context to initialise
* @param[in] selfSSRC The SSRC given to the first channel context created within the zrtpContext
*
* @return 0 on success
*/
BZRTP_EXPORT int bzrtp_initBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC);
/**
* Free memory of context structure to a channel, if all channels are freed, free the global zrtp context
* @param[in] context Context hosting the channel to be destroyed.(note: the context zrtp context itself is destroyed with the last channel)
* @param[in] selfSSRC The SSRC identifying the channel to be destroyed
*
* @return the number of channel still active in this ZRTP context
*/
BZRTP_EXPORT int bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC);
/**
* @brief Allocate a function pointer to the callback function identified by his id
* @param[in/out] context The zrtp context to set the callback function
* @param[in] cbs A structure containing all the callbacks to supply.
*
* @return 0 on success
*
*/
BZRTP_EXPORT int bzrtp_setCallbacks(bzrtpContext_t *context, const bzrtpCallbacks_t *cbs);
/**
* @brief Set the pointer allowing cache access,
* this version of the function get a mutex to lock the cache when accessing it
*
* @param[in] zidCachePointer Used by internal function to access cache: turn into a sqlite3 pointer if cache is enabled
* @param[in] selfURI Local URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
* @param[in] peerURI Peer URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
* @param[in] zidCacheMutex Points to a mutex used to lock zidCache database access
*
* @return 0 or BZRTP_CACHE_SETUP(if cache is populated by this call) on success, error code otherwise
*/
BZRTP_EXPORT int bzrtp_setZIDCache_lock(bzrtpContext_t *context, void *zidCache, const char *selfURI, const char *peerURI, bctbx_mutex_t *zidCacheMutex);
/**
* @brief Set the pointer allowing cache access
*
* @param[in] zidCachePointer Used by internal function to access cache: turn into a sqlite3 pointer if cache is enabled
* @param[in] selfURI Local URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
* @param[in] peerURI Peer URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
*
* @return 0 or BZRTP_CACHE_SETUP(if cache is populated by this call) on success, error code otherwise
*/
BZRTP_EXPORT int bzrtp_setZIDCache(bzrtpContext_t *context, void *zidCache, const char *selfURI, const char *peerURI);
/**
* @brief Set the client data pointer in a channel context
* This pointer is returned to the client by the callbacks function, used to store associated contexts (RTP session)
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel to be linked to the client Data
* @param[in] clientData The clientData pointer, casted to a (void *)
*
* @return 0 on success
*
*/
BZRTP_EXPORT int bzrtp_setClientData(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, void *clientData);
/**
* @brief Add a channel to an existing context
*
* @param[in/out] zrtpContext The zrtp context who will get the additionnal channel
* @param[in] selfSSRC The SSRC given to the channel context
*
* @return 0 on succes, error code otherwise
*/
BZRTP_EXPORT int bzrtp_addChannel(bzrtpContext_t *zrtpContext, uint32_t selfSSRC);
/**
* @brief Start the state machine of the specified channel
* To be able to start an addional channel, we must be in secure state
*
* @param[in/out] zrtpContext The ZRTP context hosting the channel to be started
* @param[in] selfSSRC The SSRC identifying the channel to be started(will start sending Hello packets and listening for some)
*
* @return 0 on succes, error code otherwise
*/
BZRTP_EXPORT int bzrtp_startChannelEngine(bzrtpContext_t *zrtpContext, uint32_t selfSSRC);
/**
* @brief Send the current time to a specified channel, it will check if it has to trig some timer
*
* @param[in/out] zrtpContext The ZRTP context hosting the channel
* @param[in] selfSSRC The SSRC identifying the channel
* @param[in] timeReference The current time in ms
*
* @return 0 on succes, error code otherwise
*/
BZRTP_EXPORT int bzrtp_iterate(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint64_t timeReference);
/**
* @brief Process a received message
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel receiving the message
* @param[in] zrtpPacketString The packet received
* @param[in] zrtpPacketStringLength Length of the packet in bytes
*
* @return 0 on success, errorcode otherwise
*/
BZRTP_EXPORT int bzrtp_processMessage(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint8_t *zrtpPacketString, uint16_t zrtpPacketStringLength);
/**
* @brief Called by user when the SAS has been verified
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
*/
BZRTP_EXPORT void bzrtp_SASVerified(bzrtpContext_t *zrtpContext);
/**
* @brief Called by user when the SAS has been set to unverified
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
*/
BZRTP_EXPORT void bzrtp_resetSASVerified(bzrtpContext_t *zrtpContext);
/**
* @brief Reset the retransmission timer of a given channel.
* Packets will be sent again if appropriate:
* - when in responder role, zrtp engine only answer to packets sent by the initiator.
* - if we are still in discovery phase, Hello or Commit packets will be resent.
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel to reset
*
* return 0 on success, error code otherwise
*/
BZRTP_EXPORT int bzrtp_resetRetransmissionTimer(bzrtpContext_t *zrtpContext, uint32_t selfSSRC);
/**
* @brief Get the supported crypto types
*
* @param[int] zrtpContext The ZRTP context we're dealing with
* @param[in] algoType mapped to defines, must be in [ZRTP_HASH_TYPE, ZRTP_CIPHERBLOCK_TYPE, ZRTP_AUTHTAG_TYPE, ZRTP_KEYAGREEMENT_TYPE or ZRTP_SAS_TYPE]
* @param[out] supportedTypes mapped to uint8_t value of the 4 char strings giving the supported types as string according to rfc section 5.1.2 to 5.1.6
*
* @return number of supported types, 0 on error
*/
BZRTP_EXPORT uint8_t bzrtp_getSupportedCryptoTypes(bzrtpContext_t *zrtpContext, uint8_t algoType, uint8_t supportedTypes[7]);
/**
* @brief set the supported crypto types
*
* @param[int/out] zrtpContext The ZRTP context we're dealing with
* @param[in] algoType mapped to defines, must be in [ZRTP_HASH_TYPE, ZRTP_CIPHERBLOCK_TYPE, ZRTP_AUTHTAG_TYPE, ZRTP_KEYAGREEMENT_TYPE or ZRTP_SAS_TYPE]
* @param[in] supportedTypes mapped to uint8_t value of the 4 char strings giving the supported types as string according to rfc section 5.1.2 to 5.1.6
* @param[in] supportedTypesCount number of supported crypto types
*/
BZRTP_EXPORT void bzrtp_setSupportedCryptoTypes(bzrtpContext_t *zrtpContext, uint8_t algoType, uint8_t supportedTypes[7], uint8_t supportedTypesCount);
/**
* @brief Set the peer hello hash given by signaling to a ZRTP channel
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel
* @param[in] peerHelloHashHexString A NULL terminated string containing the hexadecimal form of the hash received in signaling,
* may contain ZRTP version as header.
* @param[in] peerHelloHashHexStringLength Length of hash string (shall be at least 64 as the hash is a SHA256 so 32 bytes,
* more if it contains the version header)
*
* @return 0 on success, errorcode otherwise
*/
BZRTP_EXPORT int bzrtp_setPeerHelloHash(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint8_t *peerHelloHashHexString, size_t peerHelloHashHexStringLength);
/**
* @brief Get the self hello hash from ZRTP channel
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel
* @param[out] output A NULL terminated string containing the hexadecimal form of the hash received in signaling,
* contain ZRTP version as header. Buffer must be allocated by caller.
* @param[in] outputLength Length of output buffer, shall be at least 70 : 5 chars for version, 64 for the hash itself, SHA256), NULL termination
*
* @return 0 on success, errorcode otherwise
*/
BZRTP_EXPORT int bzrtp_getSelfHelloHash(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint8_t *output, size_t outputLength);
/**
* @brief Get the channel status
*
* @param[in] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel
*
* @return BZRTP_CHANNEL_NOTFOUND no channel matching this SSRC doesn't exists in the zrtp context
* BZRTP_CHANNEL_INITIALISED channel initialised but not started
* BZRTP_CHANNEL_ONGOING ZRTP key exchange in ongoing
* BZRTP_CHANNEL_SECURE Channel is secure
* BZRTP_CHANNEL_ERROR An error occured on this channel
*/
BZRTP_EXPORT int bzrtp_getChannelStatus(bzrtpContext_t *zrtpContext, uint32_t selfSSRC);
/**
* @brief Set Auxiliary Secret for this channel(shall be used only on primary audio channel)
* The given auxSecret is appended to any aux secret found in ZIDcache
* This function must be called before reception of peerHello packet
*
* @param[in] zrtpContext The ZRTP context we're dealing with
* @param[in] auxSecret A buffer holding the auxiliary shared secret to use (see RFC 6189 section 4.3)
* @param[in] auxSecretLength lenght of the previous buffer
*
* @return 0 on success, error code otherwise
*
* @note The auxiliary shared secret mechanic is used by LIMEv2 for encryption security purposes but might be used for its original purpose in a regular
* ZRTP session if it becomes necessary in the future, or by another encryption engine for example. In that case the API will need an adaptation work.
*/
BZRTP_EXPORT int bzrtp_setAuxiliarySharedSecret(bzrtpContext_t *zrtpContext, const uint8_t *auxSecret, size_t auxSecretLength);
/**
* @brief Get the ZRTP auxiliary shared secret mismatch status
* @param[in] ctx MSZRTP context
* @return 0 on match, 1 otherwise
*/
BZRTP_EXPORT uint8_t bzrtp_getAuxiliarySharedSecretMismatch(bzrtpContext_t *zrtpContext);
/*** Cache related functions ***/
/**
* @brief Check the given sqlite3 DB and create requested tables if needed
* Also manage DB schema upgrade
* @param[in/out] db Pointer to the sqlite3 db open connection
* Use a void * to keep this API when building cacheless
*
* @return 0 on success, BZRTP_CACHE_SETUP if cache was empty, BZRTP_CACHE_UPDATE if db structure was updated, error code otherwise
*/
BZRTP_EXPORT BZRTP_DEPRECATED int bzrtp_initCache(void *db);
/**
* @brief Check the given sqlite3 DB and create requested tables if needed
* Also manage DB schema upgrade
*
* this version of the function gets a mutex to lock the cache when accessing it
*
* @param[in/out] db Pointer to the sqlite3 db open connection
* Use a void * to keep this API when building cacheless
* @param[in] zidCacheMutex Points to a mutex used to lock zidCache database access, ignored if NULL
*
* @return 0 on success, BZRTP_CACHE_SETUP if cache was empty, BZRTP_CACHE_UPDATE if db structure was updated, error code otherwise
*/
BZRTP_EXPORT int bzrtp_initCache_lock(void *db, bctbx_mutex_t *zidCacheMutex);
/**
* @brief : retrieve ZID from cache
* ZID is randomly generated if cache is empty or inexistant
* ZID is randomly generated in case of cacheless implementation(db argument is NULL)
*
* @param[in/out] db sqlite3 database(or NULL if we don't use cache at runtime)
* Use a void * to keep this API when building cacheless
* @param[in] selfURI the sip uri of local user, NULL terminated string
* @param[out] selfZID the ZID, retrieved from cache or randomly generated
* @param[in] RNGContext A RNG context used to generate ZID if needed
*
* @return 0 on success, or BZRTP_CACHE_DATA_NOTFOUND if no ZID matching the URI was found and no RNGContext is given to generate one
*/
BZRTP_EXPORT BZRTP_DEPRECATED int bzrtp_getSelfZID(void *db, const char *selfURI, uint8_t selfZID[12], bctbx_rng_context_t *RNGContext);
/**
* @brief : retrieve ZID from cache
* ZID is randomly generated if cache is empty or inexistant
* ZID is randomly generated in case of cacheless implementation(db argument is NULL)
* this version of the function gets a mutex to lock the cache when accessing it
*
* @param[in/out] db sqlite3 database(or NULL if we don't use cache at runtime)
* Use a void * to keep this API when building cacheless
* @param[in] selfURI the sip uri of local user, NULL terminated string
* @param[out] selfZID the ZID, retrieved from cache or randomly generated
* @param[in] RNGContext A RNG context used to generate ZID if needed
* @param[in] zidCacheMutex Points to a mutex used to lock zidCache database access, ignored if NULL
*
* @return 0 on success, or BZRTP_CACHE_DATA_NOTFOUND if no ZID matching the URI was found and no RNGContext is given to generate one
*/
BZRTP_EXPORT int bzrtp_getSelfZID_lock(void *db, const char *selfURI, uint8_t selfZID[12], bctbx_rng_context_t *RNGContext, bctbx_mutex_t *zidCacheMutex);
/**
* @brief Write(insert or update) data in cache, adressing it by zuid (ZID/URI binding id used in cache)
* Get arrays of column names, values to be inserted, lengths of theses values
* All three arrays must be the same lenght: columnsCount
* If the row isn't present in the given table, it will be inserted
*
* @param[in/out] dbPointer Pointer to an already opened sqlite db
* @param[in] zuid The DB internal id to adress the correct row(binding between local uri and peer ZID+URI)
* @param[in] tableName The name of the table to write in the db, must already exists. Null terminated string
* @param[in] columns An array of null terminated strings containing the name of the columns to update
* @param[in] values An array of buffers containing the values to insert/update matching the order of columns array
* @param[in] lengths An array of integer containing the lengths of values array buffer matching the order of columns array
* @param[in] columnsCount length common to columns,values and lengths arrays
*
* @return 0 on succes, error code otherwise
*/
BZRTP_EXPORT BZRTP_DEPRECATED int bzrtp_cache_write(void *dbPointer, int zuid, const char *tableName, const char **columns, uint8_t **values, size_t *lengths, uint8_t columnsCount);
/**
* @brief Write(insert or update) data in cache, adressing it by zuid (ZID/URI binding id used in cache)
* Get arrays of column names, values to be inserted, lengths of theses values
* All three arrays must be the same lenght: columnsCount
* If the row isn't present in the given table, it will be inserted
* this version of the function gets a mutex to lock the cache when accessing it
*
* @param[in/out] dbPointer Pointer to an already opened sqlite db
* @param[in] zuid The DB internal id to adress the correct row(binding between local uri and peer ZID+URI)
* @param[in] tableName The name of the table to write in the db, must already exists. Null terminated string
* @param[in] columns An array of null terminated strings containing the name of the columns to update
* @param[in] values An array of buffers containing the values to insert/update matching the order of columns array
* @param[in] lengths An array of integer containing the lengths of values array buffer matching the order of columns array
* @param[in] columnsCount length common to columns,values and lengths arrays
* @param[in] zidCacheMutex Points to a mutex used to lock zidCache database access, ignored if NULL
*
* @return 0 on succes, error code otherwise
*/
BZRTP_EXPORT int bzrtp_cache_write_lock(void *dbPointer, int zuid, const char *tableName, const char **columns, uint8_t **values, size_t *lengths, uint8_t columnsCount, bctbx_mutex_t *zidCacheMutex);
/**
* @brief Read data from specified table/columns from cache adressing it by zuid (ZID/URI binding id used in cache)
* Get arrays of column names, values to be read, and the number of colums to be read
* Produce an array of values(uint8_t arrays) and a array of corresponding lengths
* Values memory is allocated by this function and must be freed by caller
*
* @param[in/out] dbPointer Pointer to an already opened sqlite db
* @param[in] zuid The DB internal id to adress the correct row(binding between local uri and peer ZID+URI)
* @param[in] tableName The name of the table to read in the db. Null terminated string
* @param[in] columns An array of null terminated strings containing the name of the columns to read, the array's length is columnsCount
* @param[out] values An array of uint8_t pointers, each one will be allocated to the read value and they must be freed by caller
* @param[out] lengths An array of integer containing the lengths of values array buffer read
* @param[in] columnsCount length common to columns,values and lengths arrays
*
* @return 0 on succes, error code otherwise
*/
BZRTP_EXPORT BZRTP_DEPRECATED int bzrtp_cache_read(void *dbPointer, int zuid, const char *tableName, const char **columns, uint8_t **values, size_t *lengths, uint8_t columnsCount);
/**
* @brief Read data from specified table/columns from cache adressing it by zuid (ZID/URI binding id used in cache)
* Get arrays of column names, values to be read, and the number of colums to be read
* Produce an array of values(uint8_t arrays) and a array of corresponding lengths
* Values memory is allocated by this function and must be freed by caller
* this version of the function gets a mutex to lock the cache when accessing it
*
* @param[in/out] dbPointer Pointer to an already opened sqlite db
* @param[in] zuid The DB internal id to adress the correct row(binding between local uri and peer ZID+URI)
* @param[in] tableName The name of the table to read in the db. Null terminated string
* @param[in] columns An array of null terminated strings containing the name of the columns to read, the array's length is columnsCount
* @param[out] values An array of uint8_t pointers, each one will be allocated to the read value and they must be freed by caller
* @param[out] lengths An array of integer containing the lengths of values array buffer read
* @param[in] columnsCount length common to columns,values and lengths arrays
* @param[in] zidCacheMutex Points to a mutex used to lock zidCache database access, ignored if NULL
*
* @return 0 on succes, error code otherwise
*/
BZRTP_EXPORT int bzrtp_cache_read_lock(void *dbPointer, int zuid, const char *tableName, const char **columns, uint8_t **values, size_t *lengths, uint8_t columnsCount, bctbx_mutex_t *zidCacheMutex);
/**
* @brief Perform migration from xml version to sqlite3 version of cache
* Warning: new version of cache associate a ZID to each local URI, the old one did not
* the migration function will associate any data in the cache to the sip URI given in parameter which shall be the default URI
* @param[in] cacheXml a pointer to an xmlDocPtr structure containing the old cache to be migrated
* @param[in/out] cacheSqlite a pointer to an sqlite3 structure containing a cache initialised using bzrtp_cache_init function
* @param[in] selfURI default sip URI for this end point, NULL terminated char
*
* @return 0 on success, BZRTP_ERROR_CACHEDISABLED when bzrtp was not compiled with cache enabled, BZRTP_ERROR_CACHEMIGRATIONFAILED on error during migration
*/
BZRTP_EXPORT int bzrtp_cache_migration(void *cacheXmlPtr, void *cacheSqlite, const char *selfURI);
/*
* @brief Allow client to compute an exported according to RFC section 4.5.2
* Check the context is ready(we already have a master exported key and KDF context)
* and run KDF(master exported key, "Label", KDF_Context, negotiated hash Length)
*
* @param[in] zrtpContext The ZRTP context we're dealing with
* @param[in] label Label used in the KDF
* @param[in] labelLength Length of previous buffer
* @param[out] derivedKey Buffer to store the derived key
* @param[in/out] derivedKeyLength Length of previous buffer(updated to fit actual length of data produced if too long)
*
* @return 0 on succes, error code otherwise
*/
BZRTP_EXPORT int bzrtp_exportKey(bzrtpContext_t *zrtpContext, char *label, size_t labelLength, uint8_t *derivedKey, size_t *derivedKeyLength);
/**
* @brief Retrieve from bzrtp cache the trust status(based on the previously verified flag) of a peer URI
*
* This function will return the SAS validation status of the active device
* associated to the given peerURI.
*
* Important note about the active device:
* - any ZRTP exchange with a peer device will set it to be the active one for its sip:uri
* - the concept of active device is shared between local accounts if there are several of them, it means that :
* - if you have several local users on your device, each of them may have an entry in the ZRTP cache with a particular peer sip:uri (if they ever got in contact with it) but only one of this entry is set to active
* - this function will return the status associated to the last updated entry without any consideration for the local users it is associated with
* - any call where the SAS was neither accepted or rejected will not update the trust status but will set as active device for the peer sip:uri the one involved in the call
*
* This function is intended for use in a mono-device environment.
*
* @param[in] dbPointer Pointer to an already opened sqlite db
* @param[in] peerURI The peer sip:uri we're interested in
* @param[in] zidCacheMutex Points to a mutex used to lock zidCache database access, ignored if NULL
*
* @return one of:
* - BZRTP_CACHE_PEER_STATUS_UNKNOWN : this uri is not present in cache OR during calls with the active device, SAS never was validated or rejected
* Note: once the SAS has been validated or rejected, the status will never return to UNKNOWN(unless you delete your cache)
* - BZRTP_CACHE_PEER_STATUS_VALID : the active device status is set to valid
* - BZRTP_CACHE_PEER_STATUS_INVALID : the active peer device status is set to invalid
*
*/
BZRTP_EXPORT int bzrtp_cache_getPeerStatus_lock(void *dbPointer, const char *peerURI, bctbx_mutex_t *zidCacheMutex);
#ifdef __cplusplus
}
#endif
#endif /* ifndef BZRTP_H */
bzrtp-4.4.13/include/cryptoUtils.h 0000664 0000000 0000000 00000023354 13641445014 0017112 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2014-2019 Belledonne Communications SARL.
*
* This file is part of bzrtp.
*
* 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, see .
*/
#ifndef CRYPTOUTILS_H
#define CRYPTOUTILS_H
#include "typedef.h"
#include "packetParser.h"
/** Return available crypto functions. For now we have
*
* - Hash: HMAC-SHA256(Mandatory)
* - CipherBlock: AES128(Mandatory)
* - Auth Tag: HMAC-SHA132 and HMAC-SHA180 (These are mandatory for SRTP and depends on the SRTP implementation thus we can just suppose they are both available)
* - Key Agreement: DHM3k(Mandatory), DHM2k(optional and shall not be used except on low power devices)
* - Sas: base32(Mandatory), b256(pgp words)
*/
uint8_t bzrtpUtils_getAvailableCryptoTypes(uint8_t algoType, uint8_t availableTypes[7]);
/**
*
* @brief ZRTP Key Derivation Function as in rfc 4.5.1
*
* KDF(KI, Label, Context, L) = HMAC(KI, i || Label ||
* 0x00 || Context || L)
* where
* - i is a 32-bits integer fixed to 0x00000001
* - L is a 32-bit big-endian positive
* integer, not to exceed the length in bits of the output of the HMAC.
* The output of the KDF is truncated to the leftmost L bits.
*
* @param[in] key The key for HMAC
* @param[in] keyLength Length of the key in bytes
* @param[in] label A string to be included in the hash
* @param[in] labelLength Length of the label in bytes
* @param[in] context a context string for the key derivation
* @param[in] contextLength Length of the context string in bytes
* @param[in] hmacLength The output of the KDF is the HMAC truncated to the leftmost L bytes
* @param[in] hmacFunction The hashmac function to be used to compute the KDF
* @param[out] output A buffer to store the hmacLength bytes of output
*
* @return 0 on succes, error code otherwise
*/
BZRTP_EXPORT int bzrtp_keyDerivationFunction(const uint8_t *key, const size_t keyLength,
const uint8_t *label, const size_t labelLength,
const uint8_t *context, const size_t contextLength,
const uint16_t hmacLength,
void (*hmacFunction)(const uint8_t *, size_t, const uint8_t *, size_t, uint8_t, uint8_t *),
uint8_t *output);
/**
* @brief SAS rendering from 32 bits to 4 characters
* Function defined in rfc section 5.1.6
*
* @param[in] sas The 32 bits SAS
* @param[out] output The 4 chars string to be displayed to user for vocal confirmation
*
*/
void bzrtp_base32(uint32_t sas, char *output, int outputSize);
/**
* @brief SAS rendering from 32 bits to pgp word list
* Function defined in rfc section 5.1.6
*
* @param[in] sas The 32 bits SAS
* @param[out] output The output list. Passed in array must be at least 32 bytes
*
*/
void bzrtp_base256(uint32_t sas, char *output, int outputSize);
/**
* @brief CRC32 as defined in RFC4960 Appendix B - Polynomial is 0x1EDC6F41
*
* CRC is computed in reverse bit mode (least significant bit first within each byte)
* reversed value of polynom (0x82F63B78) was used to compute the lookup table (source
* http://en.wikipedia.org/wiki/Cyclic_redundancy_check#Commonly_used_and_standardized_CRCs)
*
* @param[in] input input data
* @param[in] length length of data in bytes
*
* @return the 32 bits CRC value
*
*/
BZRTP_EXPORT uint32_t bzrtp_CRC32(uint8_t *input, uint16_t length);
/* error code for the cryptoAlgoAgreement and function pointer update functions */
#define ZRTP_CRYPTOAGREEMENT_INVALIDCONTEXT 0x1001
#define ZRTP_CRYPTOAGREEMENT_INVALIDMESSAGE 0x1002
#define ZRTP_CRYPTOAGREEMENT_INVALIDSELFALGO 0x1003
#define ZRTP_CRYPTOAGREEMENT_NOCOMMONALGOFOUND 0x1004
#define ZRTP_CRYPTOAGREEMENT_INVALIDCIPHER 0x1005
#define ZRTP_CRYPTOAGREEMENT_INVALIDHASH 0x1006
#define ZRTP_CRYPTOAGREEMENT_INVALIDAUTHTAG 0x1007
#define ZRTP_CRYPTOAGREEMENT_INVALIDSAS 0x1008
/**
* @brief select a key agreement algorithm from the one available in context and the one provided by
* peer in Hello Message as described in rfc section 4.1.2
* - other algorithm are selected according to availability and selected key agreement as described in
* rfc section 5.1.5
* The other algorithm choice will finally be set by the endpoint acting as initiator in the commit packet
*
* @param[in] zrtpContext The context contains the list of available algo
* @param[out] zrtpChannelContext The bzrtp channel context to be updated
* @param[in] peerHelloMessage The peer hello message containing his set of available algos
*
* return 0 on succes, error code otherwise
*
*/
BZRTP_EXPORT int bzrtp_cryptoAlgoAgreement(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, bzrtpHelloMessage_t *peerHelloMessage);
/**
* @brief Update context crypto function pointer according to related values of choosen algorithms fields (hashAlgo, cipherAlgo, etc..)
*
* @param[in/out] zrtpChannelContext The bzrtp channel context to be updated
*
* @return 0 on succes
*/
BZRTP_EXPORT int bzrtp_updateCryptoFunctionPointers(bzrtpChannelContext_t *zrtpChannelContext);
/**
* @brief Select common algorithm from the given array where algo are represented by their 4 chars string defined in rfc section 5.1.2 to 5.1.6
* Master array is the one given the preference order
* All algo are designed by their uint8_t mapped values
*
* @param[in] masterArray The ordered available algo, result will follow this ordering
* @param[in] masterArrayLength Number of valids element in the master array
* @param[in] slaveArray The available algo, order is not taken in account
* @param[in] slaveArrayLength Number of valids element in the slave array
* @param[out] commonArray Common algorithms found, max size 7
*
* @return the number of common algorithms found
*/
uint8_t selectCommonAlgo(uint8_t masterArray[7], uint8_t masterArrayLength, uint8_t slaveArray[7], uint8_t slaveArrayLength, uint8_t commonArray[7]);
/**
* @brief add mandatory crypto functions if they are not already included
* - Hash function
* - Cipher Block
* - Auth Tag
* - Key agreement
* - SAS
*
* @param[in] algoType mapped to defines, must be in [ZRTP_HASH_TYPE, ZRTP_CIPHERBLOCK_TYPE, ZRTP_AUTHTAG_TYPE, ZRTP_KEYAGREEMENT_TYPE or ZRTP_SAS_TYPE]
* @param[in/out] algoTypes mapped to uint8_t value of the 4 char strings giving the algo types as string according to rfc section 5.1.2 to 5.1.6
* @param[in/out] algoTypesCount number of algo types
*/
BZRTP_EXPORT void bzrtp_addMandatoryCryptoTypesIfNeeded(uint8_t algoType, uint8_t algoTypes[7], uint8_t *algoTypesCount);
/**
* @brief Map the string description of algo type to an int defined in cryptoWrapper.h
*
* @param[in] algoType A 4 chars string containing the algo type as listed in rfc sections 5.1.2 to 5.1.6
* @param[in] algoFamily The integer mapped algo family (ZRTP_HASH_TYPE, ZRTP_CIPHERBLOCK_TYPE, ZRTP_AUTHTAG_TYPE,
* ZRTP_KEYAGREEMENT_TYPE or ZRTP_SAS_TYPE)
* @return The int value mapped to the algo type, ZRTP_UNSET_ALGO on error
*/
BZRTP_EXPORT uint8_t bzrtp_cryptoAlgoTypeStringToInt(uint8_t algoType[4], uint8_t algoFamily);
/**
* @brief Unmap the string description of algo type to an int defined in cryptoWrapper.h
*
* @param[in] algoTypeInt The integer algo type defined in crypoWrapper.h
* @param[in] algoFamily The string code for the algorithm as defined in rfc 5.1.2 to 5.1.6
*/
BZRTP_EXPORT void bzrtp_cryptoAlgoTypeIntToString(uint8_t algoTypeInt, uint8_t algoTypeString[4]);
/**
* @brief Destroy a key by setting it to a random number
* Key is not freed, caller must deal with memory management.
* Does nothing if the key pointer is NULL
*
* @param[in/out] key The key to be destroyed
* @param[in] keyLength The keyLength in bytes
* @param[in] rngContext The context for RNG
*/
BZRTP_EXPORT void bzrtp_DestroyKey(uint8_t *key, uint8_t keyLength, void *rngContext);
/**
* @brief Convert an hexadecimal string into the corresponding byte buffer
*
* @param[out] outputBytes The output bytes buffer, must have a length of half the input string buffer
* @param[in] inputString The input string buffer, must be hexadecimal(it is not checked by function, any non hexa char is converted to 0)
* @param[in] inputStringLength The length in chars of the string buffer, output is half this length
*/
void bzrtp_strToUint8(uint8_t *outputBytes, uint8_t *inputString, uint16_t inputStringLength);
/**
* @brief Convert a byte buffer into the corresponding hexadecimal string
*
* @param[out] outputString The output string buffer, must have a length of twice the input bytes buffer
* @param[in] inputBytes The input bytes buffer
* @param[in] inputBytesLength The length in bytes buffer, output is twice this length
*/
void bzrtp_int8ToStr(uint8_t *outputString, uint8_t *inputBytes, uint16_t inputBytesLength);
/**
* @brief convert an hexa char [0-9a-fA-F] into the corresponding unsigned integer value
* Any invalid char will be converted to zero without any warning
*
* @param[in] inputChar a char which shall be in range [0-9a-fA-F]
*
* @return the unsigned integer value in range [0-15]
*/
uint8_t bzrtp_charToByte(uint8_t inputChar);
/**
* @brief convert a byte which value is in range [0-15] into an hexa char [0-9a-fA-F]
*
* @param[in] inputByte an integer which shall be in range [0-15]
*
* @return the hexa char [0-9a-f] corresponding to the input
*/
uint8_t bzrtp_byteToChar(uint8_t inputByte);
#endif /* CRYPTOUTILS_H */
bzrtp-4.4.13/include/packetParser.h 0000664 0000000 0000000 00000050017 13641445014 0017171 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2014-2019 Belledonne Communications SARL.
*
* This file is part of bzrtp.
*
* 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, see .
*/
#ifndef PACKETPARSER_H
#define PACKETPARSER_H
#include
#include "bzrtp/bzrtp.h"
/* header of ZRTP packet is 12 bytes : Preambule/Sequence Number + ZRTP Magic Cookie + SSRC */
#define ZRTP_PACKET_HEADER_LENGTH 12
#define ZRTP_PACKET_CRC_LENGTH 4
#define ZRTP_PACKET_OVERHEAD 16
#define BZRTP_PARSER_ERROR_INVALIDCRC 0xa001
#define BZRTP_PARSER_ERROR_INVALIDPACKET 0xa002
#define BZRTP_PARSER_ERROR_OUTOFORDER 0xa004
#define BZRTP_PARSER_ERROR_INVALIDMESSAGE 0xa008
#define BZRTP_PARSER_ERROR_INVALIDCONTEXT 0xa010
#define BZRTP_PARSER_ERROR_UNMATCHINGCONFIRMMAC 0xa020
#define BZRTP_PARSER_ERROR_UNMATCHINGSSRC 0xa040
#define BZRTP_PARSER_ERROR_UNMATCHINGHASHCHAIN 0xa080
#define BZRTP_PARSER_ERROR_UNMATCHINGMAC 0xa100
#define BZRTP_PARSER_ERROR_UNEXPECTEDMESSAGE 0xa200
#define BZRTP_PARSER_ERROR_UNMATCHINGHVI 0xa400
#define BZRTP_BUILDER_ERROR_INVALIDPACKET 0x5001
#define BZRTP_BUILDER_ERROR_INVALIDMESSAGE 0x5002
#define BZRTP_BUILDER_ERROR_INVALIDMESSAGETYPE 0x5004
#define BZRTP_BUILDER_ERROR_UNKNOWN 0x5008
#define BZRTP_BUILDER_ERROR_INVALIDCONTEXT 0x5010
#define BZRTP_CREATE_ERROR_INVALIDMESSAGETYPE 0x0a01
#define BZRTP_CREATE_ERROR_UNABLETOCREATECRYPTOCONTEXT 0x0a02
#define BZRTP_CREATE_ERROR_INVALIDCONTEXT 0x0a04
/* map all message type to an uint8_t value */
#define MSGTYPE_INVALID 0x00
#define MSGTYPE_HELLO 0x01
#define MSGTYPE_HELLOACK 0x02
#define MSGTYPE_COMMIT 0x03
#define MSGTYPE_DHPART1 0x04
#define MSGTYPE_DHPART2 0x05
#define MSGTYPE_CONFIRM1 0x06
#define MSGTYPE_CONFIRM2 0x07
#define MSGTYPE_CONF2ACK 0x08
#define MSGTYPE_ERROR 0x10
#define MSGTYPE_ERRORACK 0x11
#define MSGTYPE_GOCLEAR 0x12
#define MSGTYPE_CLEARACK 0x13
#define MSGTYPE_SASRELAY 0x14
#define MSGTYPE_RELAYACK 0x15
#define MSGTYPE_PING 0x16
#define MSGTYPE_PINGACK 0x17
/**
* @brief Store all zrtpPacket informations
* according to type a specific structure type is mapped to the void * data pointer
*/
typedef struct bzrtpPacket_struct {
uint16_t sequenceNumber; /**< set by packet parser to enable caller to retrieve the packet sequence number. This field is not used buy the packet creator, sequence number is given as a parameter when converting the message to a packet string. Used only when parsing a string into a packet struct */
uint32_t sourceIdentifier; /**< the SSRC of current RTP stream */
uint8_t messageType; /**< the ZRTP message type mapped from strings to hard defined byte */
uint16_t messageLength; /**< the ZRTP message length in bytes - the message length indicated in the message itself is in 32 bits words. Is not the packet length(do not include packet header and CRC) */
void *messageData; /**< a pointer to the structure containing all the message field according to message type */
uint8_t *packetString; /**< used to stored the string version of the packet build from the message data or keep a string copy of received packets */
} bzrtpPacket_t;
/**
* Structure definition for all zrtp message type according to rfc section 5.2 to 5.16
*
*/
/**
* @brief Hello Message rfc 5.2
*/
typedef struct bzrtpHelloMessage_struct {
uint8_t version[4]; /**< a string defining the current version, shall be 1.10 */
uint8_t clientIdentifier[17]; /**< a string identifing the vendor and release of ZRTP software, actual content is 16, but last character forced to '\0' */
uint8_t H3[32]; /**< the hash image H3 (256 bits) */
uint8_t ZID[12]; /**< unique identifier for ZRTP endpoint (96 bits) */
uint8_t S; /**< The signature-capable flag. If signatures are not supported, the (S) flag MUST be set to zero (1 bit) */
uint8_t M; /**< The MiTM flag (M) is a Boolean that is set to true if and only if this Hello message is sent from a device, usually a PBX, that has the capability to send an SASrelay message (1 bit) **/
uint8_t P; /**< The Passive flag (P) is a Boolean normally set to false, and is set to true if and only if this Hello message is sent from a device that is configured to never send a Commit message (Section 5.4). This would mean it cannot initiate secure sessions, but may act as a responder. (1 bit) */
uint8_t hc; /**< hash count -zrtpPacket set to 0 means we support only HMAC-SHA256 (4 bits) */
uint8_t supportedHash[7]; /**< list of supported hash algorithms mapped to uint8_t */
uint8_t cc; /**< cipher count - set to 0 means we support only AES128-CFB128 (4 bits) */
uint8_t supportedCipher[7]; /**< list of supported cipher algorithms mapped to uint8_t */
uint8_t ac; /**< auth tag count - set to 0 mean we support only HMAC-SHA1-32 (4 bits) */
uint8_t supportedAuthTag[7]; /**< list of supported SRTP authentication tag algorithms mapped to uint8_t */
uint8_t kc; /**< key agreement count - set to 0 means we support only Diffie-Hellman-Merkle 3072 (4 bits) */
uint8_t supportedKeyAgreement[7]; /**< list of supported key agreement algorithms mapped to uint8_t */
uint8_t sc; /**< sas count - set to 0 means we support only base32 (4 bits) */
uint8_t supportedSas[7]; /**< list of supported Sas representations (4 chars string) */
uint8_t MAC[8]; /**< HMAC over the whole message, keyed by the hash image H2 (64 bits)*/
} bzrtpHelloMessage_t;
/**
* @brief Hello ACK Message rfc 5.3
* This message contains no data but only a length and message type which are stored in the bzrtpPacket_t structure
* There the no need to define a structure type for this packet
*/
/**
*
* @brief Commit Message rfc 5.4
* This message can be of 3 different types: DHM, PreShared and Multistream, some field of it may be used only by certain type of message
* It is generated by the initiator (see section 4.2 for commit contention)
*/
typedef struct bzrtpCommitMessage_struct {
uint8_t H2[32]; /**< the hash image H2 (256 bits) */
uint8_t ZID[12]; /**< initiator's unique identifier for ZRTP endpoint (96 bits) */
uint8_t hashAlgo; /**< the hash algorithm identifier rfc section 5.1.2 mapped to an integer */
uint8_t cipherAlgo; /**< the cipher algorithm identifier rfc section 5.1.3 mapped to an integer */
uint8_t authTagAlgo; /**< the auth tag algorithm identifier rfc section 5.1.4 mapped to an integer */
uint8_t keyAgreementAlgo; /**< the key agreement algorithm identifier rfc section 5.1.5. It can either be a key exchange algorithm or the commit packet type in case of preShared or multistream commit message mapped to an integer */
uint8_t sasAlgo; /**< the sas rendering algorithm identifier rfc section 5.1.6 mapped to an integer */
uint8_t hvi[32]; /**< only for DH commit : a hash of initiator's DHPart2 and responder's Hello message rfc section 4.4.1.1 */
uint8_t nonce[16]; /**< only for preShared or Multistream modes : a 128 bits random number generated by the initiator */
uint8_t keyID[8]; /**< only for preShared mode : the preshared key identifier */
uint8_t MAC[8]; /**< HMAC over the whole message, keyed by the hash image H1 (64 bits)*/
} bzrtpCommitMessage_t;
/**
*
* @brief DHPart Message rfc 5.5 and rfc 5.6
* DHPart1 and DHPart2 message have the same structure
* DHPart1 is generated by the responder, and DHPart2 by the initiator
*/
typedef struct bzrtpDHPartMessage_struct {
uint8_t H1[32]; /**< the hash image H1 (256 bits) */
uint8_t rs1ID[8]; /**< hash of the retained secret 1 (64 bits) */
uint8_t rs2ID[8]; /**< hash of the retained secret 2 (64 bits) */
uint8_t auxsecretID[8]; /**< hash of the auxiliary shared secret (64 bits) */
uint8_t pbxsecretID[8]; /**< hash of the trusted MiTM PBX shared secret pbxsecret, defined in section 7.3.1 (64 bits) */
uint8_t *pv; /* Key exchange public value (length depends on key agreement type) */
uint8_t MAC[8]; /**< HMAC over the whole message, keyed by the hash image H1 (64 bits)*/
} bzrtpDHPartMessage_t;
/**
*
* @brief Confirm Message rfc 5.7
* Confirm1 and Confirm2 messages have the same structure
* Confirm1 is generated by the responder and Confirm2 by the initiator
* Part of the message is encrypted using the negotiated block cipher for media encryption. Keys ares zrtpkeyr for responder and zrtpkeyi for initiator
*/
typedef struct bzrtpConfirmMessage_struct {
uint8_t confirm_mac[8]; /**< a MAC computed over the encrypted part of the message (64 bits) */
uint8_t CFBIV[16]; /**< The CFB Initialization Vector is a 128-bit random nonce (128 bits) */
uint8_t H0[32]; /**< the hash image H0 - Encrypted - (256 bits) */
uint16_t sig_len; /**< The SAS signature length. If no SAS signature (described in Section 7.2) is present, all bits are set to zero. The signature length is in words and includes the signature type block. If the calculated signature octet count is not a multiple of 4, zeros are added to pad it out to a word boundary. If no signature is present, the overall length of the Confirm1 or Confirm2 message will be set to 19 words - Encrypted - (9 bits) */
uint8_t E; /**< The PBX Enrollment flag (E) is a Boolean bit defined in Section 7.3.1 - Encrypted - (1 bit) */
uint8_t V; /**< The SAS Verified flag (V) is a Boolean bit defined in Section 7.1. - Encrypted - (1 bit) */
uint8_t A; /**< The Allow Clear flag (A) is a Boolean bit defined in Section 4.7.2 - Encrypted - (1 bit) */
uint8_t D; /**< The Disclosure Flag (D) is a Boolean bit defined in Section 11. - Encrypted - (1 bit) */
uint32_t cacheExpirationInterval; /**< The cache expiration interval is defined in Section 4.9 - Encrypted - (32 bits) */
uint8_t signatureBlockType[4]; /**< Optionnal signature type : "PGP " or "X509" string - Encrypted - (32 bits) */
uint8_t *signatureBlock; /**< Optionnal signature block as decribded in section 7.2 - Encrypted - (variable length) */
} bzrtpConfirmMessage_t;
/**
* @brief Conf2 ACK Message rfc 5.8
* This message contains no data but only a length and message type which are stored in the bzrtpPacket_t structure
* There the no need to define a structure type for this packet
*/
/**
* @brief Error Message rfc section 5.9
* The Error message is sent to terminate an in-process ZRTP key agreement exchange due to an error.
* There is no need to define a structure for this packet as it contains length and message type which are stored
* in the bzrtpPacket_t structure and a 32 bits integer error code only
*/
/**
* @brief Error ACK Message rfc 5.10
* This message contains no data but only a length and message type which are stored in the bzrtpPacket_t structure
* There the no need to define a structure type for this packet
*/
/**
* @brief GoClear Message rfc 5.11
* Support for the GoClear message is OPTIONAL in the protocol, and it is sent to switch from SRTP to RTP.
*/
typedef struct bzrtpGoClearMessage_struct {
uint8_t clear_mac[8]; /**< The clear_mac is used to authenticate the GoClear message so that bogus GoClear messages introduced by an attacker can be detected and discarded. (64 bits) */
} bzrtpGoClearMessage_t;
/**
*
* @brief Clear ACK Message rfc 5.12
* This message contains no data but only a length and message type which are stored in the bzrtpPacket_t structure
* There the no need to define a structure type for this packet
*/
/**
* @brief SASRelay Message rfc 5.13
* The SASrelay message is sent by a trusted MiTM, most often a PBX. It is not sent as a response to a packet, but is sent as a self-initiated packet by the trusted MiTM (Section 7.3). It can only be sent after the rest of the ZRTP key negotiations have completed, after the Confirm messages and their ACKs. It can only be sent after the trusted MiTM has finished key negotiations with the other party, because it is the other party's SAS that is being relayed. It is sent with retry logic until a RelayACK message (Section 5.14) is received or the retry schedule has been exhausted. Part of the message is encrypted using the negotiated block cipher for media encryption.
* Depending on whether the trusted MiTM had taken the role of the initiator or the responder during the ZRTP key negotiation, the
* SASrelay message is encrypted with zrtpkeyi or zrtpkeyr.
*/
typedef struct bzrtpSASRelayMessage_struct {
uint8_t MAC[8]; /**< a MAC computed over the encrypted part of the message (64 bits) */
uint8_t CFBIV[16]; /**< The CFB Initialization Vector is a 128-bit random nonce (128 bits) */
uint16_t sig_len; /**< The SAS signature length. The trusted MiTM MAY compute a digital signature on the SAS hash, as described in Section 7.2, using a persistent signing key owned by the trusted MiTM. If no SAS signature is present, all bits are set to zero. The signature length is in words and includes the signature type block. If the calculated signature octet count is not a multiple of 4, zeros are added to pad it out to a word boundary. If no signature block is present, the overall length of the SASrelay message will be set to 19 words.*/
uint8_t V; /**< The SAS Verified flag (V) is a Boolean bit defined in Section 7.1. - Encrypted - (1 bit) */
uint8_t A; /**< The Allow Clear flag (A) is a Boolean bit defined in Section 4.7.2 - Encrypted - (1 bit) */
uint8_t D; /**< The Disclosure Flag (D) is a Boolean bit defined in Section 11. - Encrypted - (1 bit) */
uint8_t renderingScheme[4]; /**< the SAS rendering scheme for the relayed sashash, which will be the same rendering scheme used by the other party on the other side of the trusted MiTM. - Encrypted - (32 bits) */
uint8_t relayedSasHash[32]; /**< the sashash relayed from the other party. The first 32-bit word of the sashash contains the sasvalue, which may be rendered to the user using the specified SAS rendering scheme. If this SASrelay message is being sent to a ZRTP client that does not trust this MiTM, the sashash will be ignored by the recipient and should be set to zeros by the PBX. - Encrypted - (256 bits) */
uint8_t signatureBlockType; /**< Optionnal signature type : "PGP " or "X509" string - Encrypted - (32 bits) */
uint8_t *signatureBlock; /**< Optionnal signature block as decribded in section 7.2 - Encrypted - (variable length) */
} bzrtpSASRelayMessage_t;
/**
* @brief Relay ACK Message rfc 5.14
* This message contains no data but only a length and message type which are stored in the bzrtpPacket_t structure
* There the no need to define a structure type for this packet
*/
/**
* @brief Ping Message
* The Ping and PingACK messages are unrelated to the rest of the ZRTP protocol. No ZRTP endpoint is required to generate a Ping message, but every ZRTP endpoint MUST respond to a Ping message with a PingACK message.
*/
typedef struct bzrtpPingMessage_struct {
uint8_t version[4]; /**< a string defining the current version, shall be 1.10 (32 bits) */
uint8_t endpointHash[8]; /**< see section 5.16 for the endpointHash definition (64 bits) */
} bzrtpPingMessage_t;
/**
*
* @brief PingAck Message
* The Ping and PingACK messages are unrelated to the rest of the ZRTP protocol. No ZRTP endpoint is required to generate a Ping message, but every ZRTP endpoint MUST respond to a Ping message with a PingACK message.
*/
typedef struct bzrtpPingAckMessage_struct {
uint8_t version[4]; /**< a string defining the current version, shall be 1.10 (32 bits) */
uint8_t endpointHash[8]; /**< see section 5.16 for the endpointHash definition (64 bits) */
uint8_t endpointHashReceived[8]; /**< the endpoint hash received in the ping Message we're acknowledging (64 bits) */
uint32_t SSRC; /**< the SSRC received in the ping packet we're acknowledging (32 bits) */
} bzrtpPingAckMessage_t;
/**
* @brief Parse a string which shall be a valid ZRTP packet
* Check validity and allocate the bzrtpPacket structure but do not parse the message except for type and length.
* messageData structure field is not allocated by this function (use then bzrtp_packetParse for that).
* The packet check and actual message parsing are split in two functions to avoid useless parsing when message is
* to be discarded as the check will give message type (in case of message repetition for example)
*
* @param[in] input The string buffer storing the complete ZRTP packet
* @param[in] inputLength Input length in bytes
* @param[in] lastValidSequenceNumber If the sequence number of this packet is smaller than this param, packet will be discarded
* and an error code returned
* @param[out] exitCode 0 on success, error code otherwise
*
* @return The create bzrtpPacket structure(to be freed using bzrtp_freeZrtpPacket). NULL on error
*/
BZRTP_EXPORT bzrtpPacket_t *bzrtp_packetCheck(const uint8_t * input, uint16_t inputLength, uint16_t lastValidSequenceNumber, int *exitCode);
/**
* @brief Parse the packet to extract the message and allocate the matching message structure if needed
*
* @param[in] zrtpContext The current ZRTP context, some parameters(key agreement algorithm) may be needed to parse packet.
* @param[in] zrtpChannelContext The channel context this packet is intended to(channel context and packet must match peer SSRC).
* @param[in] input The string buffer storing the complete ZRTP packet
* @param[in] inputLength Input length in bytes
* @param[in] zrtpPacket The zrtpPacket structure allocated by previous call to bzrtpPacketCheck
*
* @return 0 on sucess, error code otherwise
*/
BZRTP_EXPORT int bzrtp_packetParser(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, const uint8_t * input, uint16_t inputLength, bzrtpPacket_t *zrtpPacket);
/**
* @brief Create an empty packet and allocate the messageData according to requested packetType
*
* @param[in] zrtpContext The current ZRTP context, some data (H chain or others, may be needed to create messages)
* @param[in] zrtpChannelContext The channel context this packet is intended to
* @param[in] messageType The 32bit integer mapped to the message type to be created
* @param[out] exitCode 0 on success, error code otherwise
*
* @return An empty packet initialised to get data for the requested paquet tyep. NULL on error
*/
BZRTP_EXPORT bzrtpPacket_t *bzrtp_createZrtpPacket(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, uint32_t messageType, int *exitCode);
/**
* @brief Create a ZRTP packet string from the ZRTP packet values present in the structure
* messageType, messageData and sourceIdentifier in zrtpPacket must have been correctly set before calling this function
*
* @param[in] zrtpContext A zrtp context where to find H0-H3 to compute MAC requested by some paquets or encryption's key for commit/SASRelay packet
* @param[in] zrtpChannelContext The channel context this packet is intended to
* @param[in/out] zrtpPacket The zrtpPacket structure containing the message Data structure, output is stored in ->packetString
* @param[in] sequenceNumber Sequence number of this packet
*
* @return 0 on success, error code otherwise
*
*/
BZRTP_EXPORT int bzrtp_packetBuild(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, bzrtpPacket_t *zrtpPacket, uint16_t sequenceNumber);
/**
* @brief Deallocate zrtp Packet
*
* @param[in] zrtpPacket The packet to be freed
*
*/
BZRTP_EXPORT void bzrtp_freeZrtpPacket(bzrtpPacket_t *zrtpPacket);
/**
* @brief Modify the current sequence number of the packet in the packetString and sequenceNumber fields
* The CRC at the end of packetString is also updated
*
* param[in/out] zrtpPacket The zrtpPacket to modify, the packetString must have been generated by
* a call to bzrtp_packetBuild on this packet
* param[in] sequenceNumber The new sequence number to insert in the packetString
*
* return 0 on succes, error code otherwise
*/
BZRTP_EXPORT int bzrtp_packetUpdateSequenceNumber(bzrtpPacket_t *zrtpPacket, uint16_t sequenceNumber);
#endif /* PACKETPARSER_H */
bzrtp-4.4.13/include/stateMachine.h 0000664 0000000 0000000 00000015653 13641445014 0017161 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2014-2019 Belledonne Communications SARL.
*
* This file is part of bzrtp.
*
* 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, see .
*/
#ifndef STATEMACHINE_H
#define STATEMACHINE_H
#include "typedef.h"
/* types definition for event and state function */
/* the INIT event type is used to run some state for the firt time : create packet and send it */
#define BZRTP_EVENT_INIT 0
#define BZRTP_EVENT_MESSAGE 1
#define BZRTP_EVENT_TIMER 2
/* error code definition */
#define BZRTP_ERROR_UNSUPPORTEDZRTPVERSION 0xe001
#define BZRTP_ERROR_UNMATCHINGPACKETREPETITION 0xe002
#define BZRTP_ERROR_CACHEMISMATCH 0xe004
/**
* @brief The event type, used as a parameter for the state function
*/
typedef struct bzrtpEvent_struct {
uint8_t eventType; /**< Event can be a message or a timer's end */
uint8_t *bzrtpPacketString; /**< a pointer to the zrtp packet string, NULL in case of timer event */
uint16_t bzrtpPacketStringLength; /**< the length of packet string in bytes */
bzrtpPacket_t *bzrtpPacket; /**< a pointer to the zrtp packet structure created by the processMessage function */
bzrtpContext_t *zrtpContext; /**< the current ZRTP context */
bzrtpChannelContext_t *zrtpChannelContext; /**< the current ZRTP channel hosting this state machine context */
} bzrtpEvent_t;
/**
* @brief the state function pointer definition
*/
typedef int (*bzrtpStateMachine_t)(bzrtpEvent_t);
/* state functions prototypes, split in categories corresponding to the differents protocol phases: discovery, key agreement, confirmation */
/**
* @brief This is the initial state
* On first call, we will create the Hello message and start sending it until we receive an helloACK or a hello message from peer
*
* Arrives from :
* - This is the initial state
* Goes to:
* - state_discovery_waitingForHello upon HelloACK reception
* - state_discovery_waitingForHelloAck upon Hello reception
* Send :
* - Hello until timer's end or transition
*/
int state_discovery_init(bzrtpEvent_t event);
/**
* @brief Arrives in this state coming from init upon reception on Hello ACK, we are now waiting for the Hello packet from peer
*
* Arrives from :
* - state_discovery_init upon HelloACK reception
* Goes to:
* - state_keyAgreement_sendingCommit upon Hello reception
* Send :
* - HelloACK on Hello reception
*
*/
int state_discovery_waitingForHello(bzrtpEvent_t event);
/**
* @brief We are now waiting for the HelloACK packet from peer or a Commit packet
*
* Arrives from :
* - state_discovery_init upon Hello reception
* Goes to:
* - state_keyAgreement_sendingCommit upon HelloACK reception
* - state_keyAgreement_responderSendingDHPart1 upon Commit reception in DHM mode
* - state_confirmation_responderSendingConfirm1 upon Commit reception in non DHM mode
* Send :
* - Hello until timer's end or transition
* - HelloACK on Hello reception
*
*/
int state_discovery_waitingForHelloAck(bzrtpEvent_t event);
/**
* @brief For any kind of key agreement (DHM, Mult, PreShared), we keep sending commit.
*
* Arrives from :
* - state_discovery_waitingForHello upon Hello received
* - state_discovery_waitingForHelloAck upon HelloACK received
* Goes to:
* - state_keyAgreement_initiatorSendingDHPart2 upon DHPart1 reception in DHM mode
* - state_confirmation_initiatorSendingConfirm2 upon Confirm1 reception in non DHM mode
* - state_keyAgreement_responderSendingDHPart1 upon Commit reception in DHM mode and commit contention gives us the responder role
* - state_confirmation_responderSendingConfirm1 upon Commit reception in non DHM mode and commit contention gives us the responder role
* Send :
* - Commit until timer's end or transition
* - HelloACK on Hello reception
*
*/
int state_keyAgreement_sendingCommit(bzrtpEvent_t event);
/**
* @brief For DHM mode only, responder send DHPart1 packet
*
* Arrives from:
* - state_discovery_waitingForHelloAck upon Commit reception in DHM mode
* - state_keyAgreement_sendingCommit upon Commit reception in DHM mode and commit contention gives us the responder role
* Goes to:
* - state_confirmation_responderSendingConfirm1 upon DHPart2 reception
* Send :
* - DHPart1 on Commit reception
*
*/
int state_keyAgreement_responderSendingDHPart1(bzrtpEvent_t event);
/**
* @brief For DHM mode only, initiator send DHPart2 packet
*
* Arrives from:
* - state_keyAgreement_sendingCommit upon DHPart1 reception
* Goes to:
* - state_confirmation_initiatorSendingConfirm2 upon reception of Confirm1
* Send :
* - DHPart2 until timer's end or transition
*
*/
int state_keyAgreement_initiatorSendingDHPart2(bzrtpEvent_t event);
/**
* @brief Responder send the confirm1 message
*
* Arrives from:
* - state_keyAgreement_responderSendingDHPart1 upon DHPart2 reception
* - state_keyAgreement_sendingCommit upon Commit reception in non DHM mode and commit contention gives us the responder role
* - state_discovery_waitingForHelloAck upon Commit reception in non DHM mode
* Goes to:
* - state_secure on Confirm2 reception
* Send :
* - Confirm1 on Commit or DHPart2 reception
*
*/
int state_confirmation_responderSendingConfirm1(bzrtpEvent_t event);
/**
* @brief Initiator send the confirm2 message
*
* Arrives from:
* - state_keyAgreement_initiatorSendingDHPart2 upon confirm1 reception
* - state_keyAgreement_sendingCommit upon Confirm1 reception in non DHM mode
* Goes to:
* - state_secure on Conf2ACK reception or first SRTP message
* Send :
* - Confirm2 until timer's end or transition
*
*/
int state_confirmation_initiatorSendingConfirm2(bzrtpEvent_t event);
/**
* @brief We are in secure state
*
* Arrives from:
* - state_confirmation_responderSendingConfirm1 on Confirm2 reception
* - state_confirmation_initiatorSendingConfirm2 on conf2ACK or first SRTP message
* Goes to:
* - This is the end(we do not support GoClear message), state machine may be destroyed after going to secure mode
* Send :
* - Conf2ACK on Confirm2 reception
*
*/
int state_secure(bzrtpEvent_t event);
/**
* @brief Compute the new rs1 and update the cached secrets according to rfc section 4.6.1
*
* param[in] zrtpContext The context we are operation on
* param[in/out] zrtpChannelContext The channel context we are operation on(contains s0)
*
* return 0 on success, error code otherwise
*/
int bzrtp_updateCachedSecrets(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext);
#endif /* STATEMACHINE_H */
bzrtp-4.4.13/include/typedef.h 0000664 0000000 0000000 00000036467 13641445014 0016222 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2014-2019 Belledonne Communications SARL.
*
* This file is part of bzrtp.
*
* 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, see .
*/
#ifndef TYPEDEF_H
#define TYPEDEF_H
/* maximum number of simultaneous channels opened in a ZRTP session */
#define ZRTP_MAX_CHANNEL_NUMBER 2
/* aux secret may rarely be used define his maximum length in bytes */
#define MAX_AUX_SECRET_LENGTH 64
/* the context will store some of the sent or received packets */
#define PACKET_STORAGE_CAPACITY 4
#define HELLO_MESSAGE_STORE_ID 0
#define COMMIT_MESSAGE_STORE_ID 1
#define DHPART_MESSAGE_STORE_ID 2
#define CONFIRM_MESSAGE_STORE_ID 3
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#ifdef ZIDCACHE_ENABLED
#include "sqlite3.h"
#endif /* ZIDCACHE_ENABLED */
typedef struct bzrtpChannelContext_struct bzrtpChannelContext_t;
#include
#include
#include "packetParser.h"
#include "stateMachine.h"
/* logging */
/* log domain is defined in CMakeList */
#include "bctoolbox/logging.h"
#ifdef _WIN32
#define snprintf _snprintf
#endif
/* timer related definitions */
#define BZRTP_TIMER_ON 1
#define BZRTP_TIMER_OFF 2
/* values for retransmission timers, as recommended in rfc section 6 */
#define HELLO_BASE_RETRANSMISSION_STEP 50
#define HELLO_CAP_RETRANSMISSION_STEP 200
#define HELLO_MAX_RETRANSMISSION_NUMBER 20
#define NON_HELLO_BASE_RETRANSMISSION_STEP 150
#define NON_HELLO_CAP_RETRANSMISSION_STEP 1200
#define NON_HELLO_MAX_RETRANSMISSION_NUMBER 10
/* Client identifier can contain up to 16 characters, it identify the BZRTP library version */
/* Use it to pass bzrtp version number to peer, is it part of Hello message */
/* custom Linphone Instant Messaging Encryption depends on bzrtp version */
/* Note: ZRTP_VERSION and BZrtp version are for now both at 1.1 but they are unrelated */
/* historically since the creation of bzrtp, it used client idenfiers : */
#define ZRTP_CLIENT_IDENTIFIERv1_0a "LINPHONE-ZRTPCPP"
#define ZRTP_CLIENT_IDENTIFIERv1_0b "BZRTP"
/* Since version 1.1 which implement correctly the key export mechanism described in ZRTP RFC 4.5.2, bzrtp lib identifies itself as */
#define ZRTP_CLIENT_IDENTIFIERv1_1 "BZRTPv1.1"
#define ZRTP_CLIENT_IDENTIFIER ZRTP_CLIENT_IDENTIFIERv1_1
/* pgp word list for use with SAS */
extern const char * pgpWordsEven[];
extern const char * pgpWordsOdd[];
/**
* @brief Timer structure : The timer mechanism receives a tick giving a current time in ms
* a timer object will check on tick reception if it must fire or not
*/
typedef struct bzrtpTimer_struct {
uint8_t status; /**< Status is BZRTP_TIMER_ON or BZRTP_TIMER_OFF */
uint64_t firingTime; /**< in ms. The timer will fire if currentTime >= firingTime */
uint8_t firingCount; /**< Timer is used to resend packets, count the number of times a packet has been resent */
int timerStep; /**< in ms. Step between next timer fire: used to reset firingTime for next timer fire */
} bzrtpTimer_t;
/* the rs1 and rs2 are 256 bits long - see rfc section 4.6.1 */
#define RETAINED_SECRET_LENGTH 32
/**
* @brief A set of cached secrets retrieved from the cache as defined
*/
typedef struct cachedSecrets_struct {
uint8_t *rs1; /**< retained secret 1 */
uint8_t rs1Length; /**< retained secret 1 length in bytes */
uint8_t *rs2; /**< retained secret 2 */
uint8_t rs2Length; /**< retained secret 2 length in bytes */
uint8_t *auxsecret; /**< auxiliary secret */
uint8_t auxsecretLength; /**< auxiliary secret length in bytes */
uint8_t *pbxsecret; /**< PBX secret */
uint8_t pbxsecretLength; /**< PBX secret length in bytes */
uint8_t previouslyVerifiedSas; /* boolean, is a SAS has been previously verified with this user */
} cachedSecrets_t;
/**
* @brief The hash of cached secret truncated to the 64 leftmost bits
* aux secret ID is not part of it because channel context dependend while these one are session wise
*/
typedef struct cachedSecretsHash_struct {
uint8_t rs1ID[8]; /**< retained secret 1 Hash */
uint8_t rs2ID[8]; /**< retained secret 2 Hash */
uint8_t pbxsecretID[8]; /**< pbx secret Hash */
} cachedSecretsHash_t;
/**
* @brief The zrtp context of a channel
*
*/
struct bzrtpChannelContext_struct {
void *clientData; /**< this is a pointer provided by the client which is then resent as a parameter of the callbacks functions. Usefull to store RTP session context for example */
uint8_t role;/**< can be INITIATOR or RESPONDER, is set to INITIATOR at creation, may switch to responder later */
bzrtpStateMachine_t stateMachine; /**< The state machine function, holds the current state of the channel: points to the current state function */
bzrtpTimer_t timer; /**< a timer used to manage packets retransmission */
uint32_t selfSSRC; /**< A context is identified by his own SSRC and the peer one */
/* flags */
uint8_t isSecure; /**< This flag is set to 1 when the ZRTP negociation ends and SRTP secrets are generated and confirmed for this channel */
uint8_t isMainChannel; /**< this flag is set for the firt channel only, allow to distinguish channel to be secured using DHM or multiStream */
/* Hash chains, self is generated at channel context init */
uint8_t selfH[4][32]; /**< Store self 256 bits Hash images H0-H3 used to generate messages MAC */
uint8_t peerH[4][32]; /**< Store peer 256 bits Hash images H0-H3 used to check messages authenticity */
/* packet storage : shall store some sent and received packets */
bzrtpPacket_t *selfPackets[PACKET_STORAGE_CAPACITY]; /**< Hello, Commit and DHPart packet locally generated */
bzrtpPacket_t *peerPackets[PACKET_STORAGE_CAPACITY]; /**< Hello, Commit and DHPart packet received from peer */
/* peer Hello hash : store the peer hello hash when given by signaling */
uint8_t *peerHelloHash; /**< peer hello hash - SHA256 of peer Hello packet, given through signaling, shall be a 32 bytes buffer */
/* sequence number: self and peer */
uint16_t selfSequenceNumber; /**< Sequence number of the next packet to be sent */
uint16_t peerSequenceNumber; /**< Sequence number of the last valid received packet */
/* algorithm agreed after Hello message exchange(use mapping define in cryptoUtils.h) and the function pointer to use them */
uint8_t hashAlgo; /**< hash algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoUtils.h */
uint8_t hashLength; /**< the length in bytes of a hash generated with the agreed hash algo */
uint8_t cipherAlgo; /**< cipher algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoUtils.h */
uint8_t cipherKeyLength; /**< the length in bytes of the key needed by the agreed cipher block algo */
uint8_t authTagAlgo; /**< srtp authentication tag algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoUtils.h */
uint8_t keyAgreementAlgo; /**< key agreement algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoUtils.h */
uint16_t keyAgreementLength; /**< the length in byte of the secret generated by the agreed key exchange algo */
uint8_t sasAlgo; /**< sas rendering algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoUtils.h */
uint8_t sasLength; /**< length of the SAS depends on the algorithm agreed */
/* function pointer to the agreed algorithms - Note, key agreement manage directly this selection so it is not set here */
void (*hmacFunction)(const uint8_t *key, size_t keyLength, const uint8_t *input, size_t inputLength, uint8_t hmacLength, uint8_t *output); /**< function pointer to the agreed hmacFunction */
void (*hashFunction)(const uint8_t *input, size_t inputLength, uint8_t hashLength, uint8_t *output); /**< function pointer to the agreed hash function */
void (*cipherEncryptionFunction)(const uint8_t *key, const uint8_t *IV, const uint8_t *input, size_t inputLength, uint8_t *output); /**< function pointer to the agreed cipher block function, encryption mode */
void (*cipherDecryptionFunction)(const uint8_t *key, const uint8_t *IV, const uint8_t *input, size_t inputLength, uint8_t *output); /**< function pointer to the agreed cipher block function, decryption mode */
void (*sasFunction)(uint32_t sas, char * output, int outputSize); /**< function pointer to the agreed sas rendering function */
/* keys */
uint8_t *s0; /**< the s0 as describred rfc section 4.4 - have a length of hashLength */
uint8_t *KDFContext; /**< defined in rfc section 4.4 */
uint16_t KDFContextLength; /**< length of the KDF context, is 24 + output length of the selected hash algo */
uint8_t *mackeyi; /**< the initiator mackey as defined in rfc section 4.5.3 - have a length of hashLength */
uint8_t *mackeyr; /**< the responder mackey as defined in rfc section 4.5.3 - have a length of hashLength*/
uint8_t *zrtpkeyi; /**< the initiator mackey as defined in rfc section 4.5.3 - have a length of cipherKeyLength */
uint8_t *zrtpkeyr; /**< the responder mackey as defined in rfc section 4.5.3 - have a length of cipherKeyLength*/
bzrtpSrtpSecrets_t srtpSecrets; /**< the secrets keys and salt needed by SRTP */
/* shared secret hash : unlike pbx, rs1 and rs2 secret hash, the auxsecret hash use a channel dependent data (H3) and is then stored in the channel context */
uint8_t initiatorAuxsecretID[8]; /**< initiator auxiliary secret Hash */
uint8_t responderAuxsecretID[8]; /**< responder auxiliary secret Hash */
/* temporary buffer stored in the channel context */
bzrtpPacket_t *pingPacket; /**< Temporary stores a ping packet when received to be used to create the pingACK response */
};
/**
* @brief structure of the ZRTP engine context
* Store current state, timers, HMAC and encryption keys
*/
struct bzrtpContext_struct {
/* contexts */
bctbx_rng_context_t *RNGContext; /**< context for random number generation */
void *keyAgreementContext; /**< context for the key agreement operations. Only one key agreement computation may be done during a call, so this belongs to the general context and not the channel one */
uint8_t keyAgreementAlgo; /**< key agreement algorithm agreed on the first channel, the one performing key exchange, stored using integer mapping defined in cryptoUtils.h, */
/* flags */
uint8_t isInitialised; /**< this flag is set once the context was initialised : self ZID retrieved from cache or generated, used to unlock the creation of addtional channels */
uint8_t isSecure; /**< this flag is set to 1 after the first channel have completed the ZRTP protocol exchange(i.e. when the responder have sent the conf2ACK message), must be set in order to start an additional channel */
uint8_t peerSupportMultiChannel; /**< this flag is set to 1 when the first valid HELLO packet from peer arrives if it support Multichannel ZRTP */
uint64_t timeReference; /**< in ms. This field will set at each channel State Machine start and updated at each tick after creation of the context, it is used to set the firing time of a channel timer */
/* callbacks */
bzrtpCallbacks_t zrtpCallbacks; /**< structure holding all the pointers to callbacks functions needed by the ZRTP engine. Functions are set by client using the bzrtp_setCallback function */
/* channel contexts */
bzrtpChannelContext_t *channelContext[ZRTP_MAX_CHANNEL_NUMBER]; /**< All the context data needed for a channel are stored in a dedicated structure */
/* List of available algorithms, initialised with algo implemented in cryptoWrapper but can be then be modified according to user settings */
uint8_t hc; /**< hash count -zrtpPacket set to 0 means we support only HMAC-SHA256 (4 bits) */
uint8_t supportedHash[7]; /**< list of supported hash algorithms mapped to uint8_t */
uint8_t cc; /**< cipher count - set to 0 means we support only AES128-CFB128 (4 bits) */
uint8_t supportedCipher[7]; /**< list of supported cipher algorithms mapped to uint8_t */
uint8_t ac; /**< auth tag count - set to 0 mean we support only HMAC-SHA1-32 (4 bits) */
uint8_t supportedAuthTag[7]; /**< list of supported SRTP authentication tag algorithms mapped to uint8_t */
uint8_t kc; /**< key agreement count - set to 0 means we support only Diffie-Hellman-Merkle 3072 (4 bits) */
uint8_t supportedKeyAgreement[7]; /**< list of supported key agreement algorithms mapped to uint8_t */
uint8_t sc; /**< sas count - set to 0 means we support only base32 (4 bits) */
uint8_t supportedSas[7]; /**< list of supported Sas representations mapped to uint8_t */
/* ZIDs and cache */
#ifdef ZIDCACHE_ENABLED
sqlite3 *zidCache; /**< an sqlite3 db pointer to the zid cache **/
#else
void *zidCache; /**< an empty pointer always set to NULL when cache is disabled **/
#endif /* ZIDCACHE_ENABLED */
bctbx_mutex_t *zidCacheMutex; /**< lock access to the cache if provided **/
int zuid; /**< internal id used to address zid cache SIP/ZID pair binding **/
char *selfURI; /**< a null terminated string storing the local user URI **/
uint8_t selfZID[12]; /**< The ZRTP Identifier of this ZRTP end point - a random if running cache less */
char *peerURI; /**< a null terminated string storing the peer user URI **/
uint8_t peerZID[12]; /**< The ZRTP Identifier of the peer ZRTP end point - given by the Hello packet */
uint32_t peerBzrtpVersion; /**< The Bzrtp library version used by peer, retrieved from the peer Hello packet Client identifier and used for backward compatibility in exported key computation */
cachedSecrets_t cachedSecret; /**< the local cached secrets */
cachedSecretsHash_t initiatorCachedSecretHash; /**< The hash of cached secret from initiator side, computed as described in rfc section 4.3.1 */
cachedSecretsHash_t responderCachedSecretHash; /**< The hash of cached secret from responder side, computed as described in rfc section 4.3.1 */
uint8_t cacheMismatchFlag; /**< Flag set in case of cache mismatch(detected in DHM mode when DH part packet arrives) */
uint8_t peerPVS; /**< used to store value of PVS flag sent by peer in the confirm packet on first channel only, then used to compute the PVS value sent to the application */
/* transient auxiliary shared secret : in addition to the auxiliary shared secret stored in ZID cache, caller can provide a shared secret to the zrtp context which will be used for this transaction only */
/* both auxiliary secret are used and combined as transientAuxiliarySecret appended to cachedAuxiliarySecret*/
uint8_t *transientAuxSecret; /**< an auxiliary secret not stored in cache, provided after context creation and before the main channel is started */
size_t transientAuxSecretLength; /**< size of the previous buffer */
/* keys */
uint8_t *ZRTPSess; /**< ZRTP session key as described in rfc section 4.5.2 */
uint8_t ZRTPSessLength; /**< length of ZRTP session key depends on agreed hash algorithm */
uint8_t *exportedKey; /**< computed as in rfc section 4.5.2 only if needed */
uint8_t exportedKeyLength; /**< length of previous buffer, shall be channel[0]->hashLength */
};
#endif /* ifndef TYPEDEF_H */
bzrtp-4.4.13/include/zidCache.h 0000664 0000000 0000000 00000010566 13641445014 0016264 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2014-2019 Belledonne Communications SARL.
*
* This file is part of bzrtp.
*
* 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, see .
*/
#ifndef ZIDCACHE_H
#define ZIDCACHE_H
#include "typedef.h"
/**
* @brief Parse the cache to find secrets associated to the given ZID, set them and their length in the context if they are found
* Note: this function also retrieve zuid(set in the context) wich allow successive calls to cache operation to be faster.
*
* @param[in/out] context the current context, used to get the cache db pointer, self and peer URI and store results
* @param[in] peerZID a byte array of the peer ZID
*
* return 0 on succes, error code otherwise
*/
BZRTP_EXPORT int bzrtp_getPeerAssociatedSecrets(bzrtpContext_t *context, uint8_t peerZID[12]);
/**
* @brief get the cache internal id used to bind local uri(hence local ZID associated to it)<->peer uri/peer ZID.
* Providing a valid local URI(already present in cache), a peer ZID and peer URI will return the zuid creating it if needed and requested
* Any pair ZID/sipURI shall identify an account on a device.
*
* @param[in/out] db the opened sqlite database pointer
* @param[in] selfURI local URI, must be already associated to a ZID in the DB(association is performed by any call of getSelfZID on this URI)
* @param[in] peerURI peer URI
* @param[in] peerZID peer ZID
* @param[in] insertFlag A boolean managing insertion or not of a new row:
* - BZRTP_ZIDCACHE_DONT_INSERT_ZUID : if not found identity binding won't lead to insertion and return zuid will be 0
* - BZRTP_ZIDCACHE_INSERT_ZUID : if not found, insert a new row in ziduri table and return newly inserted zuid
* @param[out] zuid the internal db reference to the data row matching this particular pair of correspondant
* if identity binding is not found and insertFlag set to 0, this value is set to 0
* @param[in] zidCacheMutex Points to a mutex used to lock zidCache database access, ignored if NULL
*
* @return 0 on success, BZRTP_ERROR_CACHE_PEERNOTFOUND if peer was not in and the insert flag is not set to BZRTP_ZIDCACHE_INSERT_ZUID, error code otherwise
*/
#define BZRTP_ZIDCACHE_DONT_INSERT_ZUID 0
#define BZRTP_ZIDCACHE_INSERT_ZUID 1
BZRTP_EXPORT int bzrtp_cache_getZuid(void *dbPointer, const char *selfURI, const char *peerURI, const uint8_t peerZID[12], const uint8_t insertFlag, int *zuid, bctbx_mutex_t *zidCacheMutex);
/**
* @brief This is a convenience wrapper to the bzrtp_cache_write function which will also take care of
* setting the ziduri table 'active' flag to one for the current row and reset all other rows with matching peeruri
*
* Write(insert or update) data in cache, adressing it by zuid (ZID/URI binding id used in cache)
* Get arrays of column names, values to be inserted, lengths of theses values
* All three arrays must be the same lenght: columnsCount
* If the row isn't present in the given table, it will be inserted
*
* @param[in/out] context the current context, used to get the cache db pointer, zuid and cache mutex
* @param[in] tableName The name of the table to write in the db, must already exists. Null terminated string
* @param[in] columns An array of null terminated strings containing the name of the columns to update
* @param[in] values An array of buffers containing the values to insert/update matching the order of columns array
* @param[in] lengths An array of integer containing the lengths of values array buffer matching the order of columns array
* @param[in] columnsCount length common to columns,values and lengths arrays
*
* @return 0 on succes, error code otherwise
*/
BZRTP_EXPORT int bzrtp_cache_write_active(bzrtpContext_t *context, const char *tableName, const char **columns, uint8_t **values, size_t *lengths, uint8_t columnsCount);
#endif /* ZIDCACHE_H */
bzrtp-4.4.13/libbzrtp.pc.in 0000664 0000000 0000000 00000000437 13641445014 0015533 0 ustar 00root root 0000000 0000000 # This is a comment
prefix=@prefix@
exec_prefix=@exec_prefix@
includedir=@includedir@
Name: libbzrtp
Description: Implement the ZRTP Media Path Key agreement for unicast secure RTP
Version: @PACKAGE_VERSION@
Libs: -L@libdir@ -lbzrtp
Cflags: -I@includedir@
bzrtp-4.4.13/src/ 0000775 0000000 0000000 00000000000 13641445014 0013535 5 ustar 00root root 0000000 0000000 bzrtp-4.4.13/src/CMakeLists.txt 0000664 0000000 0000000 00000006310 13641445014 0016275 0 ustar 00root root 0000000 0000000 ############################################################################
# CMakeLists.txt
# Copyright (C) 2014 Belledonne Communications, Grenoble France
#
############################################################################
#
# 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 2
# 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.
#
############################################################################
set(SOURCE_FILES
bzrtp.c
cryptoUtils.c
packetParser.c
pgpwords.c
stateMachine.c
zidCache.c
)
add_definitions(
-DBCTBX_LOG_DOMAIN="bzrtp"
)
if(POLARSSL_FOUND)
list(APPEND SOURCE_FILES cryptoPolarssl.c)
elseif(MBEDTLS_FOUND)
list(APPEND SOURCE_FILES cryptoMbedtls.c)
endif()
bc_apply_compile_flags(SOURCE_FILES STRICT_OPTIONS_CPP)
set(INCLUDE_DIRS )
set(LIBS )
if(SQLITE3_FOUND)
list(APPEND INCLUDE_DIRS ${SQLITE3_INCLUDE_DIRS})
list(APPEND LIBS $ $)
endif()
if(XML2_FOUND)
list(APPEND INCLUDE_DIRS ${XML2_INCLUDE_DIRS})
list(APPEND LIBS $ $)
endif()
if(ENABLE_STATIC)
add_library(bzrtp STATIC ${SOURCE_FILES})
set_target_properties(bzrtp PROPERTIES OUTPUT_NAME bzrtp)
target_include_directories(bzrtp INTERFACE
$
PRIVATE ${INCLUDE_DIRS})
target_link_libraries(bzrtp PUBLIC bctoolbox ${LIBS})
install(TARGETS bzrtp EXPORT ${EXPORT_TARGETS_NAME}Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
endif()
if(ENABLE_SHARED)
add_library(bzrtp SHARED ${SOURCE_FILES})
target_compile_definitions(bzrtp PRIVATE "-DBZRTP_EXPORTS")
set_target_properties(bzrtp PROPERTIES VERSION 0)
target_include_directories(bzrtp INTERFACE
$
$
PRIVATE ${INCLUDE_DIRS}
)
target_link_libraries(bzrtp PUBLIC bctoolbox ${LIBS})
if(MSVC)
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/bzrtp.pdb
DESTINATION ${CMAKE_INSTALL_BINDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
endif()
endif()
install(TARGETS bzrtp EXPORT ${EXPORT_TARGETS_NAME}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
endif()
bzrtp-4.4.13/src/Makefile.am 0000664 0000000 0000000 00000000555 13641445014 0015576 0 ustar 00root root 0000000 0000000 lib_LTLIBRARIES = libbzrtp.la
libbzrtp_la_LIBADD= $(SQLITE3_LIBS) $(LIBXML2_LIBS) $(BCTOOLBOX_LIBS)
libbzrtp_la_SOURCES= bzrtp.c cryptoUtils.c packetParser.c zidCache.c stateMachine.c pgpwords.c
AM_CPPFLAGS= -I$(top_srcdir)/include
AM_CFLAGS= $(LIBXML2_CFLAGS) $(LIBSQLITE3_CFLAGS) $(BCTOOLBOX_CFLAGS)
libbzrtp_la_LDFLAGS=-fvisibility=hidden -no-undefined
bzrtp-4.4.13/src/bzrtp.c 0000664 0000000 0000000 00000147000 13641445014 0015044 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2014-2019 Belledonne Communications SARL.
*
* This file is part of bzrtp.
*
* 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, see .
*/
#include
#include
#include "bzrtp/bzrtp.h"
#include "typedef.h"
#include "bctoolbox/crypto.h"
#include "cryptoUtils.h"
#include "zidCache.h"
#include "packetParser.h"
#include "stateMachine.h"
#define BZRTP_ERROR_INVALIDCHANNELCONTEXT 0x8001
/* local functions prototypes */
static int bzrtp_initChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, uint32_t selfSSRC, uint8_t isMain);
static void bzrtp_destroyChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext);
static bzrtpChannelContext_t *getChannelContext(bzrtpContext_t *zrtpContext, uint32_t selfSSRC);
static uint8_t copyCryptoTypes(uint8_t destination[7], uint8_t source[7], uint8_t size);
/*
* Create context structure and initialise it
*
* @return The ZRTP engine context data
*
*/
bzrtpContext_t *bzrtp_createBzrtpContext(void) {
int i;
/*** create and intialise the context structure ***/
bzrtpContext_t *context = malloc(sizeof(bzrtpContext_t));
memset(context, 0, sizeof(bzrtpContext_t));
/* start the random number generator */
context->RNGContext = bctbx_rng_context_new(); /* TODO: give a seed for the RNG? */
/* set the DHM context to NULL, it will be created if needed when creating a DHPart packet */
context->keyAgreementContext = NULL;
context->keyAgreementAlgo = ZRTP_UNSET_ALGO;
/* set flags */
context->isSecure = 0; /* start unsecure */
context->peerSupportMultiChannel = 0; /* peer does not support Multichannel by default */
context->isInitialised = 0; /* will be set by bzrtp_initBzrtpContext */
/* set to NULL all callbacks pointer */
context->zrtpCallbacks.bzrtp_statusMessage = NULL;
context->zrtpCallbacks.bzrtp_sendData = NULL;
context->zrtpCallbacks.bzrtp_srtpSecretsAvailable = NULL;
context->zrtpCallbacks.bzrtp_startSrtpSession = NULL;
context->zrtpCallbacks.bzrtp_contextReadyForExportedKeys = NULL;
for (i=1; ichannelContext[i] = NULL;
}
/* get the list of crypto algorithms provided by the crypto module */
/* this list may then be updated according to users settings */
context->hc = bzrtpUtils_getAvailableCryptoTypes(ZRTP_HASH_TYPE, context->supportedHash);
context->cc = bzrtpUtils_getAvailableCryptoTypes(ZRTP_CIPHERBLOCK_TYPE, context->supportedCipher);
context->ac = bzrtpUtils_getAvailableCryptoTypes(ZRTP_AUTHTAG_TYPE, context->supportedAuthTag);
context->kc = bzrtpUtils_getAvailableCryptoTypes(ZRTP_KEYAGREEMENT_TYPE, context->supportedKeyAgreement);
context->sc = bzrtpUtils_getAvailableCryptoTypes(ZRTP_SAS_TYPE, context->supportedSas);
/* initialise cached secret buffer to null */
context->zidCache = NULL; /* a pointer to the sqlite3 db accessor, can be NULL if running cacheless */
context->zidCacheMutex = NULL; /* a pointer to a mutex provided by the environment to lock database during access, ignored if NULL */
context->zuid = 0;
context->peerBzrtpVersion = 0;
context->selfURI = NULL;
context->cachedSecret.rs1 = NULL;
context->cachedSecret.rs1Length = 0;
context->cachedSecret.rs2 = NULL;
context->cachedSecret.rs2Length = 0;
context->cachedSecret.pbxsecret = NULL;
context->cachedSecret.pbxsecretLength = 0;
context->cachedSecret.auxsecret = NULL;
context->cachedSecret.auxsecretLength = 0;
context->cacheMismatchFlag = 0;
context->peerPVS = 0;
/* initialise transient shared auxiliary secret buffer */
context->transientAuxSecret = NULL;
context->transientAuxSecretLength = 0;
/* initialise key buffers */
context->ZRTPSess = NULL;
context->ZRTPSessLength = 0;
context->exportedKey = NULL;
context->exportedKeyLength = 0;
return context;
}
/**
* @brief Set the pointer allowing cache access
*
* @param[in] zidCachePointer Used by internal function to access cache: turn into a sqlite3 pointer if cache is enabled
* @param[in] selfURI Local URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
* @param[in] peerURI Peer URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
*
* @return 0 or BZRTP_CACHE_SETUP(if cache is populated by this call) on success, error code otherwise
*/
int bzrtp_setZIDCache(bzrtpContext_t *context, void *zidCache, const char *selfURI, const char *peerURI) {
#ifdef ZIDCACHE_ENABLED
/* is zrtp context valid */
if (context==NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* zidCache pointer is actually a pointer to sqlite3 db, store it in context */
context->zidCache = (sqlite3 *)zidCache;
if (context->selfURI != NULL) {
free(context->selfURI);
}
context->selfURI = strdup(selfURI);
if (context->peerURI != NULL) {
free(context->peerURI);
}
context->peerURI = strdup(peerURI);
/* and init the cache(create needed tables if they don't exist) */
return bzrtp_initCache_lock(context->zidCache, context->zidCacheMutex);
#else /* ZIDCACHE_ENABLED */
return BZRTP_ERROR_CACHEDISABLED;
#endif /* ZIDCACHE_ENABLED */
}
/**
* @brief Set the pointer allowing cache access, this version of the function get a mutex to lock the cache when accessing it
*
* Note: bzrtp does not manage the given mutex pointer, it has to be already initialized
* and shall be destroyed by environment after the BZRTP session is completed.
*
* @param[in] zidCachePointer Used by internal function to access cache: turn into a sqlite3 pointer if cache is enabled
* @param[in] selfURI Local URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
* @param[in] peerURI Peer URI used for this communication, needed to perform cache operation, NULL terminated string, duplicated by this function
* @param[in] zidCacheMutex Points to a mutex used to lock zidCache database access. Can be NULL, the zidcache is then non locked.
*
* @return 0 or BZRTP_CACHE_SETUP(if cache is populated by this call) on success, error code otherwise
*/
int bzrtp_setZIDCache_lock(bzrtpContext_t *context, void *zidCache, const char *selfURI, const char *peerURI, bctbx_mutex_t *zidCacheMutex) {
#ifdef ZIDCACHE_ENABLED
/* is zrtp context valid */
if (context==NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
context->zidCacheMutex = zidCacheMutex;
/* have the non lockable function finish the job */
return bzrtp_setZIDCache(context, zidCache, selfURI, peerURI);
#else /* ZIDCACHE_ENABLED */
return BZRTP_ERROR_CACHEDISABLED;
#endif /* ZIDCACHE_ENABLED */
}
/**
* @brief Perform some initialisation which can't be done without some callback functions:
* This function is called once per session when the first channel is created.
* It must be called after the cache access pointer have been set
* - Get ZID from cache or generate a random ZID
* - Initialise the first channel
*
* @param[in] context The context to initialise
* @param[in] selfSSRC SSRC of the first channel
* @return 0 on success
*/
int bzrtp_initBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC) {
/* is zrtp context valid */
if (context==NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* initialise self ZID. Randomly generated if no ZID is found in cache or no cache found */
bzrtp_getSelfZID_lock(context->zidCache, context->selfURI, context->selfZID, context->RNGContext, context->zidCacheMutex);
context->isInitialised = 1;
/* allocate 1 channel context, set all the others pointers to NULL */
context->channelContext[0] = (bzrtpChannelContext_t *)malloc(sizeof(bzrtpChannelContext_t));
memset(context->channelContext[0], 0, sizeof(bzrtpChannelContext_t));
return bzrtp_initChannelContext(context, context->channelContext[0], selfSSRC, 1);
}
/*
* Free memory of context structure to a channel, if all channels are freed, free the global zrtp context
* @param[in] context Context hosting the channel to be destroyed.(note: the context zrtp context itself is destroyed with the last channel)
* @param[in] selfSSRC The SSRC identifying the channel to be destroyed
*
* @return the number of channel still active in this ZRTP context
*
*/
int bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC) {
int i;
int validChannelsNumber = 0;
if (context == NULL) {
return 0;
}
/* Find the channel to be destroyed, destroy it and check if we have anymore valid channels */
for (i=0; ichannelContext[i] != NULL) {
if (context->channelContext[i]->selfSSRC == selfSSRC) {
bzrtp_destroyChannelContext(context, context->channelContext[i]);
context->channelContext[i] = NULL;
} else {
validChannelsNumber++;
}
}
}
if (validChannelsNumber>0) {
return validChannelsNumber; /* we have more valid channels, keep the zrtp context */
}
/* We have no more channel, destroy the zrtp context */
/* key agreement context shall already been destroyed after s0 computation, but just in case */
if (context->keyAgreementContext != NULL) {
if (context->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X255 || context->keyAgreementAlgo == ZRTP_KEYAGREEMENT_X448) {
bctbx_DestroyECDHContext((bctbx_ECDHContext_t *)context->keyAgreementContext);
}
if (context->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH2k || context->keyAgreementAlgo == ZRTP_KEYAGREEMENT_DH3k) {
bctbx_DestroyDHMContext((bctbx_DHMContext_t *)context->keyAgreementContext);
}
context->keyAgreementContext = NULL;
context->keyAgreementAlgo = ZRTP_UNSET_ALGO;
}
/* Destroy keys and secrets */
/* rs1, rs2, pbxsecret and auxsecret shall already been destroyed, just in case */
if (context->cachedSecret.rs1!=NULL) {
bzrtp_DestroyKey(context->cachedSecret.rs1, context->cachedSecret.rs1Length, context->RNGContext);
free(context->cachedSecret.rs1);
context->cachedSecret.rs1 = NULL;
}
if (context->cachedSecret.rs2!=NULL) {
bzrtp_DestroyKey(context->cachedSecret.rs2, context->cachedSecret.rs2Length, context->RNGContext);
free(context->cachedSecret.rs2);
context->cachedSecret.rs2 = NULL;
}
if (context->cachedSecret.auxsecret!=NULL) {
bzrtp_DestroyKey(context->cachedSecret.auxsecret, context->cachedSecret.auxsecretLength, context->RNGContext);
free(context->cachedSecret.auxsecret);
context->cachedSecret.auxsecret = NULL;
}
if (context->cachedSecret.pbxsecret!=NULL) {
bzrtp_DestroyKey(context->cachedSecret.pbxsecret, context->cachedSecret.pbxsecretLength, context->RNGContext);
free(context->cachedSecret.pbxsecret);
context->cachedSecret.pbxsecret = NULL;
}
if (context->ZRTPSess!=NULL) {
bzrtp_DestroyKey(context->ZRTPSess, context->ZRTPSessLength, context->RNGContext);
free(context->ZRTPSess);
context->ZRTPSess=NULL;
}
if (context->exportedKey!=NULL) {
bzrtp_DestroyKey(context->exportedKey, context->exportedKeyLength, context->RNGContext);
free(context->exportedKey);
context->ZRTPSess=NULL;
}
free(context->selfURI);
free(context->peerURI);
/* transient shared auxiliary secret */
if (context->transientAuxSecret != NULL) {
bzrtp_DestroyKey(context->transientAuxSecret, context->transientAuxSecretLength, context->RNGContext);
free(context->transientAuxSecret);
context->transientAuxSecret=NULL;
}
/* destroy the RNG context at the end because it may be needed to destroy some keys */
bctbx_rng_context_free(context->RNGContext);
context->RNGContext = NULL;
free(context);
return 0;
}
/*
* @brief Allocate a function pointer to the callback function identified by his id
* @param[in/out] context The zrtp context to set the callback function
* @param[in] cbs A structure containing all the callbacks to supply.
*
* @return 0 on success
*/
int bzrtp_setCallbacks(bzrtpContext_t *context, const bzrtpCallbacks_t *cbs) {
/* is zrtp context valid */
if (context==NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
context->zrtpCallbacks=*cbs;
return 0;
}
/**
* @brief Add a channel to an existing context, this can be done only if the first channel has concluded a DH key agreement
*
* @param[in/out] zrtpContext The zrtp context who will get the additionnal channel. Must be in secure state.
* @param[in] selfSSRC The SSRC given to the channel context
*
* @return 0 on succes, error code otherwise
*/
int bzrtp_addChannel(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) {
bzrtpChannelContext_t *zrtpChannelContext = NULL;
int i=0;
/* is zrtp context valid */
if (zrtpContext==NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* context must be initialised(selfZID available) to enable the creation of an additional channel */
if (zrtpContext->isInitialised == 0) {
return BZRTP_ERROR_CONTEXTNOTREADY;
}
/* get the first free channel context from ZRTP context and create a channel context */
while(ichannelContext[i] == NULL) {
int retval;
zrtpChannelContext = (bzrtpChannelContext_t *)malloc(sizeof(bzrtpChannelContext_t));
memset(zrtpChannelContext, 0, sizeof(bzrtpChannelContext_t));
retval = bzrtp_initChannelContext(zrtpContext, zrtpChannelContext, selfSSRC, 0);
if (retval != 0) {
free(zrtpChannelContext);
return retval;
}
} else {
i++;
}
}
if (zrtpChannelContext == NULL) {
return BZRTP_ERROR_UNABLETOADDCHANNEL;
}
/* attach the created channel to the ZRTP context */
zrtpContext->channelContext[i] = zrtpChannelContext;
return 0;
}
/*
* @brief Start the state machine of the specified channel
*
* @param[in/out] zrtpContext The ZRTP context hosting the channel to be started
* @param[in] selfSSRC The SSRC identifying the channel to be started(will start sending Hello packets and listening for some)
*
* @return 0 on succes, error code otherwise
*/
int bzrtp_startChannelEngine(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) {
bzrtpEvent_t initEvent;
/* get channel context */
bzrtpChannelContext_t *zrtpChannelContext = getChannelContext(zrtpContext, selfSSRC);
if (zrtpChannelContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* is this channel already started? */
if (zrtpChannelContext->stateMachine != NULL) {
return BZRTP_ERROR_CHANNELALREADYSTARTED;
}
/* if this is an additional channel(not channel 0), we must be sure that channel 0 is already secured */
if (zrtpChannelContext->isMainChannel == 0) {
/* is ZRTP context able to add a channel (means channel 0 has already performed the secrets generation) */
if (zrtpContext->isSecure == 0) {
return BZRTP_ERROR_CONTEXTNOTREADY;
}
/* check the peer support Multichannel(shall be set in the first Hello message received) */
if (zrtpContext->peerSupportMultiChannel == 0) {
return BZRTP_ERROR_MULTICHANNELNOTSUPPORTEDBYPEER;
}
}
/* set the timer reference to 0 to force a message to be sent at first timer tick */
zrtpContext->timeReference = 0;
/* start the engine by setting the state to init and calling it */
zrtpChannelContext->stateMachine = state_discovery_init;
/* create an INIT event to call the init state function which will create a hello packet and start sending it */
initEvent.eventType = BZRTP_EVENT_INIT;
initEvent.bzrtpPacketString = NULL;
initEvent.bzrtpPacketStringLength = 0;
initEvent.zrtpContext = zrtpContext;
initEvent.zrtpChannelContext = zrtpChannelContext;
return zrtpChannelContext->stateMachine(initEvent);
}
/*
* @brief Send the current time to a specified channel, it will check if it has to trig some timer
*
* @param[in/out] zrtpContext The ZRTP context hosting the channel
* @param[in] selfSSRC The SSRC identifying the channel
* @param[in] timeReference The current time in ms
*
* @return 0 on succes, error code otherwise
*/
int bzrtp_iterate(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint64_t timeReference) {
/* get channel context */
bzrtpChannelContext_t *zrtpChannelContext = getChannelContext(zrtpContext, selfSSRC);
if (zrtpChannelContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* update the context time reference used when arming timers */
zrtpContext->timeReference = timeReference;
if (zrtpChannelContext->timer.status == BZRTP_TIMER_ON) {
if (zrtpChannelContext->timer.firingTime<=timeReference) { /* we must trig the timer */
bzrtpEvent_t timerEvent;
zrtpChannelContext->timer.firingCount++;
/* create a timer event */
timerEvent.eventType = BZRTP_EVENT_TIMER;
timerEvent.bzrtpPacketString = NULL;
timerEvent.bzrtpPacketStringLength = 0;
timerEvent.bzrtpPacket = NULL;
timerEvent.zrtpContext = zrtpContext;
timerEvent.zrtpChannelContext = zrtpChannelContext;
/* send it to the state machine*/
if (zrtpChannelContext->stateMachine != NULL) {
return zrtpChannelContext->stateMachine(timerEvent);
}
}
}
return 0;
}
/*
* @brief Set the client data pointer in a channel context
* This pointer is returned to the client by the callbacks function, used to store associated contexts (RTP session)
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel to be linked to the client Data
* @param[in] clientData The clientData pointer, casted to a (void *)
*
* @return 0 on success
*
*/
int bzrtp_setClientData(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, void *clientData) {
/* get channel context */
bzrtpChannelContext_t *zrtpChannelContext = getChannelContext(zrtpContext, selfSSRC);
if (zrtpChannelContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
zrtpChannelContext->clientData = clientData;
return 0;
}
/*
* @brief Process a received message
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel receiving the message
* @param[in] zrtpPacketString The packet received
* @param[in] zrtpPacketStringLength Length of the packet in bytes
*
* @return 0 on success, errorcode otherwise
*/
int bzrtp_processMessage(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint8_t *zrtpPacketString, uint16_t zrtpPacketStringLength) {
int retval;
bzrtpPacket_t *zrtpPacket;
bzrtpEvent_t event;
/* get channel context */
bzrtpChannelContext_t *zrtpChannelContext = getChannelContext(zrtpContext, selfSSRC);
if (zrtpChannelContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* check the context is initialised (we may receive packets before initialisation is complete i.e. between channel initialisation and channel start) */
if (zrtpChannelContext->stateMachine == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT; /* drop the message */
}
/* first check the packet */
zrtpPacket = bzrtp_packetCheck(zrtpPacketString, zrtpPacketStringLength, zrtpChannelContext->peerSequenceNumber, &retval);
if (retval != 0) {
/*TODO: check the returned error code and do something or silent drop? */
return retval;
}
/* TODO: Intercept error and ping zrtp packets */
/* if we have a ping packet, just answer with a ping ACK and do not forward to the state machine */
if (zrtpPacket->messageType == MSGTYPE_PING) {
bzrtpPacket_t *pingAckPacket = NULL;
bzrtp_packetParser(zrtpContext, zrtpChannelContext, zrtpPacketString, zrtpPacketStringLength, zrtpPacket);
/* store ping packet in the channel context as packet creator will need it to create the pingACK */
zrtpChannelContext->pingPacket = zrtpPacket;
/* create the pingAck packet */
pingAckPacket = bzrtp_createZrtpPacket(zrtpContext, zrtpChannelContext, MSGTYPE_PINGACK, &retval);
if (retval == 0) {
retval = bzrtp_packetBuild(zrtpContext, zrtpChannelContext, pingAckPacket, zrtpChannelContext->selfSequenceNumber);
if (retval==0 && zrtpContext->zrtpCallbacks.bzrtp_sendData!=NULL) { /* send the packet */
zrtpContext->zrtpCallbacks.bzrtp_sendData(zrtpChannelContext->clientData, pingAckPacket->packetString, pingAckPacket->messageLength+ZRTP_PACKET_OVERHEAD);
zrtpChannelContext->selfSequenceNumber++;
}
}
/* free packets and reset channel context storage */
bzrtp_freeZrtpPacket(zrtpPacket);
bzrtp_freeZrtpPacket(pingAckPacket);
zrtpChannelContext->pingPacket = NULL;
return retval;
}
/* build a packet event of it and send it to the state machine */
event.eventType = BZRTP_EVENT_MESSAGE;
event.bzrtpPacketString = zrtpPacketString;
event.bzrtpPacketStringLength = zrtpPacketStringLength;
event.bzrtpPacket = zrtpPacket;
event.zrtpContext = zrtpContext;
event.zrtpChannelContext = zrtpChannelContext;
return zrtpChannelContext->stateMachine(event);
}
/*
* @brief Called by user when the SAS has been verified
* update the cache(if any) to set the previously verified flag
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
*/
void bzrtp_SASVerified(bzrtpContext_t *zrtpContext) {
if (zrtpContext != NULL) {
uint8_t pvsFlag = 1;
const char *colNames[] = {"pvs"};
uint8_t *colValues[] = {&pvsFlag};
size_t colLength[] = {1};
/* check if we must update the cache(delayed until sas verified in case of cache mismatch) */
if (zrtpContext->cacheMismatchFlag == 1) {
zrtpContext->cacheMismatchFlag = 0;
bzrtp_updateCachedSecrets(zrtpContext, zrtpContext->channelContext[0]); /* channel[0] is the only one in DHM mode, so the only one able to have a cache mismatch */
}
bzrtp_cache_write_lock(zrtpContext->zidCache, zrtpContext->zuid, "zrtp", colNames, colValues, colLength, 1, zrtpContext->zidCacheMutex);
}
}
/*
* @brief Called by user when the SAS has been set to unverified
* update the cache(if any) to unset the previously verified flag
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
*/
void bzrtp_resetSASVerified(bzrtpContext_t *zrtpContext) {
if (zrtpContext != NULL) {
uint8_t pvsFlag = 0;
const char *colNames[] = {"pvs"};
uint8_t *colValues[] = {&pvsFlag};
size_t colLength[] = {1};
bzrtp_cache_write_lock(zrtpContext->zidCache, zrtpContext->zuid, "zrtp", colNames, colValues, colLength, 1, zrtpContext->zidCacheMutex);
}
}
/*
* @brief Allow client to compute an exported according to RFC section 4.5.2
* Check the context is ready(we already have a master exported key and KDF context)
* and run KDF(master exported key, "Label", KDF_Context, negotiated hash Length)
*
* @param[in] zrtpContext The ZRTP context we're dealing with
* @param[in] label Label used in the KDF
* @param[in] labelLength Length of previous buffer
* @param[out] derivedKey Buffer to store the derived key
* @param[in/out] derivedKeyLength Length of previous buffer(updated to fit actual length of data produced if too long)
*
* @return 0 on succes, error code otherwise
*/
int bzrtp_exportKey(bzrtpContext_t *zrtpContext, char *label, size_t labelLength, uint8_t *derivedKey, size_t *derivedKeyLength) {
/* check we have s0 or exportedKey and KDFContext in channel[0] - export keys is available only on channel 0 completion - see RFC 4.5.2 */
bzrtpChannelContext_t *zrtpChannelContext = zrtpContext->channelContext[0];
if (zrtpContext->peerBzrtpVersion == 0x010000) { /* keep compatibility with older implementation of bzrtp */
#ifdef SUPPORT_EXPORTEDKEY_V010000
/* before version 1.1.0 (turned into an int MMmmpp -> 010100) exported keys wrongly derives from given label and s0 direclty instead of
deriving one Exported Key from S0 and then as many as needed from the exported key as specified in the RFC section 4.5.2 */
if (zrtpChannelContext->s0 == NULL || zrtpChannelContext->KDFContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* We derive a maximum of hashLength bytes */
if (*derivedKeyLength > zrtpChannelContext->hashLength) {
*derivedKeyLength = zrtpChannelContext->hashLength;
}
bzrtp_keyDerivationFunction(zrtpChannelContext->s0, zrtpChannelContext->hashLength, (uint8_t *)label, labelLength, zrtpChannelContext->KDFContext, zrtpChannelContext->KDFContextLength, *derivedKeyLength, zrtpChannelContext->hmacFunction, derivedKey);
#else /* SUPPORT_EXPORTEDKEY_V010000 */
/* We do not support anymore backward compatibility, just do nothing but send an error message*/
if (zrtpContext->zrtpCallbacks.bzrtp_statusMessage!=NULL && zrtpContext->zrtpCallbacks.bzrtp_messageLevel>=BZRTP_MESSAGE_ERROR) { /* use error level as we explicitely compile with no support for older version */
zrtpContext->zrtpCallbacks.bzrtp_statusMessage(zrtpChannelContext->clientData, BZRTP_MESSAGE_ERROR, BZRTP_MESSAGE_PEERVERSIONOBSOLETE, "obsolete bzrtp version are not supported anymore");
}
#endif /* SUPPORT_EXPORTEDKEY_V010000 */
} else { /* peer either use version 1.1 of BZRTP or another library, just stick to the RFC to create the export key */
if ((zrtpChannelContext->s0 == NULL && zrtpContext->exportedKey) || zrtpChannelContext->KDFContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* if we didn't already computed the master exported key, do it now */
if (zrtpContext->exportedKey == NULL) {
zrtpContext->exportedKeyLength = zrtpChannelContext->hashLength;
zrtpContext->exportedKey = (uint8_t *)malloc(zrtpContext->exportedKeyLength*sizeof(uint8_t));
bzrtp_keyDerivationFunction(zrtpChannelContext->s0, zrtpChannelContext->hashLength, (uint8_t *)"Exported key", 12, zrtpChannelContext->KDFContext, zrtpChannelContext->KDFContextLength, zrtpContext->exportedKeyLength, zrtpChannelContext->hmacFunction, zrtpContext->exportedKey);
}
/* We derive a maximum of hashLength bytes */
if (*derivedKeyLength > zrtpChannelContext->hashLength) {
*derivedKeyLength = zrtpChannelContext->hashLength;
}
bzrtp_keyDerivationFunction(zrtpContext->exportedKey, zrtpChannelContext->hashLength, (uint8_t *)label, labelLength, zrtpChannelContext->KDFContext, zrtpChannelContext->KDFContextLength, *derivedKeyLength, zrtpChannelContext->hmacFunction, derivedKey);
}
return 0;
}
/*
* @brief Reset the retransmission timer of a given channel.
* Packets will be sent again if appropriate:
* - when in responder role, zrtp engine only answer to packets sent by the initiator.
* - if we are still in discovery phase, Hello or Commit packets will be resent.
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel to reset
*
* return 0 on success, error code otherwise
*/
int bzrtp_resetRetransmissionTimer(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) {
/* get channel context */
bzrtpChannelContext_t *zrtpChannelContext = getChannelContext(zrtpContext, selfSSRC);
if (zrtpChannelContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* reset timer only when not in secure mode yet and for initiator(engine start as initiator so if we call this function in discovery phase, it will reset the timer */
if ((zrtpChannelContext->isSecure == 0) && (zrtpChannelContext->role == BZRTP_ROLE_INITIATOR)) {
zrtpChannelContext->timer.status = BZRTP_TIMER_ON;
zrtpChannelContext->timer.firingTime = 0; /* be sure it will trigger at next call to bzrtp_iterate*/
zrtpChannelContext->timer.firingCount = -1; /* -1 to count the initial packet and then retransmit the regular number of packets */
/* reset timerStep to the base value */
if ((zrtpChannelContext->timer.timerStep % NON_HELLO_BASE_RETRANSMISSION_STEP) == 0) {
zrtpChannelContext->timer.timerStep = NON_HELLO_BASE_RETRANSMISSION_STEP;
} else {
zrtpChannelContext->timer.timerStep = HELLO_BASE_RETRANSMISSION_STEP;
}
}
return 0;
}
/**
* @brief Get the supported crypto types
*
* @param[int] zrtpContext The ZRTP context we're dealing with
* @param[in] algoType mapped to defines, must be in [ZRTP_HASH_TYPE, ZRTP_CIPHERBLOCK_TYPE, ZRTP_AUTHTAG_TYPE, ZRTP_KEYAGREEMENT_TYPE or ZRTP_SAS_TYPE]
* @param[out] supportedTypes mapped to uint8_t value of the 4 char strings giving the supported types as string according to rfc section 5.1.2 to 5.1.6
*
* @return number of supported types, 0 on error
*/
uint8_t bzrtp_getSupportedCryptoTypes(bzrtpContext_t *zrtpContext, uint8_t algoType, uint8_t supportedTypes[7])
{
if (zrtpContext==NULL) {
return 0;
}
switch(algoType) {
case ZRTP_HASH_TYPE:
return copyCryptoTypes(supportedTypes, zrtpContext->supportedHash, zrtpContext->hc);
case ZRTP_CIPHERBLOCK_TYPE:
return copyCryptoTypes(supportedTypes, zrtpContext->supportedCipher, zrtpContext->cc);
case ZRTP_AUTHTAG_TYPE:
return copyCryptoTypes(supportedTypes, zrtpContext->supportedAuthTag, zrtpContext->ac);
case ZRTP_KEYAGREEMENT_TYPE:
return copyCryptoTypes(supportedTypes, zrtpContext->supportedKeyAgreement, zrtpContext->kc);
case ZRTP_SAS_TYPE:
return copyCryptoTypes(supportedTypes, zrtpContext->supportedSas, zrtpContext->sc);
default:
return 0;
}
}
/**
* @brief set the supported crypto types
*
* @param[int/out] zrtpContext The ZRTP context we're dealing with
* @param[in] algoType mapped to defines, must be in [ZRTP_HASH_TYPE, ZRTP_CIPHERBLOCK_TYPE, ZRTP_AUTHTAG_TYPE, ZRTP_KEYAGREEMENT_TYPE or ZRTP_SAS_TYPE]
* @param[in] supportedTypes mapped to uint8_t value of the 4 char strings giving the supported types as string according to rfc section 5.1.2 to 5.1.6
* @param[in] supportedTypesCount number of supported crypto types
*/
void bzrtp_setSupportedCryptoTypes(bzrtpContext_t *zrtpContext, uint8_t algoType, uint8_t supportedTypes[7], uint8_t supportedTypesCount)
{
uint8_t implementedTypes[7];
uint8_t implementedTypesCount;
if (zrtpContext==NULL) {
return;
}
implementedTypesCount = bzrtpUtils_getAvailableCryptoTypes(algoType, implementedTypes);
switch(algoType) {
case ZRTP_HASH_TYPE:
zrtpContext->hc = selectCommonAlgo(supportedTypes, supportedTypesCount, implementedTypes, implementedTypesCount, zrtpContext->supportedHash);
bzrtp_addMandatoryCryptoTypesIfNeeded(algoType, zrtpContext->supportedHash, &zrtpContext->hc);
break;
case ZRTP_CIPHERBLOCK_TYPE:
zrtpContext->cc = selectCommonAlgo(supportedTypes, supportedTypesCount, implementedTypes, implementedTypesCount, zrtpContext->supportedCipher);
bzrtp_addMandatoryCryptoTypesIfNeeded(algoType, zrtpContext->supportedCipher, &zrtpContext->cc);
break;
case ZRTP_AUTHTAG_TYPE:
zrtpContext->ac = selectCommonAlgo(supportedTypes, supportedTypesCount, implementedTypes, implementedTypesCount, zrtpContext->supportedAuthTag);
bzrtp_addMandatoryCryptoTypesIfNeeded(algoType, zrtpContext->supportedAuthTag, &zrtpContext->ac);
break;
case ZRTP_KEYAGREEMENT_TYPE:
zrtpContext->kc = selectCommonAlgo(supportedTypes, supportedTypesCount, implementedTypes, implementedTypesCount, zrtpContext->supportedKeyAgreement);
bzrtp_addMandatoryCryptoTypesIfNeeded(algoType, zrtpContext->supportedKeyAgreement, &zrtpContext->kc);
break;
case ZRTP_SAS_TYPE:
zrtpContext->sc = selectCommonAlgo(supportedTypes, supportedTypesCount, implementedTypes, implementedTypesCount, zrtpContext->supportedSas);
bzrtp_addMandatoryCryptoTypesIfNeeded(algoType, zrtpContext->supportedSas, &zrtpContext->sc);
break;
}
}
/**
* @brief Set the peer hello hash given by signaling to a ZRTP channel
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel
* @param[out] peerHelloHashHexString A NULL terminated string containing the hexadecimal form of the hash received in signaling,
* may contain ZRTP version as header.
* @param[in] peerHelloHashHexStringLength Length of hash string (shall be at least 64 as the hash is a SHA256 so 32 bytes,
* more if it contains the version header)
*
* @return 0 on success, errorcode otherwise
*/
int bzrtp_setPeerHelloHash(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint8_t *peerHelloHashHexString, size_t peerHelloHashHexStringLength) {
size_t i=0;
uint8_t *hexHashString = NULL;
size_t hexHashStringLength = peerHelloHashHexStringLength;
/* get channel context */
bzrtpChannelContext_t *zrtpChannelContext = getChannelContext(zrtpContext, selfSSRC);
if (zrtpChannelContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* parse the given peerHelloHash, it may formatted or just */
/* just ignore anything(we do not care about version number) before a ' ' if found */
while (hexHashString==NULL && ipeerHelloHash) {
free(zrtpChannelContext->peerHelloHash);
}
zrtpChannelContext->peerHelloHash = (uint8_t *)malloc(hexHashStringLength/2*sizeof(uint8_t));
/* convert to uint8 the hex string */
bzrtp_strToUint8(zrtpChannelContext->peerHelloHash, hexHashString, hexHashStringLength);
/* Do we already have the peer Hello packet, if yes, check it match the hash */
if (zrtpChannelContext->peerPackets[HELLO_MESSAGE_STORE_ID] != NULL) {
uint8_t computedPeerHelloHash[32];
/* compute hash using implicit hash function: SHA256, skip packet header in the packetString buffer as the hash must be computed on message only */
bctbx_sha256(zrtpChannelContext->peerPackets[HELLO_MESSAGE_STORE_ID]->packetString+ZRTP_PACKET_HEADER_LENGTH,
zrtpChannelContext->peerPackets[HELLO_MESSAGE_STORE_ID]->messageLength,
32,
computedPeerHelloHash);
/* check they are the same */
if (memcmp(computedPeerHelloHash, zrtpChannelContext->peerHelloHash, 32)!=0) {
/* a session already started on this channel but with a wrong Hello we must reset and restart it */
/* note: caller may decide to abort the ZRTP session */
/* reset state Machine */
zrtpChannelContext->stateMachine = NULL;
/* set timer off */
zrtpChannelContext->timer.status = BZRTP_TIMER_OFF;
/* destroy and free the key buffers */
bzrtp_DestroyKey(zrtpChannelContext->s0, zrtpChannelContext->hashLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->KDFContext, zrtpChannelContext->KDFContextLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->mackeyi, zrtpChannelContext->hashLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->mackeyr, zrtpChannelContext->hashLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->zrtpkeyi, zrtpChannelContext->cipherKeyLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->zrtpkeyr, zrtpChannelContext->cipherKeyLength, zrtpContext->RNGContext);
free(zrtpChannelContext->s0);
free(zrtpChannelContext->KDFContext);
free(zrtpChannelContext->mackeyi);
free(zrtpChannelContext->mackeyr);
free(zrtpChannelContext->zrtpkeyi);
free(zrtpChannelContext->zrtpkeyr);
zrtpChannelContext->s0=NULL;
zrtpChannelContext->KDFContext=NULL;
zrtpChannelContext->mackeyi=NULL;
zrtpChannelContext->mackeyr=NULL;
zrtpChannelContext->zrtpkeyi=NULL;
zrtpChannelContext->zrtpkeyr=NULL;
/* free the allocated buffers but not our self Hello packet */
for (i=0; iselfPackets[i]);
zrtpChannelContext->selfPackets[i] = NULL;
}
bzrtp_freeZrtpPacket(zrtpChannelContext->peerPackets[i]);
zrtpChannelContext->peerPackets[i] = NULL;
}
/* destroy and free the srtp and sas struture */
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.selfSrtpKey, zrtpChannelContext->srtpSecrets.selfSrtpKeyLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.selfSrtpSalt, zrtpChannelContext->srtpSecrets.selfSrtpSaltLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.peerSrtpKey, zrtpChannelContext->srtpSecrets.peerSrtpKeyLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.peerSrtpSalt, zrtpChannelContext->srtpSecrets.peerSrtpSaltLength, zrtpContext->RNGContext);
bzrtp_DestroyKey((uint8_t *)zrtpChannelContext->srtpSecrets.sas, zrtpChannelContext->srtpSecrets.sasLength, zrtpContext->RNGContext);
free(zrtpChannelContext->srtpSecrets.selfSrtpKey);
free(zrtpChannelContext->srtpSecrets.selfSrtpSalt);
free(zrtpChannelContext->srtpSecrets.peerSrtpKey);
free(zrtpChannelContext->srtpSecrets.peerSrtpSalt);
free(zrtpChannelContext->srtpSecrets.sas);
/* re-initialise srtpSecrets structure */
zrtpChannelContext->srtpSecrets.selfSrtpKey = NULL;
zrtpChannelContext->srtpSecrets.selfSrtpSalt = NULL;
zrtpChannelContext->srtpSecrets.peerSrtpKey = NULL;
zrtpChannelContext->srtpSecrets.peerSrtpSalt = NULL;
zrtpChannelContext->srtpSecrets.selfSrtpKeyLength = 0;
zrtpChannelContext->srtpSecrets.selfSrtpSaltLength = 0;
zrtpChannelContext->srtpSecrets.peerSrtpKeyLength = 0;
zrtpChannelContext->srtpSecrets.peerSrtpSaltLength = 0;
zrtpChannelContext->srtpSecrets.cipherAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->srtpSecrets.cipherKeyLength = 0;
zrtpChannelContext->srtpSecrets.authTagAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->srtpSecrets.sas = NULL;
zrtpChannelContext->srtpSecrets.sasLength = 0;
zrtpChannelContext->srtpSecrets.hashAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->srtpSecrets.keyAgreementAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->srtpSecrets.sasAlgo = ZRTP_UNSET_ALGO;
/* reset choosen algo and their functions */
zrtpChannelContext->hashAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->cipherAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->authTagAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->keyAgreementAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->sasAlgo = ZRTP_UNSET_ALGO;
bzrtp_updateCryptoFunctionPointers(zrtpChannelContext);
/* restart channel */
bzrtp_startChannelEngine(zrtpContext, selfSSRC);
return BZRTP_ERROR_HELLOHASH_MISMATCH;
}
}
return 0;
}
/**
* @brief Get the self hello hash from ZRTP channel
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel
* @param[out] output A NULL terminated string containing the hexadecimal form of the hash received in signaling,
* contain ZRTP version as header. Buffer must be allocated by caller.
* @param[in] outputLength Length of output buffer, shall be at least 70 : 5 chars for version, 64 for the hash itself, SHA256), NULL termination
*
* @return 0 on success, errorcode otherwise
*/
int bzrtp_getSelfHelloHash(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint8_t *output, size_t outputLength) {
uint8_t helloHash[32];
/* get channel context */
bzrtpChannelContext_t *zrtpChannelContext = getChannelContext(zrtpContext, selfSSRC);
if (zrtpChannelContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* check we have the Hello packet in context */
if (zrtpChannelContext->selfPackets[HELLO_MESSAGE_STORE_ID] == NULL) {
return BZRTP_ERROR_CONTEXTNOTREADY;
}
/* check output length : version length +' '+64 hex hash + null termination */
if (outputLength < strlen(ZRTP_VERSION)+1+64+1) {
return BZRTP_ERROR_OUTPUTBUFFER_LENGTH;
}
/* compute hash using implicit hash function: SHA256, skip packet header in the packetString buffer as the hash must be computed on message only */
bctbx_sha256(zrtpChannelContext->selfPackets[HELLO_MESSAGE_STORE_ID]->packetString+ZRTP_PACKET_HEADER_LENGTH,
zrtpChannelContext->selfPackets[HELLO_MESSAGE_STORE_ID]->messageLength,
32,
helloHash);
/* add version header */
strcpy((char *)output, ZRTP_VERSION);
output[strlen(ZRTP_VERSION)]=' ';
/* convert hash to hex string and set it in the output buffer */
bzrtp_int8ToStr(output+strlen(ZRTP_VERSION)+1, helloHash, 32);
/* add NULL termination */
output[strlen(ZRTP_VERSION)+1+64]='\0';
return 0;
}
/**
* @brief Set Auxiliary Secret for this channel(shall be used only on primary audio channel)
* The given auxSecret is appended to any aux secret found in ZIDcache
* This function must be called before reception of peerHello packet
*
* @param[in] zrtpContext The ZRTP context we're dealing with
* @param[in] auxSecret A buffer holding the auxiliary shared secret to use (see RFC 6189 section 4.3)
* @param[in] auxSecretLength lenght of the previous buffer
*
* @return 0 on success, error code otherwise
*
* @note The auxiliary shared secret mechanic is used by LIMEv2 for encryption security purposes but might be used for its original purpose in a regular
* ZRTP session if it becomes necessary in the future, or by another encryption engine for example. In that case the API will need an adaptation work.
*/
int bzrtp_setAuxiliarySharedSecret(bzrtpContext_t *zrtpContext, const uint8_t *auxSecret, size_t auxSecretLength) {
if (zrtpContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
if (zrtpContext->channelContext[0] && zrtpContext->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID] != NULL) {
return BZRTP_ERROR_CONTEXTNOTREADY;
}
/* allocate memory to store the secret - check it wasn't already allocated */
if (zrtpContext->transientAuxSecret) {
free(zrtpContext->transientAuxSecret);
}
zrtpContext->transientAuxSecret = (uint8_t *)malloc(auxSecretLength*sizeof(uint8_t));
/* copy the aux secret and length */
memcpy(zrtpContext->transientAuxSecret, auxSecret, auxSecretLength);
zrtpContext->transientAuxSecretLength = auxSecretLength;
return 0;
}
/**
* @brief Get the ZRTP auxiliary shared secret mismatch status
*
* @param[in] zrtpContext The ZRTP context we're dealing with
* @return BZRTP_AUXSECRET_MATCH on match, BZRTP_AUXSECRET_MISMATCH on mismatch, BZRTP_AUXSECRET_UNSET if auxiliary shared secret is unused
*/
uint8_t bzrtp_getAuxiliarySharedSecretMismatch(bzrtpContext_t *zrtpContext) {
return zrtpContext->channelContext[0]->srtpSecrets.auxSecretMismatch;
}
/**
* @brief Get the channel status
*
* @param[in] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel
*
* @return BZRTP_CHANNEL_NOTFOUND no channel matching this SSRC doesn't exists in the zrtp context
* BZRTP_CHANNEL_INITIALISED channel initialised but not started
* BZRTP_CHANNEL_ONGOING ZRTP key exchange in ongoing
* BZRTP_CHANNEL_SECURE Channel is secure
* BZRTP_CHANNEL_ERROR An error occured on this channel
*/
int bzrtp_getChannelStatus(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) {
/* get channel context */
bzrtpChannelContext_t *zrtpChannelContext = getChannelContext(zrtpContext, selfSSRC);
if (zrtpChannelContext == NULL) {
return BZRTP_CHANNEL_NOTFOUND;
}
if (zrtpChannelContext->stateMachine == NULL) {
return BZRTP_CHANNEL_INITIALISED;
}
if (zrtpChannelContext->isSecure == 1) {
return BZRTP_CHANNEL_SECURE;
}
return BZRTP_CHANNEL_ONGOING;
}
/* Local functions implementation */
/**
* @brief Look in the given ZRTP context for a channel referenced with given SSRC
*
* @param[in] zrtpContext The zrtp context which shall contain the channel context we are looking for
* @param[in] selfSSRC The SSRC identifying the channel context
*
* @return a pointer to the channel context, NULL if the context is invalid or channel not found
*/
static bzrtpChannelContext_t *getChannelContext(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) {
int i;
if (zrtpContext==NULL) {
return NULL;
}
for (i=0; ichannelContext[i]!=NULL) {
if (zrtpContext->channelContext[i]->selfSSRC == selfSSRC) {
return zrtpContext->channelContext[i];
}
}
}
return NULL; /* found no channel with this SSRC */
}
/**
* @brief Initialise the context of a channel and create and store the Hello packet
* Initialise some vectors
*
* @param[in] zrtpContext The zrtpContext hosting this channel, needed to acces the RNG
* @param[out] zrtpChanneContext The channel context to be initialised
* @param[in] selfSSRC The SSRC allocated to this channel
* @param[in] isMain This channel is channel 0 or an additional channel
*
* @return 0 on success, error code otherwise
*/
static int bzrtp_initChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, uint32_t selfSSRC, uint8_t isMain) {
int i;
int retval;
bzrtpPacket_t *helloPacket;
if (zrtpChannelContext == NULL) {
return BZRTP_ERROR_INVALIDCHANNELCONTEXT;
}
zrtpChannelContext->clientData = NULL;
/* the state machine is not started at the creation of the channel but on explicit call to the start function */
zrtpChannelContext->stateMachine = NULL;
/* timer is off */
zrtpChannelContext->timer.status = BZRTP_TIMER_OFF;
zrtpChannelContext->timer.timerStep = HELLO_BASE_RETRANSMISSION_STEP; /* we must initialise the timeStep just in case the resettimer function is called between init and start */
zrtpChannelContext->selfSSRC = selfSSRC;
/* flags */
zrtpChannelContext->isSecure = 0;
zrtpChannelContext->isMainChannel = isMain;
/* initialise as initiator, switch to responder later if needed */
zrtpChannelContext->role = BZRTP_ROLE_INITIATOR;
/* create H0 (32 bytes random) and derive using implicit Hash(SHA256) H1,H2,H3 */
bctbx_rng_get(zrtpContext->RNGContext, zrtpChannelContext->selfH[0], 32);
bctbx_sha256(zrtpChannelContext->selfH[0], 32, 32, zrtpChannelContext->selfH[1]);
bctbx_sha256(zrtpChannelContext->selfH[1], 32, 32, zrtpChannelContext->selfH[2]);
bctbx_sha256(zrtpChannelContext->selfH[2], 32, 32, zrtpChannelContext->selfH[3]);
/* initialisation of packet storage */
for (i=0; iselfPackets[i] = NULL;
zrtpChannelContext->peerPackets[i] = NULL;
}
zrtpChannelContext->peerHelloHash = NULL;
/* initialise the self Sequence number to a random and peer to 0 */
bctbx_rng_get(zrtpContext->RNGContext, (uint8_t *)&(zrtpChannelContext->selfSequenceNumber), 2);
zrtpChannelContext->selfSequenceNumber &= 0x0FFF; /* first 4 bits to zero in order to avoid reaching FFFF and turning back to 0 */
zrtpChannelContext->selfSequenceNumber++; /* be sure it is not initialised to 0 */
zrtpChannelContext->peerSequenceNumber = 0;
/* reset choosen algo and their functions */
zrtpChannelContext->hashAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->cipherAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->authTagAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->keyAgreementAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->sasAlgo = ZRTP_UNSET_ALGO;
bzrtp_updateCryptoFunctionPointers(zrtpChannelContext);
/* initialise key buffers */
zrtpChannelContext->s0 = NULL;
zrtpChannelContext->KDFContext = NULL;
zrtpChannelContext->KDFContextLength = 0;
zrtpChannelContext->mackeyi = NULL;
zrtpChannelContext->mackeyr = NULL;
zrtpChannelContext->zrtpkeyi = NULL;
zrtpChannelContext->zrtpkeyr = NULL;
/* initialise srtpSecrets structure */
zrtpChannelContext->srtpSecrets.selfSrtpKey = NULL;
zrtpChannelContext->srtpSecrets.selfSrtpSalt = NULL;
zrtpChannelContext->srtpSecrets.peerSrtpKey = NULL;
zrtpChannelContext->srtpSecrets.peerSrtpSalt = NULL;
zrtpChannelContext->srtpSecrets.selfSrtpKeyLength = 0;
zrtpChannelContext->srtpSecrets.selfSrtpSaltLength = 0;
zrtpChannelContext->srtpSecrets.peerSrtpKeyLength = 0;
zrtpChannelContext->srtpSecrets.peerSrtpSaltLength = 0;
zrtpChannelContext->srtpSecrets.cipherAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->srtpSecrets.cipherKeyLength = 0;
zrtpChannelContext->srtpSecrets.authTagAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->srtpSecrets.sas = NULL;
zrtpChannelContext->srtpSecrets.sasLength = 0;
zrtpChannelContext->srtpSecrets.hashAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->srtpSecrets.keyAgreementAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->srtpSecrets.sasAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->srtpSecrets.cacheMismatch = 0;
zrtpChannelContext->srtpSecrets.auxSecretMismatch = BZRTP_AUXSECRET_UNSET;
/* create the Hello packet and store it */
helloPacket = bzrtp_createZrtpPacket(zrtpContext, zrtpChannelContext, MSGTYPE_HELLO, &retval);
if (retval != 0) {
return retval;
}
/* build the packet string and store the packet */
if (bzrtp_packetBuild(zrtpContext, zrtpChannelContext, helloPacket, zrtpChannelContext->selfSequenceNumber) ==0) {
zrtpChannelContext->selfPackets[HELLO_MESSAGE_STORE_ID] = helloPacket;
} else {
bzrtp_freeZrtpPacket(helloPacket);
return retval;
}
return 0;
}
/**
* @brief Destroy the context of a channel
* Free allocated buffers, destroy keys
*
* @param[in] zrtpContext The zrtpContext hosting this channel, needed to acces the RNG
* @param[in] zrtpChannelContext The channel context to be destroyed
*/
static void bzrtp_destroyChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext) {
int i;
/* check there is something to be freed */
if (zrtpChannelContext == NULL) {
return;
}
/* reset state Machine */
zrtpChannelContext->stateMachine = NULL;
/* set timer off */
zrtpChannelContext->timer.status = BZRTP_TIMER_OFF;
/* destroy and free the key buffers */
bzrtp_DestroyKey(zrtpChannelContext->s0, zrtpChannelContext->hashLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->KDFContext, zrtpChannelContext->KDFContextLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->mackeyi, zrtpChannelContext->hashLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->mackeyr, zrtpChannelContext->hashLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->zrtpkeyi, zrtpChannelContext->cipherKeyLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->zrtpkeyr, zrtpChannelContext->cipherKeyLength, zrtpContext->RNGContext);
free(zrtpChannelContext->s0);
free(zrtpChannelContext->KDFContext);
free(zrtpChannelContext->mackeyi);
free(zrtpChannelContext->mackeyr);
free(zrtpChannelContext->zrtpkeyi);
free(zrtpChannelContext->zrtpkeyr);
zrtpChannelContext->s0=NULL;
zrtpChannelContext->KDFContext=NULL;
zrtpChannelContext->mackeyi=NULL;
zrtpChannelContext->mackeyr=NULL;
zrtpChannelContext->zrtpkeyi=NULL;
zrtpChannelContext->zrtpkeyr=NULL;
/* free the allocated buffers */
for (i=0; iselfPackets[i]);
bzrtp_freeZrtpPacket(zrtpChannelContext->peerPackets[i]);
zrtpChannelContext->selfPackets[i] = NULL;
zrtpChannelContext->peerPackets[i] = NULL;
}
free(zrtpChannelContext->peerHelloHash);
zrtpChannelContext->peerHelloHash = NULL;
/* destroy and free the srtp and sas struture */
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.selfSrtpKey, zrtpChannelContext->srtpSecrets.selfSrtpKeyLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.selfSrtpSalt, zrtpChannelContext->srtpSecrets.selfSrtpSaltLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.peerSrtpKey, zrtpChannelContext->srtpSecrets.peerSrtpKeyLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.peerSrtpSalt, zrtpChannelContext->srtpSecrets.peerSrtpSaltLength, zrtpContext->RNGContext);
bzrtp_DestroyKey((uint8_t *)zrtpChannelContext->srtpSecrets.sas, zrtpChannelContext->srtpSecrets.sasLength, zrtpContext->RNGContext);
free(zrtpChannelContext->srtpSecrets.selfSrtpKey);
free(zrtpChannelContext->srtpSecrets.selfSrtpSalt);
free(zrtpChannelContext->srtpSecrets.peerSrtpKey);
free(zrtpChannelContext->srtpSecrets.peerSrtpSalt);
free(zrtpChannelContext->srtpSecrets.sas);
/* free the channel context */
free(zrtpChannelContext);
}
static uint8_t copyCryptoTypes(uint8_t destination[7], uint8_t source[7], uint8_t size)
{
int i;
for (i=0; i