Don't forget to include intermediate ACME certificate

Thanks to Konstantinos Kallas
This commit is contained in:
Evgeniy Khramtsov 2017-11-17 17:17:19 +03:00
parent f599c2ef82
commit 4f12359b9c
2 changed files with 28 additions and 9 deletions

View File

@ -331,16 +331,20 @@ create_new_certificate(CAUrl, {DomainName, AllSubDomains}, PrivateKey) ->
{<<"notBefore">>, NotBefore},
{<<"NotAfter">>, NotAfter}
],
{ok, {_CertUrl, Certificate}, _Nonce1} =
{ok, {IssuerCertLink, Certificate}, _Nonce1} =
ejabberd_acme_comm:new_cert(Dirs, PrivateKey, Req, Nonce0),
DecodedCert = public_key:pkix_decode_cert(list_to_binary(Certificate), plain),
PemEntryCert = public_key:pem_entry_encode('Certificate', DecodedCert),
{ok, IssuerCert, _Nonce2} = ejabberd_acme_comm:get_issuer_cert(IssuerCertLink),
DecodedIssuerCert = public_key:pkix_decode_cert(list_to_binary(IssuerCert), plain),
PemEntryIssuerCert = public_key:pem_entry_encode('Certificate', DecodedIssuerCert),
{_, CSRKeyKey} = jose_jwk:to_key(CSRKey),
PemEntryKey = public_key:pem_entry_encode('ECPrivateKey', CSRKeyKey),
PemCertKey = public_key:pem_encode([PemEntryKey, PemEntryCert]),
PemCertKey = public_key:pem_encode([PemEntryKey, PemEntryCert, PemEntryIssuerCert]),
{ok, DomainName, PemCertKey}
catch
@ -1100,13 +1104,13 @@ save_certificate({ok, DomainName, Cert}) ->
%% that there is no certificate saved if it cannot be added in
%% certificate persistent storage
write_cert(CertificateFile, Cert, DomainName),
ok = ejabberd_pkix:add_certfile(CertificateFile),
DataCert = #data_cert{
domain = DomainName,
pem = Cert,
path = CertificateFile
},
add_certificate_persistent(DataCert),
ok = ejabberd_pkix:add_certfile(CertificateFile),
{ok, DomainName, saved}
catch
throw:Throw ->

View File

@ -15,7 +15,8 @@
%% Certificate
new_cert/4,
get_cert/1,
revoke_cert/4
revoke_cert/4,
get_issuer_cert/1
%% Not yet implemented
%% key_roll_over/5
%% delete_authz/3
@ -124,7 +125,7 @@ complete_challenge({CAUrl, AuthzId, ChallId}, PrivateKey, Req, Nonce) ->
new_cert(Dirs, PrivateKey, Req, Nonce) ->
#{"new-cert" := Url} = Dirs,
EJson = {[{<<"resource">>, <<"new-cert">>}] ++ Req},
prepare_post_request(Url, PrivateKey, EJson, Nonce, fun get_response_location/1,
prepare_post_request(Url, PrivateKey, EJson, Nonce, fun get_response_link_up/1,
"application/pkix-cert").
-spec get_cert({url(), string()}) -> {ok, list(), nonce()} | {error, _}.
@ -140,6 +141,9 @@ revoke_cert(Dirs, PrivateKey, Req, Nonce) ->
prepare_post_request(Url, PrivateKey, EJson, Nonce, fun get_response/1,
"application/pkix-cert").
-spec get_issuer_cert(url()) -> {ok, list(), nonce()} | {error, _}.
get_issuer_cert(IssuerCertUrl) ->
prepare_get_request(IssuerCertUrl, fun get_response/1, "application/pkix-cert").
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@ -172,7 +176,11 @@ get_response_location({ok, Head, Return}) ->
NewNonce = get_nonce(Head),
{ok, {Location, Return}, NewNonce}.
-spec get_response_link_up({ok, proplist(), proplist()}) -> {ok, {url(), proplist()}, nonce()}.
get_response_link_up({ok, Head, Return}) ->
LinkUp = get_link_up(Head),
NewNonce = get_nonce(Head),
{ok, {LinkUp, Return}, NewNonce}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@ -332,14 +340,21 @@ get_location(Head) ->
none -> none
end.
%% Very bad way to extract this
%% TODO: Find a better way
-spec get_tos(proplist()) -> url() | 'none'.
get_tos(Head) ->
get_header_link(Head, "\"terms-of-service\"").
-spec get_link_up(proplist()) -> url() | 'none'.
get_link_up(Head) ->
get_header_link(Head, "rel=\"up\"").
%% TODO: Find a more reliable way to extract this
-spec get_header_link(proplist(), string()) -> url() | 'none'.
get_header_link(Head, Suffix) ->
try
[{_, Link}] = [{K, V} || {K, V} <- Head,
K =:= "link" andalso
lists:suffix("\"terms-of-service\"", V)],
lists:suffix(Suffix, V)],
[Link1, _] = string:tokens(Link, ";"),
Link2 = string:strip(Link1, left, $<),
string:strip(Link2, right, $>)