/* Set the SPA packet message type */ static int set_message_type(fko_ctx_t ctx, fko_cli_options_t *options) { short message_type; if(options->server_command[0] != 0x0) { message_type = FKO_COMMAND_MSG; } else if(options->nat_local) { if (options->fw_timeout >= 0) message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG; else message_type = FKO_LOCAL_NAT_ACCESS_MSG; } else if(options->nat_access_str[0] != 0x0) { if (options->fw_timeout >= 0) message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG; else message_type = FKO_NAT_ACCESS_MSG; } else { if (options->fw_timeout >= 0) message_type = FKO_CLIENT_TIMEOUT_ACCESS_MSG; else message_type = FKO_ACCESS_MSG; } return fko_set_spa_message_type(ctx, message_type); }
/* set_spa_message_type */ static PyObject * set_spa_message_type(PyObject *self, PyObject *args) { fko_ctx_t ctx; short message_type; int res; if(!PyArg_ParseTuple(args, "kh", &ctx, &message_type)) return NULL; res = fko_set_spa_message_type(ctx, message_type); if(res != FKO_SUCCESS) { PyErr_SetString(FKOError, fko_errstr(res)); return NULL; } return Py_BuildValue("", NULL); }
static void spa_default_ctx(fko_ctx_t *ctx) { fko_new(ctx); fko_set_rand_value(*ctx, NULL); fko_spa_data_final(*ctx, ENC_KEY, 16, HMAC_KEY, 16); fko_set_spa_message(*ctx, "123.123.123.123,tcp/22"); fko_spa_data_final(*ctx, ENC_KEY, 16, HMAC_KEY, 16); fko_set_spa_message_type(*ctx, FKO_ACCESS_MSG); fko_spa_data_final(*ctx, ENC_KEY, 16, HMAC_KEY, 16); fko_set_username(*ctx, "someuser"); fko_spa_data_final(*ctx, ENC_KEY, 16, HMAC_KEY, 16); fko_set_spa_encryption_type(*ctx, FKO_ENCRYPTION_RIJNDAEL); fko_spa_data_final(*ctx, ENC_KEY, 16, HMAC_KEY, 16); fko_set_spa_encryption_mode(*ctx, FKO_ENC_MODE_CBC); fko_spa_data_final(*ctx, ENC_KEY, 16, HMAC_KEY, 16); fko_set_spa_digest_type(*ctx, FKO_DEFAULT_DIGEST); fko_spa_data_final(*ctx, ENC_KEY, 16, HMAC_KEY, 16); fko_set_spa_hmac_type(*ctx, FKO_HMAC_SHA256); fko_spa_data_final(*ctx, ENC_KEY, 16, HMAC_KEY, 16); // display_ctx(*ctx); spa_calls += 16; return; }
/* JNI interface: constructs arguments and calls main function */ jstring Java_biz_incomsystems_fwknop2_SendSPA_sendSPAPacket(JNIEnv* env, jobject thiz) { fko_ctx_t ctx; fwknop_options_t opts; int res, hmac_str_len = 0; short message_type; short digest_type = FKO_DIGEST_SHA256; short hmac_type = FKO_HMAC_SHA256; int key_len, hmac_key_len; char res_msg[MSG_BUFSIZE+1] = {0}; char spa_msg[MSG_BUFSIZE+1] = {0}; char nat_msg[MSG_BUFSIZE+1] = {0}; jstring ourSpa; char *key_tmp[MAX_KEY_LEN+1] = {0}, *hmac_key_tmp[MAX_KEY_LEN+1] = {0}; LOGV("**** Init fwknop ****"); memset(&opts, 0, sizeof(fwknop_options_t)); /* Read the member values from the Java Object that called sendSPAPacket() method */ jclass c = (*env)->GetObjectClass(env,thiz); jfieldID fid = (*env)->GetFieldID(env, c, "access_str", "Ljava/lang/String;"); jstring jaccess = (*env)->GetObjectField(env, thiz, fid); const char *access_str = (*env)->GetStringUTFChars(env, jaccess, 0); fid = (*env)->GetFieldID(env, c, "allowip_str", "Ljava/lang/String;"); jstring jallowip = (*env)->GetObjectField(env, thiz, fid); const char *allowip_str = (*env)->GetStringUTFChars(env, jallowip, 0); fid = (*env)->GetFieldID(env, c, "passwd_str", "Ljava/lang/String;"); jstring jpasswd = (*env)->GetObjectField(env, thiz, fid); char *passwd_str = (*env)->GetStringUTFChars(env, jpasswd, 0); fid = (*env)->GetFieldID(env, c, "passwd_b64", "Ljava/lang/String;"); jstring jpasswd_b64 = (*env)->GetObjectField(env, thiz, fid); const char *passwd_b64 = (*env)->GetStringUTFChars(env, jpasswd_b64, 0); fid = (*env)->GetFieldID(env, c, "digest_type", "Ljava/lang/String;"); jstring jdigest_type = (*env)->GetObjectField(env, thiz, fid); char *set_digest_type = (*env)->GetStringUTFChars(env, jdigest_type, 0); fid = (*env)->GetFieldID(env, c, "hmac_str", "Ljava/lang/String;"); jstring jhmac = (*env)->GetObjectField(env, thiz, fid); char *hmac_str = (*env)->GetStringUTFChars(env, jhmac, 0); fid = (*env)->GetFieldID(env, c, "hmac_b64", "Ljava/lang/String;"); jstring jhmac_b64 = (*env)->GetObjectField(env, thiz, fid); const char *hmac_b64 = (*env)->GetStringUTFChars(env, jhmac_b64, 0); fid = (*env)->GetFieldID(env, c, "hmac_type", "Ljava/lang/String;"); jstring jhmac_type = (*env)->GetObjectField(env, thiz, fid); char *set_hmac_type = (*env)->GetStringUTFChars(env, jhmac_type, 0); fid = (*env)->GetFieldID(env, c, "fw_timeout_str", "Ljava/lang/String;"); jstring jfwtimeout = (*env)->GetObjectField(env, thiz, fid); const char *fw_timeout_str = (*env)->GetStringUTFChars(env, jfwtimeout, 0); fid = (*env)->GetFieldID(env, c, "nat_access_str", "Ljava/lang/String;"); jstring jnat_access_str = (*env)->GetObjectField(env, thiz, fid); const char *nat_access_str = (*env)->GetStringUTFChars(env, jnat_access_str, 0); fid = (*env)->GetFieldID(env, c, "nat_local", "Ljava/lang/String;"); jstring jnat_local = (*env)->GetObjectField(env, thiz, fid); const char *nat_local = (*env)->GetStringUTFChars(env, jnat_local, 0); fid = (*env)->GetFieldID(env, c, "server_cmd_str", "Ljava/lang/String;"); jstring jserver_cmd = (*env)->GetObjectField(env, thiz, fid); const char *server_cmd_str = (*env)->GetStringUTFChars(env, jserver_cmd, 0); fid = (*env)->GetFieldID(env, c, "legacy", "Ljava/lang/String;"); jstring jlegacy = (*env)->GetObjectField(env, thiz, fid); const char *legacy = (*env)->GetStringUTFChars(env, jlegacy, 0); /* Sanity checks */ if(access_str == NULL) { sprintf(res_msg, "Error: Invalid or missing access string"); goto cleanup2; } if(allowip_str == NULL) { sprintf(res_msg, "Error: Invalid or missing allow IP"); goto cleanup2; } if(passwd_str == NULL) { sprintf(res_msg, "Error: Invalid or missing password"); goto cleanup2; } if(fw_timeout_str == NULL) { sprintf(res_msg, "Error: Invalid or missing firewall timeout value"); goto cleanup2; } if(hmac_str != NULL) { hmac_str_len = (int)strlen(hmac_str); } key_len = (int)strlen(passwd_str); if(legacy == NULL) { sprintf(legacy, "false"); } if(strcmp(hmac_b64, "true") == 0) { hmac_str_len = fko_base64_decode( hmac_str, (unsigned char *)hmac_key_tmp); if(hmac_str_len > MAX_KEY_LEN || hmac_str_len < 0) { LOGV("[*] Invalid key length: '%d', must be in [1,%d]", hmac_str_len, MAX_KEY_LEN); goto cleanup2; } else { memcpy(hmac_str, hmac_key_tmp, hmac_str_len); } } if(strcmp(passwd_b64, "true") == 0) { LOGV("Detected key b64"); key_len = fko_base64_decode(passwd_str, (unsigned char *)key_tmp); if(key_len > MAX_KEY_LEN || key_len < 0) { LOGV( "[*] Invalid key length: '%d', must be in [1,%d]", key_len, MAX_KEY_LEN); goto cleanup2; } else { memcpy(passwd_str, key_tmp, key_len); } } /* Using an HMAC is optional in the pre-rfc mode. */ if (server_cmd_str[0] != 0x0) { message_type = FKO_COMMAND_MSG; } else { message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG; } /* Intialize the context */ res = fko_new(&ctx); if (res != FKO_SUCCESS) { strcpy(res_msg, fko_errmsg("Unable to create FKO context", res)); goto cleanup2; } /* Set server command */ if (server_cmd_str[0] != 0x0) { message_type = FKO_COMMAND_MSG; fko_set_spa_message_type(ctx, message_type); res = fko_set_spa_message(ctx, server_cmd_str); if (res != FKO_SUCCESS) { strcpy(res_msg, fko_errmsg("Error setting SPA request message", res)); goto cleanup; } } else { /* Set client timeout */ res = fko_set_spa_client_timeout(ctx, atoi(fw_timeout_str)); if (res != FKO_SUCCESS) { strcpy(res_msg, fko_errmsg("Error setting FW timeout", res)); goto cleanup; } /* Set the spa message string */ snprintf(spa_msg, MSG_BUFSIZE, "%s,%s", allowip_str, access_str); res = fko_set_spa_message(ctx, spa_msg); if (res != FKO_SUCCESS) { strcpy(res_msg, fko_errmsg("Error setting SPA request message", res)); goto cleanup; } } /* Set the HMAC mode if necessary */ if (strcmp(legacy, "true") == 0) { res = fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_CBC_LEGACY_IV); if (key_len > 16) { key_len = 16; } } if (hmac_str_len > 0) { if (strcmp(set_hmac_type, "MD5") == 0) { hmac_type = FKO_HMAC_MD5; } else if (strcmp(set_hmac_type, "SHA1") == 0) { hmac_type = FKO_HMAC_SHA1; } else if (strcmp(set_hmac_type, "SHA256") == 0) { hmac_type = FKO_HMAC_SHA256; } else if (strcmp(set_hmac_type, "SHA384") == 0) { hmac_type = FKO_HMAC_SHA384; } else if (strcmp(set_hmac_type, "SHA512") == 0) { hmac_type = FKO_HMAC_SHA512; } res = fko_set_spa_hmac_type(ctx, hmac_type); if (res != FKO_SUCCESS) { strcpy(res_msg, fko_errmsg("Error setting SPA HMAC type", res)); goto cleanup; } } /* Set Nat */ if (nat_access_str[0] != 0x0){ // if nat_access_str is not blank, push it into fko context if (strncmp(nat_local, "true", 4) == 0) { message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG; fko_set_spa_message_type(ctx, message_type); LOGV("Finished setting local-nat."); } res = fko_set_spa_nat_access(ctx, nat_access_str); if (res != FKO_SUCCESS) { strcpy(res_msg, fko_errmsg("Error setting NAT string", res)); goto cleanup; } } LOGV("Setting digest type to %s.", set_digest_type); if (strcmp(set_digest_type, "MD5") == 0) { digest_type = FKO_HMAC_MD5; } else if (strcmp(set_digest_type, "SHA1") == 0) { digest_type = FKO_HMAC_SHA1; } else if (strcmp(set_digest_type, "SHA256") == 0) { digest_type = FKO_HMAC_SHA256; } else if (strcmp(set_digest_type, "SHA384") == 0) { digest_type = FKO_HMAC_SHA384; } else if (strcmp(set_digest_type, "SHA512") == 0) { digest_type = FKO_HMAC_SHA512; } res = fko_set_spa_digest_type(ctx, digest_type); if (res != FKO_SUCCESS) { strcpy(res_msg, fko_errmsg("Error setting SPA digest type", res)); goto cleanup; } LOGV("Finished setting digest type."); /* Finalize the context data (Encrypt and encode). */ res = fko_spa_data_final(ctx, (char*)passwd_str, key_len, (char *)hmac_str, hmac_str_len); if (res != FKO_SUCCESS) { strcpy(res_msg, fko_errmsg("Error generating SPA data", res)); goto cleanup; } LOGV("Finished finalize."); res = fko_get_spa_data(ctx, &opts.spa_data); if (res != FKO_SUCCESS) { strcpy(res_msg, fko_errmsg("Error getting SPA data", res)); goto cleanup; } /* Generate the spa data packet */ ourSpa = (*env)->NewStringUTF(env, opts.spa_data); cleanup: /* Release the resources used by the fko context. */ fko_destroy(ctx); cleanup2: /* Release mem */ (*env)->ReleaseStringUTFChars(env, jaccess, access_str); (*env)->ReleaseStringUTFChars(env, jallowip, allowip_str); (*env)->ReleaseStringUTFChars(env, jpasswd, passwd_str); (*env)->ReleaseStringUTFChars(env, jpasswd_b64, passwd_b64); (*env)->ReleaseStringUTFChars(env, jdigest_type, set_digest_type); (*env)->ReleaseStringUTFChars(env, jhmac, hmac_str); (*env)->ReleaseStringUTFChars(env, jhmac_b64, hmac_b64); (*env)->ReleaseStringUTFChars(env, jhmac_type, set_hmac_type); (*env)->ReleaseStringUTFChars(env, jfwtimeout, fw_timeout_str); (*env)->ReleaseStringUTFChars(env, jnat_access_str, nat_access_str); (*env)->ReleaseStringUTFChars(env, jnat_local, nat_local); return ourSpa; }
static void test_loop_compounded(void) { fko_ctx_t ctx = NULL, decrypt_ctx = NULL; char *spa_data = NULL; int i, j, k, l, res; for (i=0; i<FCN_CALLS; i++) { fko_new(&ctx); res = fko_set_spa_client_timeout(ctx, i); if (res != FKO_SUCCESS) printf("fko_set_spa_client_timeout(): %s\n", fko_errstr(res)); for (j=-1; j<FKO_LAST_MSG_TYPE+1; j++) { res = fko_set_spa_message_type(ctx, j); if (res != FKO_SUCCESS) printf("fko_set_spa_message_type(): %s\n", fko_errstr(res)); res = fko_set_timestamp(ctx, 100); if (res != FKO_SUCCESS) printf("fko_set_timestamp(): %s\n", fko_errstr(res)); fko_set_spa_message(ctx, "1.1.1.1,tcp/22"); res = fko_set_spa_message(ctx, "123.123.123.123,tcp/22"); if (res != FKO_SUCCESS) printf("fko_set_spa_message(): %s\n", fko_errstr(res)); res = fko_set_spa_nat_access(ctx, "1.2.3.4,1234"); if (res != FKO_SUCCESS) printf("fko_set_spa_nat_access(): %s\n", fko_errstr(res)); res = fko_set_username(ctx, "someuser"); if (res != FKO_SUCCESS) printf("fko_set_username(): %s\n", fko_errstr(res)); res = fko_set_spa_server_auth(ctx, "passwd"); if (res != FKO_SUCCESS) printf("fko_set_spa_server_auth(): %s\n", fko_errstr(res)); res = fko_set_spa_hmac_type(ctx, FKO_HMAC_SHA256); if (res != FKO_SUCCESS) printf("fko_set_spa_hmac_type(): %s\n", fko_errstr(res)); for (k=-4; k<=16; k+=4) { for (l=-4; l<=16; l+=4) { res = fko_spa_data_final(ctx, ENC_KEY, k, HMAC_KEY, l); if (res == FKO_SUCCESS) { res = fko_get_spa_data(ctx, &spa_data); if (res == FKO_SUCCESS) { res = fko_new_with_data(&decrypt_ctx, spa_data, NULL, 0, FKO_ENC_MODE_CBC, HMAC_KEY, l, FKO_HMAC_SHA256); if (res == FKO_SUCCESS) { res = fko_decrypt_spa_data(decrypt_ctx, ENC_KEY, k); if (res != FKO_SUCCESS) printf("fko_decrypt_spa_data(): %s\n", fko_errstr(res)); fko_destroy(decrypt_ctx); decrypt_ctx = NULL; spa_calls += 13; spa_compounded_calls += 13; } else { printf("fko_new_with_data(): %s\n", fko_errstr(res)); } } else { printf("fko_get_spa_data(): %s\n", fko_errstr(res)); } } else { printf("fko_spa_data_final(): %s\n", fko_errstr(res)); } } } } fko_destroy(ctx); ctx = NULL; spa_calls += 3; spa_compounded_calls += 3; } }
/* Initialize an fko context. */ int fko_new(fko_ctx_t *r_ctx) { fko_ctx_t ctx; int res; char *ver; ctx = calloc(1, sizeof *ctx); if(ctx == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Set default values and state. * * Note: We have to explicitly set the ctx->state to initialized * just before making an fko_xxx function call, then set it * back to zero just afer. During initialization, we need * to make these functions think they are operating on an * initialized context, or else they would fail. */ /* Set the version string. */ ctx->initval = FKO_CTX_INITIALIZED; ver = strdup(FKO_PROTOCOL_VERSION); ctx->initval = 0; if(ver == NULL) { free(ctx); return(FKO_ERROR_MEMORY_ALLOCATION); } ctx->version = ver; /* Rand value. */ ctx->initval = FKO_CTX_INITIALIZED; res = fko_set_rand_value(ctx, NULL); ctx->initval = 0; if(res != FKO_SUCCESS) { fko_destroy(ctx); return res; } /* Username. */ ctx->initval = FKO_CTX_INITIALIZED; res = fko_set_username(ctx, NULL); ctx->initval = 0; if(res != FKO_SUCCESS) { fko_destroy(ctx); return res; } /* Timestamp. */ ctx->initval = FKO_CTX_INITIALIZED; res = fko_set_timestamp(ctx, 0); ctx->initval = 0; if(res != FKO_SUCCESS) { fko_destroy(ctx); return res; } /* Default Digest Type. */ ctx->initval = FKO_CTX_INITIALIZED; res = fko_set_spa_digest_type(ctx, FKO_DEFAULT_DIGEST); ctx->initval = 0; if(res != FKO_SUCCESS) { fko_destroy(ctx); return res; } /* Default Message Type. */ ctx->initval = FKO_CTX_INITIALIZED; res = fko_set_spa_message_type(ctx, FKO_DEFAULT_MSG_TYPE); ctx->initval = 0; if(res != FKO_SUCCESS) { fko_destroy(ctx); return res; } /* Default Encryption Type. */ ctx->initval = FKO_CTX_INITIALIZED; res = fko_set_spa_encryption_type(ctx, FKO_DEFAULT_ENCRYPTION); ctx->initval = 0; if(res != FKO_SUCCESS) { fko_destroy(ctx); return res; } #if HAVE_LIBGPGME /* Set gpg signature verify on. */ ctx->verify_gpg_sigs = 1; #endif /* HAVE_LIBGPGME */ /* Now we mean it. */ ctx->initval = FKO_CTX_INITIALIZED; FKO_SET_CTX_INITIALIZED(ctx); *r_ctx = ctx; return(FKO_SUCCESS); }
wxString Config::gen_SPA(wxString ip_resolver_url, wxString gpgEngine, wxString gpgHomeFolder, bool debug) { CURLcode curl_Res; fko_ctx_t ctx; fwknop_options_t opts; int key_len = 0; int res; int hmac_str_len = 0; short message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG; short digest_type = FKO_DIGEST_SHA256; short hmac_type = FKO_HMAC_SHA256; char key_str[129] = {0}, hmac_str[129] = {0}; char spa_msg[256] = {0}; // char spa_buf[4096] = {0}; // char * spa_buf_ptr; // char crypt_buf[4096] = {0}; char nat_access_str[25] = {0}; // char * hmac_buf; // char * spa_digest_ptr; memset(&opts, 0, sizeof(fwknop_options_t)); if (this->KEY.IsEmpty() && !this->USE_GPG_CRYPT) return _("Key cannot be blank!"); wxBusyInfo wait(_("Please wait, working...")); if (this->SERVER_PORT.CmpNoCase(wxT("random")) == 0) { srand((int)wxGetLocalTime()); this->SERVER_PORT.Empty(); this->SERVER_PORT << (rand()%55535 + 10000); // do this better, this isn't a horribly good random function } if (this->ACCESS_IP.CmpNoCase(wxT("Source IP")) == 0) this->ACCESS_IP = wxT("0.0.0.0"); else if (this->ACCESS_IP.CmpNoCase(wxT("Resolve IP")) == 0) { std::ostringstream oss; curl_Res = curl_read(std::string(ip_resolver_url.mb_str()), oss); if (curl_Res == CURLE_OK) { wxString result_tmp = wxString::FromUTF8(oss.str().c_str()); wxRegEx findIP( wxT("(([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])")); if (!findIP.Matches(result_tmp)) return _("Unable to resolve our IP!"); this->ACCESS_IP = findIP.GetMatch(result_tmp); } else return _("Libcurl returned the error: ") + wxString::FromUTF8(curl_easy_strerror(curl_Res)); } //end resolve ip if (fko_new(&ctx) != FKO_SUCCESS) return _("Could not get new FKO context"); if (USE_GPG_CRYPT) { fko_set_spa_encryption_type(ctx, FKO_ENCRYPTION_GPG); fko_set_gpg_exe(ctx, gpgEngine.mb_str()); fko_set_gpg_home_dir(ctx, gpgHomeFolder.mb_str()); fko_set_gpg_recipient(ctx, GPG_CRYPT_ID.mb_str()); if (GPG_SIG_ID.CmpNoCase(_("None")) != 0) fko_set_gpg_signer(ctx, GPG_SIG_ID.mb_str()); fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_ASYMMETRIC); } else { if (this->KEY_BASE64) { key_len = fko_base64_decode(this->KEY.mb_str(), (unsigned char *)key_str); } else { strncpy(key_str, (const char*)this->KEY.mb_str(wxConvUTF8), 128); key_len = (int)strlen(key_str); } } if (this->HMAC_BASE64) { hmac_str_len = fko_base64_decode(this->HMAC.mb_str(), (unsigned char *)hmac_str); } else { strncpy(hmac_str, (const char*)this->HMAC.mb_str(wxConvUTF8), 128); hmac_str_len = (int)strlen(hmac_str); } if (MESS_TYPE.CmpNoCase(wxT("Server Command")) == 0) { message_type = FKO_COMMAND_MSG; if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS) return _("Could not set message type"); snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->SERVER_CMD.mb_str(wxConvUTF8)); res = fko_set_spa_message(ctx, spa_msg); if (res != FKO_SUCCESS) return _("Could not set command message"); } else { if (fko_set_spa_client_timeout(ctx, wxAtoi(this->SERVER_TIMEOUT)) != FKO_SUCCESS) return _("Could not set SPA timeout"); snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->PORTS.mb_str(wxConvUTF8)); if (fko_set_spa_message(ctx, spa_msg) != FKO_SUCCESS) return _("Could not set SPA Message"); } if (this->LEGACY) { // technically should trim hmac keys if (fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_CBC_LEGACY_IV) != FKO_SUCCESS) return _("Could not set Legacy mode."); } if (!this->HMAC.IsEmpty()){ if (this->HMAC_TYPE.CmpNoCase(wxT("MD5"))==0) hmac_type = FKO_HMAC_MD5; else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA1"))==0) hmac_type = FKO_HMAC_SHA1; else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA256"))==0) hmac_type = FKO_HMAC_SHA256; else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA384"))==0) hmac_type = FKO_HMAC_SHA384; else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA512"))==0) hmac_type = FKO_HMAC_SHA512; if (fko_set_spa_hmac_type(ctx, hmac_type) != FKO_SUCCESS) return _("Could not set HMAC type."); } if (this->MESS_TYPE.CmpNoCase(wxT("Nat Access")) == 0) { sprintf(nat_access_str, "%s,%s", (const char*)this->NAT_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8)); if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS) return _("Could not set nat access string."); } else if (this->MESS_TYPE.CmpNoCase(wxT("Local Nat Access")) == 0) { message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG; if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS) return _("Chould not set message type"); sprintf(nat_access_str, "%s,%s", (const char*)this->SERVER_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8)); if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS) return _("Could not set nat access string."); } if (this->DIGEST_TYPE.CmpNoCase(wxT("MD5"))==0) digest_type = FKO_DIGEST_MD5; else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA1"))==0) digest_type = FKO_DIGEST_SHA1; else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA256"))==0) digest_type = FKO_DIGEST_SHA256; else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA384"))==0) digest_type = FKO_DIGEST_SHA384; else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA512"))==0) digest_type = FKO_DIGEST_SHA512; if (fko_set_spa_digest_type(ctx, digest_type) != FKO_SUCCESS) return _("Could not set SPA digest type."); if (fko_spa_data_final(ctx, key_str, key_len, hmac_str, hmac_str_len) != FKO_SUCCESS) return _("Could not generate SPA data."); if (fko_get_spa_data(ctx, &opts.spa_data) != FKO_SUCCESS) return _("Could not retrieve SPA data."); // if (!USE_GPG_CRYPT) { this->SPA_STRING = wxString::FromUTF8(opts.spa_data); /*} else { //could retain this for libfko without gpg support fko_get_encoded_data(ctx, &spa_buf_ptr); fko_get_spa_digest(ctx, &spa_digest_ptr); sprintf(spa_buf,"%s:%s", spa_buf_ptr, spa_digest_ptr); ourGPG->encryptAndSign(GPG_CRYPT_ID, GPG_SIG_ID, spa_buf, crypt_buf); fko_set_spa_data(ctx, crypt_buf); fko_set_spa_hmac(ctx, hmac_str, hmac_str_len); fko_get_spa_hmac(ctx, &hmac_buf); strcat(crypt_buf, hmac_buf); this->SPA_STRING = wxString::FromUTF8(crypt_buf + 2); }*/ if (debug) { wxTextEntryDialog *debugMessage = new wxTextEntryDialog(NULL, _("Debug info"), _("Debug info"), "Source IP: " + this->ACCESS_IP +"\n" + "SPA String: " + this->SPA_STRING, wxOK | wxTE_MULTILINE ); debugMessage->SetSize(620, 320); debugMessage->ShowModal(); debugMessage->Destroy(); } return _("Success"); }
/* Initialize an fko context. */ int fko_new(fko_ctx_t *r_ctx) { fko_ctx_t ctx = NULL; int res; char *ver; #if HAVE_LIBFIU fiu_return_on("fko_new_calloc", FKO_ERROR_MEMORY_ALLOCATION); #endif ctx = calloc(1, sizeof *ctx); if(ctx == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Set default values and state. * * Note: We initialize the context early so that the fko_set_xxx * functions can operate properly. If there are any problems during * initialization, then fko_destroy() is called which will clean up * the context. */ ctx->initval = FKO_CTX_INITIALIZED; /* Set the version string. */ ver = strdup(FKO_PROTOCOL_VERSION); if(ver == NULL) { fko_destroy(ctx); ctx = NULL; return(FKO_ERROR_MEMORY_ALLOCATION); } ctx->version = ver; /* Rand value. */ res = fko_set_rand_value(ctx, NULL); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Username. */ res = fko_set_username(ctx, NULL); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Timestamp. */ res = fko_set_timestamp(ctx, 0); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Default Digest Type. */ res = fko_set_spa_digest_type(ctx, FKO_DEFAULT_DIGEST); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Default Message Type. */ res = fko_set_spa_message_type(ctx, FKO_DEFAULT_MSG_TYPE); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Default Encryption Type. */ res = fko_set_spa_encryption_type(ctx, FKO_DEFAULT_ENCRYPTION); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Default is Rijndael in CBC mode */ res = fko_set_spa_encryption_mode(ctx, FKO_DEFAULT_ENC_MODE); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } #if HAVE_LIBGPGME /* Set gpg signature verify on. */ ctx->verify_gpg_sigs = 1; #endif /* HAVE_LIBGPGME */ FKO_SET_CTX_INITIALIZED(ctx); *r_ctx = ctx; return(FKO_SUCCESS); }
wxString Config::gen_SPA(wxString ip_resolver_url) { CURLcode curl_Res; fko_ctx_t ctx; fwknop_options_t opts; int key_len, res; int hmac_str_len = 0; short message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG; short digest_type = FKO_DIGEST_SHA256; short hmac_type = FKO_HMAC_SHA256; char key_str[129] = {0}, hmac_str[129] = {0}; char spa_msg[256] = {0}; char debug_buf[4096] = {0}; char nat_access_str[25] = {0}; memset(&opts, 0, sizeof(fwknop_options_t)); if (this->KEY.IsEmpty()) return _("Key cannot be blank!"); wxBusyInfo wait(_("Please wait, working...")); if (this->SERVER_PORT.CmpNoCase(wxT("random")) == 0) { srand((int)wxGetLocalTime()); this->SERVER_PORT.Empty(); this->SERVER_PORT << (rand()%55535 + 10000); // do this better, this isn't a horribly good random function } if (this->ACCESS_IP.CmpNoCase(wxT("Source IP")) == 0) this->ACCESS_IP = wxT("0.0.0.0"); else if (this->ACCESS_IP.CmpNoCase(wxT("Resolve IP")) == 0) { std::ostringstream oss; curl_Res = curl_read(std::string(ip_resolver_url.mb_str()), oss); //Eventually make this a user definable service. if (curl_Res == CURLE_OK) { wxString result_tmp = wxString::FromUTF8(oss.str().c_str()); wxRegEx findIP( wxT("(([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])")); if (!findIP.Matches(result_tmp)) return _("Unable to resolve our IP!"); this->ACCESS_IP = findIP.GetMatch(result_tmp); } else return _("Libcurl returned the error: ") + wxString::FromUTF8(curl_easy_strerror(curl_Res)); } //end resolve ip if (this->KEY_BASE64) { key_len = fko_base64_decode(this->KEY.mb_str(), (unsigned char *)key_str); } else { strncpy(key_str, (const char*)this->KEY.mb_str(wxConvUTF8), 128); key_len = (int)strlen(key_str); } if (this->HMAC_BASE64) { hmac_str_len = fko_base64_decode(this->HMAC.mb_str(), (unsigned char *)hmac_str); } else { strncpy(hmac_str, (const char*)this->HMAC.mb_str(wxConvUTF8), 128); hmac_str_len = (int)strlen(hmac_str); } if (fko_new(&ctx) != FKO_SUCCESS) return _("Could not get new FKO context"); if (MESS_TYPE.CmpNoCase(wxT("Server Command")) == 0) { message_type = FKO_COMMAND_MSG; if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS) return _("Could not set message type"); snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->SERVER_CMD.mb_str(wxConvUTF8)); res = fko_set_spa_message(ctx, spa_msg); if (res != FKO_SUCCESS) return _("Could not set command message"); } else { if (fko_set_spa_client_timeout(ctx, wxAtoi(this->SERVER_TIMEOUT)) != FKO_SUCCESS) return _("Could not set SPA timeout"); snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->PORTS.mb_str(wxConvUTF8)); if (fko_set_spa_message(ctx, spa_msg) != FKO_SUCCESS) return _("Could not set SPA Message"); } if (this->LEGACY) { // technically should trim hmac keys if (fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_CBC_LEGACY_IV) != FKO_SUCCESS) return _("Could not set Legacy mode."); } if (!this->HMAC.IsEmpty()){ if (this->HMAC_TYPE.CmpNoCase(wxT("MD5"))==0) hmac_type = FKO_HMAC_MD5; else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA1"))==0) hmac_type = FKO_HMAC_SHA1; else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA256"))==0) hmac_type = FKO_HMAC_SHA256; else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA384"))==0) hmac_type = FKO_HMAC_SHA384; else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA512"))==0) hmac_type = FKO_HMAC_SHA512; if (fko_set_spa_hmac_type(ctx, hmac_type) != FKO_SUCCESS) return _("Could not set HMAC type."); } if (this->MESS_TYPE.CmpNoCase(wxT("Nat Access")) == 0) { sprintf(nat_access_str, "%s,%s", (const char*)this->NAT_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8)); if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS) return _("Could not set nat access string."); } else if (this->MESS_TYPE.CmpNoCase(wxT("Local Nat Access")) == 0) { message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG; if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS) return _("Chould not set message type"); sprintf(nat_access_str, "%s,%s", (const char*)this->SERVER_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8)); if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS) return _("Could not set nat access string."); } if (this->DIGEST_TYPE.CmpNoCase(wxT("MD5"))==0) digest_type = FKO_DIGEST_MD5; else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA1"))==0) digest_type = FKO_DIGEST_SHA1; else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA256"))==0) digest_type = FKO_DIGEST_SHA256; else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA384"))==0) digest_type = FKO_DIGEST_SHA384; else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA512"))==0) digest_type = FKO_DIGEST_SHA512; if (fko_set_spa_digest_type(ctx, digest_type) != FKO_SUCCESS) return _("Could not set SPA digest type."); if (fko_spa_data_final(ctx, key_str, key_len, hmac_str, hmac_str_len) != FKO_SUCCESS) return _("Could not generate SPA data."); if (fko_get_spa_data(ctx, &opts.spa_data) != FKO_SUCCESS) return _("Could not retrieve SPA data."); //dump_ctx_to_buffer(ctx, debug_buf, sizeof(debug_buf)); this->SPA_STRING = wxString::FromUTF8(opts.spa_data); return _("Success"); }