void HandshakeResponder::responderParseHalfKeyAndResponderIntegrity(){ //R:2 parse
    m_timeout.stop();
    QByteArray encryptedSymKey;
    m_socketStream >> encryptedSymKey;
    if(isError(encryptedSymKey)) return;

    QByteArray clearSymKey = rsaDecrypt(encryptedSymKey);
    if(clearSymKey.size()<32){
        processError(BadSymmetricKey);
        return;
    }
    m_gcmKey.append(clearSymKey.left(16));      //second half key
    m_gcmBaseIV.append(clearSymKey.right(16));  //second half IV

    QByteArray encryptedRespIntegrity, responderIntegrity;
    m_socketStream >> encryptedRespIntegrity;
    responderIntegrity = gcmDecrypt(encryptedRespIntegrity);

    if(responderIntegrity != m_responderIntegrityHash){
        processError(DataCorrupted);
        return;
    }

    updateIntegrityHash(&m_starterIntegrityHash, clearSymKey+responderIntegrity);
    responderSendStarterIntegrity();
}
static void getContract(TrustedContractArgs *args){
	int rsaErr = 0, aesErr = 0;
	//hello(REP_TRUSTED_NAME);
	printf("In trusted mode getContract()");

	//X1XXuseDMA(); //DMA the encrypted data into trusted space
	rsaErr = rsaDecrypt(encryptedAESKey,g_d,g_modulus,decryptedAESKey);
	if(rsaErr != 0){
		printf("RSA encryption failed.\n");
		//*args->success = 0;
	}
	else{
		aesErr = aesDecrypt(decryptedAESKey,encrypted,decrypted,nbytes);
	}

	if(aesErr != 0){
		printf("AES encryption failed.\n");
		//*args->success = 0;
	}
	else if(aesErr == 0 && rsaErr == 0){
		//*(args)->success = 1;
		memcpy(contract,decrypted,nbytes);
	}
	/*Clear decrypted aeskey*/
	memset(decryptedAESKey,0, 128);

}
void HandshakeResponder::responderParseStarterHello(){ //R:1 parse
    QByteArray packet;
    m_socketStream >> packet;
    QDataStream packetStream(&packet, QIODevice::ReadOnly);

    if(isError(packet)) return;

    quint8 secLevel;
    packetStream >> secLevel;
    if(static_cast<SecurityLevel>(secLevel) != PreSharedIdentity){
        processError(BadSecurityLevel);
        return;
    }

    QByteArray rsaCypherText;
    packetStream >> rsaCypherText;
    QByteArray clearText = rsaDecrypt(rsaCypherText);
    if(clearText.isEmpty()){
        processError(DataCorrupted);
        return;
    }
    QDataStream clearTextStream(&clearText, QIODevice::ReadOnly);
    QByteArray key;
    clearTextStream >> key;
    m_contact = m_contactDB->findByKey(key);
    if(m_contact == NULL){
        processError(IdentityCheckFailed);
        return;
    }
    try{
        m_rsaEncryptor.AccessKey().Load(ArraySource((byte*)m_contact->getKey().data(),
                                                    m_contact->getKey().size(),
                                                    true));
    }catch(CryptoPP::BERDecodeErr&){
        processError(BadContactKey);
    }

    quint8 version;
    clearTextStream >> version;
    if((version & 0xF0) != (SUPPORTED_PROTOCOL_VERSION & 0xF0)){
        processError(IncompatibleProtocolVersions);
        return;
    }

    updateIntegrityHash(&m_starterIntegrityHash, (char)secLevel+clearText);
    responderRespondHello();
}
int main(int argc, char* argv[])
{
    char hostName[200] = DEFAULT_HOSTNAME;
    int port = DEFAULT_RESMGR_TPM_PORT;

    TPMI_DH_OBJECT keyHandle;
    TPM2B_PUBLIC_KEY_RSA cipherText;
    char outFilePath[PATH_MAX] = {0};
    char *contextKeyFile = NULL;

    setbuf(stdout, NULL);
    setvbuf (stdout, NULL, _IONBF, BUFSIZ);

    int opt = -1;
    const char *optstring = "hvk:P:I:o:p:d:c:";
    static struct option long_options[] = {
      {"help",0,NULL,'h'},
      {"version",0,NULL,'v'},
      {"keyHandle",1,NULL,'k'},
      {"pwdk",1,NULL,'P'},
      {"inFile",1,NULL,'I'},
      {"outFile",1,NULL,'o'},
      {"port",1,NULL,'p'},
      {"debugLevel",1,NULL,'d'},
      {"keyContext",1,NULL,'c'},
      {0,0,0,0}
    };

    int returnVal = 0;
    int flagCnt = 0;
    int h_flag = 0,
        v_flag = 0,
        k_flag = 0,
        P_flag = 0,
        I_flag = 0,
        c_flag = 0,
        o_flag = 0;

    if(argc == 1)
    {
        showHelp(argv[0]);
        return 0;
    }

    while((opt = getopt_long(argc,argv,optstring,long_options,NULL)) != -1)
    {
        switch(opt)
        {
        case 'h':
            h_flag = 1;
            break;
        case 'v':
            v_flag = 1;
            break;
        case 'k':
            if(getSizeUint32Hex(optarg,&keyHandle) != 0)
            {
                returnVal = -1;
                break;
            }
            k_flag = 1;
            break;
        case 'P':
            sessionData.hmac.t.size = sizeof(sessionData.hmac.t) - 2;
            if(str2ByteStructure(optarg,&sessionData.hmac.t.size,sessionData.hmac.t.buffer) != 0)
            {
                returnVal = -2;
                break;
            }
            P_flag = 1;
            break;
        case 'I':
            cipherText.t.size = sizeof(cipherText) - 2;
            if(loadDataFromFile(optarg, cipherText.t.buffer, &cipherText.t.size) != 0)
            {
                returnVal = -3;
                break;
            }
            I_flag = 1;
            break;
        case 'o':
            safeStrNCpy(outFilePath, optarg, sizeof(outFilePath));
            if(checkOutFile(outFilePath) != 0)
            {
                returnVal = -4;
                break;
            }
            o_flag = 1;
            break;
        case 'p':
            if( getPort(optarg, &port) )
            {
                printf("Incorrect port number.\n");
                returnVal = -5;
            }
            break;
        case 'd':
            if( getDebugLevel(optarg, &debugLevel) )
            {
                printf("Incorrect debug level.\n");
                returnVal = -6;
            }
            break;
        case 'c':
            contextKeyFile = optarg;
            if(contextKeyFile == NULL || contextKeyFile[0] == '\0')
            {
                returnVal = -7;
                break;
            }
            printf("contextKeyFile = %s\n", contextKeyFile);
            c_flag = 1;
            break;
        case ':':
//              printf("Argument %c needs a value!\n",optopt);
            returnVal = -8;
            break;
        case '?':
//              printf("Unknown Argument: %c\n",optopt);
            returnVal = -9;
            break;
        //default:
        //  break;
        }
        if(returnVal)
            break;
    };

    if(returnVal != 0)
        return returnVal;

    if(P_flag == 0)
        sessionData.hmac.t.size = 0;

    flagCnt = h_flag + v_flag + k_flag + I_flag + o_flag + c_flag;

    if(flagCnt == 1)
    {
        if(h_flag == 1)
            showHelp(argv[0]);
        else if(v_flag == 1)
            showVersion(argv[0]);
        else
        {
            showArgMismatch(argv[0]);
            return -10;
        }
    }
    else if((flagCnt == 3) && (k_flag == 1 || c_flag == 1) && (I_flag == 1) && (o_flag == 1))
    {
        prepareTest(hostName, port, debugLevel);

        if(c_flag)
            returnVal = loadTpmContextFromFile(sysContext, &keyHandle, contextKeyFile);
        if(returnVal == 0)
            returnVal = rsaDecrypt(keyHandle, &cipherText, outFilePath);

        finishTest();

        if(returnVal)
            return -11;
    }
    else
    {
        showArgMismatch(argv[0]);
        return -12;
    }

    return 0;
}