From 5390d1fcec32587eafb507461eb8c842ed5917ae Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 13:51:08 -0700 Subject: [PATCH] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- openapi/openroaming_globalreach.yaml | 4 ++ .../RESTAPI_openroaming_gr_acct_handler.cpp | 32 +++------- src/RESTObjects/RESTAPI_ProvObjects.cpp | 4 ++ src/RESTObjects/RESTAPI_ProvObjects.h | 2 +- src/framework/ow_constants.h | 1 + src/framework/utils.cpp | 63 +++++++++++++------ src/framework/utils.h | 14 ++++- src/storage/storage_glblraccounts.cpp | 10 ++- src/storage/storage_glblraccounts.h | 2 + 9 files changed, 85 insertions(+), 47 deletions(-) diff --git a/openapi/openroaming_globalreach.yaml b/openapi/openroaming_globalreach.yaml index c71e471..8627d56 100644 --- a/openapi/openroaming_globalreach.yaml +++ b/openapi/openroaming_globalreach.yaml @@ -55,6 +55,10 @@ components: type: string CSR: type: string + CSRPrivateKey: + type: string + CSRPublicKey: + type: string GlobalReachAcctId: type: string diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp index ab64484..1578323 100644 --- a/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp @@ -67,7 +67,16 @@ namespace OpenWifi { return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); } - NewObject.CSR = Utils::CreateX509CSR(NewObject.country,NewObject.province, NewObject.city, NewObject.organization, NewObject.commonName); + Utils::CSRCreationParameters P; + P.Country = NewObject.country; + P.CommonName = NewObject.commonName; + P.Province = NewObject.province; + P.City = NewObject.city; + P.Organization = NewObject.organization; + Utils::CSRCreationResults R; + if(!Utils::CreateX509CSR(P,R)) { + return BadRequest(RESTAPI::Errors::CannotCreateCSR); + } ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info); @@ -101,27 +110,6 @@ namespace OpenWifi { return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); } - if(RawObject->has("privateKey")) { - if(!Modify.privateKey.empty() && !Utils::VerifyECKey(Modify.privateKey)) { - return BadRequest(RESTAPI::Errors::NotAValidECKey); - } - Existing.privateKey = Modify.privateKey; - } - - std::string GlobalReachName; - if(!OpenRoaming_GlobalReach()->VerifyAccount(Existing.GlobalReachAcctId,Existing.privateKey,GlobalReachName)) { - return BadRequest(RESTAPI::Errors::InvalidGlobalReachAccount); - } - - auto Modified = AssignIfPresent(RawObject,"country",Existing.country) || - AssignIfPresent(RawObject,"commonName",Existing.commonName) || - AssignIfPresent(RawObject,"city",Existing.city) || - AssignIfPresent(RawObject,"province",Existing.province) || - AssignIfPresent(RawObject,"organization",Existing.organization); - if(Modified) { - Existing.CSR = Utils::CreateX509CSR(Existing.country,Existing.province, Existing.city, Existing.organization, Existing.commonName); - } - if(DB_.UpdateRecord("id",Existing.info.id,Existing)) { ProvObjects::GLBLRAccountInfo StoredObject; DB_.GetRecord("id",Existing.info.id,StoredObject); diff --git a/src/RESTObjects/RESTAPI_ProvObjects.cpp b/src/RESTObjects/RESTAPI_ProvObjects.cpp index 6254e4a..cf88234 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.cpp +++ b/src/RESTObjects/RESTAPI_ProvObjects.cpp @@ -1203,6 +1203,8 @@ namespace OpenWifi::ProvObjects { field_to_json(Obj, "organization", organization); field_to_json(Obj, "commonName", commonName); field_to_json(Obj, "CSR", CSR); + field_to_json(Obj, "CSRPrivateKey", CSRPrivateKey); + field_to_json(Obj, "CSRPublicKey", CSRPublicKey); field_to_json(Obj, "GlobalReachAcctId", GlobalReachAcctId); } @@ -1216,6 +1218,8 @@ namespace OpenWifi::ProvObjects { field_from_json(Obj, "organization", organization); field_from_json(Obj, "commonName", commonName); field_from_json(Obj, "CSR", CSR); + field_from_json(Obj, "CSRPrivateKey", CSRPrivateKey); + field_from_json(Obj, "CSRPublicKey", CSRPublicKey); field_from_json(Obj, "GlobalReachAcctId", GlobalReachAcctId); return true; } catch (const Poco::Exception &E) { diff --git a/src/RESTObjects/RESTAPI_ProvObjects.h b/src/RESTObjects/RESTAPI_ProvObjects.h index 1ef7b27..ec8f449 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.h +++ b/src/RESTObjects/RESTAPI_ProvObjects.h @@ -751,7 +751,7 @@ namespace OpenWifi::ProvObjects { ObjectInfo info; std::string privateKey; std::string country, province, city, organization, commonName; - std::string CSR; + std::string CSR, CSRPrivateKey, CSRPublicKey; std::string GlobalReachAcctId; void to_json(Poco::JSON::Object &Obj) const; diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 95da446..eba39c2 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -409,6 +409,7 @@ namespace OpenWifi::RESTAPI::Errors { static const struct msg DefFirmwareNameExists { 1172, "Firmware name already exists." }; static const struct msg NotAValidECKey { 1173, "Provided key supplied is not valid." }; static const struct msg InvalidGlobalReachAccount { 1174, "Invalid Global Reach account information (id or key)." }; + static const struct msg CannotCreateCSR { 1175, "Could not create CSR" }; static const struct msg SimulationDoesNotExist { 7000, "Simulation Instance ID does not exist." diff --git a/src/framework/utils.cpp b/src/framework/utils.cpp index ad65bcf..b4486ba 100644 --- a/src/framework/utils.cpp +++ b/src/framework/utils.cpp @@ -609,8 +609,14 @@ namespace OpenWifi::Utils { return DT.timestamp().epochTime(); } - std::string CreateX509CSR(const std::string &Country, const std::string &Province, const std::string &City, - const std::string &Organization, const std::string &CommonName, int bits ) { + static std::string FileToString(const std::string &Filename) { + std::ifstream ifs(Filename.c_str(),std::ios_base::in|std::ios_base::binary); + std::ostringstream os; + Poco::StreamCopier::copyStream(ifs,os); + return os.str(); + } + + bool CreateX509CSR(const CSRCreationParameters & Parameters, CSRCreationResults & Results) { int ret = 0; RSA *r = nullptr; BIGNUM *bne = nullptr; @@ -622,21 +628,23 @@ namespace OpenWifi::Utils { X509_NAME *x509_name = nullptr; EVP_PKEY *pKey = nullptr; // RSA *tem = nullptr; - BIO *out = nullptr; // BIO *bio_err = nullptr; - const char *szCountry = Country.c_str(); - const char *szProvince = Province.c_str(); - const char *szCity = City.c_str(); - const char *szOrganization = Organization.c_str(); - const char *szCommon = CommonName.c_str(); + const char *szCountry = Parameters.Country.c_str(); + const char *szProvince = Parameters.Province.c_str(); + const char *szCity = Parameters.City.c_str(); + const char *szOrganization = Parameters.Organization.c_str(); + const char *szCommon = Parameters.CommonName.c_str(); - Poco::TemporaryFile CsrPath; + Poco::TemporaryFile CsrPath, PubKey, PrivateKey; std::string Result; std::ifstream ifs; std::ostringstream ss; + BIO *bp_public = nullptr, + *bp_private = nullptr, + *bp_csr = nullptr; - // 1. generate rsa key + // 1. generate rsa key bne = BN_new(); ret = BN_set_word(bne,e); if(ret != 1){ @@ -644,11 +652,23 @@ namespace OpenWifi::Utils { } r = RSA_new(); - ret = RSA_generate_key_ex(r, bits, bne, nullptr); + ret = RSA_generate_key_ex(r, Parameters.bits, bne, nullptr); if(ret != 1){ goto free_all; } + bp_public = BIO_new_file(PubKey.path().c_str(), "w+"); + ret = PEM_write_bio_RSAPublicKey(bp_public, r); + if(ret != 1) { + goto free_all; + } + + bp_private = BIO_new_file(PrivateKey.path().c_str(), "w+"); + ret = PEM_write_bio_RSAPrivateKey(bp_private, r, NULL, NULL, 0, NULL, NULL); + if(ret != 1) { + goto free_all; + } + // 2. set version of x509 req x509_req = X509_REQ_new(); ret = X509_REQ_set_version(x509_req, nVersion); @@ -700,22 +720,25 @@ namespace OpenWifi::Utils { goto free_all; } - out = BIO_new_file(CsrPath.path().c_str(),"w"); - ret = PEM_write_bio_X509_REQ(out, x509_req); + bp_csr = BIO_new_file(CsrPath.path().c_str(),"w"); + ret = PEM_write_bio_X509_REQ(bp_csr, x509_req); - ifs.open(CsrPath.path().c_str(),std::ios_base::binary|std::ios_base::in); - Poco::StreamCopier::copyStream(ifs,ss); - ifs.close(); - Result = ss.str(); // 6. free - free_all: + free_all: X509_REQ_free(x509_req); - BIO_free_all(out); + BIO_free_all(bp_csr); + BIO_free_all(bp_public); + BIO_free_all(bp_private); EVP_PKEY_free(pKey); BN_free(bne); + if(ret==1) { + Results.CSR = FileToString(CsrPath.path()); + Results.PrivateKey = FileToString(PrivateKey.path()); + Results.PublicKey = FileToString(PubKey.path()); + } - return Result; + return ret; } bool VerifyECKey(const std::string &key) { diff --git a/src/framework/utils.h b/src/framework/utils.h index 2580b78..9a9c939 100644 --- a/src/framework/utils.h +++ b/src/framework/utils.h @@ -247,7 +247,17 @@ namespace OpenWifi::Utils { return count; } - std::string CreateX509CSR(const std::string &Country, const std::string &Province, const std::string &City, - const std::string &Organization, const std::string &CommonName, int bits=2048); + struct CSRCreationParameters { + std::string Country, Province, City, + Organization, CommonName; + int bits=2048; + }; + + struct CSRCreationResults { + std::string CSR, PublicKey, PrivateKey; + }; + + bool CreateX509CSR(const CSRCreationParameters & Parameters, CSRCreationResults & Results); + bool VerifyECKey(const std::string &key); } // namespace OpenWifi::Utils diff --git a/src/storage/storage_glblraccounts.cpp b/src/storage/storage_glblraccounts.cpp index 37210b0..2d0bee7 100644 --- a/src/storage/storage_glblraccounts.cpp +++ b/src/storage/storage_glblraccounts.cpp @@ -25,6 +25,8 @@ namespace OpenWifi { ORM::Field{"organization", ORM::FieldType::FT_TEXT}, ORM::Field{"commonName", ORM::FieldType::FT_TEXT}, ORM::Field{"CSR", ORM::FieldType::FT_TEXT}, + ORM::Field{"CSRPrivateKey", ORM::FieldType::FT_TEXT}, + ORM::Field{"CSRPublicKey", ORM::FieldType::FT_TEXT}, ORM::Field{"GlobalReachAcctId", ORM::FieldType::FT_TEXT} }; @@ -68,7 +70,9 @@ void ORM::DB(); Out.commonName = In.get<11>(); Out.CSR = In.get<12>(); - Out.GlobalReachAcctId = In.get<13>(); + Out.CSRPrivateKey = In.get<13>(); + Out.CSRPublicKey = In.get<14>(); + Out.GlobalReachAcctId = In.get<15>(); } template <> @@ -87,5 +91,7 @@ void ORM::DB(In.organization); Out.set<11>(In.commonName); Out.set<12>(In.CSR); - Out.set<13>(In.GlobalReachAcctId); + Out.set<13>(In.CSRPrivateKey); + Out.set<14>(In.CSRPublicKey); + Out.set<15>(In.GlobalReachAcctId); } diff --git a/src/storage/storage_glblraccounts.h b/src/storage/storage_glblraccounts.h index dc0f8d3..cfb0a69 100644 --- a/src/storage/storage_glblraccounts.h +++ b/src/storage/storage_glblraccounts.h @@ -19,6 +19,8 @@ namespace OpenWifi { std::string, std::string, std::string, + std::string, + std::string, std::string> GLBLRAccountsDBRecordType;