summaryrefslogtreecommitdiffstats
path: root/fluent-bit/src/flb_crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/src/flb_crypto.c')
-rw-r--r--fluent-bit/src/flb_crypto.c405
1 files changed, 405 insertions, 0 deletions
diff --git a/fluent-bit/src/flb_crypto.c b/fluent-bit/src/flb_crypto.c
new file mode 100644
index 000000000..c2811039a
--- /dev/null
+++ b/fluent-bit/src/flb_crypto.c
@@ -0,0 +1,405 @@
+/* Fluent Bit
+ * ==========
+ * Copyright (C) 2019-2020 The Fluent Bit Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fluent-bit/flb_crypto.h>
+#include <openssl/bio.h>
+#include <string.h>
+
+static int flb_crypto_get_rsa_padding_type_by_id(int padding_type_id)
+{
+ int result;
+
+ if (padding_type_id == FLB_CRYPTO_PADDING_PKCS1) {
+ result = RSA_PKCS1_PADDING;
+ }
+ else if (padding_type_id == FLB_CRYPTO_PADDING_PKCS1_OEAP) {
+ result = RSA_PKCS1_OAEP_PADDING;
+ }
+ else if (padding_type_id == FLB_CRYPTO_PADDING_PKCS1_X931) {
+ result = RSA_X931_PADDING;
+ }
+ else if (padding_type_id == FLB_CRYPTO_PADDING_PKCS1_PSS) {
+ result = RSA_PKCS1_PSS_PADDING;
+ }
+ else {
+ result = FLB_CRYPTO_PADDING_NONE;
+ }
+
+ return result;
+}
+
+static const EVP_MD *flb_crypto_get_digest_algorithm_instance_by_id(int algorithm_id)
+{
+ const EVP_MD *algorithm;
+
+ if (algorithm_id == FLB_HASH_SHA256) {
+ algorithm = EVP_sha256();
+ }
+ else if (algorithm_id == FLB_HASH_SHA512) {
+ algorithm = EVP_sha512();
+ }
+ else if (algorithm_id == FLB_HASH_MD5) {
+ algorithm = EVP_md5();
+ }
+ else {
+ algorithm = NULL;
+ }
+
+ return algorithm;
+}
+
+static int flb_crypto_import_pem_key(int key_type,
+ unsigned char *key,
+ size_t key_length,
+ EVP_PKEY **ingested_key)
+{
+ BIO *io_provider;
+ int result;
+
+ if (key_type != FLB_CRYPTO_PUBLIC_KEY &&
+ key_type != FLB_CRYPTO_PRIVATE_KEY) {
+ return FLB_CRYPTO_INVALID_ARGUMENT;
+ }
+
+ if (ingested_key == NULL) {
+ return FLB_CRYPTO_INVALID_ARGUMENT;
+ }
+
+ result = FLB_CRYPTO_BACKEND_ERROR;
+
+ io_provider = BIO_new_mem_buf((void*) key, key_length);
+
+ if (io_provider != NULL) {
+ if (ingested_key != NULL) {
+ if (key_type == FLB_CRYPTO_PRIVATE_KEY) {
+ *ingested_key = PEM_read_bio_PrivateKey(io_provider,
+ NULL, NULL,
+ NULL);
+ }
+ else if (key_type == FLB_CRYPTO_PUBLIC_KEY) {
+ *ingested_key = PEM_read_bio_PUBKEY(io_provider,
+ NULL, NULL,
+ NULL);
+
+ // printf("\n\nFAILURE? %p\n\n", *ingested_key);
+ // printf("ERROR : %s\n", ERR_error_string(ERR_get_error(), NULL));
+ // exit(0);
+ }
+
+ if (*ingested_key != NULL) {
+ result = FLB_CRYPTO_SUCCESS;
+ }
+ }
+
+ BIO_free_all(io_provider);
+ }
+
+ return result;
+}
+
+int flb_crypto_init(struct flb_crypto *context,
+ int padding_type,
+ int digest_algorithm,
+ int key_type,
+ unsigned char *key,
+ size_t key_length)
+{
+ int result;
+
+ if (context == NULL) {
+ return FLB_CRYPTO_INVALID_ARGUMENT;
+ }
+
+ if (key == NULL) {
+ return FLB_CRYPTO_INVALID_ARGUMENT;
+ }
+
+ if (key_length == 0) {
+ return FLB_CRYPTO_INVALID_ARGUMENT;
+ }
+
+ memset(context, 0, sizeof(struct flb_crypto));
+
+ result = flb_crypto_import_pem_key(key_type,
+ key,
+ key_length,
+ &context->key);
+
+ if (result != FLB_CRYPTO_SUCCESS) {
+ if (result == FLB_CRYPTO_BACKEND_ERROR) {
+ context->last_error = ERR_get_error();
+ }
+
+ flb_crypto_cleanup(context);
+
+ return result;
+ }
+
+ context->backend_context = EVP_PKEY_CTX_new(context->key, NULL);
+
+ if (context->backend_context == NULL) {
+ context->last_error = ERR_get_error();
+
+ flb_crypto_cleanup(context);
+
+ return result;
+ }
+
+ context->block_size = (size_t) EVP_PKEY_size(context->key);
+
+ context->padding_type = flb_crypto_get_rsa_padding_type_by_id(padding_type);
+
+ context->digest_algorithm = flb_crypto_get_digest_algorithm_instance_by_id(digest_algorithm);
+
+ return FLB_CRYPTO_SUCCESS;
+}
+
+
+int flb_crypto_cleanup(struct flb_crypto *context)
+{
+ if (context->backend_context != NULL) {
+ EVP_PKEY_free(context->key);
+
+ context->key = NULL;
+ }
+
+ if (context->backend_context != NULL) {
+ EVP_PKEY_CTX_free(context->backend_context);
+
+ context->backend_context = NULL;
+ }
+
+ return FLB_CRYPTO_SUCCESS;
+}
+
+int flb_crypto_transform(struct flb_crypto *context,
+ int operation,
+ unsigned char *input_buffer,
+ size_t input_length,
+ unsigned char *output_buffer,
+ size_t *output_length)
+{
+ int result = FLB_CRYPTO_BACKEND_ERROR;
+
+ if (context == NULL) {
+ return FLB_CRYPTO_INVALID_ARGUMENT;
+ }
+
+ if (operation != FLB_CRYPTO_OPERATION_SIGN &&
+ operation != FLB_CRYPTO_OPERATION_ENCRYPT &&
+ operation != FLB_CRYPTO_OPERATION_DECRYPT) {
+ return FLB_CRYPTO_INVALID_ARGUMENT;
+ }
+
+ if (context->last_operation == FLB_CRYPTO_OPERATION_NONE) {
+ if (operation == FLB_CRYPTO_OPERATION_SIGN) {
+ result = EVP_PKEY_sign_init(context->backend_context);
+ }
+ else if (operation == FLB_CRYPTO_OPERATION_ENCRYPT) {
+ result = EVP_PKEY_encrypt_init(context->backend_context);
+ }
+ else if (operation == FLB_CRYPTO_OPERATION_DECRYPT) {
+ result = EVP_PKEY_decrypt_init(context->backend_context);
+ }
+
+ if (result == 1) {
+ result = EVP_PKEY_CTX_set_rsa_padding(context->backend_context,
+ context->padding_type);
+
+ if (result > 0) {
+ if (context->digest_algorithm != NULL) {
+ result = EVP_PKEY_CTX_set_signature_md(context->backend_context,
+ context->digest_algorithm);
+ }
+ }
+
+ if (result > 0) {
+ result = 1;
+ }
+ }
+
+ if (result != 1) {
+ context->last_error = ERR_get_error();
+
+ return FLB_CRYPTO_BACKEND_ERROR;
+ }
+
+ context->last_operation = operation;
+ }
+ else if (context->last_operation != operation) {
+ return FLB_CRYPTO_INVALID_STATE;
+ }
+
+ if (operation == FLB_CRYPTO_OPERATION_SIGN) {
+ result = EVP_PKEY_sign(context->backend_context,
+ output_buffer, output_length,
+ input_buffer, input_length);
+ }
+ else if(operation == FLB_CRYPTO_OPERATION_ENCRYPT) {
+ result = EVP_PKEY_encrypt(context->backend_context,
+ output_buffer, output_length,
+ input_buffer, input_length);
+ }
+ else if(operation == FLB_CRYPTO_OPERATION_DECRYPT) {
+ result = EVP_PKEY_decrypt(context->backend_context,
+ output_buffer, output_length,
+ input_buffer, input_length);
+ }
+
+ if (result != 1) {
+ context->last_error = ERR_get_error();
+
+ return FLB_CRYPTO_BACKEND_ERROR;
+ }
+
+ return FLB_CRYPTO_SUCCESS;
+}
+
+int flb_crypto_sign(struct flb_crypto *context,
+ unsigned char *input_buffer,
+ size_t input_length,
+ unsigned char *output_buffer,
+ size_t *output_length)
+{
+ return flb_crypto_transform(context,
+ FLB_CRYPTO_OPERATION_SIGN,
+ input_buffer,
+ input_length,
+ output_buffer,
+ output_length);
+}
+
+int flb_crypto_encrypt(struct flb_crypto *context,
+ unsigned char *input_buffer,
+ size_t input_length,
+ unsigned char *output_buffer,
+ size_t *output_length)
+{
+ return flb_crypto_transform(context,
+ FLB_CRYPTO_OPERATION_ENCRYPT,
+ input_buffer,
+ input_length,
+ output_buffer,
+ output_length);
+}
+
+int flb_crypto_decrypt(struct flb_crypto *context,
+ unsigned char *input_buffer,
+ size_t input_length,
+ unsigned char *output_buffer,
+ size_t *output_length)
+{
+ return flb_crypto_transform(context,
+ FLB_CRYPTO_OPERATION_DECRYPT,
+ input_buffer,
+ input_length,
+ output_buffer,
+ output_length);
+}
+
+int flb_crypto_sign_simple(int key_type,
+ int padding_type,
+ int digest_algorithm,
+ unsigned char *key,
+ size_t key_length,
+ unsigned char *input_buffer,
+ size_t input_length,
+ unsigned char *output_buffer,
+ size_t *output_length)
+{
+ struct flb_crypto context;
+ int result;
+
+ result = flb_crypto_init(&context,
+ padding_type,
+ digest_algorithm,
+ key_type,
+ key,
+ key_length);
+
+ if (result == FLB_CRYPTO_SUCCESS) {
+ result = flb_crypto_sign(&context,
+ input_buffer, input_length,
+ output_buffer, output_length);
+
+ flb_crypto_cleanup(&context);
+ }
+
+ return result;
+}
+
+int flb_crypto_encrypt_simple(int padding_type,
+ unsigned char *key,
+ size_t key_length,
+ unsigned char *input_buffer,
+ size_t input_length,
+ unsigned char *output_buffer,
+ size_t *output_length)
+{
+ struct flb_crypto context;
+ int result;
+
+ result = flb_crypto_init(&context,
+ padding_type,
+ FLB_HASH_NONE,
+ FLB_CRYPTO_PUBLIC_KEY,
+ key,
+ key_length);
+
+ if (result == FLB_CRYPTO_SUCCESS) {
+ result = flb_crypto_encrypt(&context,
+ input_buffer, input_length,
+ output_buffer, output_length);
+
+
+ flb_crypto_cleanup(&context);
+ }
+
+ return result;
+}
+
+int flb_crypto_decrypt_simple(int padding_type,
+ unsigned char *key,
+ size_t key_length,
+ unsigned char *input_buffer,
+ size_t input_length,
+ unsigned char *output_buffer,
+ size_t *output_length)
+{
+ struct flb_crypto context;
+ int result;
+
+ result = flb_crypto_init(&context,
+ padding_type,
+ FLB_HASH_NONE,
+ FLB_CRYPTO_PRIVATE_KEY,
+ key,
+ key_length);
+
+ if (result == FLB_CRYPTO_SUCCESS) {
+ result = flb_crypto_decrypt(&context,
+ input_buffer, input_length,
+ output_buffer, output_length);
+
+ flb_crypto_cleanup(&context);
+ }
+
+ return result;
+}
+
+
+