static void spa_func_getset_short(fko_ctx_t *ctx, char *set_name, int (*spa_set)(fko_ctx_t ctx, const short modifier), char *get_name, int (*spa_get)(fko_ctx_t ctx, short *val), int min, int max, int final_val, int digest_flag, int new_ctx_flag, int destroy_ctx_flag) { fko_ctx_t default_ctx = NULL; short get_val; int i, res; spa_default_ctx(&default_ctx); printf("[+] calling libfko get/set: %s/%s\n", get_name, set_name); for (i=min; i <= max; i++) { get_val = 1234; /* meaningless default */ printf("%s(%d): %s\n", set_name, i, fko_errstr((spa_set)(*ctx, i))); printf("%s(%d): %s (DUPE)\n", set_name, i, fko_errstr((spa_set)(*ctx, i))); if (digest_flag == DO_DIGEST) fko_set_spa_digest(*ctx); else if (digest_flag == RAW_DIGEST) fko_set_raw_spa_digest(*ctx); res = (spa_get)(*ctx, &get_val); printf("%s(%d): %s\n", get_name, get_val, fko_errstr(res)); ctx_update(ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT); if (digest_flag == NO_DIGEST) spa_calls += 3; else spa_calls += 4; /* also set on a fully populated context */ (spa_set)(default_ctx, i); } printf("%s(%d): %s (FINAL)\n", set_name, final_val, fko_errstr((spa_set)(*ctx, final_val))); display_ctx(*ctx); fko_spa_data_final(default_ctx, ENC_KEY, 16, HMAC_KEY, 16); fko_destroy(default_ctx); default_ctx = NULL; return; }
/* set_spa_digest */ static PyObject * set_spa_digest(PyObject *self, PyObject *args) { fko_ctx_t ctx; int res; if(!PyArg_ParseTuple(args, "k", &ctx)) return NULL; res = fko_set_spa_digest(ctx); if(res != FKO_SUCCESS) { PyErr_SetString(FKOError, fko_errstr(res)); return NULL; } return Py_BuildValue("", NULL); }
/* Set the SPA encryption type. */ int fko_encode_spa_data(fko_ctx_t ctx) { int res, offset = 0; char *tbuf; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* Check prerequisites. * --DSS XXX: Needs review. Also, we could make this more robust (or * (at leaset expand the error reporting for the missing * data). */ if( validate_username(ctx->username) != FKO_SUCCESS || ctx->version == NULL || strnlen(ctx->version, MAX_SPA_VERSION_SIZE) == 0 || ctx->message == NULL || strnlen(ctx->message, MAX_SPA_MESSAGE_SIZE) == 0) { return(FKO_ERROR_INCOMPLETE_SPA_DATA); } if(ctx->message_type == FKO_NAT_ACCESS_MSG) { if(ctx->nat_access == NULL || strnlen(ctx->nat_access, MAX_SPA_MESSAGE_SIZE) == 0) return(FKO_ERROR_INCOMPLETE_SPA_DATA); } /* Allocate our initial tmp buffer. */ tbuf = calloc(1, FKO_ENCODE_TMP_BUF_SIZE); if(tbuf == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Put it together a piece at a time, starting with the rand val. */ strlcpy(tbuf, ctx->rand_val, FKO_ENCODE_TMP_BUF_SIZE); /* Add the base64-encoded username. */ strlcat(tbuf, ":", FKO_ENCODE_TMP_BUF_SIZE); if((res = append_b64(tbuf, ctx->username)) != FKO_SUCCESS) { free(tbuf); return(res); } /* Add the timestamp. */ offset = strlen(tbuf); sprintf(((char*)tbuf+offset), ":%u:", (unsigned int) ctx->timestamp); /* Add the version string. */ strlcat(tbuf, ctx->version, FKO_ENCODE_TMP_BUF_SIZE); /* Before we add the message type value, we will once again * check for whether or not a client_timeout was specified * since the message_type was set. If this is the case, then * we want to adjust the message_type first. The easy way * to do this is simply call fko_set_spa_client_timeout and set * it to its current value. This will force a re-check and * possible reset of the message type. * */ fko_set_spa_client_timeout(ctx, ctx->client_timeout); /* Add the message type value. */ offset = strlen(tbuf); sprintf(((char*)tbuf+offset), ":%i:", ctx->message_type); /* Add the base64-encoded SPA message. */ if((res = append_b64(tbuf, ctx->message)) != FKO_SUCCESS) { free(tbuf); return(res); } /* If a nat_access message was given, add it to the SPA * message. */ if(ctx->nat_access != NULL) { strlcat(tbuf, ":", FKO_ENCODE_TMP_BUF_SIZE); if((res = append_b64(tbuf, ctx->nat_access)) != FKO_SUCCESS) { free(tbuf); return(res); } } /* If we have a server_auth field set. Add it here. * */ if(ctx->server_auth != NULL) { strlcat(tbuf, ":", FKO_ENCODE_TMP_BUF_SIZE); if((res = append_b64(tbuf, ctx->server_auth)) != FKO_SUCCESS) { free(tbuf); return(res); } } /* If a client timeout is specified and we are not dealing with a * SPA command message, add the timeout here. */ if(ctx->client_timeout > 0 && ctx->message_type != FKO_COMMAND_MSG) { offset = strlen(tbuf); sprintf(((char*)tbuf+offset), ":%i", ctx->client_timeout); } /* If encoded_msg is not null, then we assume it needs to * be freed before re-assignment. */ if(ctx->encoded_msg != NULL) free(ctx->encoded_msg); /* Copy our encoded data into the context. */ ctx->encoded_msg = strdup(tbuf); if(ctx->encoded_msg == NULL) { free(tbuf); return(FKO_ERROR_MEMORY_ALLOCATION); } /* At this point we can compute the digest for this SPA data. */ if((res = fko_set_spa_digest(ctx)) != FKO_SUCCESS) { free(tbuf); return(res); } /* Here we can clear the modified flags on the SPA data fields. */ FKO_CLEAR_SPA_DATA_MODIFIED(ctx); free(tbuf); return(FKO_SUCCESS); }