mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-26 16:26:24 +01:00
Add support to revoke a certificate by providing the pem
This is important so that a user can revoke a certificate that is not acquired or logged from our acme client
This commit is contained in:
parent
73f0b6707a
commit
a72a7f830a
@ -9,6 +9,7 @@
|
|||||||
is_valid_account_opt/1,
|
is_valid_account_opt/1,
|
||||||
is_valid_verbose_opt/1,
|
is_valid_verbose_opt/1,
|
||||||
is_valid_domain_opt/1,
|
is_valid_domain_opt/1,
|
||||||
|
is_valid_revoke_cert/1,
|
||||||
%% Key Related
|
%% Key Related
|
||||||
generate_key/0,
|
generate_key/0,
|
||||||
to_public/1
|
to_public/1
|
||||||
@ -54,6 +55,11 @@ is_valid_domain_opt(DomainString) ->
|
|||||||
true
|
true
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec is_valid_revoke_cert(string()) -> boolean().
|
||||||
|
is_valid_revoke_cert(DomainOrFile) ->
|
||||||
|
lists:prefix("file:", DomainOrFile) orelse
|
||||||
|
lists:prefix("domain:", DomainOrFile).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
@ -457,10 +463,10 @@ get_utc_validity(#'Certificate'{tbsCertificate = TbsCertificate}) ->
|
|||||||
%%
|
%%
|
||||||
|
|
||||||
-spec revoke_certificate(string()) -> {ok, deleted} | {error, _}.
|
-spec revoke_certificate(string()) -> {ok, deleted} | {error, _}.
|
||||||
revoke_certificate(Domain) ->
|
revoke_certificate(DomainOrFile) ->
|
||||||
try
|
try
|
||||||
CAUrl = binary_to_list(get_config_ca_url()),
|
CAUrl = binary_to_list(get_config_ca_url()),
|
||||||
revoke_certificate0(CAUrl, Domain)
|
revoke_certificate0(CAUrl, DomainOrFile)
|
||||||
catch
|
catch
|
||||||
throw:Throw ->
|
throw:Throw ->
|
||||||
Throw;
|
Throw;
|
||||||
@ -469,28 +475,50 @@ revoke_certificate(Domain) ->
|
|||||||
{error, revoke_certificate}
|
{error, revoke_certificate}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec revoke_certificate0(url(), string()) -> {ok, deleted} | {error, not_found}.
|
-spec revoke_certificate0(url(), string()) -> {ok, deleted}.
|
||||||
revoke_certificate0(CAUrl, Domain) ->
|
revoke_certificate0(CAUrl, DomainOrFile) ->
|
||||||
BinDomain = list_to_bitstring(Domain),
|
ParsedCert = parse_revoke_cert_argument(DomainOrFile),
|
||||||
case domain_certificate_exists(BinDomain) of
|
revoke_certificate1(CAUrl, ParsedCert).
|
||||||
{BinDomain, Certificate} ->
|
|
||||||
ok = revoke_certificate1(CAUrl, Certificate),
|
-spec revoke_certificate1(url(), {domain, bitstring()} | {file, file:filename()}) ->
|
||||||
|
{ok, deleted}.
|
||||||
|
revoke_certificate1(CAUrl, {domain, Domain}) ->
|
||||||
|
case domain_certificate_exists(Domain) of
|
||||||
|
{Domain, Cert = #data_cert{pem=PemCert}} ->
|
||||||
|
ok = revoke_certificate2(CAUrl, PemCert),
|
||||||
|
ok = remove_certificate_persistent(Cert),
|
||||||
{ok, deleted};
|
{ok, deleted};
|
||||||
false ->
|
false ->
|
||||||
{error, not_found}
|
?ERROR_MSG("Certificate for domain: ~p not found", [Domain]),
|
||||||
|
throw({error, not_found})
|
||||||
|
end;
|
||||||
|
revoke_certificate1(CAUrl, {file, File}) ->
|
||||||
|
case file:read_file(File) of
|
||||||
|
{ok, Pem} ->
|
||||||
|
ok = revoke_certificate2(CAUrl, Pem),
|
||||||
|
{ok, deleted};
|
||||||
|
{error, Reason} ->
|
||||||
|
?ERROR_MSG("Error: ~p reading pem certificate-key file: ~p", [Reason, File]),
|
||||||
|
throw({error, Reason})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec revoke_certificate1(url(), data_cert()) -> ok.
|
|
||||||
revoke_certificate1(CAUrl, Cert = #data_cert{pem=PemEncodedCert}) ->
|
-spec revoke_certificate2(url(), data_cert()) -> ok.
|
||||||
|
revoke_certificate2(CAUrl, PemEncodedCert) ->
|
||||||
{Certificate, CertPrivateKey} = prepare_certificate_revoke(PemEncodedCert),
|
{Certificate, CertPrivateKey} = prepare_certificate_revoke(PemEncodedCert),
|
||||||
|
|
||||||
{ok, Dirs, Nonce} = ejabberd_acme_comm:directory(CAUrl),
|
{ok, Dirs, Nonce} = ejabberd_acme_comm:directory(CAUrl),
|
||||||
|
|
||||||
Req = [{<<"certificate">>, Certificate}],
|
Req = [{<<"certificate">>, Certificate}],
|
||||||
{ok, [], Nonce1} = ejabberd_acme_comm:revoke_cert(Dirs, CertPrivateKey, Req, Nonce),
|
{ok, [], Nonce1} = ejabberd_acme_comm:revoke_cert(Dirs, CertPrivateKey, Req, Nonce),
|
||||||
ok = remove_certificate_persistent(Cert),
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
-spec parse_revoke_cert_argument(string()) -> {domain, bitstring()} | {file, file:filename()}.
|
||||||
|
parse_revoke_cert_argument([$f, $i, $l, $e, $:|File]) ->
|
||||||
|
{file, File};
|
||||||
|
parse_revoke_cert_argument([$d, $o, $m, $a, $i, $n, $: | Domain]) ->
|
||||||
|
{domain, list_to_bitstring(Domain)}.
|
||||||
|
|
||||||
-spec prepare_certificate_revoke(pem()) -> bitstring().
|
-spec prepare_certificate_revoke(pem()) -> bitstring().
|
||||||
prepare_certificate_revoke(PemEncodedCert) ->
|
prepare_certificate_revoke(PemEncodedCert) ->
|
||||||
PemList = public_key:pem_decode(PemEncodedCert),
|
PemList = public_key:pem_decode(PemEncodedCert),
|
||||||
|
@ -270,8 +270,8 @@ get_commands_spec() ->
|
|||||||
#ejabberd_commands{name = revoke_certificate, tags = [acme],
|
#ejabberd_commands{name = revoke_certificate, tags = [acme],
|
||||||
desc = "Revokes the selected certificate",
|
desc = "Revokes the selected certificate",
|
||||||
module = ?MODULE, function = revoke_certificate,
|
module = ?MODULE, function = revoke_certificate,
|
||||||
args_desc = ["The domain of the certificate in question"],
|
args_desc = ["The domain or file (in pem format) of the certificate in question {domain:Domain | file:File}"],
|
||||||
args = [{domain, string}],
|
args = [{domain_or_file, string}],
|
||||||
result = {res, restuple}},
|
result = {res, restuple}},
|
||||||
|
|
||||||
#ejabberd_commands{name = import_piefxis, tags = [mnesia],
|
#ejabberd_commands{name = import_piefxis, tags = [mnesia],
|
||||||
@ -602,8 +602,14 @@ list_certificates(Verbose) ->
|
|||||||
{invalid_option, String}
|
{invalid_option, String}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
revoke_certificate(Domain) ->
|
revoke_certificate(DomainOrFile) ->
|
||||||
ejabberd_acme:revoke_certificate(Domain).
|
case ejabberd_acme:is_valid_revoke_cert(DomainOrFile) of
|
||||||
|
true ->
|
||||||
|
ejabberd_acme:revoke_certificate(DomainOrFile);
|
||||||
|
false ->
|
||||||
|
String = io_lib:format("Bad argument: ~s", [DomainOrFile]),
|
||||||
|
{invalid_argument, String}
|
||||||
|
end.
|
||||||
|
|
||||||
%%%
|
%%%
|
||||||
%%% Purge DB
|
%%% Purge DB
|
||||||
|
Loading…
Reference in New Issue
Block a user