aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>2017-11-17 17:17:19 +0300
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>2017-11-17 17:17:19 +0300
commit4f12359b9c9c482eb0a7aa10eafb84f1c53b96c3 (patch)
tree1c2e0e4f9c51d1dfd323336ef2d766d3caaec73d /src
parentFix ACME options validation (diff)
Don't forget to include intermediate ACME certificate
Thanks to Konstantinos Kallas
Diffstat (limited to '')
-rw-r--r--src/ejabberd_acme.erl10
-rw-r--r--src/ejabberd_acme_comm.erl27
2 files changed, 28 insertions, 9 deletions
diff --git a/src/ejabberd_acme.erl b/src/ejabberd_acme.erl
index eb0a340da..0a25e8bf5 100644
--- a/src/ejabberd_acme.erl
+++ b/src/ejabberd_acme.erl
@@ -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 ->
diff --git a/src/ejabberd_acme_comm.erl b/src/ejabberd_acme_comm.erl
index acd552f7e..a5668d088 100644
--- a/src/ejabberd_acme_comm.erl
+++ b/src/ejabberd_acme_comm.erl
@@ -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, $>)