Completed and fully tested refactoring of TLV8

Next up: remove old TLV code and clean up
This commit is contained in:
Gregg 2023-12-25 22:04:02 -06:00
parent 76a6a2bde9
commit 3c172da714
5 changed files with 209 additions and 198 deletions

View File

@ -112,17 +112,17 @@ void HAPClient::init(){
printControllers(); printControllers();
tlv8.create(kTLVType_Separator,0,"SEPARATOR"); // define the actual TLV records needed for the implementation of HAP; one for each kTLVType needed (HAP Table 5-6) // tlv8.create(kTLVType_Separator,0,"SEPARATOR"); // define the actual TLV records needed for the implementation of HAP; one for each kTLVType needed (HAP Table 5-6)
tlv8.create(kTLVType_State,1,"STATE"); // tlv8.create(kTLVType_State,1,"STATE");
tlv8.create(kTLVType_PublicKey,384,"PUBKEY"); // tlv8.create(kTLVType_PublicKey,384,"PUBKEY");
tlv8.create(kTLVType_Method,1,"METHOD"); // tlv8.create(kTLVType_Method,1,"METHOD");
tlv8.create(kTLVType_Salt,16,"SALT"); // tlv8.create(kTLVType_Salt,16,"SALT");
tlv8.create(kTLVType_Error,1,"ERROR"); // tlv8.create(kTLVType_Error,1,"ERROR");
tlv8.create(kTLVType_Proof,64,"PROOF"); // tlv8.create(kTLVType_Proof,64,"PROOF");
tlv8.create(kTLVType_EncryptedData,1024,"ENC.DATA"); // tlv8.create(kTLVType_EncryptedData,1024,"ENC.DATA");
tlv8.create(kTLVType_Signature,64,"SIGNATURE"); // tlv8.create(kTLVType_Signature,64,"SIGNATURE");
tlv8.create(kTLVType_Identifier,64,"IDENTIFIER"); // tlv8.create(kTLVType_Identifier,64,"IDENTIFIER");
tlv8.create(kTLVType_Permissions,1,"PERMISSION"); // tlv8.create(kTLVType_Permissions,1,"PERMISSION");
if(!nvs_get_blob(hapNVS,"HAPHASH",NULL,&len)){ // if found HAP HASH structure if(!nvs_get_blob(hapNVS,"HAPHASH",NULL,&len)){ // if found HAP HASH structure
nvs_get_blob(hapNVS,"HAPHASH",&homeSpan.hapConfig,&len); // retrieve data nvs_get_blob(hapNVS,"HAPHASH",&homeSpan.hapConfig,&len); // retrieve data
@ -217,33 +217,23 @@ void HAPClient::processRequest(){
if(cLen==0){ if(cLen==0){
badRequestError(); badRequestError();
LOG0("\n*** ERROR: HTTP POST request contains no Content\n\n"); LOG0("\n*** ERROR: HTTP POST request contains no Content\n\n");
return;
} }
if(!strncmp(body,"POST /pair-setup ",17) && strstr(body,"Content-Type: application/pairing+tlv8")){ // POST PAIR-SETUP else if(!strncmp(body,"POST /pair-setup ",17) && strstr(body,"Content-Type: application/pairing+tlv8")) // POST PAIR-SETUP
postPairSetupURL(content,cLen); postPairSetupURL(content,cLen);
return;
}
if(!strncmp(body,"POST /pair-verify ",18) && strstr(body,"Content-Type: application/pairing+tlv8")){ // POST PAIR-VERIFY else if(!strncmp(body,"POST /pair-verify ",18) && strstr(body,"Content-Type: application/pairing+tlv8")) // POST PAIR-VERIFY
postPairVerifyURL(content,cLen); postPairVerifyURL(content,cLen);
return;
}
if(!strncmp(body,"POST /pairings ",15) && // POST PAIRINGS else if(!strncmp(body,"POST /pairings ",15) && strstr(body,"Content-Type: application/pairing+tlv8")) // POST PAIRINGS
strstr(body,"Content-Type: application/pairing+tlv8") && // check that content is TLV8 postPairingsURL(content,cLen);
tlv8.unpack(content,cLen)){ // read TLV content
tlv8.print(2); // print TLV records in form "TAG(INT) LENGTH(INT) VALUES(HEX)"
LOG2("------------ END TLVS! ------------\n");
postPairingsURL(); // process URL
return;
}
else {
notFoundError(); notFoundError();
LOG0("\n*** ERROR: Bad POST request - URL not found\n\n"); LOG0("\n*** ERROR: Bad POST request - URL not found\n\n");
return; }
return;
} // POST request } // POST request
if(!strncmp(body,"PUT ",4)){ // this is a PUT request if(!strncmp(body,"PUT ",4)){ // this is a PUT request
@ -381,7 +371,7 @@ int HAPClient::postPairSetupURL(uint8_t *content, size_t len){
auto itState=iosTLV.find(kTLVType_State); auto itState=iosTLV.find(kTLVType_State);
if(iosTLV.len(itState)!=1){ // missing STATE TLV if(iosTLV.len(itState)!=1){ // missing STATE TLV
LOG0("\n*** ERROR: Missing or invalid <M#> State TLV\n\n"); LOG0("\n*** ERROR: Missing or invalid 'State' TLV\n\n");
badRequestError(); // return with 400 error, which closes connection badRequestError(); // return with 400 error, which closes connection
return(0); return(0);
} }
@ -627,7 +617,7 @@ int HAPClient::postPairVerifyURL(uint8_t *content, size_t len){
auto itState=iosTLV.find(kTLVType_State); auto itState=iosTLV.find(kTLVType_State);
if(iosTLV.len(itState)!=1){ // missing STATE TLV if(iosTLV.len(itState)!=1){ // missing STATE TLV
LOG0("\n*** ERROR: Missing or invalid <M#> State TLV\n\n"); LOG0("\n*** ERROR: Missing or invalid 'State' TLV\n\n");
badRequestError(); // return with 400 error, which closes connection badRequestError(); // return with 400 error, which closes connection
return(0); return(0);
} }
@ -828,101 +818,129 @@ int HAPClient::getAccessoriesURL(){
////////////////////////////////////// //////////////////////////////////////
int HAPClient::postPairingsURL(){ int HAPClient::postPairingsURL(uint8_t *content, size_t len){
if(!cPair){ // unverified, unencrypted session if(!cPair){ // unverified, unencrypted session
unauthorizedError(); unauthorizedError();
return(0); return(0);
} }
LOG1("In Post Pairings #"); HAPTLV iosTLV;
LOG1(conNum); HAPTLV responseTLV;
LOG1(" (");
LOG1(client.remoteIP());
LOG1(")...");
if(tlv8.val(kTLVType_State)!=1){ iosTLV.unpack(content,len);
LOG0("\n*** ERROR: 'State' TLV record is either missing or not set to <M1> as required\n\n"); iosTLV.print();
LOG2("------------ END TLVS! ------------\n");
LOG2("In Post Pairings #%d (%s)...",conNum,client.remoteIP().toString().c_str());
auto itState=iosTLV.find(kTLVType_State);
auto itMethod=iosTLV.find(kTLVType_Method);
if(iosTLV.len(itState)!=1 || (*itState)[0]!=1){ // missing STATE TLV
LOG0("\n*** ERROR: Parirings 'State' is either missing or not set to <M1>\n\n");
badRequestError(); // return with 400 error, which closes connection badRequestError(); // return with 400 error, which closes connection
return(0); return(0);
} }
switch(tlv8.val(kTLVType_Method)){ if(iosTLV.len(itMethod)!=1){ // missing METHOD TLV
LOG0("\n*** ERROR: Missing or invalid 'Method' TLV\n\n");
badRequestError(); // return with 400 error, which closes connection
return(0);
}
int tlvMethod=(*itMethod)[0];
responseTLV.add(kTLVType_State,pairState_M2); // all responses include State=M2
switch(tlvMethod){ // List-Pairings received -- process request! (HAP Sections 5.10-5.12)
case 3: { case 3: {
LOG1("Add...\n"); LOG1("Add...\n");
if(!tlv8.len(kTLVType_Identifier) || !tlv8.len(kTLVType_PublicKey) || !tlv8.len(kTLVType_Permissions)){ auto itIdentifier=iosTLV.find(kTLVType_Identifier);
auto itPublicKey=iosTLV.find(kTLVType_PublicKey);
auto itPermissions=iosTLV.find(kTLVType_Permissions);
if(iosTLV.len(itIdentifier)!=hap_controller_IDBYTES || iosTLV.len(itPublicKey)!=crypto_sign_PUBLICKEYBYTES || iosTLV.len(itPermissions)!=1){
LOG0("\n*** ERROR: One or more of required 'Identifier,' 'PublicKey,' and 'Permissions' TLV records for this step is bad or missing\n\n"); LOG0("\n*** ERROR: One or more of required 'Identifier,' 'PublicKey,' and 'Permissions' TLV records for this step is bad or missing\n\n");
tlv8.clear(); responseTLV.add(kTLVType_Error,tagError_Unknown);
tlv8.val(kTLVType_Error,tagError_Unknown); tlvRespond(responseTLV);
return(0);
} else if(!cPair->admin){
LOG0("\n*** ERROR: Controller making request does not have admin privileges to add/update other Controllers\n\n");
tlv8.clear();
tlv8.val(kTLVType_Error,tagError_Authentication);
} else {
tagError err=addController(tlv8.buf(kTLVType_Identifier),tlv8.buf(kTLVType_PublicKey),tlv8.val(kTLVType_Permissions));
tlv8.clear();
if(err!=tagError_None)
tlv8.val(kTLVType_Error,err);
} }
tlv8.val(kTLVType_State,pairState_M2); if(!cPair->admin){
tlvRespond(); LOG0("\n*** ERROR: Controller making request does not have admin privileges to add/update other Controllers\n\n");
responseTLV.add(kTLVType_Error,tagError_Authentication);
tlvRespond(responseTLV);
return(0);
}
tagError err=addController(*itIdentifier,*itPublicKey,(*itPermissions)[0]);
if(err!=tagError_None)
responseTLV.add(kTLVType_Error,err);
tlvRespond(responseTLV);
return(1); return(1);
} }
break;
case 4: { case 4: {
LOG1("Remove...\n"); LOG1("Remove...\n");
uint8_t id[36]; auto itIdentifier=iosTLV.find(kTLVType_Identifier);
if(!tlv8.len(kTLVType_Identifier)){ if(iosTLV.len(itIdentifier)!=hap_controller_IDBYTES){
LOG0("\n*** ERROR: Required 'Identifier' TLV record for this step is bad or missing\n\n"); LOG0("\n*** ERROR: Required 'Identifier' TLV record for this step is bad or missing\n\n");
tlv8.clear(); responseTLV.add(kTLVType_Error,tagError_Unknown);
tlv8.val(kTLVType_Error,tagError_Unknown); tlvRespond(responseTLV);
return(0);
} else if(!cPair->admin){
LOG0("\n*** ERROR: Controller making request does not have admin privileges to remove Controllers\n\n");
tlv8.clear();
tlv8.val(kTLVType_Error,tagError_Authentication);
} else {
memcpy(id,tlv8.buf(kTLVType_Identifier),36);
tlv8.clear();
} }
tlv8.val(kTLVType_State,pairState_M2); if(!cPair->admin){
tlvRespond(); // must send response before removing Controller below LOG0("\n*** ERROR: Controller making request does not have admin privileges to remove Controllers\n\n");
responseTLV.add(kTLVType_Error,tagError_Authentication);
tlvRespond(responseTLV);
return(0);
}
if(tlv8.val(kTLVType_Error)==-1) tlvRespond(responseTLV); // must send response before removing Controller
removeController(id); removeController(*itIdentifier);
return(1); return(1);
} }
break;
case 5: { case 5: {
LOG1("List...\n"); LOG1("List...\n");
TempBuffer<uint8_t> tBuf(listControllers(NULL)); if(!cPair->admin){
LOG0("\n*** ERROR: Controller making request does not have admin privileges to remove Controllers\n\n");
char *body; responseTLV.add(kTLVType_Error,tagError_Authentication);
asprintf(&body,"HTTP/1.1 200 OK\r\nContent-Type: application/pairing+tlv8\r\nContent-Length: %d\r\n\r\n",tBuf.len()); // create Body with Content Length = size of TLV data tlvRespond(responseTLV);
return(0);
LOG2("\n>>>>>>>>>> ");
LOG2(client.remoteIP());
LOG2(" >>>>>>>>>>\n");
LOG2(body);
listControllers(tBuf);
sendEncrypted(body,tBuf,tBuf.len());
free(body);
return(1);
} }
boolean addSeparator=false;
for(auto it=controllerList.begin();it!=controllerList.end();it++){
if((*it).allocated){
if(addSeparator)
responseTLV.add(kTLVType_Separator);
responseTLV.add(kTLVType_Permissions,(*it).admin);
responseTLV.add(kTLVType_Identifier,hap_controller_IDBYTES,(*it).ID);
responseTLV.add(kTLVType_PublicKey,crypto_sign_PUBLICKEYBYTES,(*it).LTPK);
addSeparator=true;
}
}
tlvRespond(responseTLV);
return(1);
}
break;
default: { default: {
LOG0("\n*** ERROR: 'Method' TLV record is either missing or not set to either 3, 4, or 5 as required\n\n"); LOG0("\n*** ERROR: Undefined List-Pairings Method: %d. Must be 3, 4, or 5\n\n",tlvMethod);
badRequestError(); // return with 400 error, which closes connection badRequestError(); // return with 400 error, which closes connection
return(0); return(0);
} }
@ -1372,31 +1390,31 @@ void HAPClient::tlvRespond(TLV8 &tlv8){
////////////////////////////////////// //////////////////////////////////////
void HAPClient::tlvRespond(){ //void HAPClient::tlvRespond(){
//
TempBuffer<uint8_t> tBuf(tlv8.pack(NULL)); // create buffer to hold TLV data // TempBuffer<uint8_t> tBuf(tlv8.pack(NULL)); // create buffer to hold TLV data
tlv8.pack(tBuf); // pack TLV records into buffer // tlv8.pack(tBuf); // pack TLV records into buffer
//
char *body; // char *body;
asprintf(&body,"HTTP/1.1 200 OK\r\nContent-Type: application/pairing+tlv8\r\nContent-Length: %d\r\n\r\n",tBuf.len()); // create Body with Content Length = size of TLV data // asprintf(&body,"HTTP/1.1 200 OK\r\nContent-Type: application/pairing+tlv8\r\nContent-Length: %d\r\n\r\n",tBuf.len()); // create Body with Content Length = size of TLV data
//
LOG2("\n>>>>>>>>>> "); // LOG2("\n>>>>>>>>>> ");
LOG2(client.remoteIP()); // LOG2(client.remoteIP());
LOG2(" >>>>>>>>>>\n"); // LOG2(" >>>>>>>>>>\n");
LOG2(body); // LOG2(body);
tlv8.print(2); // tlv8.print(2);
//
if(!cPair){ // unverified, unencrypted session // if(!cPair){ // unverified, unencrypted session
client.print(body); // client.print(body);
client.write(tBuf,tBuf.len()); // client.write(tBuf,tBuf.len());
LOG2("------------ SENT! --------------\n"); // LOG2("------------ SENT! --------------\n");
} else { // } else {
sendEncrypted(body,tBuf,tBuf.len()); // sendEncrypted(body,tBuf,tBuf.len());
} // }
//
free(body); // free(body);
//
} // tlvRespond //} // tlvRespond
////////////////////////////////////// //////////////////////////////////////
@ -1619,33 +1637,33 @@ void HAPClient::tearDown(uint8_t *id){
////////////////////////////////////// //////////////////////////////////////
int HAPClient::listControllers(uint8_t *tlvBuf){ //int HAPClient::listControllers(uint8_t *tlvBuf){
//
int nBytes=0; // int nBytes=0;
int n; // int n;
//
tlv8.clear(); // tlv8.clear();
tlv8.val(kTLVType_State,pairState_M2); // tlv8.val(kTLVType_State,pairState_M2);
//
for(auto it=controllerList.begin();it!=controllerList.end();it++){ // for(auto it=controllerList.begin();it!=controllerList.end();it++){
if((*it).allocated){ // if((*it).allocated){
if(tlv8.val(kTLVType_State)==-1) // if State is not set then this is not the first controller found // if(tlv8.val(kTLVType_State)==-1) // if State is not set then this is not the first controller found
tlv8.val(kTLVType_Separator,1); // tlv8.val(kTLVType_Separator,1);
tlv8.val(kTLVType_Permissions,(*it).admin); // tlv8.val(kTLVType_Permissions,(*it).admin);
tlv8.buf(kTLVType_Identifier,(*it).ID,36); // tlv8.buf(kTLVType_Identifier,(*it).ID,36);
tlv8.buf(kTLVType_PublicKey,(*it).LTPK,32); // tlv8.buf(kTLVType_PublicKey,(*it).LTPK,32);
n=tlv8.pack(tlvBuf); // n=tlv8.pack(tlvBuf);
nBytes+=n; // nBytes+=n;
if(tlvBuf){ // if(tlvBuf){
tlvBuf+=n; // tlvBuf+=n;
tlv8.print(); // tlv8.print();
} // }
tlv8.clear(); // tlv8.clear();
} // }
} // }
//
return(nBytes); // return(nBytes);
} //}
////////////////////////////////////// //////////////////////////////////////
@ -1716,7 +1734,7 @@ void Nonce::inc(){
// instantiate all static HAP Client structures and data // instantiate all static HAP Client structures and data
TLV<kTLVType,11> HAPClient::tlv8; //TLV<kTLVType,11> HAPClient::tlv8;
nvs_handle HAPClient::hapNVS; nvs_handle HAPClient::hapNVS;
nvs_handle HAPClient::srpNVS; nvs_handle HAPClient::srpNVS;
HKDF HAPClient::hkdf; HKDF HAPClient::hkdf;

View File

@ -30,26 +30,29 @@
#include <WiFi.h> #include <WiFi.h>
#include "HomeSpan.h" #include "HomeSpan.h"
#include "TLV.h" //#include "TLV.h"
#include "HAPConstants.h" #include "HAPConstants.h"
#include "HKDF.h" #include "HKDF.h"
#include "SRP.h" #include "SRP.h"
#include "TLV8.h" #include "TLV8.h"
const TLV8_names HAP_Names[] = { const TLV8_names HAP_Names[] = {
{kTLVType_Separator,"*SEPARATOR"}, {kTLVType_Separator,"SEPARATOR"},
{kTLVType_State,"*STATE"}, {kTLVType_State,"STATE"},
{kTLVType_PublicKey,"*PUBKEY"}, {kTLVType_PublicKey,"PUBKEY"},
{kTLVType_Method,"*METHOD"}, {kTLVType_Method,"METHOD"},
{kTLVType_Salt,"*SALT"}, {kTLVType_Salt,"SALT"},
{kTLVType_Error,"*ERROR"}, {kTLVType_Error,"ERROR"},
{kTLVType_Proof,"*PROOF"}, {kTLVType_Proof,"PROOF"},
{kTLVType_EncryptedData,"*ENC.DATA"}, {kTLVType_EncryptedData,"ENC.DATA"},
{kTLVType_Signature,"*SIGNATURE"}, {kTLVType_Signature,"SIGNATURE"},
{kTLVType_Identifier,"*IDENTIFIER"}, {kTLVType_Identifier,"IDENTIFIER"},
{kTLVType_Permissions,"*PERMISSION"} {kTLVType_Permissions,"PERMISSION"}
}; };
#define hap_controller_IDBYTES 36
#define hap_accessory_IDBYTES 17
///////////////////////////////////////////////// /////////////////////////////////////////////////
// NONCE Structure (HAP used last 64 of 96 bits) // NONCE Structure (HAP used last 64 of 96 bits)
@ -67,7 +70,7 @@ struct Nonce {
struct Controller { struct Controller {
boolean allocated=false; // DEPRECATED (but needed for backwards compatability with original NVS storage of Controller info) boolean allocated=false; // DEPRECATED (but needed for backwards compatability with original NVS storage of Controller info)
boolean admin; // Controller has admin privileges boolean admin; // Controller has admin privileges
uint8_t ID[36]; // Pairing ID uint8_t ID[hap_controller_IDBYTES]; // Pairing ID
uint8_t LTPK[crypto_sign_PUBLICKEYBYTES]; // Long Term Ed2519 Public Key uint8_t LTPK[crypto_sign_PUBLICKEYBYTES]; // Long Term Ed2519 Public Key
Controller(){} Controller(){}
@ -85,9 +88,9 @@ struct Controller {
// Accessory Structure for Permanently-Stored Data // Accessory Structure for Permanently-Stored Data
struct Accessory { struct Accessory {
uint8_t ID[17]; // Pairing ID in form "XX:XX:XX:XX:XX:XX" uint8_t ID[hap_accessory_IDBYTES]; // Pairing ID in form "XX:XX:XX:XX:XX:XX" (no null terminator)
uint8_t LTSK[crypto_sign_SECRETKEYBYTES]; // secret key for Ed25519 signatures uint8_t LTSK[crypto_sign_SECRETKEYBYTES]; // Long Term Ed2519 Secret Key
uint8_t LTPK[crypto_sign_PUBLICKEYBYTES]; // public key for Ed25519 signatures uint8_t LTPK[crypto_sign_PUBLICKEYBYTES]; // Long Term Ed2519 Public Key
}; };
///////////////////////////////////////////////// /////////////////////////////////////////////////
@ -102,7 +105,7 @@ struct HAPClient {
static const int MAX_CONTROLLERS=16; // maximum number of paired controllers (HAP requires at least 16) static const int MAX_CONTROLLERS=16; // maximum number of paired controllers (HAP requires at least 16)
static const int MAX_ACCESSORIES=150; // maximum number of allowed Accessories (HAP limit=150) static const int MAX_ACCESSORIES=150; // maximum number of allowed Accessories (HAP limit=150)
static TLV<kTLVType,11> tlv8; // TLV8 structure (HAP Section 14.1) with space for 11 TLV records of type kTLVType (HAP Table 5-6) // static TLV<kTLVType,11> tlv8; // TLV8 structure (HAP Section 14.1) with space for 11 TLV records of type kTLVType (HAP Table 5-6)
static nvs_handle hapNVS; // handle for non-volatile-storage of HAP data static nvs_handle hapNVS; // handle for non-volatile-storage of HAP data
static nvs_handle srpNVS; // handle for non-volatile-storage of SRP data static nvs_handle srpNVS; // handle for non-volatile-storage of SRP data
static HKDF hkdf; // generates (and stores) HKDF-SHA-512 32-byte keys derived from an inputKey of arbitrary length, a salt string, and an info string static HKDF hkdf; // generates (and stores) HKDF-SHA-512 32-byte keys derived from an inputKey of arbitrary length, a salt string, and an info string
@ -136,14 +139,14 @@ struct HAPClient {
void processRequest(); // process HAP request void processRequest(); // process HAP request
int postPairSetupURL(uint8_t *content, size_t len); // POST /pair-setup (HAP Section 5.6) int postPairSetupURL(uint8_t *content, size_t len); // POST /pair-setup (HAP Section 5.6)
int postPairVerifyURL(uint8_t *content, size_t len); // POST /pair-verify (HAP Section 5.7) int postPairVerifyURL(uint8_t *content, size_t len); // POST /pair-verify (HAP Section 5.7)
int postPairingsURL(uint8_t *content, size_t len); // POST /pairings (HAP Sections 5.10-5.12)
int getAccessoriesURL(); // GET /accessories (HAP Section 6.6) int getAccessoriesURL(); // GET /accessories (HAP Section 6.6)
int postPairingsURL(); // POST /pairings (HAP Sections 5.10-5.12)
int getCharacteristicsURL(char *urlBuf); // GET /characteristics (HAP Section 6.7.4) int getCharacteristicsURL(char *urlBuf); // GET /characteristics (HAP Section 6.7.4)
int putCharacteristicsURL(char *json); // PUT /characteristics (HAP Section 6.7.2) int putCharacteristicsURL(char *json); // PUT /characteristics (HAP Section 6.7.2)
int putPrepareURL(char *json); // PUT /prepare (HAP Section 6.7.2.4) int putPrepareURL(char *json); // PUT /prepare (HAP Section 6.7.2.4)
int getStatusURL(); // GET / status (an optional, non-HAP feature) int getStatusURL(); // GET / status (an optional, non-HAP feature)
void tlvRespond(); // respond to client with HTTP OK header and all defined TLV data records (those with length>0) // void tlvRespond(); // respond to client with HTTP OK header and all defined TLV data records (those with length>0)
void tlvRespond(TLV8 &tlv8); // respond to client with HTTP OK header and all defined TLV data records void tlvRespond(TLV8 &tlv8); // respond to client with HTTP OK header and all defined TLV data records
void sendEncrypted(char *body, uint8_t *dataBuf, int dataLen); // send client complete ChaCha20-Poly1305 encrypted HTTP mesage comprising a null-terminated 'body' and 'dataBuf' with 'dataLen' bytes void sendEncrypted(char *body, uint8_t *dataBuf, int dataLen); // send client complete ChaCha20-Poly1305 encrypted HTTP mesage comprising a null-terminated 'body' and 'dataBuf' with 'dataLen' bytes
int receiveEncrypted(uint8_t *httpBuf, int messageSize); // decrypt HTTP request (HAP Section 6.5) int receiveEncrypted(uint8_t *httpBuf, int messageSize); // decrypt HTTP request (HAP Section 6.5)
@ -164,7 +167,7 @@ struct HAPClient {
static tagError addController(uint8_t *id, uint8_t *ltpk, boolean admin); // stores data for new Controller with specified data. Returns tagError (if any) static tagError addController(uint8_t *id, uint8_t *ltpk, boolean admin); // stores data for new Controller with specified data. Returns tagError (if any)
static void removeController(uint8_t *id); // removes specific Controller. If no remaining admin Controllers, remove all others (if any) as per HAP requirements. static void removeController(uint8_t *id); // removes specific Controller. If no remaining admin Controllers, remove all others (if any) as per HAP requirements.
static void printControllers(int minLogLevel=0); // prints IDs of all allocated (paired) Controller, subject to specified minimum log level static void printControllers(int minLogLevel=0); // prints IDs of all allocated (paired) Controller, subject to specified minimum log level
static int listControllers(uint8_t *tlvBuf); // creates and prints a multi-TLV list of Controllers (HAP Section 5.12) // static int listControllers(uint8_t *tlvBuf); // creates and prints a multi-TLV list of Controllers (HAP Section 5.12)
static void saveControllers(); // saves Controller list in NVS static void saveControllers(); // saves Controller list in NVS
static int nAdminControllers(); // returns number of admin Controller static int nAdminControllers(); // returns number of admin Controller
static void tearDown(uint8_t *id); // tears down connections using Controller with ID=id; tears down all connections if id=NULL static void tearDown(uint8_t *id); // tears down connections using Controller with ID=id; tears down all connections if id=NULL

View File

@ -578,16 +578,6 @@ void Span::processSerialCommand(const char *c){
switch(c[0]){ switch(c[0]){
case 'Z': {
HAPClient::saveControllers();
break;
TempBuffer<uint8_t> tBuf(HAPClient::listControllers(NULL));
HAPClient::listControllers(tBuf);
Serial.printf("SIZE = %d\n",tBuf.len());
HAPClient::hexPrintRow(tBuf,tBuf.len());
break;
}
case 's': { case 's': {
LOG0("\n*** HomeSpan Status ***\n\n"); LOG0("\n*** HomeSpan Status ***\n\n");

View File

@ -239,30 +239,30 @@ void SRP6A::createProof(){
////////////////////////////////////// //////////////////////////////////////
int SRP6A::loadTLV(kTLVType tag, mbedtls_mpi *mpi, int nBytes){ //int SRP6A::loadTLV(kTLVType tag, mbedtls_mpi *mpi, int nBytes){
//
uint8_t *buf=HAPClient::tlv8.buf(tag,nBytes); // uint8_t *buf=HAPClient::tlv8.buf(tag,nBytes);
//
if(!buf) // if(!buf)
return(0); // return(0);
//
mbedtls_mpi_write_binary(mpi,buf,nBytes); // mbedtls_mpi_write_binary(mpi,buf,nBytes);
return(1); // return(1);
} //}
//
////////////////////////////////////// ////////////////////////////////////////
//
int SRP6A::writeTLV(kTLVType tag, mbedtls_mpi *mpi){ //int SRP6A::writeTLV(kTLVType tag, mbedtls_mpi *mpi){
//
int nBytes=HAPClient::tlv8.len(tag); // int nBytes=HAPClient::tlv8.len(tag);
//
if(nBytes>0){ // if(nBytes>0){
mbedtls_mpi_read_binary(mpi,HAPClient::tlv8.buf(tag),nBytes); // mbedtls_mpi_read_binary(mpi,HAPClient::tlv8.buf(tag),nBytes);
return(1); // return(1);
}; // };
//
return(0); // return(0);
} //}
////////////////////////////////////// //////////////////////////////////////

View File

@ -81,8 +81,8 @@ struct SRP6A {
void createPublicKey(); // computes x, v, and B from random s, P, and b void createPublicKey(); // computes x, v, and B from random s, P, and b
void createSessionKey(); // computes u from A and B, and then S from A, v, u, and b void createSessionKey(); // computes u from A and B, and then S from A, v, u, and b
int loadTLV(kTLVType tag, mbedtls_mpi *mpi, int nBytes); // load binary contents of mpi into a TLV record and set its length // int loadTLV(kTLVType tag, mbedtls_mpi *mpi, int nBytes); // load binary contents of mpi into a TLV record and set its length
int writeTLV(kTLVType tag, mbedtls_mpi *mpi); // write binary contents of a TLV record into an mpi // int writeTLV(kTLVType tag, mbedtls_mpi *mpi); // write binary contents of a TLV record into an mpi
int verifyProof(); // verify M1 SRP6A Proof received from HAP client (return 1 on success, 0 on failure) int verifyProof(); // verify M1 SRP6A Proof received from HAP client (return 1 on success, 0 on failure)
void createProof(); // create M2 server-side SRP6A Proof based on M1 as received from HAP Client void createProof(); // create M2 server-side SRP6A Proof based on M1 as received from HAP Client