476

(7 replies, posted in wolfSSL)

Hi Andrey,

I think this goes back to the other question for "Minimum ECC Build". Since currently ecc enables all of the public key functionality, which in turn requires asn.c for certificate processing... That is why the build is not working. I have let Rod Weaver know of your situation and he should be in touch soon to discuss the option of adding this as a feature to our library. IE compiling with ECC enabled and public key functionality disables to allow for generating a shared secret with ECDHE_PSK only cipher suites.

Warm Regards,

Kaleb

477

(5 replies, posted in wolfSSL)

Hi Ornelas,

What is your build environment like? Are you working with an IDE or cross-compiling for the STM32F4?

Regards,

Kaleb

478

(2 replies, posted in wolfSSL)

Hi Guit,

You said you are trying to run this command on your server. The error that is occurring is a socket bind error. This means there is another service already using the port you are attempting to assign to your client OR those ports are disabled for security purposes.

Could you start up wireshark and execute the client as done above and check which port is being selected as the "Source Port" on the client side?

See screen shot for example:

Warm Regards,

Kaleb

479

(1 replies, posted in wolfSSL)

Hi cxdinter,

This has never been the case for default behavior. You can easily test this yourself by doing the following:


# test wolfSSL v3.12.0
git clone https://github.com/wolfssl/wolfssl.git
cd wolfssl
./autogen.sh && ./configure && make && ./examples/client/client -h www.google.com -p 443 -g

RESULT: err = -188, ASN no signer error to confirm failure
RESULT: wolfSSL error: wolfSSL_connect failed

#
# test wolfSSL v3.9.10
git checkout v3.9.10-stable
./autogen.sh && ./configure && make && ./examples/client/client -h www.google.com -p 443 -g

RESULT: err = -188, ASN no signer error to confirm failure
RESULT: wolfSSL error: wolfSSL_connect failed

#
# test wolfSSL v3.11.0
git checkout v3.11.0-stable
./autogen.sh && ./configure && make && ./examples/client/client -h www.google.com -p 443 -g

RESULT: err = -188, ASN no signer error to confirm failure
RESULT: wolfSSL error: wolfSSL_connect failed


Is it possible that instead you had introduced a modification to v3.9.10, perhaps a callback override of some sort that would ignore certain errors?

We are aware there was a bug in v3.11.0 where the callback override would NOT ignore errors as intended. This bug was fixed in release 3.12.0. Would you mind running your test with v3.12.0 and see if you encounter the same issue?

Warm Regards,

Kaleb

480

(6 replies, posted in wolfSSL)

Hi andrey,

Can you tell me who you are with and where in the world you are so I can put the correct resource in touch with you to assist with this evaluation?

If you do not wish to share on the public forum feel free to contact me directly kaleb@wolfssl.com


Warm Regards,

Kaleb

481

(6 replies, posted in wolfSSL)

Hi andrey,

So, if I understood correctly, at this moment if defining HAVE_ECC the sign/verify/key_import/key_export options cannot be excluded from the build and these four defines are not allowed to be used?

At this time that is correct, it is currently not a supported configuration. HOWEVER we do understand the build you are after and it makes sense.

It should be possible and would likely only take us anywhere from a few hours to a day of engineering work to make the changes then document and test the changes.


Warm Regards,

Kaleb

482

(7 replies, posted in wolfSSL)

Hi andrey,

I just discussed your question with the team and one of my peers pointed out that if you do have access to a hardware RNG then you could disable SHA256 and the HASH_DRBG in favor of your hardware based RNG. To do that you could use this configuration:

#NOTE: <customfunc> would need to be replaced by the API you implement to call your hardware RNG.
./configure CFLAGS="-DCUSTOM_RAND_GENERATE_BLOCK=<customfunc> -DNO_SHA256" --disable-hashdrbg

Let me know if you have any questions on that.


Warm Regards,

Kaleb

483

(7 replies, posted in wolfSSL)

Hi andrey,

SHA256 and HMAC are required in the HASH_DRBG used by wolfSSL to generate RANDOM data. If you are using any portion of the library that requires random data then SHA256 is a dependancy. In this case you are using TLS which requires a random data string in the CLIENT HELLO message so it is not supported to disable SHA256 with TLS enabled (not unique to ASN).


Warm Regards,

Kaleb

484

(6 replies, posted in wolfSSL)

Hi andrey.ribalko,

Currently that configuration is not supported with TLS. The only configuration we currently allow that exposes generating the shared secret but does not include sign/verify/key import/key export would also have to include the setting "WOLFCRYPT_ONLY" which disables SSL/TLS functionality.

Could you tell us a little about the project you are working on and your memory constraints? What do you have available and what is your ideal build size, what is the current build size with all of that additional functionality enabled?

So you are aware wolfSSL does offer traditional engineering consulting services if you would like to explore the option of adding a "PSK with perfect forward secrecy and no ECC Public Key Support" build option. That is something we can definitely do!


Warm Regards,

Kaleb Himes

485

(1 replies, posted in wolfSSL)

Hi annettets,

Could you tell us which version of wolfSSL are you working with?

Could you send me the configuration you are using and also let me know if you are using the API:

wolfSSL_CTX_set_cipher_list

?

Would it also be possible for you to enable debugging and make sure you call the API

wolfSSL_Debugging_ON

Could you send me the output of the debug connection attempt?

Finally one other useful bit of information for us would be a wireshark trace of the connection if possible.


Warm Regards,

Kaleb

486

(2 replies, posted in wolfSSL)

Hi muyouyuwan,

Could you tell us which version of wolfSSL you are working with so we have a better reference on the line numbers you provided?

I new a ctx by calling wolfSSL_CTX_new, then I new two ssl object ssl1 and ssl2 based on the same ctx.
If I free ssl1 by calling wolfSSL_free(ssl1), is the ctx is also freed? Does it influence ssl2?

Q1: Calling free on SSL1 will NOT free the CTX.
Q2: Calling free on SSL1 will NOT influence ssl2.

Both scenarios you asked about are OK to do.


Warm Regards,

Kaleb

487

(2 replies, posted in wolfCrypt)

Hi cxdinter,

It has been awhile since we heard from you! December of 2016 I believe, how are things?

Anyway, I can see where the confusion might come in given the lack of "commentary" in that function. Since the output buffer being passed in is a pass by reference (pointer) we also need a way of controlling memory access beyond the call to this function. We accomplish that by setting outSz to the result length of the CMAC operation.

Typically we would expect a user to call

wc_AesCmacGenerate(out, outSz, in, inSz, key, keySz);

Now imagine the user did the following:

byte buf[4096] = {... some data ...};
int bufSz = sizeof(buf);
byte out[4096] = {0};
int outSz = sizeof(out);
byte key[KEY_LEN] = { .... some key ... };
int keySz = sizeof(key);
int ret;

ret = wc_AesCmacGenerate(out, outSz, in, inSz, key, keySz);
if (ret == 0)
    do something interesting with "out" based on outSz **ALERT**

If we did not adjust outSz to the fixed length of the resulting CmacFinal operation then the user would be accessing bad data, sure they would get their CMAC tag at the beginning of the buffer but they would be accessing 4096 - AES_BLOCK_SIZE data that they didn't need here. That is why we set it explicitly on exiting the function successfully.

    if (outSz != NULL)                                                           
         *outSz = AES_BLOCK_SIZE;

Also this sanity check protects against the case where the buffer being used is too small to store the result of the operation:

if (outSz != NULL && *outSz < AES_BLOCK_SIZE)
    return BUFFER_E;

Does that make sense? Let me know if you have any other questions on this.


Warm Regards,

Kaleb

488

(3 replies, posted in wolfSSL)

Hi muyouyuwan,

No problem, glad to hear you were able to get out the expected digest(s)!

Let us know if anything else comes up, we are always happy to help in any way we can!


Sincere Regards,

Kaleb

489

(6 replies, posted in wolfSSL)

Hi gussabina,

You can call that API many times. Each call will append a new cert for verification. Then when connecting to an entity that sends a certificate wolfSSL will iterate over ALL the certs that have been loaded in "verify locations". If it finds one that can validate the entity then everything continues as expected. If the entity can not be validate with any of the loaded verify certs then -188 ASN NO SIGNER error will be returned as you see in your case.

Obviously the cert currently being loaded is not capable of verifying the cert sent by the server. Please double check the domain you are connecting to and the certificate that signed that domains cert. Load that CA ALSO or ONLY. The one currently being loaded is NOT able to validate the domain in question.


Warm Regards,

Kaleb

490

(1 replies, posted in wolfSSL)

Hi huba,

There is nothing wrong with that certificate and with a default configuration wolfSSL can parse it just fine.

Please see the attached cert to be included in the test program and I am including the test app inline here:

#include <stdio.h>
#include <wolfssl/options.h>

#include <stdlib.h>
#include <unistd.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/ssl.h>
#include "kaleb-cert.h"

int main(int argc, char** argv)
{
    int ret;
    int fail = 0;
    WOLFSSL* ssl;
    WOLFSSL_CTX* ctx;

    wolfSSL_Init();
    wolfSSL_Debugging_ON();

    ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
    if (ctx == NULL) {
        printf("CTX creation failed\n");
        return -1;
    }

    if ((ret = wolfSSL_CTX_use_certificate_buffer(ctx, myCert,
                        sizeof(myCert), SSL_FILETYPE_ASN1)) != SSL_SUCCESS) {
        printf("load_certificate_buffer returned err: %d\n", ret);
        fail = 1;
    }

    if (fail != 1)
        printf("Successfully loaded certificate\n");

    wolfSSL_CTX_free(ctx);

    return 0;

}

Could you tell me the settings you are using to build wolfSSL perhaps there is a misconfiguration for the algorithms necessary to parse the cert.


Warm Regards,

Kaleb

DEBUG LOG from test program:

wolfSSL Entering WOLFSSL_CTX_new_ex
wolfSSL Entering wolfSSL_CertManagerNew
wolfSSL Leaving WOLFSSL_CTX_new, return 0
wolfSSL Entering wolfSSL_CTX_use_certificate_buffer
Checking cert signature type
wolfSSL Entering GetExplicitVersion
wolfSSL Entering GetSerialNumber
Got Cert Header
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
Got Algo ID
Getting Cert Name
Getting Cert Name
Got Subject Name
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
wolfSSL Entering GetObjectId()
Got Key
ECDSA cert signature
Successfully loaded certificate
wolfSSL Entering SSL_CTX_free
CTX ref count down to 0, doing full free
wolfSSL Entering wolfSSL_CertManagerFree
wolfSSL Leaving SSL_CTX_free, return 0

491

(3 replies, posted in wolfSSL)

Hi muyouyuwan,

You are using a %s to print the "Hex filled array" and a strlen operation to detect the length. Keep in mind all string operations will treat a 0 value hex as a NULL terminator and try to interpret the hex values as ASCII. I suspect you are encountering the following:

EXAMPLE of Hash:

12bad3007839... up to sha256 len
       |
       String operations will see the hex 0 and think it is the end of the string

Here is a simple example program to show this difference:

PROGRAM:
  #include <stdio.h>                                                               
  #include <string.h>                                                              
                                                                                   
  int main(void)                                                                   
  {                                                                                
      int i;                                                                       
      unsigned char x[] = {                                                        
          0x12, 0x34, 0x45, 0x1b, 0xab, 0x89, 0x99,                                
          0x54, 0x78, 0x00, 0x12, 0x34, 0x45, 0x1b                                 
      };                                                                           
                                                                                   
      printf("Hash1: %s, length %d\n", x, (int) strlen((const char*)x));           
                                                                                   
      printf("Hash2: ");                                                           
      for (i = 0; i < (int)sizeof(x); i++)                                         
          printf("%02x", x[i]);                                                    
      printf(", length %d\n", (int)sizeof(x));                                     
                                                                                  
      return 0;                                                                    
  }
OUTPUT:
Hash1: 4E??Tx, length 9
Hash2: 1234451bab89995478001234451b, length 14

Please try the same thing but iterate over the HEX ARRAY using a for loop and printing each value rather than using string operations on hexidecimal values which are very likely to contain 0's.

SIDE NOTE: (Do not use sizeof() on a pointer as it will return the size of the pointer and not the size of the array)

Let me know your results!


Warm Regards,

Kaleb

492

(6 replies, posted in wolfSSL)

Hi gussabina,

Good deal, you are nearly there. To solve this issue please use the API

wolfSSL_CTX_load_verify_(locations/buffer)

prior to calling wolfSSL_new(ctx); to create the ssl object.

The certificate that is loaded with that API MUST be AT A MINIMUM the CA ROOT that signed the servers certificate.

FOR EXAMPLE:

If I got to aws.amazon.com and look at the certificate chain that was sent to my browser I see:

Starfield Services Root Certificate Authority - G2
    Amazon Root CA 1
        Amazon
            aws.amazon.com

So at a minimum if I was connecting to that domain with a wolfSSL client and doing peer auth I would need to load the "Starfield Services Root Certificate Authority - G2" with wolfSSL_CTX_load_verify_locations (or optionally place that cert in a buffer and load with wolfSSL_CTX_load_verify_buffer)

You can get a copy of that cert in either pem or der format from the amazon trust services repo here: https://www.amazontrust.com/repository/

This IS NOT necessarily the certificate you will need as your amazon instance might have a different ROOT CA signer. Please check YOUR amazon web service domain and ROOT CA. This was an example of how you might go about locating that.


Warm Regards,

Kaleb

Hi dodge55,

wolfSSL has ported to many devices and has settings for each in the file <wolf-root>/wolfssl/wolfcrypt/settings.h where you would uncomment the device your are building on if it is included in the list. If your device is not in the list, we also have a comprehensive porting guide for porting to new devices! That guide can be found here: https://wolfssl.com/wolfSSL/Docs-wolfss … guide.html


Warm Regards,

Kaleb

494

(6 replies, posted in wolfSSL)

Hi gussabina,

Thanks for the update it looks like you were able to resolve the -150, ASN_BEFORE_DATE_E issue by updating the device clock. As you had asked, the -150 stands for ASN_BEFORE_DATE_E (E short for error).

You can find a list of our error codes in <wolf-root>/wolfssl/wolfcrypt/error-crypt.h where the error falls between -100 and -300.
Any error code less than -300 would be an SSL/TLS level error and can be found in <wolf-root>/wolfssl/error-ssl.h


Best Regards,

Kaleb

Hi delphiwolf,

Yes this functionality is currently being worked on but is a lower priority as it is something we are doing internally and is currently un-funded. Paid work takes priority as I am sure you understand.

If you want to begin working with our internal stuff it's sitting in a PR here: https://github.com/wolfSSL/wolfssl/pull/724

These are currently the available API's for what you noted:

     bio = BIO_new(BIO_s_file());
     BIO_set_fp(bio, stdout, BIO_NOCLOSE);
     X509_print(bio, x509);
     BIO_free(bio);

This example sets the file descriptor to stdout but you could also give it a file stream instead.

Unfortunately I do not have a date for when we will return to that work or when it will be available in our master branch but we welcome anyone who wants to work with it!


Warm Regards,

Kaleb

496

(1 replies, posted in wolfSSL)

Hi gussabina,

Thanks for using the wolfSSL forums. You are correct there is a callback set in the WOLFSSL_CTX by default.

ctx->CBIORecv = EmbedReceive;
ctx->CBIOSend = EmbedSend;

You can find the Embed(Receive/Send) implementations in <wolf-root>/src/io.c

These will call wolfIO_Recv or wolfIO_Send which used the defined SEND_FUNCTION or RECEIVE_FUNCTION respectively. The (SEND/RECEIVE)_FUNCTION defines are in <wolf-root>/wolfssl/io.h

Let us know if you have any other questions.


Warm Regards,

Kaleb

497

(3 replies, posted in wolfSSL)

Hi clacount,

Thank you for these reports. Were you able to resolve all the issues?

We will try to get updates into the example based on your feedback as soon as we can.


Warm Regards,

Kaleb

Hi delphiwolf,

Sure thing, we have an example of creating a CA signed certificate here:

https://github.com/wolfSSL/wolfssl-exam … er/certgen

Let me know if you have any questions on that!


Warm Regards,

Kaleb

499

(7 replies, posted in wolfSSL)

Hi huba,

Thank you for bringing me up to date on what wolfSSL version you are developing with.

Our records show that 2N purchased a Commercial License from wolfSSL July 31, 2011 and maintained Technical Support and Maintenance until the expiry of July 31 2012.

If you are using version 3.11.0 in your development for the  wolfSSL Commercial Licensed Application then 2N will need to enter into an active Support/Maintenance agreement to be able to deploy newer releases of wolfSSL and to receive formal Technical Support.

It is my understanding that our Business Director, Rod Weaver has reached out to the 2N team on multiple occasions but has not received a formal response on this topic.

Are you the new key contact at 2N?


Best Regards,

Kaleb

Hi delphiwolf,

Regretfully at this time wolfSSL does not fully support the same output noted by the command:

openssl pkcs8 -topk8 -in server-key.pem -out server-keyPkcs8Enc.pem

This essentially is doing the following steps and I will not what wolfSSL supports:

Step 1: Load in a pem formatted private key - OK supported in wolfSSL
Step 2: Convert PEM key to DER key - OK supported in wolfSSL
Step 3: Create DER formatted PKCS8 object from key - OK supported in wolfSSL
Step 4: Encrypt the PKCS8 object - NOT SUPPORTED
Step 5: Convert DER formatted PKCS8 object to PEM - NOT SUPPORTED

We can get you as for as the unencrypted DER formatted PKCS8 object at this time. The equivalent command in openssl would be:

openssl -pkcs8 -nocrypt -topk8 -inform pem -in server-key.pem -outform der -out server-keyPkcs8.der

Would that be acceptable for your needs? If so please see example code below:

#include <stdio.h>

#include <wolfssl/options.h>
#include <wolfssl/ssl.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/asn_public.h>

byte key[] = "\n\
-----BEGIN RSA PRIVATE KEY-----\n\
MIIEpQIBAAKCAQEAwJUI4VdB8nFtt9JFQScBZcZFrvK8JDC4lc4vTtb2HIi8fJ/7\n\
qGd//lycUXX3isoH5zUvj+G9e8AvfKtkqBf8yl17uuAh5XIuby6G2JVz2qwbU7lf\n\
P9cZDSVP4WNjUYsLZD+tQ7ilHFw0s64AoGPF9n8LWWh4c6aMGKkCba/DGQEuuBDj\n\
xsxAtGmjRjNph27Euxem8+jdrXO8ey8htf1mUQy9VLPhbV8cvCNz0QkDiRTSELlk\n\
wyrQoZZKvOHUGlvHoMDBY3gPRDcwMpaAMiOVoXe6E9KXc+JdJclqDcM5YKS0sGlC\n\
Qgnp2Ai8MyCzWCKnquvE4eZhg8XSlt/Z0E+t1wIDAQABAoIBAQCa0DQPUmIFUAHv\n\
n+1kbsLE2hryhNeSEEiSxOlq64t1bMZ5OPLJckqGZFSVd8vDmp231B2kAMieTuTd\n\
x7pnFsF0vKnWlI8rMBr77d8hBSPZSjm9mGtlmrjcxH3upkMVLj2+HSJgKnMw1T7Y\n\
oqyGQy7E9WReP4l1DxHYUSVOn9iqo85gs+KK2X4b8GTKmlsFC1uqy+XjP24yIgXz\n\
0PrvdFKB4l90073/MYNFdfpjepcu1rYZxpIm5CgGUFAOeC6peA0Ul7QS2DFAq6EB\n\
QcIw+AdfFuRhd9Jg8p+N6PS662PeKpeB70xs5lU0USsoNPRTHMRYCj+7r7X3SoVD\n\
LTzxWFiBAoGBAPIsVHY5I2PJEDK3k62vvhl1loFk5rW4iUJB0W3QHBv4G6xpyzY8\n\
ZH3c9Bm4w2CxV0hfUk9ZOlV/MsAZQ1A/rs5vF/MOn0DKTq0VO8l56cBZOHNwnAp8\n\
yTpIMqfYSXUKhcLC/RVz2pkJKmmanwpxv7AEpox6Wm9IWlQ7xrFTF9/nAoGBAMuT\n\
3ncVXbdcXHzYkKmYLdZpDmOzo9ymzItqpKISjI57SCyySzfcBhh96v52odSh6T8N\n\
zRtfr1+elltbD6F8r7ObkNtXczrtsCNErkFPHwdCEyNMy/r0FKTV9542fFufqDzB\n\
hV900jkt/9CE3/uzIHoumxeu5roLrl9TpFLtG8SRAoGBAOyY2rvV/vlSSn0CVUlv\n\
VW5SL4SjK7OGYrNU0mNS2uOIdqDvixWl0xgUcndex6MEH54ZYrUbG57D8rUy+UzB\n\
qusMJn3UX0pRXKRFBnBEp1bA1CIUdp7YY1CJkNPiv4GVkjFBhzkaQwsYpVMfORpf\n\
H0O8h2rfbtMiAP4imHBOGhkpAoGBAIpBVihRnl/Ungs7mKNU8mxW1KrpaTOFJAza\n\
1AwtxL9PAmk4fNTm3Ezt1xYRwz4A58MmwFEC3rt1nG9WnHrzju/PisUr0toGakTJ\n\
c/5umYf4W77xfOZltU9s8MnF/xbKixsX4lg9ojerAby/QM5TjI7t7+5ZneBj5nxe\n\
9Y5L8TvBAoGATUX5QIzFW/QqGoq08hysa+kMVja3TnKW1eWK0uL/8fEYEz2GCbjY\n\
dqfJHHFSlDBD4PF4dP1hG0wJzOZoKnGtHN9DvFbbpaS+NXCkXs9P/ABVmTo9I89n\n\
WvUi+LUp0EQR6zUuRr79jhiyX6i/GTKh9dwD5nyaHwx8qbAOITc78bA=\n\
-----END RSA PRIVATE KEY-----\n\n";

int main(int argc, char** argv)
{
    int ret;
    int writeSz = 0;

    byte out[4096];
    byte tmp[4096];
    int tmpSz = (int) sizeof(tmp);
    word32 outSz = sizeof(out);
    word32 keySz = sizeof(key);
    int algoID = RSAk;
    const byte* curveOID = NULL;
    word32 oidSz = 0;
    FILE* file;
    char fName[] = "./wolfSSL-PKCS8-out.pem";
    char fNameDer[] = "./wolfSSL-PKCS8-out.der";

    XMEMSET(out, 0, outSz);
    XMEMSET(tmp, 0, tmpSz);

    /* convert pem to der */
    ret = wolfSSL_KeyPemToDer(key, (int) keySz, tmp, tmpSz, NULL);
    if (ret <= 0) {
        printf("key pem to der failed with error: %d\n", ret);
        return -1;
    }
    printf("Key pem to der successful, returned: %d\n", ret);
    writeSz = ret;

    ret = wc_CreatePKCS8Key(out, &outSz, tmp, (word32) writeSz, algoID, curveOID, oidSz);
    if (ret < 0) {
        printf("Create PKCS8 Key failed, error returned: %d\n", ret);
        return -1;
    }

    printf("SUCCESS, ret = %d\n", ret);
    writeSz = ret;

/* write DER File */
    file = fopen(fNameDer, "wb");
    if (!file) {
        printf("Failed to open file: %s\n", fNameDer);
        return -1;
    }

    ret = (int) fwrite(out, 1, (size_t) writeSz, file);
    fclose(file);

    if (ret <= 0) {
        printf("Failed to write file\n");
        return -1;
    }

/* CURRENTLY NOT SUPPORTED:
 * NOTES:
 * Works but the header is wrong, by default the "PRIVATEKEY_TYPE"
 * actually results in the header:  "-----BEGIN RSA PRIVATE KEY-----"
 * That is incorrect for this particular use-case, it should be: "-----BEGIN PRIVATE KEY-----"
 * we need a new type RSA_PRIVATEKEY_TYPE and for PRIVATEKEY_TYPE to just be
 * private key for this to be supported.
 */
//
//    ret = wc_DerToPem(out, (word32) writeSz, tmp, (word32) tmpSz, PRIVATEKEY_TYPE);
//    if (ret <= 0) {
//        printf("Der To Pem failed with error: %d\n", ret);
//        return -1;
//    }
//
//    printf("Der to Pem returned success: %d\n", ret);
//    writeSz = ret;
//
/* write PEM File */
//    file = fopen(fName, "wb");
//    if (!file) {
//        printf("Failed to open file: %s\n", fName);
//        return -1;
//    }
//
//    ret = (int) fwrite(tmp, 1, (size_t) writeSz, file);
//    fclose(file);
//
//    if (ret <= 0) {
//        printf("Failed to write file\n");
//        return -1;
//    }

    return 0;

}

Warm Regards,

Kaleb