anchor.diff:  -compile(export_all).
   
   -include_lib("public_key/include/public_key.hrl").
  -%%-include("public_key.hrl").
   
   -define(error(Format,Args), error(Format,Args,?FILE,?LINE)).
   -define(warning(Format,Args), warning(Format,Args,?FILE,?LINE)).
  
positive.code:     end,
      AbsFile.
  
  sort_chain([First|Certs], TA, Try, Found) -> 
      case public_key:pkix_is_issuer(First,TA) of
  	true -> 
  	    [First|sort_chain(Certs,First,Try,true)];
  	false ->
  	    sort_chain(Certs,TA,[First|Try],Found)
      end;
  sort_chain([], _, [],_) -> [];
  sort_chain([], Valid, Check, true) ->
      sort_chain(lists:reverse(Check), Valid, [], false);
  sort_chain([], _Valid, Check, false) ->
      Check.
  
  signature_verification() ->    
      %%  "4.1", "Signature Verification" ,
      [{ "4.1.1", "Valid Signatures Test1",                        ok},
       { "4.1.2", "Invalid CA Signature Test2",                    {bad_cert,invalid_signature}},
       { "4.1.3", "Invalid EE Signature Test3",                    {bad_cert,invalid_signature}},
       { "4.1.4", "Valid DSA Signatures Test4",                    ok},
       { "4.1.5", "Valid DSA Parameter Inheritance Test5",         ok},
       { "4.1.6", "Invalid DSA Signature Test6",                   {bad_cert,invalid_signature}}].
  validity_periods() ->
      %% { "4.2",   "Validity Periods" },
      [{ "4.2.1", "Invalid CA notBefore Date Test1",               {bad_cert, cert_expired}},
       { "4.2.2", "Invalid EE notBefore Date Test2",               {bad_cert, cert_expired}},
       { "4.2.3", "Valid pre2000 UTC notBefore Date Test3",        ok},
       { "4.2.4", "Valid GeneralizedTime notBefore Date Test4",    ok},
       { "4.2.5", "Invalid CA notAfter Date Test5",                {bad_cert, cert_expired}},
       { "4.2.6", "Invalid EE notAfter Date Test6",                {bad_cert, cert_expired}},
       { "4.2.7", "Invalid pre2000 UTC EE notAfter Date Test7",    {bad_cert, cert_expired}},
       { "4.2.8", "Valid GeneralizedTime notAfter Date Test8",     ok}].
  verifying_name_chaining() ->
      %%{ "4.3",   "Verifying Name Chaining" },
      [{ "4.3.1", "Invalid Name Chaining EE Test1",                {bad_cert, invalid_issuer}},
       { "4.3.2", "Invalid Name Chaining Order Test2",             {bad_cert, invalid_issuer}},
       { "4.3.3", "Valid Name Chaining Whitespace Test3",          ok},
       { "4.3.4", "Valid Name Chaining Whitespace Test4",          ok},
       { "4.3.5", "Valid Name Chaining Capitalization Test5",      ok},
       { "4.3.6", "Valid Name Chaining UIDs Test6",                ok},
       { "4.3.7", "Valid RFC3280 Mandatory Attribute Types Test7", ok},
       { "4.3.8", "Valid RFC3280 Optional Attribute Types Test8",  ok},
       { "4.3.9", "Valid UTF8String Encoded Names Test9",          ok},
       { "4.3.10", "Valid Rollover from PrintableString to UTF8String Test10", ok},
       { "4.3.11", "Valid UTF8String Case Insensitive Match Test11",           ok}].
  basic_certificate_revocation_tests() ->
      %%{ "4.4",    "Basic Certificate Revocation Tests" },
      [{ "4.4.1",  "Missing CRL Test1",                 3 },
       { "4.4.2", "Invalid Revoked CA Test2",          23 },
       { "4.4.3", "Invalid Revoked EE Test3",          23 },
       { "4.4.4", "Invalid Bad CRL Signature Test4",   8 },
       { "4.4.5", "Invalid Bad CRL Issuer Name Test5", 3 },
       { "4.4.6", "Invalid Wrong CRL Test6",           3 },
       { "4.4.7", "Valid Two CRLs Test7",              ok},
  
       %% The test document suggests these should return certificate revoked...
       %% Subsquent discussion has concluded they should not due to unhandle
       %% critical CRL extensions.
       { "4.4.8", "Invalid Unknown CRL Entry Extension Test8", 36 },
       { "4.4.9", "Invalid Unknown CRL Extension Test9",       36 },
  
       { "4.4.10", "Invalid Unknown CRL Extension Test10",             36 },
       { "4.4.11", "Invalid Old CRL nextUpdate Test11",                12 },
       { "4.4.12", "Invalid pre2000 CRL nextUpdate Test12",            12 },
       { "4.4.13", "Valid GeneralizedTime CRL nextUpdate Test13",      ok},
       { "4.4.14", "Valid Negative Serial Number Test14",              ok},
       { "4.4.15", "Invalid Negative Serial Number Test15",            23 },
       { "4.4.16", "Valid Long Serial Number Test16",                  ok},
       { "4.4.17", "Valid Long Serial Number Test17",                  ok},
       { "4.4.18", "Invalid Long Serial Number Test18",                23 },
       { "4.4.19", "Valid Separate Certificate and CRL Keys Test19",   ok},
       { "4.4.20", "Invalid Separate Certificate and CRL Keys Test20", 23 },
  
       %% CRL path is revoked so get a CRL path validation error
       { "4.4.21", "Invalid Separate Certificate and CRL Keys Test21",      54 }].
  verifying_paths_with_self_issued_certificates() ->
      %%{ "4.5",    "Verifying Paths with Self-Issued Certificates" },
      [{ "4.5.1",  "Valid Basic Self-Issued Old With New Test1",            ok},
       %%{ "4.5.2",  "Invalid Basic Self-Issued Old With New Test2",          23 },
       %%{ "4.5.3",  "Valid Basic Self-Issued New With Old Test3",            ok},
       %%{ "4.5.4",  "Valid Basic Self-Issued New With Old Test4",            ok},
       { "4.5.5",  "Invalid Basic Self-Issued New With Old Test5",          23 },
       %%{ "4.5.6",  "Valid Basic Self-Issued CRL Signing Key Test6",         ok},
       { "4.5.7",  "Invalid Basic Self-Issued CRL Signing Key Test7",       23 },
       { "4.5.8",  "Invalid Basic Self-Issued CRL Signing Key Test8",       {bad_cert,invalid_key_usage} }].
  verifying_basic_constraints() ->
      [%%{ "4.6",    "Verifying Basic Constraints" },
       { "4.6.1",  "Invalid Missing basicConstraints Test1",                
         {bad_cert, missing_basic_constraint} },
       { "4.6.2",  "Invalid cA False Test2",                                {bad_cert, missing_basic_constraint}},
       { "4.6.3",  "Invalid cA False Test3",                                {bad_cert, missing_basic_constraint}},
       { "4.6.4",  "Valid basicConstraints Not Critical Test4",             ok},
       { "4.6.5",  "Invalid pathLenConstraint Test5",                       {bad_cert, max_path_length_reached}},
       { "4.6.6",  "Invalid pathLenConstraint Test6",                       {bad_cert, max_path_length_reached}},
       { "4.6.7",  "Valid pathLenConstraint Test7",                         ok},
       { "4.6.8",  "Valid pathLenConstraint Test8",                         ok},
       { "4.6.9",  "Invalid pathLenConstraint Test9",                       {bad_cert, max_path_length_reached}},
       { "4.6.10", "Invalid pathLenConstraint Test10",                      {bad_cert, max_path_length_reached}},
       { "4.6.11", "Invalid pathLenConstraint Test11",                      {bad_cert, max_path_length_reached}},
       { "4.6.12", "Invalid pathLenConstraint Test12",                      {bad_cert, max_path_length_reached}},
       { "4.6.13", "Valid pathLenConstraint Test13",                        ok},
       { "4.6.14", "Valid pathLenConstraint Test14",                        ok},
       { "4.6.15", "Valid Self-Issued pathLenConstraint Test15",            ok},
       { "4.6.16", "Invalid Self-Issued pathLenConstraint Test16",          {bad_cert, max_path_length_reached}},
       { "4.6.17", "Valid Self-Issued pathLenConstraint Test17",            ok}].
  key_usage() ->
      %%{ "4.7",    "Key Usage" },
      [{ "4.7.1",  "Invalid keyUsage Critical keyCertSign False Test1",     {bad_cert,invalid_key_usage} },
       { "4.7.2",  "Invalid keyUsage Not Critical keyCertSign False Test2", {bad_cert,invalid_key_usage} },
       { "4.7.3",  "Valid keyUsage Not Critical Test3",                     ok}
       %%,{ "4.7.4",  "Invalid keyUsage Critical cRLSign False Test4",         35 }
       %%,{ "4.7.5",  "Invalid keyUsage Not Critical cRLSign False Test5",     35 }
      ].
  
  %% Certificate policy tests need special handling. They can have several
  %% sub tests and we need to check the outputs are correct.
  
negative.code:      {"4.12.8",  "Invalid Self-Issued inhibitAnyPolicy Test8",    43 },
       {"4.12.9",  "Valid Self-Issued inhibitAnyPolicy Test9",      ok},
       {"4.12.10", "Invalid Self-Issued inhibitAnyPolicy Test10",   43 }].
  