-
Notifications
You must be signed in to change notification settings - Fork 45
/
Copy pathtls-alpn-01.lua
58 lines (51 loc) · 1.77 KB
/
tls-alpn-01.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
local pkey = require("resty.openssl.pkey")
local digest = require("resty.openssl.digest")
local x509 = require("resty.openssl.x509")
local altname = require("resty.openssl.x509.altname")
local extension = require("resty.openssl.x509.extension")
local objects = require("resty.openssl.objects")
-- creates the ACME Identifier NID into openssl's internal lookup table
-- if it doesn't exist
local id_pe_acmeIdentifier = "1.3.6.1.5.5.7.1.31"
local nid = objects.txt2nid(id_pe_acmeIdentifier)
if not nid or nid == 0 then
nid = objects.create(
id_pe_acmeIdentifier, -- nid
"pe-acmeIdentifier", -- sn
"ACME Identifier" -- ln
)
end
-- generate the tls-alpn-01 challenge certificate/key per
-- https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-07
-- with given domain name and challenge token
local function serve_challenge_cert(domain, challenge)
local dgst = assert(digest.new("sha256"):final(challenge))
-- There're two ways to set ASN.1 octect string to the extension
-- The recommanded way is to pass the string directly to extension.from_der()
local _, err = extension.from_der(dgst, nid, true)
if err then
return nil, nil, err
end
-- OR we put the ASN.1 signature for this string by ourselves
-- 0x04: OCTET STRING
-- 0x20: length
local dgst_hex = "DER:0420" .. dgst:gsub("(.)", function(s) return string.format("%02x", string.byte(s)) end)
local ext, err = extension.new(nid, dgst_hex)
if err then
return nil, nil, err
end
ext:set_critical(true)
local key = pkey.new()
local cert = x509.new()
cert:set_pubkey(key)
cert:add_extension(ext)
local alt = assert(altname.new():add(
"DNS", domain
))
local _, err = cert:set_subject_alt_name(alt)
if err then
return nil, nil, err
end
cert:sign(key)
return key, cert
end