diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:57:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:57:58 +0000 |
commit | be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97 (patch) | |
tree | 9754ff1ca740f6346cf8483ec915d4054bc5da2d /fluent-bit/src/flb_crypto.c | |
parent | Initial commit. (diff) | |
download | netdata-be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97.tar.xz netdata-be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97.zip |
Adding upstream version 1.44.3.upstream/1.44.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'fluent-bit/src/flb_crypto.c')
-rw-r--r-- | fluent-bit/src/flb_crypto.c | 405 |
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 00000000..c2811039 --- /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; +} + + + |