Package: release.debian.org Severity: normal Tags: buster User: release.debian....@packages.debian.org Usertags: pu
Hi, I would like to update erlang-p1-pkix in Buster to fix a regression in ejabberd, prohibiting the use of GnuTLS certificates. The patch is directly from upstream [1] and will also be part of the next upload to unstable. To keep changes minimal I stripped the tests and example certificates added with that commit. The resulting package has been successfully tested in real life. The full diff is attached. [1] https://github.com/processone/pkix/commit/2d7a3b80bf6fc0794720aca852e487a5064d8b86
diff --git a/debian/changelog b/debian/changelog index 772931a..f7f2286 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +erlang-p1-pkix (1.0.0-3+deb10u1) buster; urgency=medium + + * Added upstream patch to fix handling of GnuTLS certificates + + -- Philipp Huebner <debala...@debian.org> Thu, 01 Aug 2019 11:34:25 +0200 + erlang-p1-pkix (1.0.0-3) unstable; urgency=medium * Updated debian/copyright diff --git a/debian/patches/2d7a3b80bf6fc0794720aca852e487a5064d8b86.patch b/debian/patches/2d7a3b80bf6fc0794720aca852e487a5064d8b86.patch new file mode 100644 index 0000000..fe1ef43 --- /dev/null +++ b/debian/patches/2d7a3b80bf6fc0794720aca852e487a5064d8b86.patch @@ -0,0 +1,109 @@ +From 2d7a3b80bf6fc0794720aca852e487a5064d8b86 Mon Sep 17 00:00:00 2001 +From: Evgeny Khramtsov <ekhramt...@process-one.net> +Date: Thu, 1 Aug 2019 12:23:48 +0300 +Subject: [PATCH] Use original DER during certification path validation + +Index: erlang-p1-pkix/src/pkix.erl +=================================================================== +--- erlang-p1-pkix.orig/src/pkix.erl ++++ erlang-p1-pkix/src/pkix.erl +@@ -35,7 +35,8 @@ + -define(CERTFILE_TAB, pkix_certfiles). + + -record(pem, {file :: filename(), +- line :: pos_integer()}). ++ line :: pos_integer(), ++ der :: binary()}). + + -record(state, {files = #{} :: map(), + certs = #{} :: map(), +@@ -437,9 +438,9 @@ pem_decode(Fd, Line, Begin, Buf) -> + -spec pem_decode_entries([{pos_integer(), binary()}], filename(), + map(), map()) -> {ok, map(), map()} | {error, bad_cert_error()}. + pem_decode_entries([{Begin, Data}|PEMs], File, Certs, PrivKeys) -> +- P = #pem{file = File, line = Begin}, + try public_key:pem_decode(Data) of +- [PemEntry] -> ++ [{_, DER, _} = PemEntry] -> ++ P = #pem{file = File, der = DER, line = Begin}, + try der_decode(PemEntry) of + undefined -> + pem_decode_entries(PEMs, File, Certs, PrivKeys); +@@ -510,7 +511,7 @@ der_decode({_, _, _}) -> + {error, filename() | dirname(), io_error()}. + commit(State, Dir, CAFile, ValidateHow) -> + {Chains, BadCertsWithReason, UnusedKeysWithReason} = build_chains(State), +- {CAError, InvalidCertsWithReason} = validate(Chains, CAFile, ValidateHow), ++ {CAError, InvalidCertsWithReason} = validate(State, Chains, CAFile, ValidateHow), + InvalidCerts = [C || {C, _} <- InvalidCertsWithReason], + SortedChains = case ValidateHow of + hard when CAError == undefined -> +@@ -730,8 +731,7 @@ store_chain(Chain, Dir, State) -> + pem_encode({Certs, Key}, State) -> + PEM1 = lists:map( + fun(Cert) -> +- Type = element(1, Cert), +- DER = public_key:pkix_encode(Type, Cert, otp), ++ DER = get_der(Cert, State#state.certs), + PemEntry = {'Certificate', DER, not_encrypted}, + Source = lists:map( + fun(#pem{file = File, line = Line}) -> +@@ -742,11 +742,14 @@ pem_encode({Certs, Key}, State) -> + PEM2 = [[io_lib:format("From ~s:~B~n", [File, Line]) + || #pem{file = File, line = Line} <- maps:get(Key, State#state.keys)], + public_key:pem_encode( +- [{element(1, Key), +- public_key:der_encode(element(1, Key), Key), +- not_encrypted}])], ++ [{element(1, Key), get_der(Key, State#state.keys), not_encrypted}])], + iolist_to_binary([PEM1, PEM2]). + ++-spec get_der(cert() | priv_key(), map()) -> binary(). ++get_der(Key, Map) -> ++ [#pem{der = DER}|_] = maps:get(Key, Map), ++ DER. ++ + %%%=================================================================== + %%% Domains extraction + %%%=================================================================== +@@ -850,12 +853,12 @@ get_cert_path(G, [Root|_] = Acc) -> + %%%=================================================================== + %%% Certificates chain validation + %%%=================================================================== +--spec validate([cert_chain()], filename(), false | soft | hard) -> ++-spec validate(state(), [cert_chain()], filename(), false | soft | hard) -> + {undefined | {filename(), bad_cert_error() | io_error()}, + [{cert(), invalid_cert_reason()}]}. +-validate(_Chains, _CAFile, false) -> ++validate(_State, _Chains, _CAFile, false) -> + {undefined, []}; +-validate(Chains, CAFile, _) -> ++validate(State, Chains, CAFile, _) -> + {CAError, IssuerCerts} = case pem_decode_file(CAFile) of + {error, Why} -> + {{CAFile, Why}, []}; +@@ -866,7 +869,7 @@ validate(Chains, CAFile, _) -> + lists:filtermap( + fun({Certs, _PrivKey}) -> + RevCerts = lists:reverse(Certs), +- case validate_path(RevCerts, IssuerCerts) of ++ case validate_path(State, RevCerts, IssuerCerts) of + ok -> + false; + {error, Reason} -> +@@ -874,11 +877,12 @@ validate(Chains, CAFile, _) -> + end + end, Chains)}. + +--spec validate_path([cert()], [cert()]) -> ok | {error, invalid_cert_reason()}. +-validate_path([Cert|_] = Certs, IssuerCerts) -> ++-spec validate_path(state(), [cert()], [cert()]) -> ok | {error, invalid_cert_reason()}. ++validate_path(State, [Cert|_] = Certs, IssuerCerts) -> + case find_issuer_cert(Cert, IssuerCerts) of + {ok, IssuerCert} -> +- case public_key:pkix_path_validation(IssuerCert, Certs, []) of ++ DERs = [get_der(C, State#state.certs) || C <- Certs], ++ case public_key:pkix_path_validation(IssuerCert, DERs, []) of + {ok, _} -> + ok; + {error, {bad_cert, Reason}} -> diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..568471b --- /dev/null +++ b/debian/patches/series @@ -0,0 +1 @@ +2d7a3b80bf6fc0794720aca852e487a5064d8b86.patch