diff --git a/README.md b/README.md index 094b628..04fc17c 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,12 @@ sudo apt install mosquitto-dev g++ cmake libmosquitto-dev mosquitto-clients open ``` ## Generating offline keys -ssh-keygen -t rsa -b 4096 -m PEM -f priv.key -rm priv.key.pub -openssl rsa -in priv.key -pubout -outform PEM -out pub.key +``` +openssl genpkey -algorithm RSA -out rsa_private.pem -pkeyopt rsa_keygen_bits:2048 +openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem +``` + +## Converting Client Keys to Format for Browser +``` +openssl pkcs12 -export -out client.p12 -inkey client-key.pem -in -client.pem -certfile ca.pem +``` diff --git a/include/j7s-plugin/utils.h b/include/j7s-plugin/utils.h index 5d0de24..1d9dc34 100644 --- a/include/j7s-plugin/utils.h +++ b/include/j7s-plugin/utils.h @@ -1,4 +1,3 @@ - // Copyright 2022 James Pace // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,7 +19,7 @@ std::optional read_key(const std::string & key_file); -std::tuple validate( +bool validate( const std::string & token, const std::string & username, const std::string & issuer, @@ -29,8 +28,7 @@ std::tuple validate( std::string gen_token( const std::string & issuer, const std::string & username, - const std::string & can_read, - const std::string & can_write, const std::string & pub_key, const std::string & priv_key, + const std::chrono::time_point & issue_time, const std::chrono::time_point & expr_time); diff --git a/src/Authorizer.cpp b/src/Authorizer.cpp index 3b7373c..e74e2e5 100644 --- a/src/Authorizer.cpp +++ b/src/Authorizer.cpp @@ -34,21 +34,16 @@ bool Authorizer::is_unknown(const std::string & username) bool Authorizer::add(const std::string & token, const std::string & username) { - const auto [can_read, can_write] = validate(token, username, _issuer, _pub_key); - if (not(can_write or can_read)) + const auto validated = validate(token, username, _issuer, _pub_key); + if (not validated) { - std::cerr << "Can't write or can't read." << std::endl; + std::cerr << "Not validated." << std::endl; return false; } - if (can_write) - { - _writeList.add(username); - } - if (can_read) - { - _readList.add(username); - } + // TODO: Check ACL file to see which one. + _writeList.add(username); + _readList.add(username); return true; } diff --git a/src/gen-token.cpp b/src/gen-token.cpp index f19694e..b6f0285 100644 --- a/src/gen-token.cpp +++ b/src/gen-token.cpp @@ -62,16 +62,16 @@ int main(int argc, char * argv[]) const std::string can_read = program.get("--can-read") ? "true" : "false"; const std::string can_write = program.get("--can-write") ? "true" : "false"; - const auto expr_time = std::chrono::system_clock::now() + - std::chrono::days(std::stoi(program.get("--valid-days"))); + const auto now = std::chrono::system_clock::now(); + const auto expr_time = + now + std::chrono::days(std::stoi(program.get("--valid-days"))); const auto token = gen_token( program.get("--issuer"), program.get("--username"), - can_read, - can_write, pub_key.value(), priv_key.value(), + now, expr_time); std::cout << token; diff --git a/src/utils.cpp b/src/utils.cpp index ecffa7a..75e073c 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -32,7 +32,7 @@ std::optional read_key(const std::string & key_file) return ss.str(); } -std::tuple validate( +bool validate( const std::string & token, const std::string & username, const std::string & issuer, @@ -50,7 +50,7 @@ std::tuple validate( catch (jwt::error::token_verification_exception & exception) { std::cerr << exception.what() << std::endl; - return std::make_tuple(false, false); + return false; } auto claims = decoded_token.get_payload_claims(); @@ -58,42 +58,38 @@ std::tuple validate( if (not claims.contains("upn")) { std::cerr << "Missing upn." << std::endl; - return std::make_tuple(false, false); + return false; } if (claims["upn"].as_string() != username) { std::cerr << "Wrong username." << std::endl; - return std::make_tuple(false, false); + return false; } // Check for mqtt-write claim value. - if (not(claims.contains("mqtt-write") and claims.contains("mqtt-read"))) + if (not claims.contains("mqtt")) { - std::cerr << "Missing mqtt-write or mqtt-read." << std::endl; - return std::make_tuple(false, false); + std::cerr << "Missing mqtt claim." << std::endl; + return false; } - bool can_read = claims["mqtt-read"].as_bool(); - bool can_write = claims["mqtt-write"].as_bool(); - - return std::make_tuple(can_read, can_write); + return claims["mqtt"].as_bool(); } std::string gen_token( const std::string & issuer, const std::string & username, - const std::string & can_read, - const std::string & can_write, const std::string & pub_key, const std::string & priv_key, + const std::chrono::time_point & issue_time, const std::chrono::time_point & expr_time) { const auto token = jwt::create() .set_type("JWT") .set_issuer(issuer) .set_payload_claim("upn", jwt::claim(username)) - .set_payload_claim("mqtt-read", jwt::claim(can_read)) - .set_payload_claim("mqtt-write", jwt::claim(can_write)) + .set_payload_claim("mqtt", jwt::claim(std::string("true"))) + .set_issued_at(issue_time) .set_expires_at(expr_time) .sign(jwt::algorithm::rs256(pub_key, priv_key, "", "")); diff --git a/test/authorizer_test.cpp b/test/token_test.cpp similarity index 100% rename from test/authorizer_test.cpp rename to test/token_test.cpp