Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support SSL_CTX_use_certificate_chain_file and SSL_CTX_use_private_key_file #194

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Mehgugs
Copy link

@Mehgugs Mehgugs commented Jul 24, 2021

  • ctx:setCertificateFromFile calls SSL_CTX_use_certificate_chain_file
    to add a certificate chain from a pem encoded file specified by the string argument path.

  • ctx:setPrivateKeyFromFile calls SSL_CTX_use_private_key_file
    to add a private key from a PEM or ASN1 encoded file using the string argument path
    and filetype integer flag argument. The filetype is optional and will default to PEM if not
    specified.

  • openssl.filetypes is a new table in the openssl module which contains the
    two filetypes used by setPrivateKeyFromFile. The .PEM field is the value of SSL_FILETYPE_PEM and
    the .ASN1 field is the value of SSL_FILETYPE_ASN1.

- `ctx:setCertificteFromFile` calls `SSL_CTX_use_certificate_chain_file`
to add a certificate chain from a pem encoded file specified by the string argument path.

- `ctx:setPrivateKeyFromFile` calls `SSL_CTX_use_private_key_file`
to add a private key from a PEM or ASN1 encoded file using the string argument path
and filetype integer flag argument. The filetype is optional and will default to PEM if not
specified.

- `openssl.filetypes` is a new table in the openssl module which contains the
two filetypes used by `setPrivateKeyFromFile`. The `.PEM` field is the value of `SSL_FILETYPE_PEM` and
the `.ASN1` field is the value of `SSL_FILETYPE_ASN1`.
@Mehgugs Mehgugs marked this pull request as ready for review July 24, 2021 22:02
Copy link
Collaborator

@daurnimator daurnimator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested this against old OpenSSL?

Do operations exist to do the same thing on an SSL object?

Please add new functions to docs

src/openssl.c Show resolved Hide resolved
src/openssl.c Outdated
#endif
{ "setPrivateKey", &sx_setPrivateKey },
{ "setPrivateKeyFromFile", &sx_usePrivateKeyFile},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please realign the section

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attempted to realign the reg declarations in keeping with the current style.

- Adds `ssl:setCertificateChainFromFile` and `ssl:setPrivateKeyFromFile`
  These both behave the same way as their context counterparts.

- Attempt to improve formatting:
  - Added double newlines between the new code sections.
  - Tried to space out the reg declarations following the style of the code.
  - Added function end comments.
  - Renamed the c functions to match their lua registry name.
@Mehgugs
Copy link
Author

Mehgugs commented Aug 1, 2021

I'll do another commit adding tex when I'm finished with the code.

Support for DER encoded private keys (SSL_FILETYPE_ASN1) in SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file() was added in 0.9.8.

Will this need to be reflected with a version pre-req somehow?

Copy link
Collaborator

@daurnimator daurnimator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add the new methods to the docs?

Comment on lines +620 to +623
#ifndef HAVE_USE_CERTIFICATE_CHAIN_FILE
#define HAVE_USE_CERTIFICATE_CHAIN_FILE (OPENSSL_PREREQ(0,9,4) || LIBRESSL_PREREQ(2,0,0))
#endif

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is old enough we can likely count on it

static int sx_setPrivateKeyFromFile(lua_State* L) {
SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
const char* filepath = luaL_checkstring(L, 2);
int typ = luaL_optinteger(L, 3, SSL_FILETYPE_PEM);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably take a string rather than an integer option? (luaL_checkoption)

@Simon-L
Copy link

Simon-L commented Jul 5, 2024

Hello, in the meantime how can one load a certificate and a key from files on the current version available from Luarocks?

@Mehgugs
Copy link
Author

Mehgugs commented Jul 9, 2024

Hello, in the meantime how can one load a certificate and a key from files on the current version available from Luarocks?

local Pkey        = require "openssl.pkey"
local Crt         = require "openssl.x509"
local Chain       = require"openssl.x509.chain"

local function decode_fullchain(crtfile, iscontent)
    local crtf  = assert(io.open(crtfile, "r"))
    local crttxt = crtf:read"a"
    crtf:close()

    local crts, pos = {}, 1

    repeat
        local st, ed = crttxt:find("-----BEGIN CERTIFICATE-----", pos, true)
        if st then
            local st2, ed2 = crttxt:find("-----END CERTIFICATE-----", ed + 1, true)
            if st2 then
                table.insert(crts, crttxt:sub(st, ed2))
                pos = ed2+1
            end
        end
    until st == nil

    local chain = Chain.new()
    local primary = asserts(Crt.new(crts[1]))
    for i = 2, #crts do
        local crt = asserts(Crt.new(crts[i]))
        chain:add(crt)
    end
    return primary,chain
end

function example_usage(ctx, crtpath, keypath) 
    local keyfile = asserts(openf(keypath, "r"))
    local primary,crt = decode_fullchain(crtpath)
    asserts(ctx:setPrivateKey(Pkey.new(keyfile:read"a")))
    asserts(ctx:setCertificate(primary))
    asserts(ctx:setCertificateChain(crt))
    keyfile:close()
end

This is my "good enough" solution but it doesnt really address all the situtations covered by these two functions.

Apologies for not continuing to develop this PR further; I am a consumer of this library by way of lua-http and cqueues and it was easier for me to set up a reverse proxy to handle all the https and have the lua processes all run behind that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants