ACME Protocol - RFC 8555
The Lua module acme/engine implements a subset of the ACME client-side protocol as specified in RFC-8555. This module is internally used by the two Mako Server modules, acme/acmebot and acme/dns. You can use the acme Lua module directly if you are not using the Mako Server or need management not provided by the two Mako Server modules.
Using module acme/bot and acme/dns in non Mako Server builds
Module acme/bot and acme/dns are designed for the Mako Server, but can be used by other Barracuda App Server builds. For example, the Xedge example copies the two modules to its own resource directory and enables the modules if the example is compiled with file system support.
The two modules require special initialization if not used by the Mako Server. The following specifies how to initialize the two modules in a non Mako Server environment. You must initialize both modules using the two functions below:
- require"acme/bot".init(io,loadcerts)
-
Set the required I/O and loadcerts callback function.
- I/O io - A read/write enabled I/O. The module creates the sub directory 'cert' in the root of the I/O and stores Let's Encrypt account information and certificates in this directory.
- Function loadcerts(keys, certs) - This function is called by the module when the certificate(s) and the associated private key(s) are ready to be dynamically installed in the running server. See the Xedge's .config script for an implementation example.
- Table keys - Associated array with one or more keys, in which each key is a string containing an X.509 pem encoded key.
- Table certs - Associated array with one or more certificates, in which each certificate is a string containing an X.509 pem encoded certificate.
- require"acme/dns".init(op [,sendmail])
-
- Table op - The option table used by the HTTP client. The option table may have a "shark" attribute set, and the SharkSSL object must have a certificate store with the Let's Encrypt CA certificate. The HTTP client library operates in strict mode and will not connect unless the server's certificate is trusted. If attribute 'shark' is not set, ba.sharkclient() is used.
- Function sendmail(msg, dnsrec, dnsauth) - The sendmail callback is called when the module operates in manual mode. You do not need to set a callback unless you plan on using the manual mode.
- String msg - A human readable string that includes information on how to set the DNS TXT record and the DNS authorization value.
- String dnsrec - The DNS TXT record name.
- String dnsauth - The DNS TXT record value.
Compile Time Requirements
The ACME module requires the auxiliary Lua bindings and the following compile time flags, which are not pre-set for any builds, except for POSIX and Win.
#define SHARKSSL_ENABLE_ASN1_KEY_CREATION 1
#define SHARKSSL_ENABLE_RSAKEY_CREATE 1
#define SHARKSSL_ENABLE_ECCKEY_CREATE 1
#define SHARKSSL_ENABLE_CSR_CREATION 1
You may add these defines to the inc/arch/[platform]/TargConfig.h header file or set them as part of your build's compiler options.
Module acme/engine
For a deeper understanding of how this module conceptually works, see the online Let's Encrypt v2 Step by Step tutorial (designed for JavaScript).
acme=require"acme/engine"
- acme.cert(account, domain, rspCB, op)
-
Initiates a certificate request for 'domain'. The certificate request is initiated immediately if no other jobs are active or queued if another certificate request job is running. In either case, the function returns immediately and returns the number of jobs queued.
Arguments:
- table account - the Let's Encrypt account information. The table must at a minimum contain a valid email address. All other fields are automatically created if not set, however, the fields must be persistently saved by your application after the response callback function 'rspCB' has been called.
- Required: String email - a valid email address.
- String key - the Let's Encrypt account key is created automatically the first time the acme.cert() function is called, when the table only includes the email address. The account key is either an ECC or RSA private key.
- String id - a unique account URL created by the Let's Encrypt service when the account is created.
- String domain - the domain name (domain.com) or wildcard domain name (*.domain.com)
- Function rspCB - the response callback is called when the certificate has been issued or if the operation failed. The function is called with parameter rspCB(key, cert) on success and rspCB(nil, error-code) on error. The key and cert are provided in the standard X.509 format.
- Table op - options table
- Required: boolean acceptterms - must be set to true for acceptance of the terms provided in the document downloadable by the URL returned by function acme.terms().
- Optional: string privkey - The private RSA/ECC key from a previous session. If not set, a new key is created.
- Optional: boolean production - Set to true if you want to use the Let's Encrypt production environment. The default is to use the staging environment (test server).
- Optional: boolean rsa - Set to true if you want to use RSA certificates. The default is to use ECC certificates.
- Optional: number bits - The key size for RSA certificates. Default is 2048.
- Optional: string curve - The curve to use for ECC certificates. Default is "SECP384R1".
- Optional: SharkSSL shark - ba.sharkclient() is used if 'shark' is not set.
- Optional: table ch - the ACME challenge option is a table (interface) with callback functions. The acme module uses the default http-01 challenge if not set.
- String type - the ACME challenge type must be set to "http-01" or "dns-01"
- Function set(dnsVal, dnsData, resumeCB) - must be set if challenge type is set to "dns-01". The function is called when the DNS text record must be set.
- String dnsVal - the DNS record name to set
- String dnsData - the DNS record value to set
- Function resumeCB(true | nil,err) - The resume callback function must be called after the DNS entry is set and after the settings are globally available for the Let's Encrypt service to check. Call the function with argument (true) on success and (nil, error) if setting the DNS entry failed.
- Function insert(tokenURL, keyAuth, resumeCB) - may be set if challenge type is set to "http-01" and if you want to implement your own http-01 challenge interface. See function httpChallengeIntf -> insert() in module acme.lua for how to use the arguments.
- Function remove(resumeCB) - must be set if challenge type is set to "dns-01". The function must also be set if challenge type is "http-01" and if the 'insert' function is set. The function may be used to clean up any resources set when function set() or insert() was called. The function must resume the ACME challenge by calling resumeCB(true).
- acme.terms()
-
Returns a URL to the Let's Encrypt terms of service (pdf).
- acme.jobs()
-
Returns the number of active/pending jobs.
- acme.revoke(account,cert,rspCB)
-
Revoke the certificate.
- acme.setTPM(tpmAPI)
- Makes the ACME engine use the functions provided in the TPM API and not the direct SharkSSL APIs when using ECC certificates. The TPM API must be a table with the following functions:
- jwtsign(keyname, payload [, header])
- keyparams(keyname)
- createcsr(keyname, dn [, san], certtype, keyusage [, hashid ])
- createkey(keyname, [{op}])
- haskey(keyname)
Function setTPM() can only be called one time.