Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #54 from cisco/new-api-ish
New API
- Loading branch information
Showing
31 changed files
with
1,007 additions
and
705 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
add_subdirectory(test_gen) | ||
add_subdirectory(api_example) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
set(APP_NAME "api_example") | ||
set(APP_SRC_PATH "${PROJECT_SOURCE_DIR}/cmd/api_example") | ||
|
||
file(GLOB APP_SOURCE_FILES "${APP_SRC_PATH}/*.cpp") | ||
set(APP_SOURCE_FILES ${APP_SOURCE_FILES} PARENT_SCOPE) | ||
|
||
add_executable(${APP_NAME} ${APP_SOURCE_FILES}) | ||
target_include_directories(${APP_NAME} PRIVATE ${LIBRARY_INCLUDE_PATH} | ||
PRIVATE ${OPENSSL_INCLUDE_DIR}) | ||
target_link_libraries(${APP_NAME} ${OPENSSL_LIBRARIES}) | ||
target_link_libraries(${APP_NAME} ${LIB_NAME}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
#include "credential.h" | ||
#include "crypto.h" | ||
#include "messages.h" | ||
#include "session.h" | ||
|
||
#include <iostream> | ||
#include <stdexcept> | ||
#include <string> | ||
|
||
using namespace mls; | ||
|
||
const auto suites = | ||
std::vector<CipherSuite>{ CipherSuite::X25519_SHA256_AES128GCM }; | ||
const auto scheme = SignatureScheme::Ed25519; | ||
|
||
class User | ||
{ | ||
public: | ||
User(const std::string& name) | ||
{ | ||
auto priv = SignaturePrivateKey::generate(scheme); | ||
auto id = bytes(name.begin(), name.end()); | ||
_cred = Credential::basic(id, priv); | ||
} | ||
|
||
ClientInitKey temp_cik() | ||
{ | ||
auto cikID = random_bytes(16); | ||
auto init = random_bytes(32); | ||
return ClientInitKey{ cikID, suites, init, _cred }; | ||
} | ||
|
||
ClientInitKey fresh_cik() | ||
{ | ||
auto cik = temp_cik(); | ||
_ciks.emplace(cik.client_init_key_id, cik); | ||
return cik; | ||
} | ||
|
||
ClientInitKey find_cik(const bytes& cik_id) | ||
{ | ||
if (_ciks.count(cik_id) == 0) { | ||
throw std::runtime_error("Unkown CIK"); | ||
} | ||
|
||
return _ciks.at(cik_id); | ||
} | ||
|
||
private: | ||
Credential _cred; | ||
std::map<bytes, ClientInitKey> _ciks; | ||
}; | ||
|
||
void | ||
verify_send(std::string label, Session& send, Session& recv) | ||
{ | ||
auto plaintext = bytes{ 0, 1, 2, 3 }; | ||
auto encrypted = send.protect(plaintext); | ||
auto decrypted = recv.unprotect(encrypted); | ||
if (plaintext != decrypted) { | ||
throw std::runtime_error(label + ": send/receive failure"); | ||
} | ||
} | ||
|
||
void | ||
verify(std::string label, Session& alice, Session& bob) | ||
{ | ||
if (alice != bob) { | ||
throw std::runtime_error(label + ": not equal"); | ||
} | ||
|
||
verify_send(label, alice, bob); | ||
verify_send(label, bob, alice); | ||
} | ||
|
||
int | ||
main() | ||
{ | ||
////////// DRAMATIS PERSONAE /////////// | ||
|
||
auto alice = User{ "alice" }; | ||
auto bob = User{ "bob" }; | ||
auto charlie = User{ "charlie" }; | ||
|
||
////////// ACT I: CREATION /////////// | ||
|
||
// Bob posts a ClientInitKey | ||
auto cikB1 = bob.fresh_cik(); | ||
|
||
// Bob starts a session with alice | ||
auto cikA = alice.temp_cik(); | ||
auto group_id = bytes{ 0, 1, 2, 3 }; | ||
auto session_welcome_add = Session::start(group_id, cikA, cikB1); | ||
auto sessionA = std::get<0>(session_welcome_add); | ||
auto welcome = std::get<1>(session_welcome_add); | ||
auto add = std::get<2>(session_welcome_add); | ||
|
||
// Alice looks up her CIK based on the welcome, and initializes | ||
// her session | ||
auto cikB2 = bob.find_cik(welcome.client_init_key_id); | ||
auto sessionB = Session::join(cikB2, welcome, add); | ||
|
||
// Alice and Bob should now be on the same page | ||
verify("create", sessionA, sessionB); | ||
|
||
////////// ACT II: ADDITION /////////// | ||
|
||
// Charlie posts a ClientInitKey | ||
auto cikC1 = charlie.fresh_cik(); | ||
|
||
// Alice adds Charlie to the session | ||
std::tie(welcome, add) = sessionA.add(cikC1); | ||
|
||
// Charlie initializes his session | ||
auto cikC2 = charlie.find_cik(welcome.client_init_key_id); | ||
auto sessionC = Session::join(cikC2, welcome, add); | ||
|
||
// Alice and Bob updates their sessions to reflect Charlie's addition | ||
sessionA.handle(add); | ||
sessionB.handle(add); | ||
|
||
verify("add A->B", sessionA, sessionB); | ||
verify("add A->C", sessionA, sessionC); | ||
verify("add B->C", sessionB, sessionC); | ||
|
||
////////// ACT III: UPDATE /////////// | ||
|
||
// Bob updates his key | ||
auto update = sessionB.update(random_bytes(32)); | ||
|
||
// Everyone processes the update | ||
sessionA.handle(update); | ||
sessionB.handle(update); | ||
sessionC.handle(update); | ||
|
||
verify("update A->B", sessionA, sessionB); | ||
verify("update A->C", sessionA, sessionC); | ||
verify("update B->C", sessionB, sessionC); | ||
|
||
////////// ACT IV: REMOVE /////////// | ||
|
||
// Charlie removes Bob | ||
auto remove = sessionC.remove(random_bytes(32), 1); | ||
|
||
// Alice and Charlie process the message (Bob is gone) | ||
sessionA.handle(remove); | ||
sessionC.handle(remove); | ||
|
||
verify("remove A->C", sessionA, sessionC); | ||
|
||
std::cout << "ok" << std::endl; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.