civetweb / civetweb

Embedded C/C++ web server
Other
2.89k stars 962 forks source link

How to embed SSL certificate into the program? #1030

Closed mfide closed 2 years ago

mfide commented 3 years ago

Hi,

We use Civetweb on our embedded Linux Platform as a TLS websocket server which works perfect.

But we don't want to distribute the certificate as a separate file. Is there a way to embed the certificate into our program which uses Civetweb? Let's say we have an array which holds certificate information as a byte stream in the memory. Is it possible to tell Civetweb that use this array as a certificate instead of external file?

Thank you.

bel2125 commented 3 years ago

You can do the setup of all SSL in your own init callback, and then return "1":

https://github.com/civetweb/civetweb/blob/1a6de4ccb2d4c8be6ea6c4c767e98f6fab55d393/include/civetweb.h#L246-L254

I somewhere had an example of how to do that, including setting up parameters for ecliptic curves, all in a C source file. But this is non-public code - I can try to give you some general hints about what OpenSSL functions you need to call there.

dearfl commented 3 years ago

@bel2125 I'm interested in this, too. Could u share more info about how to do this?

bel2125 commented 3 years ago

Essentially by providing an "init_ssl" callback to "mg_start" that does something like:

static int init_ssl(void *ssl_ctx, void *user_data)
{
    SSL_CTX *ctx = (SSL_CTX*)ssl_ctx;

    SSL_CTX_use_certificate_ASN1(ctx, sizeof(SSL_CERT_ASN1), SSL_CERT_ASN1);
    SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, ctx, SSL_KEY_ASN1, sizeof(SSL_KEY_ASN1));

    if (SSL_CTX_check_private_key(ctx) == 0) {
        printf("SSL data inconsistency detected\n");
        return -1;
    }

    return 0; /* let CivetWeb set up the rest of OpenSSL */
}

I think I will add a full example for this next week - probably containing the setup of an ecliptic curve as well.

dearfl commented 3 years ago

@bel2125 thx

bel2125 commented 3 years ago

A source example is here: https://github.com/civetweb/civetweb/tree/master/examples/embed_certificate I will need to add some text explaining the example in some detail later. Note: This is a "NO_FILESYSTEM" example, meaning the server is build in a way that it cannot access any file at all - see the "build.sh" build script for all options used here. But if you just want to use an embedded certificate while the server can still provide files from the disk, this is also possible - the "NO_FILESYSTEM" is not mandatory for this.

The lengthy hex number strings have been generated by taking the server.crt and server.key files from the /ressources/cert/ directory, copying the content into https://cryptii.com/pipes/base64-to-hex (with "Transfer Encoding (RFC 2045)" ... don't know why, but this is the only one that worked for me) , then copying the output to the source file and search/replace " " --> ", 0x" to make it valid C code. Of course you have to use your own certs and keys.

bel2125 commented 3 years ago

I added some documentation for this example. If you don't have any more questions, I would close this issue beginning of November.