From 3ef550cb6f1e8ac7e4142cc1620eb36be747b30d Mon Sep 17 00:00:00 2001
From: Linus Nordberg <linus@nordberg.se>
Date: Wed, 5 Nov 2014 13:02:16 +0100
Subject: Log some info about certs that don't parse and why.

Also move x509 specific code to the x509 module.
---
 src/catlfish.erl | 14 ++++++--------
 src/x509.erl     | 24 +++++++++++++++++++++---
 2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/src/catlfish.erl b/src/catlfish.erl
index 5d96278..3ca190a 100644
--- a/src/catlfish.erl
+++ b/src/catlfish.erl
@@ -216,7 +216,9 @@ ders_from_pemfiles(Dir, Filenames) ->
 
 ders_from_pemfile(Filename) ->
     Pems = case (catch public_key:pem_decode(pems_from_file(Filename))) of
-               {'EXIT', _} -> [];
+               {'EXIT', Reason} ->
+                   lager:info("badly encoded cert in ~p: ~p", [Filename, Reason]),
+                   [];
                P -> P
            end,
     [der_from_pem(X) || X <- Pems].
@@ -225,13 +227,9 @@ ders_from_pemfile(Filename) ->
 der_from_pem(Pem) ->
     case Pem of
         {_Type, Der, not_encrypted} ->
-            case (catch public_key:pkix_decode_cert(Der, otp)) of
-                {'EXIT', _} ->
-                    [];
-                #'OTPCertificate'{} ->
-                    Der;
-                _Unknown ->
-                    []
+            case x509:valid_cert_p(Der) of
+                true -> Der;
+                false -> []
             end;
         _ -> []
     end.
diff --git a/src/x509.erl b/src/x509.erl
index a784354..5a96a29 100644
--- a/src/x509.erl
+++ b/src/x509.erl
@@ -2,7 +2,7 @@
 %%% See LICENSE for licensing information.
 
 -module(x509).
--export([normalise_chain/2, cert_string/1]).
+-export([normalise_chain/2, cert_string/1, valid_cert_p/1]).
 
 -include_lib("public_key/include/public_key.hrl").
 
@@ -73,8 +73,9 @@ signed_by_p(Cert, IssuerCert) ->
     %% FIXME: Validate presence and contents (against constraints) of
     %% names (subject, subjectAltName, emailAddress) too?
     case (catch public_key:pkix_is_issuer(Cert, IssuerCert)) of
-        {'EXIT', _Reason} ->
-            %% Invalid ASN.1.
+        {'EXIT', Reason} ->
+            lager:info("invalid certificate: ~p: ~p",
+                       [mochihex:to_hex(crypto:hash(sha, Cert)), Reason]),
             {false, encoding_invalid};
         true ->
             %% Cert.issuer does match IssuerCert.subject. Now verify
@@ -101,6 +102,23 @@ cert_string(Der) ->
     lists:flatten([io_lib:format("~2.16.0B", [X]) ||
 		      X <- binary_to_list(crypto:hash(sha, Der))]).
 
+valid_cert_p(Der) ->
+    %% Use the customized ASN.1 specification "OTP-PKIX.asn1" since
+    %% that's what's required for public_key functions we're using
+    %% (pkix_verify, public_key:pkix_is_issuer).
+    case (catch public_key:pkix_decode_cert(Der, otp)) of
+        #'OTPCertificate'{} ->
+            true;
+        {'EXIT', Reason} ->
+            lager:info("invalid certificate: ~p: ~p",
+                       [mochihex:to_hex(crypto:hash(sha, Der)), Reason]),
+            false;
+        Unknown ->
+            lager:info("unknown error decoding cert: ~p: ~p",
+                       [mochihex:to_hex(crypto:hash(sha, Der)), Unknown]),
+            false
+    end.
+
 %%%%%%%%%%%%%%%%%%%%
 %% Precertificates according to draft-ietf-trans-rfc6962-bis-04.
 
-- 
cgit v1.1