1: %%
    2: %% %CopyrightBegin%
    3: %% 
    4: %% Copyright Ericsson AB 2008-2013. All Rights Reserved.
    5: %% 
    6: %% The contents of this file are subject to the Erlang Public License,
    7: %% Version 1.1, (the "License"); you may not use this file except in
    8: %% compliance with the License. You should have received a copy of the
    9: %% Erlang Public License along with this software. If not, it can be
   10: %% retrieved online at http://www.erlang.org/.
   11: %% 
   12: %% Software distributed under the License is distributed on an "AS IS"
   13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
   14: %% the License for the specific language governing rights and limitations
   15: %% under the License.
   16: %% 
   17: %% %CopyrightEnd%
   18: %%
   19: 
   20: 
   21: %%  Se specification here:
   22: %%  http://csrc.nist.gov/groups/ST/crypto_apps_infra/pki/pkitesting.html
   23: 
   24: -module(pkits_SUITE).
   25: 
   26: -include_lib("public_key/include/public_key.hrl").
   27: 
   28: %% Note: This directive should only be used in test suites.
   29: -compile(export_all).
   30: 
   31: -define(error(Format,Args), error(Format,Args,?FILE,?LINE)).
   32: -define(warning(Format,Args), warning(Format,Args,?FILE,?LINE)).
   33: 
   34: -define(CERTS, "pkits/certs").
   35: -define(MIME,  "pkits/smime").
   36: -define(CONV,  "pkits/smime-pem").
   37: -define(CRL,   "pkits/crls").
   38: 
   39: -define(NIST1, "2.16.840.1.101.3.2.1.48.1").
   40: -define(NIST2, "2.16.840.1.101.3.2.1.48.2").
   41: -define(NIST3, "2.16.840.1.101.3.2.1.48.3").
   42: -define(NIST4, "2.16.840.1.101.3.2.1.48.4").
   43: -define(NIST5, "2.16.840.1.101.3.2.1.48.5").
   44: -define(NIST6, "2.16.840.1.101.3.2.1.48.6").
   45: 
   46: -record(verify_state, {
   47: 	  crls,
   48: 	  crl_paths,
   49: 	  revoke_state}).
   50: %%--------------------------------------------------------------------
   51: %% Common Test interface functions -----------------------------------
   52: %%--------------------------------------------------------------------
   53: 
   54: suite() ->
   55:     [{ct_hooks,[ts_install_cth]}].
   56: 
   57: all() -> 
   58:     [{group, signature_verification},
   59:      {group, validity_periods},
   60:      {group, verifying_name_chaining},
   61:      {group, verifying_paths_with_self_issued_certificates},
   62:      {group, basic_certificate_revocation_tests},
   63:      {group, delta_crls},
   64:      {group, distribution_points},
   65:      {group, verifying_basic_constraints},
   66:      {group, key_usage},
   67:      {group, name_constraints},
   68:      {group, private_certificate_extensions}].
   69: 
   70: groups() -> 
   71:     [{signature_verification, [], [valid_rsa_signature,
   72: 				   invalid_rsa_signature, valid_dsa_signature,
   73: 				   invalid_dsa_signature]},
   74:      {validity_periods, [],
   75:       [not_before_invalid, not_before_valid, not_after_invalid, not_after_valid]},
   76:      {verifying_name_chaining, [],
   77:       [invalid_name_chain, whitespace_name_chain, capitalization_name_chain,
   78:        uid_name_chain, attrib_name_chain, string_name_chain]},
   79:      {verifying_paths_with_self_issued_certificates, [],
   80:       [basic_valid, basic_invalid, crl_signing_valid, crl_signing_invalid]},
   81:      {basic_certificate_revocation_tests, [],
   82:       [missing_CRL,
   83:        revoked_CA,
   84:        revoked_peer,
   85:        invalid_CRL_signature,
   86:        invalid_CRL_issuer, invalid_CRL, valid_CRL,
   87:        unknown_CRL_extension, old_CRL, fresh_CRL, valid_serial,
   88:        invalid_serial, valid_seperate_keys, invalid_separate_keys]},
   89:      {delta_crls, [], [delta_without_crl, valid_delta_crls, invalid_delta_crls]},
   90:      {distribution_points, [], [valid_distribution_points,
   91: 				valid_distribution_points_no_issuing_distribution_point,
   92: 				invalid_distribution_points, valid_only_contains,
   93: 				invalid_only_contains, valid_only_some_reasons,
   94: 				invalid_only_some_reasons, valid_indirect_crl,
   95: 				invalid_indirect_crl, valid_crl_issuer, invalid_crl_issuer]},
   96:      {verifying_basic_constraints,[],
   97:       [missing_basic_constraints, valid_basic_constraint, invalid_path_constraints,
   98:        valid_path_constraints]},
   99:      {key_usage, [],
  100:       [invalid_key_usage, valid_key_usage]},
  101:      {name_constraints, [],
  102:       [valid_DN_name_constraints, invalid_DN_name_constraints,
  103:        valid_rfc822_name_constraints,
  104:        invalid_rfc822_name_constraints, valid_DN_and_rfc822_name_constraints,
  105:        invalid_DN_and_rfc822_name_constraints, valid_dns_name_constraints,
  106:        invalid_dns_name_constraints, valid_uri_name_constraints,
  107:        invalid_uri_name_constraints]},
  108:      {private_certificate_extensions, [],
  109:       [unknown_critical_extension, unknown_not_critical_extension]}
  110:     ].
  111: 
  112: %%--------------------------------------------------------------------
  113: init_per_suite(Config) ->
  114:     application:stop(crypto),
  115:     try crypto:start() of
  116: 	ok ->
  117: 	    application:start(asn1),
  118: 	    crypto_support_check(Config)
  119:     catch _:_ ->
  120: 	    {skip, "Crypto did not start"}
  121:     end.
  122: 
  123: end_per_suite(_Config) ->
  124:     application:stop(asn1),
  125:     application:stop(crypto).
  126: 
  127: %%--------------------------------------------------------------------
  128: init_per_group(_GroupName, Config) ->
  129:     Config.
  130: 
  131: end_per_group(_GroupName, Config) ->
  132:     Config.
  133: %%--------------------------------------------------------------------
  134: init_per_testcase(_Func, Config) ->
  135:     Datadir = proplists:get_value(data_dir, Config),
  136:     put(datadir, Datadir),
  137:     Config.
  138: 
  139: end_per_testcase(_Func, Config) ->
  140:     Config.
  141: 
  142: %%--------------------------------------------------------------------
  143: %% Test Cases --------------------------------------------------------
  144: %%--------------------------------------------------------------------
  145: 
  146: %%--------------------------- signature_verification--------------------------------------------------
  147: valid_rsa_signature() ->
  148:     [{doc, "Test rsa signatur verification"}].
  149: valid_rsa_signature(Config) when is_list(Config) ->
  150:     run([{ "4.1.1", "Valid Certificate Path Test1 EE", ok}]).
  151: 
  152: invalid_rsa_signature() ->
  153:     [{doc,"Test rsa signatur verification"}].
  154: invalid_rsa_signature(Config) when is_list(Config) ->
  155:     run([{ "4.1.2", "Invalid CA Signature Test2 EE", {bad_cert,invalid_signature}},
  156: 	 { "4.1.3", "Invalid EE Signature Test3 EE", {bad_cert,invalid_signature}}]).
  157: 
  158: valid_dsa_signature() ->
  159:     [{doc,"Test dsa signatur verification"}].
  160: valid_dsa_signature(Config) when is_list(Config) ->
  161:     run([{ "4.1.4", "Valid DSA Signatures Test4 EE", ok},
  162: 	 { "4.1.5", "Valid DSA Parameter Inheritance Test5 EE", ok}]).
  163: 
  164: invalid_dsa_signature() ->
  165:     [{doc,"Test dsa signatur verification"}].
  166: invalid_dsa_signature(Config) when is_list(Config) ->
  167:     run([{ "4.1.6", "Invalid DSA Signature Test6 EE",{bad_cert,invalid_signature}}]).
  168: 
  169: %%-----------------------------validity_periods------------------------------------------------
  170: not_before_invalid() ->
  171:     [{doc,"Test valid periods"}].
  172: not_before_invalid(Config) when is_list(Config) ->
  173:     run([{ "4.2.1", "Invalid CA notBefore Date Test1 EE",{bad_cert, cert_expired}},
  174: 	 { "4.2.2", "Invalid EE notBefore Date Test2 EE",{bad_cert, cert_expired}}]).
  175: 
  176: not_before_valid() ->
  177:     [{doc,"Test valid periods"}].
  178: not_before_valid(Config) when is_list(Config) ->
  179:     run([{ "4.2.3", "Valid pre2000 UTC notBefore Date Test3 EE", ok},
  180: 	 { "4.2.4", "Valid GeneralizedTime notBefore Date Test4 EE", ok}]).
  181: 
  182: not_after_invalid() ->
  183:     [{doc,"Test valid periods"}].
  184: not_after_invalid(Config) when is_list(Config) ->
  185:     run([{ "4.2.5", "Invalid CA notAfter Date Test5 EE", {bad_cert, cert_expired}},
  186: 	 { "4.2.6", "Invalid EE notAfter Date Test6 EE", {bad_cert, cert_expired}},
  187: 	 { "4.2.7", "Invalid pre2000 UTC EE notAfter Date Test7 EE",{bad_cert, cert_expired}}]).
  188: 
  189: not_after_valid() ->
  190:     [{doc,"Test valid periods"}].
  191: not_after_valid(Config) when is_list(Config) ->
  192:     run([{ "4.2.8", "Valid GeneralizedTime notAfter Date Test8 EE", ok}]).
  193: 
  194: %%----------------------------verifying_name_chaining-------------------------------------------------
  195: invalid_name_chain() ->
  196:     [{doc,"Test name chaining"}].
  197: invalid_name_chain(Config) when is_list(Config) ->
  198:     run([{ "4.3.1", "Invalid Name Chaining Test1 EE", {bad_cert, invalid_issuer}},
  199: 	 { "4.3.2", "Invalid Name Chaining Order Test2 EE", {bad_cert, invalid_issuer}}]).
  200: 
  201: whitespace_name_chain() ->
  202:     [{doc,"Test name chaining"}].
  203: whitespace_name_chain(Config) when is_list(Config) ->
  204:     run([{ "4.3.3", "Valid Name Chaining Whitespace Test3 EE", ok},
  205: 	 { "4.3.4", "Valid Name Chaining Whitespace Test4 EE", ok}]).
  206: 
  207: capitalization_name_chain() ->
  208:     [{doc,"Test name chaining"}].
  209: capitalization_name_chain(Config) when is_list(Config) ->
  210:     run([{ "4.3.5", "Valid Name Chaining Capitalization Test5 EE",ok}]).
  211: 
  212: uid_name_chain() ->
  213:     [{doc,"Test name chaining"}].
  214: uid_name_chain(Config) when is_list(Config) ->
  215:     run([{ "4.3.6", "Valid Name UIDs Test6 EE",ok}]).
  216: 
  217: attrib_name_chain() ->
  218:     [{doc,"Test name chaining"}].
  219: attrib_name_chain(Config) when is_list(Config) ->
  220:     run([{ "4.3.7", "Valid RFC3280 Mandatory Attribute Types Test7 EE", ok},
  221: 	 { "4.3.8", "Valid RFC3280 Optional Attribute Types Test8 EE",  ok}]).
  222: 
  223: string_name_chain() ->
  224:     [{doc,"Test name chaining"}].
  225: string_name_chain(Config) when is_list(Config) ->
  226:     run([{ "4.3.9", "Valid UTF8String Encoded Names Test9 EE", ok},
  227: 	 %%{ "4.3.10", "Valid Rollover from PrintableString to UTF8String Test10 EE", ok},
  228: 	 { "4.3.11", "Valid UTF8String Case Insensitive Match Test11 EE", ok}]).
  229: 
  230: %%----------------------------verifying_paths_with_self_issued_certificates-------------------------------------------------
  231: basic_valid() ->
  232:     [{doc,"Test self issued certificates"}].
  233: basic_valid(Config) when is_list(Config) ->
  234:     run([{ "4.5.1",  "Valid Basic Self-Issued Old With New Test1 EE", ok},
  235: 	 { "4.5.3",  "Valid Basic Self-Issued New With Old Test3 EE", ok},
  236: 	 { "4.5.4",  "Valid Basic Self-Issued New With Old Test4 EE", ok}
  237: 	]).
  238: 
  239: basic_invalid() ->
  240:     [{doc,"Test self issued certificates"}].
  241: basic_invalid(Config) when is_list(Config) ->
  242:     run([{"4.5.2",  "Invalid Basic Self-Issued Old With New Test2 EE",
  243: 	  {bad_cert, {revoked, keyCompromise}}},
  244: 	 {"4.5.5",  "Invalid Basic Self-Issued New With Old Test5 EE",
  245: 	  {bad_cert, {revoked, keyCompromise}}}
  246: 	]).
  247: 
  248: crl_signing_valid() ->
  249:     [{doc,"Test self issued certificates"}].
  250: crl_signing_valid(Config) when is_list(Config) ->
  251:     run([{ "4.5.6",  "Valid Basic Self-Issued CRL Signing Key Test6 EE", ok}]).
  252: 
  253: crl_signing_invalid() ->
  254:     [{doc,"Test self issued certificates"}].
  255: crl_signing_invalid(Config) when is_list(Config) ->
  256:     run([{ "4.5.7",  "Invalid Basic Self-Issued CRL Signing Key Test7 EE",
  257: 	   {bad_cert, {revoked, keyCompromise}}},
  258: 	 { "4.5.8",  "Invalid Basic Self-Issued CRL Signing Key Test8 EE",
  259: 	   {bad_cert, invalid_key_usage}}
  260: 	]).
  261: 
  262: %%-----------------------------basic_certificate_revocation_tests------------------------------------------------
  263: missing_CRL() ->
  264:     [{doc,"Test basic CRL handling"}].
  265: missing_CRL(Config) when is_list(Config) ->
  266:     run([{ "4.4.1", "Invalid Missing CRL Test1 EE",{bad_cert,
  267:     revocation_status_undetermined}}]).
  268: 
  269: revoked_CA() ->
  270:     [{doc,"Test basic CRL handling"}].
  271: revoked_CA(Config) when is_list(Config) ->
  272:     run([{ "4.4.2", "Invalid Revoked CA Test2 EE", {bad_cert,
  273:     {revoked, keyCompromise}}}]).
  274: 
  275: revoked_peer() ->
  276:     [{doc,"Test basic CRL handling"}].
  277: revoked_peer(Config) when is_list(Config) ->
  278:     run([{ "4.4.3", "Invalid Revoked EE Test3 EE",
  279: 	   {bad_cert, {revoked, keyCompromise}}}]).
  280: 
  281: invalid_CRL_signature() ->
  282:     [{doc,"Test basic CRL handling"}].
  283: invalid_CRL_signature(Config) when is_list(Config) ->
  284:     run([{ "4.4.4", "Invalid Bad CRL Signature Test4 EE",
  285: 		   {bad_cert, revocation_status_undetermined}}]).
  286: invalid_CRL_issuer() ->
  287:     [{doc,"Test basic CRL handling"}].
  288: invalid_CRL_issuer(Config) when is_list(Config) ->
  289:     run({ "4.4.5", "Invalid Bad CRL Issuer Name Test5 EE",
  290: 	  {bad_cert, revocation_status_undetermined}}).
  291: 
  292: invalid_CRL() ->
  293:     [{doc,"Test basic CRL handling"}].
  294: invalid_CRL(Config) when is_list(Config) ->
  295:     run([{ "4.4.6", "Invalid Wrong CRL Test6 EE",
  296: 	   {bad_cert, revocation_status_undetermined}}]).
  297: 
  298: valid_CRL() ->
  299:     [{doc,"Test basic CRL handling"}].
  300: valid_CRL(Config) when is_list(Config) ->
  301:     run([{ "4.4.7", "Valid Two CRLs Test7 EE", ok}]).
  302: 
  303: unknown_CRL_extension() ->
  304:     [{doc,"Test basic CRL handling"}].
  305: unknown_CRL_extension(Config) when is_list(Config) ->
  306:     run([{ "4.4.8", "Invalid Unknown CRL Entry Extension Test8 EE",
  307: 	   {bad_cert, {revoked, keyCompromise}}},
  308: 	 { "4.4.9", "Invalid Unknown CRL Extension Test9 EE",
  309: 	   {bad_cert, {revoked, keyCompromise}}},
  310: 	 { "4.4.10", "Invalid Unknown CRL Extension Test10 EE",
  311: 	   {bad_cert, revocation_status_undetermined}}]).
  312: 
  313: old_CRL() ->
  314:     [{doc,"Test basic CRL handling"}].
  315: old_CRL(Config) when is_list(Config) ->
  316:     run([{ "4.4.11", "Invalid Old CRL nextUpdate Test11 EE",
  317: 	   {bad_cert, revocation_status_undetermined}},
  318: 	 { "4.4.12", "Invalid pre2000 CRL nextUpdate Test12 EE",
  319: 	   {bad_cert, revocation_status_undetermined}}]).
  320: 
  321: fresh_CRL() ->
  322:     [{doc,"Test basic CRL handling"}].
  323: fresh_CRL(Config) when is_list(Config) ->
  324:     run([{ "4.4.13", "Valid GeneralizedTime CRL nextUpdate Test13 EE", ok}]).
  325: 
  326: valid_serial() ->
  327:     [{doc,"Test basic CRL handling"}].
  328: valid_serial(Config) when is_list(Config) ->
  329:     run([
  330: 	 { "4.4.14", "Valid Negative Serial Number Test14 EE",ok},
  331: 	 { "4.4.16", "Valid Long Serial Number Test16 EE", ok},
  332: 	 { "4.4.17", "Valid Long Serial Number Test17 EE", ok}
  333: 	]).
  334: 
  335: invalid_serial() ->
  336:     [{doc,"Test basic CRL handling"}].
  337: invalid_serial(Config) when is_list(Config) ->
  338:     run([{ "4.4.15", "Invalid Negative Serial Number Test15 EE",
  339: 	   {bad_cert, {revoked, keyCompromise}}},
  340: 	 { "4.4.18", "Invalid Long Serial Number Test18 EE",
  341: 	   {bad_cert, {revoked, keyCompromise}}}]).
  342: 
  343: valid_seperate_keys() ->
  344:     [{doc,"Test basic CRL handling"}].
  345: valid_seperate_keys(Config) when is_list(Config) ->
  346:     run([{ "4.4.19", "Valid Separate Certificate and CRL Keys Test19 EE",   ok}]).
  347: 
  348: invalid_separate_keys() ->
  349:     [{doc,"Test basic CRL handling"}].
  350: invalid_separate_keys(Config) when is_list(Config) ->
  351:     run([{ "4.4.20", "Invalid Separate Certificate and CRL Keys Test20 EE",
  352: 	   {bad_cert, {revoked, keyCompromise}}},
  353: 	 { "4.4.21", "Invalid Separate Certificate and CRL Keys Test21 EE",
  354: 	   {bad_cert, revocation_status_undetermined}}
  355: 	]).
  356: %%----------------------------verifying_basic_constraints-------------------------------------------------
  357: missing_basic_constraints() ->
  358:     [{doc,"Basic constraint tests"}].
  359: missing_basic_constraints(Config) when is_list(Config) ->
  360:     run([{ "4.6.1",  "Invalid Missing basicConstraints Test1 EE",
  361: 	   {bad_cert, missing_basic_constraint}},
  362: 	 { "4.6.2",  "Invalid cA False Test2 EE",
  363: 	   {bad_cert, missing_basic_constraint}},
  364: 	 { "4.6.3",  "Invalid cA False Test3 EE",
  365: 	   {bad_cert, missing_basic_constraint}}]).
  366: 
  367: valid_basic_constraint() ->
  368:     [{doc,"Basic constraint tests"}].
  369: valid_basic_constraint(Config) when is_list(Config) ->
  370:     run([{"4.6.4", "Valid basicConstraints Not Critical Test4 EE", ok}]).
  371: 
  372: invalid_path_constraints() ->
  373:     [{doc,"Basic constraint tests"}].
  374: invalid_path_constraints(Config) when is_list(Config) ->
  375:     run([{ "4.6.5", "Invalid pathLenConstraint Test5 EE", {bad_cert, max_path_length_reached}},
  376: 	 { "4.6.6", "Invalid pathLenConstraint Test6 EE", {bad_cert, max_path_length_reached}},
  377: 	 { "4.6.9", "Invalid pathLenConstraint Test9 EE", {bad_cert, max_path_length_reached}},
  378: 	 { "4.6.10", "Invalid pathLenConstraint Test10 EE", {bad_cert, max_path_length_reached}},
  379: 	 { "4.6.11", "Invalid pathLenConstraint Test11 EE", {bad_cert, max_path_length_reached}},
  380: 	 { "4.6.12", "Invalid pathLenConstraint Test12 EE", {bad_cert, max_path_length_reached}},
  381: 	 { "4.6.16", "Invalid Self-Issued pathLenConstraint Test16 EE",
  382: 	   {bad_cert, max_path_length_reached}}]).
  383: 
  384: valid_path_constraints() ->
  385:     [{doc,"Basic constraint tests"}].
  386: valid_path_constraints(Config) when is_list(Config) ->
  387:     run([{ "4.6.7",  "Valid pathLenConstraint Test7 EE", ok},
  388: 	 { "4.6.8",  "Valid pathLenConstraint Test8 EE", ok},
  389: 	 { "4.6.13", "Valid pathLenConstraint Test13 EE", ok},
  390: 	 { "4.6.14", "Valid pathLenConstraint Test14 EE", ok},
  391: 	 { "4.6.15", "Valid Self-Issued pathLenConstraint Test15 EE", ok},
  392: 	 { "4.6.17", "Valid Self-Issued pathLenConstraint Test17 EE", ok}]).
  393: 
  394: %%-----------------------------key_usage------------------------------------------------
  395: invalid_key_usage() ->
  396:     [{doc,"Key usage tests"}].
  397: invalid_key_usage(Config) when is_list(Config) ->
  398:     run([{ "4.7.1",  "Invalid keyUsage Critical keyCertSign False Test1 EE",
  399: 	   {bad_cert,invalid_key_usage} },
  400: 	 { "4.7.2",  "Invalid keyUsage Not Critical keyCertSign False Test2 EE",
  401: 	   {bad_cert,invalid_key_usage}},
  402: 	 { "4.7.4",  "Invalid keyUsage Critical cRLSign False Test4 EE",
  403: 	   {bad_cert, invalid_key_usage}},
  404: 	 { "4.7.5",  "Invalid keyUsage Not Critical cRLSign False Test5 EE",
  405: 	   {bad_cert, invalid_key_usage}}
  406: 	]).
  407: 
  408: valid_key_usage() ->
  409:     [{doc,"Key usage tests"}].
  410: valid_key_usage(Config) when is_list(Config) ->
  411:     run([{ "4.7.3",  "Valid keyUsage Not Critical Test3 EE", ok}]).
  412: 
  413: %%-----------------------------------------------------------------------------
  414: certificate_policies() ->
  415:     [{doc,"Not supported yet"}].
  416: certificate_policies(Config) when is_list(Config) ->
  417:     run(certificate_policies_tests()).
  418: %%-----------------------------------------------------------------------------
  419: require_explicit_policy() ->
  420:     [{doc,"Not supported yet"}].
  421: require_explicit_policy(Config) when is_list(Config) ->
  422:     run(require_explicit_policy_tests()).
  423: %%-----------------------------------------------------------------------------
  424: policy_mappings() ->
  425:     [{doc,"Not supported yet"}].
  426: policy_mappings(Config) when is_list(Config) ->
  427:     run(policy_mappings_tests()).
  428: %%-----------------------------------------------------------------------------
  429: inhibit_policy_mapping() ->
  430:     [{doc,"Not supported yet"}].
  431: inhibit_policy_mapping(Config) when is_list(Config) ->
  432:     run(inhibit_policy_mapping_tests()).
  433: %%-----------------------------------------------------------------------------
  434: inhibit_any_policy() ->
  435:     [{doc,"Not supported yet"}].
  436: inhibit_any_policy(Config) when is_list(Config) ->
  437:     run(inhibit_any_policy_tests()).
  438: %%-------------------------------name_constraints----------------------------------------------
  439: 
  440: valid_DN_name_constraints() ->
  441:     [{doc, "Name constraints tests"}].
  442: valid_DN_name_constraints(Config) when is_list(Config) ->
  443:     run([{ "4.13.1",  "Valid DN nameConstraints Test1 EE", ok},
  444: 	 { "4.13.4",  "Valid DN nameConstraints Test4 EE", ok},
  445: 	 { "4.13.5",  "Valid DN nameConstraints Test5 EE", ok},
  446: 	 { "4.13.6",  "Valid DN nameConstraints Test6 EE", ok},
  447: 	 { "4.13.11", "Valid DN nameConstraints Test11 EE", ok},
  448: 	 { "4.13.14", "Valid DN nameConstraints Test14 EE", ok},
  449: 	 { "4.13.18", "Valid DN nameConstraints Test18 EE", ok},
  450: 	 { "4.13.19", "Valid DN nameConstraints Test19 EE", ok}]).
  451: 
  452: invalid_DN_name_constraints() ->
  453:     [{doc,"Name constraints tests"}].
  454: invalid_DN_name_constraints(Config) when is_list(Config) ->
  455:     run([{ "4.13.2", "Invalid DN nameConstraints Test2 EE", {bad_cert, name_not_permitted}},
  456: 	 { "4.13.3",  "Invalid DN nameConstraints Test3 EE", {bad_cert, name_not_permitted}},
  457: 	 { "4.13.7",  "Invalid DN nameConstraints Test7 EE", {bad_cert, name_not_permitted}},
  458: 	 { "4.13.8",  "Invalid DN nameConstraints Test8 EE", {bad_cert, name_not_permitted}},
  459: 	 { "4.13.9",  "Invalid DN nameConstraints Test9 EE", {bad_cert, name_not_permitted}},
  460: 	 { "4.13.10", "Invalid DN nameConstraints Test10 EE",{bad_cert, name_not_permitted}},
  461: 	 { "4.13.12", "Invalid DN nameConstraints Test12 EE",{bad_cert, name_not_permitted}},
  462: 	 { "4.13.13", "Invalid DN nameConstraints Test13 EE",{bad_cert, name_not_permitted}},
  463: 	 { "4.13.15", "Invalid DN nameConstraints Test15 EE",{bad_cert, name_not_permitted}},
  464: 	 { "4.13.16", "Invalid DN nameConstraints Test16 EE",{bad_cert, name_not_permitted}},
  465: 	 { "4.13.17", "Invalid DN nameConstraints Test17 EE",{bad_cert, name_not_permitted}},
  466: 	 { "4.13.20", "Invalid DN nameConstraints Test20 EE",
  467: 	   {bad_cert, name_not_permitted}}]).
  468: 
  469: valid_rfc822_name_constraints() ->
  470:     [{doc,"Name constraints tests"}].
  471: valid_rfc822_name_constraints(Config) when is_list(Config) ->
  472:     run([{ "4.13.21", "Valid RFC822 nameConstraints Test21 EE", ok},
  473: 	 { "4.13.23", "Valid RFC822 nameConstraints Test23 EE", ok},
  474: 	 { "4.13.25", "Valid RFC822 nameConstraints Test25 EE", ok}]).
  475: 
  476: invalid_rfc822_name_constraints() ->
  477:     [{doc,"Name constraints tests"}].
  478: invalid_rfc822_name_constraints(Config) when is_list(Config) ->
  479:     run([{ "4.13.22", "Invalid RFC822 nameConstraints Test22 EE",
  480: 	   {bad_cert, name_not_permitted}},
  481: 	 { "4.13.24", "Invalid RFC822 nameConstraints Test24 EE",
  482: 	   {bad_cert, name_not_permitted}},
  483: 	 { "4.13.26", "Invalid RFC822 nameConstraints Test26 EE",
  484: 	   {bad_cert, name_not_permitted}}]).
  485: 
  486: valid_DN_and_rfc822_name_constraints() ->
  487:     [{doc,"Name constraints tests"}].
  488: valid_DN_and_rfc822_name_constraints(Config) when is_list(Config) ->
  489:     run([{ "4.13.27", "Valid DN and RFC822 nameConstraints Test27 EE", ok}]).
  490: 
  491: invalid_DN_and_rfc822_name_constraints() ->
  492:     [{doc,"Name constraints tests"}].
  493: invalid_DN_and_rfc822_name_constraints(Config) when is_list(Config) ->
  494:     run([{ "4.13.28", "Invalid DN and RFC822 nameConstraints Test28 EE",
  495: 	   {bad_cert, name_not_permitted}},
  496: 	 { "4.13.29", "Invalid DN and RFC822 nameConstraints Test29 EE",
  497: 	   {bad_cert, name_not_permitted}}]).
  498: 
  499: valid_dns_name_constraints() ->
  500:     [{doc,"Name constraints tests"}].
  501: valid_dns_name_constraints(Config) when is_list(Config) ->
  502:     run([{ "4.13.30", "Valid DNS nameConstraints Test30 EE", ok},
  503: 	 { "4.13.32", "Valid DNS nameConstraints Test32 EE", ok}]).
  504: 
  505: invalid_dns_name_constraints() ->
  506:     [{doc,"Name constraints tests"}].
  507: invalid_dns_name_constraints(Config) when is_list(Config) ->
  508:     run([{ "4.13.31", "Invalid DNS nameConstraints Test31 EE", {bad_cert, name_not_permitted}},
  509: 	 { "4.13.33", "Invalid DNS nameConstraints Test33 EE", {bad_cert, name_not_permitted}},
  510: 	 { "4.13.38", "Invalid DNS nameConstraints Test38 EE", {bad_cert, name_not_permitted}}]).
  511: 
  512: valid_uri_name_constraints() ->
  513:     [{doc,"Name constraints tests"}].
  514: valid_uri_name_constraints(Config) when is_list(Config) ->
  515:     run([{ "4.13.34", "Valid URI nameConstraints Test34 EE", ok},
  516: 	 { "4.13.36", "Valid URI nameConstraints Test36 EE", ok}]).
  517: 
  518: invalid_uri_name_constraints() ->
  519:     [{doc,"Name constraints tests"}].
  520: invalid_uri_name_constraints(Config) when is_list(Config) ->
  521:     run([{ "4.13.35", "Invalid URI nameConstraints Test35 EE",{bad_cert, name_not_permitted}},
  522: 	 { "4.13.37", "Invalid URI nameConstraints Test37 EE",{bad_cert, name_not_permitted}}]).
  523: 
  524: %%------------------------------delta_crls-----------------------------------------------
  525: delta_without_crl() ->
  526:     [{doc,"Delta CRL tests"}].
  527: delta_without_crl(Config) when is_list(Config) ->
  528:   run([{ "4.15.1",  "Invalid deltaCRLIndicator No Base Test1 EE",{bad_cert,
  529: 							       revocation_status_undetermined}},
  530:        {"4.15.10", "Invalid delta-CRL Test10 EE", {bad_cert,
  531: 						   revocation_status_undetermined}}]).
  532: valid_delta_crls() ->
  533:     [{doc,"Delta CRL tests"}].
  534: valid_delta_crls(Config) when is_list(Config) ->
  535:     run([{ "4.15.2",  "Valid delta-CRL Test2 EE", ok},
  536: 	 { "4.15.5",  "Valid delta-CRL Test5 EE", ok},
  537: 	 { "4.15.7",  "Valid delta-CRL Test7 EE", ok},
  538: 	 { "4.15.8",  "Valid delta-CRL Test8 EE", ok}
  539: 	]).
  540: 
  541: invalid_delta_crls() ->
  542:     [{doc,"Delta CRL tests"}].
  543: invalid_delta_crls(Config) when is_list(Config) ->
  544:     run([{ "4.15.3",  "Invalid delta-CRL Test3 EE", {bad_cert,{revoked, keyCompromise}}},
  545: 	 { "4.15.4",  "Invalid delta-CRL Test4 EE", {bad_cert,{revoked, keyCompromise}}},
  546: 	 { "4.15.6",  "Invalid delta-CRL Test6 EE", {bad_cert,{revoked, keyCompromise}}},
  547: 	 { "4.15.9",  "Invalid delta-CRL Test9 EE", {bad_cert,{revoked, keyCompromise}}}]).
  548: 
  549: %%---------------------------distribution_points--------------------------------------------------
  550: valid_distribution_points() ->
  551:     [{doc,"CRL Distribution Point tests"}].
  552: valid_distribution_points(Config) when is_list(Config) ->
  553:     run([{ "4.14.1",  "Valid distributionPoint Test1 EE", ok},
  554: 	 { "4.14.4",  "Valid distributionPoint Test4 EE", ok},
  555: 	 { "4.14.5",  "Valid distributionPoint Test5 EE", ok},
  556: 	 { "4.14.7",  "Valid distributionPoint Test7 EE", ok}
  557: 	]).
  558: 
  559: valid_distribution_points_no_issuing_distribution_point() ->
  560:     [{doc,"CRL Distribution Point tests"}].
  561: valid_distribution_points_no_issuing_distribution_point(Config) when is_list(Config) ->
  562:     run([{ "4.14.10", "Valid No issuingDistributionPoint Test10 EE", ok}
  563: 	]).
  564: 
  565: invalid_distribution_points() ->
  566:     [{doc,"CRL Distribution Point tests"}].
  567: invalid_distribution_points(Config) when is_list(Config) ->
  568:     run([{ "4.14.2",  "Invalid distributionPoint Test2 EE", {bad_cert,{revoked, keyCompromise}}},
  569: 	 { "4.14.3",  "Invalid distributionPoint Test3 EE", {bad_cert,
  570: 							  revocation_status_undetermined}},
  571: 	 { "4.14.6",  "Invalid distributionPoint Test6 EE", {bad_cert,{revoked, keyCompromise}}},
  572: 	 { "4.14.8",  "Invalid distributionPoint Test8 EE", {bad_cert,
  573: 							  revocation_status_undetermined}},
  574: 	 { "4.14.9",  "Invalid distributionPoint Test9 EE", {bad_cert,
  575: 							  revocation_status_undetermined}}
  576: 	]).
  577: 
  578: valid_only_contains() ->
  579:     [{doc,"CRL Distribution Point tests"}].
  580: valid_only_contains(Config) when is_list(Config) ->
  581:     run([{ "4.14.13", "Valid only Contains CA Certs Test13 EE", ok}]).
  582: 
  583: invalid_only_contains() ->
  584:     [{doc,"CRL Distribution Point tests"}].
  585: invalid_only_contains(Config) when is_list(Config) ->
  586:     run([{ "4.14.11", "Invalid onlyContainsUserCerts Test11 EE",
  587: 	   {bad_cert, revocation_status_undetermined}},
  588: 	 { "4.14.12", "Invalid onlyContainsCACerts Test12 EE",
  589: 	   {bad_cert, revocation_status_undetermined}},
  590: 	 { "4.14.14", "Invalid onlyContainsAttributeCerts Test14 EE",
  591: 	   {bad_cert, revocation_status_undetermined}}
  592: 	]).
  593: 
  594: valid_only_some_reasons() ->
  595:     [{doc,"CRL Distribution Point tests"}].
  596: valid_only_some_reasons(Config) when is_list(Config) ->
  597:     run([{ "4.14.18", "Valid onlySomeReasons Test18 EE", ok},
  598: 	 { "4.14.19", "Valid onlySomeReasons Test19 EE", ok}
  599: 	]).
  600: 
  601: invalid_only_some_reasons() ->
  602:     [{doc,"CRL Distribution Point tests"}].
  603: invalid_only_some_reasons(Config) when is_list(Config) ->
  604:     run([{ "4.14.15", "Invalid onlySomeReasons Test15 EE",
  605: 	   {bad_cert,{revoked, keyCompromise}}},
  606: 	 { "4.14.16", "Invalid onlySomeReasons Test16 EE",
  607: 	   {bad_cert,{revoked, certificateHold}}},
  608: 	 { "4.14.17", "Invalid onlySomeReasons Test17 EE",
  609: 	   {bad_cert, revocation_status_undetermined}},
  610: 	 { "4.14.20", "Invalid onlySomeReasons Test20 EE",
  611: 	   {bad_cert,{revoked, keyCompromise}}},
  612: 	 { "4.14.21", "Invalid onlySomeReasons Test21 EE",
  613: 	   {bad_cert,{revoked, affiliationChanged}}}
  614: 	]).
  615: 
  616: valid_indirect_crl() ->
  617:     [{doc,"CRL Distribution Point tests"}].
  618: valid_indirect_crl(Config) when is_list(Config) ->
  619:     run([{ "4.14.22", "Valid IDP with indirectCRL Test22 EE", ok},
  620: 	 { "4.14.24", "Valid IDP with indirectCRL Test24 EE", ok},
  621: 	 { "4.14.25", "Valid IDP with indirectCRL Test25 EE", ok}
  622: 	]).
  623: 
  624: invalid_indirect_crl() ->
  625:     [{doc,"CRL Distribution Point tests"}].
  626: invalid_indirect_crl(Config) when is_list(Config) ->
  627:     run([{ "4.14.23", "Invalid IDP with indirectCRL Test23 EE",
  628: 	   {bad_cert,{revoked, keyCompromise}}},
  629: 	 { "4.14.26", "Invalid IDP with indirectCRL Test26 EE",
  630: 	   {bad_cert, revocation_status_undetermined}}
  631: 	]).
  632: 
  633: valid_crl_issuer() ->
  634:     [{doc,"CRL Distribution Point tests"}].
  635: valid_crl_issuer(Config) when is_list(Config) ->
  636:     run([{ "4.14.28", "Valid cRLIssuer Test28 EE", ok},
  637: 	 { "4.14.29", "Valid cRLIssuer Test29 EE", ok},
  638: 	 { "4.14.33", "Valid cRLIssuer Test33 EE", ok}
  639: 	]).
  640: 
  641: invalid_crl_issuer() ->
  642:     [{doc,"CRL Distribution Point tests"}].
  643: invalid_crl_issuer(Config) when is_list(Config) ->
  644:     run([
  645: 	 { "4.14.27", "Invalid cRLIssuer Test27 EE", {bad_cert, revocation_status_undetermined}},
  646: 	 { "4.14.31", "Invalid cRLIssuer Test31 EE", {bad_cert,{revoked, keyCompromise}}},
  647: 	 { "4.14.32", "Invalid cRLIssuer Test32 EE", {bad_cert,{revoked, keyCompromise}}},
  648: 	 { "4.14.34", "Invalid cRLIssuer Test34 EE", {bad_cert,{revoked, keyCompromise}}},
  649: 	 { "4.14.35", "Invalid cRLIssuer Test35 EE", {bad_cert, revocation_status_undetermined}}
  650: 	]).
  651: 
  652: %% Although this test is valid it has a circular dependency. As a result
  653: %% an attempt is made to reursively checks a CRL path and rejected due to
  654: %% a CRL path validation error. PKITS notes suggest this test does not
  655: %% need to be run due to this issue.
  656: %%	 { "4.14.30", "Valid cRLIssuer Test30", 54 }
  657: 
  658: 
  659: %%-------------------------------private_certificate_extensions----------------------------------------------
  660: 
  661: unknown_critical_extension() ->
  662:     [{doc,"Test that a cert with an unknown critical extension is recjected"}].
  663: unknown_critical_extension(Config) when is_list(Config) ->
  664:     run([{ "4.16.2",  "Invalid Unknown Critical Certificate Extension Test2 EE",
  665: 	   {bad_cert,unknown_critical_extension}}]).
  666: 
  667: unknown_not_critical_extension() ->
  668:     [{doc,"Test that a not critical unknown extension is ignored"}].
  669: unknown_not_critical_extension(Config) when is_list(Config) ->
  670:     run([{ "4.16.1",  "Valid Unknown Not Critical Certificate Extension Test1 EE", ok}]).
  671: 
  672: %%--------------------------------------------------------------------
  673: %% Internal functions ------------------------------------------------
  674: %%--------------------------------------------------------------------
  675: 
  676: run(Tests) ->    
  677:     [TA] = read_certs("Trust Anchor Root Certificate"),
  678:     run(Tests, TA).
  679: 
  680: run({Chap, Test, Result}, TA) ->
  681:     CertChain = cas(Chap) ++ read_certs(Test),
  682:     Options = path_validation_options(TA, Chap,Test),
  683:     try public_key:pkix_path_validation(TA, CertChain, Options) of
  684: 	{Result, _} -> ok;
  685: 	{error,Result} when Result =/= ok ->
  686: 	    ok;
  687: 	{error, Error}  ->
  688: 	    ?error(" ~p ~p~n  Expected ~p got ~p ~n", [Chap, Test, Result, Error]),
  689: 	    fail;
  690: 	{ok, _OK} when Result =/= ok ->
  691: 	    ?error(" ~p ~p~n  Expected ~p got ~p ~n", [Chap, Test, Result, ok]),
  692: 	    fail
  693:     catch Type:Reason ->
  694: 	    Stack = erlang:get_stacktrace(),
  695: 	    io:format("Crash ~p:~p in ~p~n",[Type,Reason,Stack]),
  696: 	    io:format("   ~p ~p Expected ~p ~n", [Chap, Test, Result]),
  697:             exit(crash)
  698:     end;
  699: 
  700: run([Test|Rest],TA) ->
  701:     run(Test,TA),
  702:     run(Rest,TA);
  703: run([],_) -> ok.
  704: 
  705: path_validation_options(TA, Chap, Test) ->
  706:     case needs_crl_options(Chap) of
  707: 	true ->
  708: 	    crl_options(TA, Chap, Test);
  709: 	false ->
  710: 	     Fun =
  711: 		fun(_,{bad_cert, _} = Reason, _) ->
  712: 			{fail, Reason};
  713: 		   (_,{extension, _}, UserState) ->
  714: 			{unknown, UserState};
  715: 		   (_, Valid, UserState) when Valid == valid;
  716: 					      Valid == valid_peer ->
  717: 			{valid, UserState}
  718: 		 end,
  719: 	    [{verify_fun, {Fun, []}}]
  720:     end.
  721: 
  722: read_certs(Test) ->
  723:     File = cert_file(Test),
  724:     Ders = erl_make_certs:pem_to_der(File),
  725:     [Cert || {'Certificate', Cert, not_encrypted} <- Ders].
  726: 
  727: read_crls(Test) ->
  728:     File = crl_file(Test),
  729:     Ders = erl_make_certs:pem_to_der(File),
  730:     [CRL || {'CertificateList', CRL, not_encrypted} <- Ders].
  731: 
  732: cert_file(Test) ->
  733:     file(?CONV, lists:append(string:tokens(Test, " -")) ++ ".pem").
  734: 
  735: crl_file(Test) ->
  736:     file(?CRL, lists:append(string:tokens(Test, " -")) ++ ".pem").
  737: 
  738: 
  739: file(Sub,File) ->
  740:     TestDir = case get(datadir) of
  741: 		  undefined -> "./pkits_SUITE_data";
  742: 		  Dir when is_list(Dir) ->
  743: 		      Dir
  744: 	      end,
  745:     AbsFile = filename:join([TestDir,Sub,File]),
  746:     case filelib:is_file(AbsFile) of
  747: 	true -> ok;
  748: 	false ->
  749: 	    ?error("Couldn't read data from ~p ~n",[AbsFile])
  750:     end,
  751:     AbsFile.
  752: 
  753: error(Format, Args, File0, Line) ->
  754:     File = filename:basename(File0),
  755:     Pid = group_leader(),
  756:     Pid ! {failed, File, Line},
  757:     io:format(Pid, "~s(~p): ERROR"++Format, [File,Line|Args]).
  758: 
  759: warning(Format, Args, File0, Line) ->
  760:     File = filename:basename(File0),
  761:     io:format("~s(~p): Warning "++Format, [File,Line|Args]).
  762: 
  763: crypto_support_check(Config) ->
  764:     CryptoSupport = crypto:supports(),
  765:     Hashs = proplists:get_value(hashs, CryptoSupport),
  766:     case proplists:get_bool(sha256, Hashs) of
  767: 	true ->
  768: 	    Config;
  769: 	false ->
  770: 	    {skip, "To old version of openssl"}
  771:     end.
  772: 
  773: needs_crl_options("4.4" ++ _) ->
  774:     true;
  775: needs_crl_options("4.5" ++ _) ->
  776:     true;
  777: needs_crl_options("4.7.4" ++ _) ->
  778:     true;
  779: needs_crl_options("4.7.5" ++ _) ->
  780:     true;
  781: needs_crl_options("4.14" ++ _) ->
  782:     true;
  783: needs_crl_options("4.15" ++ _) ->
  784:     true;
  785: needs_crl_options(_) ->
  786:     false.
  787: 
  788: crl_options(_TA, Chap, _Test) ->
  789:     CRLNames = crl_names(Chap),
  790:     CRLs = crls(CRLNames),
  791:     Paths = lists:map(fun(CRLName) -> crl_path(CRLName) end, CRLNames),
  792: 
  793:     ct:print("Paths ~p ~n  Names ~p ~n", [Paths, CRLNames]),
  794:     Fun =
  795: 	fun(_,{bad_cert, _} = Reason, _) ->
  796: 		{fail, Reason};
  797: 	   (_,{extension,
  798: 	       #'Extension'{extnID = ?'id-ce-cRLDistributionPoints',
  799: 			    extnValue = Value}}, UserState0) ->
  800: 		UserState = update_crls(Value, UserState0),
  801: 		{valid, UserState};
  802: 	   (_,{extension, _}, UserState) ->
  803: 		{unknown, UserState};
  804: 	   (OtpCert, Valid, UserState) when Valid == valid;
  805: 					    Valid == valid_peer ->
  806: 		DerCRLs = UserState#verify_state.crls,
  807: 		Paths =  UserState#verify_state.crl_paths,
  808: 		Crls = [{DerCRL, public_key:der_decode('CertificateList',
  809: 						       DerCRL)} || DerCRL <- DerCRLs],
  810: 
  811: 		CRLInfo0 = crl_info(OtpCert, Crls, []),
  812: 		CRLInfo = lists:reverse(CRLInfo0),
  813: 		PathDb = crl_path_db(lists:reverse(Crls), Paths, []),
  814: 
  815: 		Fun = fun(DP, CRLtoValidate, Id, PathDb0) ->
  816: 			      trusted_cert_and_path(DP, CRLtoValidate, Id, PathDb0)
  817: 		      end,
  818: 
  819: 		case CRLInfo of
  820: 		    [] ->
  821: 			{valid, UserState};
  822: 		    [_|_] ->
  823: 			case public_key:pkix_crls_validate(OtpCert, CRLInfo,
  824: 							   [{issuer_fun,{Fun, PathDb}}]) of
  825: 			    valid ->
  826: 				{valid, UserState};
  827: 			    Reason  ->
  828: 				{fail, Reason}
  829: 			end
  830: 		end
  831: 	end,
  832: 
  833:     [{verify_fun, {Fun, #verify_state{crls = CRLs,
  834: 				      crl_paths = Paths}}}].
  835: 
  836: crl_path_db([], [], Acc) ->
  837:     Acc;
  838: crl_path_db([{_, CRL} |CRLs], [Path | Paths], Acc) ->
  839:     CertPath = lists:flatten(lists:map(fun([]) ->
  840: 					       [];
  841: 					  (CertFile) ->
  842: 					       ct:print("Certfile ~p", [CertFile]),
  843: 					       read_certs(CertFile)
  844: 				       end, Path)),
  845:     crl_path_db(CRLs, Paths, [{CRL, CertPath}| Acc]).
  846: 
  847: 
  848: crl_info(_, [], Acc) ->
  849:     Acc;
  850: crl_info(OtpCert, [{_, #'CertificateList'{tbsCertList =
  851: 						     #'TBSCertList'{issuer = Issuer,
  852: 								    crlExtensions = CRLExtensions}}}
  853: 				= CRL | Rest], Acc) ->
  854:     OtpTBSCert =  OtpCert#'OTPCertificate'.tbsCertificate,
  855:     Extensions = OtpTBSCert#'OTPTBSCertificate'.extensions,
  856:     ExtList = pubkey_cert:extensions_list(CRLExtensions),
  857:     DPs  = case pubkey_cert:select_extension(?'id-ce-cRLDistributionPoints', Extensions) of
  858: 	      #'Extension'{extnValue = Value} ->
  859: 		   lists:foldl(fun(Point, Acc0) ->
  860: 				       Dp = pubkey_cert_records:transform(Point, decode),
  861: 				       IDP = pubkey_cert:select_extension(?'id-ce-issuingDistributionPoint',
  862: 									  Extensions),
  863: 				       case Dp#'DistributionPoint'.cRLIssuer of
  864: 					   asn1_NOVALUE ->
  865: 					       [Dp | Acc0];
  866: 					   DpCRLIssuer ->
  867: 					       CRLIssuer = dp_crlissuer_to_issuer(DpCRLIssuer),
  868: 					       CertIssuer =  OtpTBSCert#'OTPTBSCertificate'.issuer,
  869: 					       case  pubkey_cert:is_issuer(CRLIssuer, CertIssuer) of
  870: 						   true ->
  871: 						       [Dp | Acc0];
  872: 						   false when (IDP =/= undefined) ->
  873: 						       Acc0;
  874: 						   false ->
  875: 						       [Dp | Acc0]
  876: 					       end
  877: 				       end
  878: 			       end, [], Value);
  879: 	       _ ->
  880: 		   case same_issuer(OtpCert, Issuer) of
  881: 		       true ->
  882: 			   [make_dp(ExtList, asn1_NOVALUE, Issuer)];
  883: 		       false ->
  884: 			   [make_dp(ExtList, Issuer, ignore)]
  885: 		   end
  886: 	   end,
  887:     DPsCRLs = lists:map(fun(DP) -> {DP, CRL} end, DPs),
  888:     crl_info(OtpCert, Rest, DPsCRLs ++ Acc).
  889: 
  890: same_issuer(OTPCert, Issuer) ->
  891:     DecIssuer = pubkey_cert_records:transform(Issuer, decode),
  892:     OTPTBSCert =  OTPCert#'OTPCertificate'.tbsCertificate,
  893:     CertIssuer =  OTPTBSCert#'OTPTBSCertificate'.issuer,
  894:     pubkey_cert:is_issuer(DecIssuer, CertIssuer).
  895: 
  896: make_dp(Extensions, Issuer0, DpInfo) ->
  897:     {Issuer, Point} = mk_issuer_dp(Issuer0, DpInfo),
  898:     case pubkey_cert:select_extension('id-ce-cRLReason', Extensions) of
  899: 	#'Extension'{extnValue = Reasons} ->
  900: 	    #'DistributionPoint'{cRLIssuer = Issuer,
  901: 				 reasons = Reasons,
  902: 				 distributionPoint = Point};
  903: 	_ ->
  904: 	    #'DistributionPoint'{cRLIssuer = Issuer,
  905: 				 reasons = [unspecified, keyCompromise,
  906: 					    cACompromise, affiliationChanged, superseded,
  907: 					    cessationOfOperation, certificateHold,
  908: 					    removeFromCRL, privilegeWithdrawn, aACompromise],
  909: 				 distributionPoint = Point}
  910:     end.
  911: 
  912: mk_issuer_dp(asn1_NOVALUE, Issuer) ->
  913:     {asn1_NOVALUE, {fullName, [{directoryName, Issuer}]}};
  914: mk_issuer_dp(Issuer, _) ->
  915:     {[{directoryName, Issuer}], asn1_NOVALUE}.
  916: 
  917: update_crls(_, State) ->
  918:     State.
  919: 
  920: trusted_cert_and_path(_, #'CertificateList'{} = CRL, _, PathDb) ->
  921:     [TrustedDERCert] =  read_certs(crl_root_cert()),
  922:     TrustedCert =  public_key:pkix_decode_cert(TrustedDERCert, otp),
  923: 
  924:     case lists:keysearch(CRL, 1, PathDb) of
  925: 	{_, {CRL, [ _| _] = Path}} ->
  926: 		      {ok, TrustedCert, [TrustedDERCert | Path]};
  927: 	{_, {CRL, []}} ->
  928: 	    {ok, TrustedCert, [TrustedDERCert]}
  929:     end.
  930: 
  931: 
  932: dp_crlissuer_to_issuer(DPCRLIssuer) ->
  933:     [{directoryName, Issuer}] = pubkey_cert_records:transform(DPCRLIssuer, decode),
  934:     Issuer.
  935: 
  936: %%%%%%%%%%%%%%% CA mappings %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  937: 
  938: cas(Chap) ->
  939:     CAS = intermidiate_cas(Chap),
  940:     lists:foldl(fun([], Acc) ->
  941: 			Acc;
  942: 		   (CA, Acc) -> 
  943: 			[CACert] = read_certs(CA),
  944: 			[CACert | Acc]
  945: 		end, [], CAS).
  946:  
  947: intermidiate_cas(Chap) when Chap == "4.1.1";
  948: 			    Chap == "4.1.3";
  949: 			    Chap == "4.2.2";
  950: 			    Chap == "4.2.3";
  951: 			    Chap == "4.2.4";
  952: 			    Chap == "4.2.6";
  953: 			    Chap == "4.2.7";
  954: 			    Chap == "4.2.8";
  955: 			    Chap == "4.3.1";
  956: 			    Chap == "4.3.3";
  957: 			    Chap == "4.3.4";
  958: 			    Chap == "4.3.5";
  959: 			    Chap == "4.4.3"
  960: 			    ->
  961:     ["Good CA Cert"];
  962: 
  963: intermidiate_cas(Chap) when Chap == "4.1.2" ->
  964:     ["Bad Signed CA Cert"];
  965: 
  966: intermidiate_cas(Chap) when Chap == "4.1.4";
  967: 			    Chap == "4.1.6" ->
  968:     ["DSA CA Cert"];
  969: 
  970: intermidiate_cas(Chap) when Chap == "4.1.5" ->
  971:     ["DSA Parameters Inherited CA Cert", "DSA CA Cert"];
  972: 
  973: intermidiate_cas(Chap) when Chap == "4.2.1";
  974: 			   Chap == "4.2.5" ->
  975:     ["Bad notBefore Date CA Cert"];
  976: 
  977: intermidiate_cas(Chap) when  Chap == "4.16.1";
  978: 			    Chap == "4.16.2" ->
  979:     ["Trust Anchor Root Certificate"];			    
  980: 
  981: intermidiate_cas(Chap) when Chap == "4.3.2" ->
  982:     ["Name Ordering CA Cert"];
  983: 
  984: intermidiate_cas(Chap) when Chap == "4.13.34";
  985: 			    Chap == "4.13.35" ->
  986:     ["nameConstraints URI1 CA Cert"];
  987: intermidiate_cas(Chap) when Chap == "4.13.36";
  988: 			   Chap == "4.13.37" ->
  989:     ["nameConstraints URI2 CA Cert"];
  990: 
  991: intermidiate_cas(Chap) when Chap == "4.13.30";
  992: 			    Chap == "4.13.31";
  993: 			    Chap == "4.13.38"
  994: 			    ->
  995:     ["nameConstraints DNS1 CA Cert"];
  996: 
  997: intermidiate_cas(Chap) when Chap == "4.13.32";
  998: 			   Chap == "4.13.33" ->
  999:     ["nameConstraints DNS2 CA Cert"];
 1000: 
 1001: intermidiate_cas(Chap) when Chap == "4.13.27";
 1002: 			    Chap == "4.13.28";
 1003: 			    Chap == "4.13.29" ->
 1004:     ["nameConstraints DN1 subCA3 Cert", 
 1005:      "nameConstraints DN1 CA Cert"];
 1006: 
 1007: intermidiate_cas(Chap) when Chap == "4.13.21";
 1008: 			    Chap == "4.13.22" ->
 1009:     ["nameConstraints RFC822 CA1 Cert"];
 1010: 
 1011: intermidiate_cas(Chap) when Chap == "4.13.23";
 1012: 			    Chap == "4.13.24" ->
 1013:     ["nameConstraints RFC822 CA2 Cert"];
 1014: 
 1015: intermidiate_cas(Chap) when Chap == "4.13.25";
 1016: 			    Chap == "4.13.26" ->
 1017:     ["nameConstraints RFC822 CA3 Cert"];
 1018: 
 1019: intermidiate_cas(Chap) when Chap == "4.6.1" ->
 1020:     ["Missing basicConstraints CA Cert"];
 1021: 
 1022: intermidiate_cas(Chap) when Chap == "4.6.2" ->
 1023:     ["basicConstraints Critical cA False CA Cert"];
 1024: 
 1025: intermidiate_cas(Chap) when Chap == "4.6.3" ->
 1026:     ["basicConstraints Not Critical cA False CA Cert"];
 1027: 
 1028: intermidiate_cas(Chap) when Chap == "4.5.1";
 1029: 			    Chap == "4.5.2" ->
 1030:     ["Basic Self-Issued New Key OldWithNew CA Cert", "Basic Self-Issued New Key CA Cert"];
 1031: 
 1032: intermidiate_cas(Chap) when	Chap == "4.5.3" ->
 1033:     ["Basic Self-Issued Old Key NewWithOld CA Cert", "Basic Self-Issued Old Key CA Cert"];
 1034: 
 1035: intermidiate_cas(Chap) when Chap == "4.5.4";
 1036: 			    Chap == "4.5.5" ->
 1037:     ["Basic Self-Issued Old Key CA Cert"];
 1038: 
 1039: intermidiate_cas(Chap) when Chap == "4.13.1"; 
 1040: 			    Chap == "4.13.2";
 1041: 			    Chap == "4.13.3";
 1042: 			    Chap == "4.13.4";
 1043: 			    Chap == "4.13.20"
 1044: 			    ->
 1045:     ["nameConstraints DN1 CA Cert"];
 1046: 
 1047: intermidiate_cas(Chap) when Chap == "4.13.5" ->
 1048:     ["nameConstraints DN2 CA Cert"];
 1049: 
 1050: intermidiate_cas(Chap) when Chap == "4.13.6";
 1051: 			    Chap == "4.13.7" ->
 1052:     ["nameConstraints DN3 CA Cert"];
 1053: 
 1054: intermidiate_cas(Chap) when Chap == "4.13.8";
 1055: 			    Chap == "4.13.9" ->
 1056:     ["nameConstraints DN4 CA Cert"];
 1057: 
 1058: intermidiate_cas(Chap) when Chap == "4.13.10";
 1059: 			    Chap == "4.13.11" ->
 1060:     ["nameConstraints DN5 CA Cert"];
 1061: 
 1062: intermidiate_cas(Chap) when Chap == "4.13.12" ->
 1063:     ["nameConstraints DN1 subCA1 Cert",
 1064:      "nameConstraints DN1 CA Cert"];
 1065: 
 1066: intermidiate_cas(Chap) when Chap == "4.13.13";
 1067: 			    Chap == "4.13.14" ->
 1068:     ["nameConstraints DN1 subCA2 Cert",
 1069:      "nameConstraints DN1 CA Cert"];
 1070: 
 1071: intermidiate_cas(Chap) when Chap == "4.13.15";
 1072: 			    Chap == "4.13.16" ->
 1073:     ["nameConstraints DN3 subCA1 Cert",
 1074:      "nameConstraints DN3 CA Cert"];
 1075: 
 1076: intermidiate_cas(Chap) when Chap == "4.13.17";
 1077: 			    Chap == "4.13.18" ->
 1078:     ["nameConstraints DN3 subCA2 Cert",
 1079:      "nameConstraints DN3 CA Cert"];
 1080: 
 1081: intermidiate_cas(Chap) when Chap == "4.13.19" ->
 1082:     ["nameConstraints DN1 Self-Issued CA Cert",
 1083:      "nameConstraints DN1 CA Cert"];
 1084: 
 1085: intermidiate_cas(Chap) when Chap == "4.7.1";
 1086: 			    Chap == "4.7.4" -> 
 1087:     ["keyUsage Critical keyCertSign False CA Cert"];
 1088: 
 1089: intermidiate_cas(Chap) when Chap == "4.7.2";
 1090: 			    Chap == "4.7.5" -> 
 1091:     ["keyUsage Not Critical keyCertSign False CA Cert"];
 1092: 
 1093: intermidiate_cas(Chap) when Chap == "4.7.3" -> 
 1094:     ["keyUsage Not Critical CA Cert"];
 1095: 
 1096: intermidiate_cas(Chap) when Chap == "4.3.7" -> 
 1097:     ["RFC3280 Mandatory Attribute Types CA Cert"];
 1098: intermidiate_cas(Chap) when Chap == "4.3.8" -> 
 1099:     ["RFC3280 Optional Attribute Types CA Cert"];
 1100: 
 1101: intermidiate_cas(Chap) when Chap == "4.3.6" -> 
 1102:     ["UIDCACert"];
 1103: 
 1104: intermidiate_cas(Chap) when Chap == "4.6.4" -> 
 1105:     ["basicConstraints Not Critical CA Cert"];
 1106: 
 1107: intermidiate_cas(Chap) when Chap == "4.1.26" -> 
 1108:     ["nameConstraints RFC822 CA3 Cert"];
 1109: 
 1110: intermidiate_cas(Chap) when Chap == "4.3.9" -> 
 1111:     ["UTF8String Encoded Names CA Cert"];
 1112: 
 1113: intermidiate_cas(Chap) when Chap == "4.3.10" -> 
 1114:     ["Rollover from PrintableString to UTF8String CA Cert"];
 1115: 
 1116: intermidiate_cas(Chap) when Chap == "4.3.11" -> 
 1117:     ["UTF8String Case Insensitive Match CA Cert"];
 1118: 
 1119: intermidiate_cas(Chap) when Chap == "4.6.7";
 1120: 			    Chap == "4.6.8"
 1121: 			    -> 
 1122:     ["pathLenConstraint0 CA Cert"];
 1123: intermidiate_cas(Chap) when Chap == "4.6.13" -> 
 1124:     [ "pathLenConstraint6 subsubsubCA41X Cert",
 1125:       "pathLenConstraint6 subsubCA41 Cert", 
 1126:       "pathLenConstraint6 subCA4 Cert", 
 1127:       "pathLenConstraint6 CA Cert"];
 1128: 
 1129: intermidiate_cas(Chap) when Chap == "4.6.14" -> 
 1130:     [ "pathLenConstraint6 subsubsubCA41X Cert",
 1131:       "pathLenConstraint6 subsubCA41 Cert", 
 1132:       "pathLenConstraint6 subCA4 Cert", 
 1133:       "pathLenConstraint6 CA Cert"];
 1134: 
 1135: intermidiate_cas(Chap) when Chap == "4.6.15" -> 
 1136:      [ "pathLenConstraint0 Self-Issued CA Cert",
 1137:        "pathLenConstraint0 CA Cert"];
 1138: 
 1139: intermidiate_cas(Chap) when Chap == "4.6.17" -> 
 1140:     ["pathLenConstraint1 Self-Issued subCA Cert",
 1141:      "pathLenConstraint1 subCA Cert", 
 1142:      "pathLenConstraint1 Self-Issued CA Cert", 
 1143:      "pathLenConstraint1 CA Cert"];
 1144: 
 1145: intermidiate_cas(Chap) when Chap == "4.6.5";
 1146: 			    Chap == "4.6.6" -> 
 1147:     ["pathLenConstraint0 subCA Cert", 
 1148:      "pathLenConstraint0 CA Cert"]; 
 1149: 
 1150: intermidiate_cas(Chap) when Chap == "4.6.9";
 1151: 			    Chap == "4.6.10" -> 
 1152:     ["pathLenConstraint6 subsubCA00 Cert",
 1153:      "pathLenConstraint6 subCA0 Cert",
 1154:      "pathLenConstraint6 CA Cert"];
 1155: 
 1156: intermidiate_cas(Chap) when Chap == "4.6.11";
 1157: 			    Chap == "4.6.12" -> 
 1158:     ["pathLenConstraint6 subsubsubCA11X Cert",
 1159:      "pathLenConstraint6 subsubCA11 Cert",
 1160:      "pathLenConstraint6 subCA1 Cert",
 1161:      "pathLenConstraint6 CA Cert"];
 1162: 
 1163: intermidiate_cas(Chap) when Chap == "4.6.16" ->
 1164:     ["pathLenConstraint0 subCA2 Cert",
 1165:      "pathLenConstraint0 Self-Issued CA Cert",
 1166:      "pathLenConstraint0 CA Cert"];
 1167: 
 1168: intermidiate_cas(Chap) when Chap == "4.4.1" ->
 1169:     ["No CRL CA Cert"];
 1170: 
 1171: intermidiate_cas(Chap) when Chap == "4.4.2" ->
 1172:     ["Revoked subCA Cert", "Good CA Cert"];
 1173: 
 1174: intermidiate_cas(Chap) when Chap == "4.4.3" ->
 1175:     ["Good CA Cert"];
 1176: 
 1177: intermidiate_cas(Chap) when Chap == "4.4.4" ->
 1178:     ["Bad CRL Signature CA Cert"];
 1179: 
 1180: intermidiate_cas(Chap) when Chap == "4.4.5" ->
 1181:     ["Bad CRL Issuer Name CA Cert"];
 1182: 
 1183: intermidiate_cas(Chap) when Chap == "4.4.6" ->
 1184:     ["Wrong CRL CA Cert"];
 1185: 
 1186: intermidiate_cas(Chap) when Chap == "4.4.7" ->
 1187:     ["Two CRLs CA Cert"];
 1188: 
 1189: intermidiate_cas(Chap) when Chap == "4.4.8" ->
 1190:     ["Unknown CRL Entry Extension CA Cert"];
 1191: 
 1192: intermidiate_cas(Chap) when Chap == "4.4.9";
 1193: 			    Chap == "4.4.10" ->
 1194:     ["Unknown CRL Extension CA Cert"];
 1195: 
 1196: intermidiate_cas(Chap) when Chap == "4.4.11" ->
 1197:     ["Old CRL nextUpdate CA Cert"];
 1198: 
 1199: intermidiate_cas(Chap) when Chap == "4.4.12" ->
 1200:     ["pre2000 CRL nextUpdate CA Cert"];
 1201: 
 1202: intermidiate_cas(Chap) when Chap == "4.4.13" ->
 1203:     ["GeneralizedTime CRL nextUpdate CA Cert"];
 1204: 
 1205: intermidiate_cas(Chap) when Chap == "4.4.14";
 1206: 			    Chap == "4.4.15" ->
 1207:     ["Negative Serial Number CA Cert"];
 1208: 
 1209: intermidiate_cas(Chap) when Chap == "4.4.16";
 1210: 			    Chap == "4.4.17";
 1211: 			    Chap == "4.4.18" ->
 1212:     ["Long Serial Number CA Cert"];
 1213: 
 1214: intermidiate_cas(Chap) when Chap == "4.4.19";
 1215: 			    Chap == "4.4.20" ->
 1216:     ["Separate Certificate and CRL Keys Certificate Signing CA Cert"];
 1217: 
 1218: intermidiate_cas(Chap) when Chap == "4.4.21" ->
 1219:     ["Separate Certificate and CRL Keys CA2 Certificate Signing CA Cert"];
 1220: 
 1221: intermidiate_cas(Chap) when Chap == "4.14.1";
 1222: 			    Chap == "4.14.2";
 1223: 			    Chap == "4.14.3";
 1224: 			    Chap == "4.14.4" ->
 1225:     ["distributionPoint1 CA Cert"];
 1226: intermidiate_cas(Chap) when Chap == "4.14.5";
 1227: 			    Chap == "4.14.6";
 1228: 			    Chap == "4.14.7";
 1229: 			    Chap == "4.14.8";
 1230: 			    Chap == "4.14.9" ->
 1231:     ["distributionPoint2 CA Cert"];
 1232: 
 1233: intermidiate_cas(Chap) when Chap == "4.14.10" ->
 1234:     ["No issuingDistributionPoint CA Cert"];
 1235: 
 1236: intermidiate_cas(Chap) when Chap == "4.14.11" ->
 1237:     ["onlyContainsUserCerts CA Cert"];
 1238: 
 1239: intermidiate_cas(Chap) when Chap == "4.14.12";
 1240: 			    Chap == "4.14.13" ->
 1241:     ["onlyContainsCACerts CA Cert"];
 1242: 
 1243: intermidiate_cas(Chap) when Chap == "4.14.14" ->
 1244:     ["onlyContainsAttributeCerts CA Cert"];
 1245: 
 1246: intermidiate_cas(Chap) when Chap == "4.14.15";
 1247: 			    Chap == "4.14.16" ->
 1248:     ["onlySomeReasons CA1 Cert"];
 1249: 
 1250: intermidiate_cas(Chap) when Chap == "4.14.17" ->
 1251:     ["onlySomeReasons CA2 Cert"];
 1252: 
 1253: intermidiate_cas(Chap) when Chap == "4.14.18" ->
 1254:     ["onlySomeReasons CA3 Cert"];
 1255: 
 1256: intermidiate_cas(Chap) when Chap == "4.14.19";
 1257: 			    Chap == "4.14.20";
 1258: 			    Chap == "4.14.21" ->
 1259:     ["onlySomeReasons CA4 Cert"];
 1260: 
 1261: intermidiate_cas(Chap) when Chap == "4.14.22";
 1262: 			    Chap == "4.14.23" ->
 1263:     ["indirectCRL CA1 Cert"];
 1264: 
 1265: intermidiate_cas(Chap) when Chap == "4.14.24";
 1266: 			    Chap == "4.14.25";
 1267: 			    Chap == "4.14.26" ->
 1268:     ["indirectCRL CA2 Cert"];
 1269: 
 1270: intermidiate_cas(Chap) when Chap == "4.14.27" ->
 1271:     ["indirectCRL CA2 Cert"];
 1272: 
 1273: intermidiate_cas(Chap) when Chap == "4.14.28";
 1274: 			    Chap == "4.14.29" ->
 1275:     ["indirectCRL CA3 Cert"];
 1276: 
 1277: intermidiate_cas(Chap) when Chap == "4.14.31";
 1278: 			    Chap == "4.14.32";
 1279: 			    Chap == "4.14.33" ->
 1280:     ["indirectCRL CA6 Cert"];
 1281: 
 1282: intermidiate_cas(Chap) when Chap == "4.14.34";
 1283: 			    Chap == "4.14.35" ->
 1284:     ["indirectCRL CA5 Cert"];
 1285: 
 1286: intermidiate_cas(Chap) when Chap == "4.15.1" ->
 1287:     ["deltaCRLIndicator No Base CA Cert"];
 1288: 
 1289: intermidiate_cas(Chap) when Chap == "4.15.2";
 1290: 			    Chap == "4.15.3";
 1291: 			    Chap == "4.15.4";
 1292: 			    Chap == "4.15.5";
 1293: 			    Chap == "4.15.6";
 1294: 			    Chap == "4.15.7" ->
 1295:     ["deltaCRL CA1 Cert"];
 1296: 
 1297: intermidiate_cas(Chap) when Chap == "4.15.8";
 1298: 			    Chap == "4.15.9" ->
 1299:     ["deltaCRL CA2 Cert"];
 1300: 
 1301: intermidiate_cas(Chap) when Chap == "4.15.10" ->
 1302:     ["deltaCRL CA3 Cert"];
 1303: 
 1304: intermidiate_cas(Chap) when Chap == "4.5.6";
 1305: 			    Chap == "4.5.7" ->
 1306:     ["Basic Self-Issued CRL Signing Key CA Cert"];
 1307: intermidiate_cas(Chap) when Chap == "4.5.8" ->
 1308:     ["Basic Self-Issued CRL Signing Key CRL Cert"].
 1309: 
 1310: 
 1311: %%%%%%%%%%%%%%% CRL mappings %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 1312: 
 1313: crl_names("4.4.1") ->
 1314:     ["Trust Anchor Root CRL"];
 1315: crl_names("4.4.2") ->
 1316:     ["Trust Anchor Root CRL", "Good CA CRL", "Revoked subCA CRL"];
 1317: crl_names("4.4.3") ->
 1318:     ["Trust Anchor Root CRL", "Good CA CRL", "Revoked subCA CRL"];
 1319: crl_names("4.4.4") ->
 1320:      ["Trust Anchor Root CRL", "Bad CRL Signature CA CRL"];
 1321: crl_names("4.4.5") ->
 1322:       ["Trust Anchor Root CRL", "Bad CRL Issuer Name CA CRL"];
 1323: crl_names("4.4.6") ->
 1324:      ["Trust Anchor Root CRL", "Wrong CRL CA CRL"];
 1325: crl_names("4.4.7") ->
 1326:    ["Trust Anchor Root CRL", "Two CRLs CA Good CRL", "Two CRLs CA Bad CRL"];
 1327: crl_names("4.4.8") ->
 1328:    ["Trust Anchor Root CRL", "Unknown CRL Entry Extension CA CRL"];
 1329: crl_names(Chap) when Chap == "4.4.9";
 1330: 		Chap == "4.4.10"->
 1331:    ["Trust Anchor Root CRL", "Unknown CRL Extension CA CRL"];
 1332: crl_names("4.4.11") ->
 1333:    ["Trust Anchor Root CRL", "Old CRL nextUpdate CA CRL"];
 1334: crl_names("4.4.12") ->
 1335:    ["Trust Anchor Root CRL", "pre2000 CRL nextUpdate CA CRL"];
 1336: crl_names("4.4.13") ->
 1337:    ["Trust Anchor Root CRL", "GeneralizedTime CRL nextUpdate CA CRL"];
 1338: crl_names(Chap) when Chap == "4.4.14";
 1339: 		Chap == "4.4.15"->
 1340:     ["Trust Anchor Root CRL", "Negative Serial Number CA CRL"];
 1341: crl_names(Chap) when Chap == "4.4.16";
 1342: 		Chap == "4.4.17";
 1343: 		Chap == "4.4.18" ->
 1344:     ["Trust Anchor Root CRL", "Long Serial Number CA CRL"];
 1345: crl_names(Chap)when Chap == "4.4.19";
 1346: 	       Chap == "4.4.20" ->
 1347:     ["Trust Anchor Root CRL", "Separate Certificate and CRL Keys CRL"];
 1348: crl_names("4.4.21") ->
 1349:    ["Trust Anchor Root CRL", "Separate Certificate and CRL Keys CA2 CRL"];
 1350: crl_names(Chap) when Chap == "4.5.1";
 1351: 		     Chap == "4.5.2"->
 1352:    ["Trust Anchor Root CRL", "Basic Self-Issued New Key CA CRL"];
 1353: crl_names(Chap) when Chap == "4.5.3";
 1354: 		Chap == "4.5.4";
 1355: 		Chap == "4.5.5" ->
 1356:    ["Trust Anchor Root CRL", "Basic Self-Issued Old Key Self-Issued Cert CRL",
 1357:     "Basic Self-Issued Old Key CA CRL"];
 1358: crl_names(Chap) when  Chap == "4.5.6";
 1359: 		      Chap == "4.5.7";
 1360: 		      Chap == "4.5.8" ->
 1361:    ["Trust Anchor Root CRL", "Basic Self-Issued CRL Signing Key CRL Cert CRL",
 1362: 	"Basic Self-Issued CRL Signing Key CA CRL"
 1363:    ];
 1364: crl_names("4.7.4") ->
 1365:    ["Trust Anchor Root CRL", "keyUsage Critical cRLSign False CA CRL"];
 1366: crl_names("4.7.5") ->
 1367:    ["Trust Anchor Root CRL", "keyUsage Not Critical cRLSign False CA CRL"];
 1368: crl_names(Chap) when Chap == "4.14.1";
 1369: 		Chap == "4.14.2";
 1370: 		Chap == "4.14.3";
 1371: 		Chap == "4.14.4" ->
 1372:     ["Trust Anchor Root CRL", "distributionPoint1 CA CRL"];
 1373: crl_names(Chap) when Chap == "4.14.5";
 1374: 		Chap == "4.14.6";
 1375: 		Chap == "4.14.7";
 1376: 		Chap == "4.14.8";
 1377: 		Chap == "4.14.9" ->
 1378:     ["Trust Anchor Root CRL", "distributionPoint2 CA CRL"];
 1379: crl_names("4.14.10") ->
 1380:    ["Trust Anchor Root CRL", "No issuingDistributionPoint CA CRL"];
 1381: crl_names("4.14.11") ->
 1382:    ["Trust Anchor Root CRL", "onlyContainsUserCerts CA CRL"];
 1383: crl_names(Chap) when Chap == "4.14.12";
 1384: 		Chap == "4.14.13" ->
 1385:     ["Trust Anchor Root CRL", "onlyContainsCACerts CA CRL"];
 1386: crl_names("4.14.14") ->
 1387:     ["Trust Anchor Root CRL", "onlyContainsAttributeCerts CA CRL"];
 1388: crl_names(Chap) when Chap == "4.14.15";
 1389: 		Chap == "4.14.16" ->
 1390:    ["Trust Anchor Root CRL", "onlySomeReasons CA1 compromise CRL",
 1391:     "onlySomeReasons CA1 other reasons CRL"];
 1392: crl_names("4.14.17") ->
 1393:    ["Trust Anchor Root CRL",
 1394:     "onlySomeReasons CA2 CRL1", "onlySomeReasons CA2 CRL2"];
 1395: crl_names("4.14.18") ->
 1396:    ["Trust Anchor Root CRL",
 1397:     "onlySomeReasons CA3 compromise CRL", "onlySomeReasons CA3 other reasons CRL"];
 1398: crl_names(Chap) when Chap == "4.14.19";
 1399: 		Chap == "4.14.20";
 1400: 		Chap == "4.14.21" ->
 1401:    ["Trust Anchor Root CRL", "onlySomeReasons CA4 compromise CRL",
 1402:     "onlySomeReasons CA4 other reasons CRL"];
 1403: crl_names(Chap) when Chap == "4.14.22";
 1404: 		Chap == "4.14.23";
 1405: 		Chap == "4.14.24";
 1406: 		Chap == "4.14.25";
 1407: 		Chap == "4.14.26" ->
 1408:    ["Trust Anchor Root CRL", "indirectCRL CA1 CRL"];
 1409: crl_names("4.14.27") ->
 1410:    ["Trust Anchor Root CRL", "Good CA CRL"];
 1411: 
 1412: crl_names(Chap) when Chap == "4.14.28";
 1413: 		     Chap == "4.14.29" ->
 1414:     ["Trust Anchor Root CRL", "indirectCRL CA3 CRL", "indirectCRL CA3 cRLIssuer CRL"];
 1415: crl_names("4.14.30") ->
 1416:    ["Trust Anchor Root CRL", "indirectCRL CA4 cRLIssuer CRL"];
 1417: crl_names(Chap) when Chap == "4.14.31";
 1418: 		Chap == "4.14.32";
 1419: 		Chap == "4.14.33";
 1420: 		Chap == "4.14.34";
 1421: 		Chap == "4.14.35" ->
 1422:    ["Trust Anchor Root CRL", "indirectCRL CA5 CRL"];
 1423: crl_names("4.15.1") ->
 1424:    ["Trust Anchor Root CRL", "deltaCRLIndicator No Base CA CRL"];
 1425: crl_names(Chap)  when Chap == "4.15.2";
 1426: 		 Chap == "4.15.3";
 1427: 		 Chap == "4.15.4";
 1428: 		 Chap == "4.15.5";
 1429: 		 Chap == "4.15.6";
 1430: 		 Chap == "4.15.7" ->
 1431:     ["Trust Anchor Root CRL", "deltaCRL CA1 CRL", "deltaCRL CA1 deltaCRL"];
 1432: crl_names(Chap) when Chap == "4.15.8";
 1433: 		Chap == "4.15.9" ->
 1434:    ["Trust Anchor Root CRL", "deltaCRL CA2 CRL", "deltaCRL CA2 deltaCRL"];
 1435: crl_names("4.15.10") ->
 1436:     ["Trust Anchor Root CRL", "deltaCRL CA3 CRL", "deltaCRL CA3 deltaCRL"].
 1437: 
 1438: crl_root_cert() ->
 1439:     "Trust Anchor Root Certificate".
 1440: 
 1441: crl_path("Trust Anchor Root CRL") ->
 1442:     []; %% Signed directly by crl_root_cert
 1443: crl_path("Revoked subCA CRL") ->
 1444:     ["Good CA Cert", "Revoked subCA Cert"];
 1445: crl_path("indirectCRL CA3 cRLIssuer CRL") ->
 1446:     ["indirectCRL CA3 Cert", "indirectCRL CA3 cRLIssuer Cert"];
 1447: crl_path("Two CRLs CA Good CRL") ->
 1448:     ["Two CRLs CA Cert"];
 1449: crl_path("Two CRLs CA Bad CRL") ->
 1450:     ["Two CRLs CA Cert"];
 1451: crl_path("Separate Certificate and CRL Keys CRL") ->
 1452:     ["Separate Certificate and CRL Keys CRL Signing Cert"];
 1453: crl_path("Separate Certificate and CRL Keys CA2 CRL") ->
 1454:     ["Separate Certificate and CRL Keys CA2 CRL Signing Cert"];
 1455: crl_path("Basic Self-Issued Old Key Self-Issued Cert CRL") ->
 1456:     ["Basic Self-Issued Old Key CA Cert"];
 1457: crl_path("Basic Self-Issued Old Key CA CRL") ->
 1458:       ["Basic Self-Issued Old Key CA Cert", "Basic Self-Issued Old Key NewWithOld CA Cert"];
 1459: 
 1460: crl_path("Basic Self-Issued CRL Signing Key CRL Cert CRL") ->
 1461:     ["Basic Self-Issued CRL Signing Key CA Cert"];
 1462: crl_path("Basic Self-Issued CRL Signing Key CA CRL") ->
 1463:     ["Basic Self-Issued CRL Signing Key CA Cert", "Basic Self-Issued CRL Signing Key CRL Cert"];
 1464: 
 1465: crl_path("onlySomeReasons CA1 compromise CRL") ->
 1466:     ["onlySomeReasons CA1 Cert"];
 1467: crl_path("onlySomeReasons CA1 other reasons CRL") ->
 1468:     ["onlySomeReasons CA1 Cert"];
 1469: crl_path("onlySomeReasons CA3 other reasons CRL") ->
 1470:     ["onlySomeReasons CA3 Cert"];
 1471: crl_path("onlySomeReasons CA3 compromise CRL") ->
 1472:     ["onlySomeReasons CA3 Cert"];
 1473: crl_path("onlySomeReasons CA4 compromise CRL") ->
 1474:     ["onlySomeReasons CA4 Cert"];
 1475: crl_path("onlySomeReasons CA4 other reasons CRL") ->
 1476:     ["onlySomeReasons CA4 Cert"];
 1477: crl_path("Basic Self-Issued New Key CA CRL") ->
 1478:     ["Basic Self-Issued New Key CA Cert"];
 1479: crl_path("deltaCRL CA1 deltaCRL") ->
 1480:     crl_path("deltaCRL CA2 CRL");
 1481: crl_path("deltaCRL CA2 deltaCRL") ->
 1482:     crl_path("deltaCRL CA2 CRL");
 1483: crl_path("deltaCRL CA3 deltaCRL") ->
 1484:     crl_path("deltaCRL CA3 CRL");
 1485: crl_path(CRL) when CRL == "onlySomeReasons CA2 CRL1";
 1486: 		   CRL == "onlySomeReasons CA2 CRL2" ->
 1487:     ["onlySomeReasons CA2 Cert"];
 1488: 
 1489: crl_path(CRL) ->
 1490:     L = length(CRL),
 1491:     Base = string:sub_string(CRL, 1, L -3),
 1492:     [Base ++ "Cert"].
 1493: 
 1494: crls(CRLS) ->
 1495:      lists:foldl(fun([], Acc) ->
 1496: 			Acc;
 1497: 		   (CRLFile, Acc) ->
 1498: 			[CRL] = read_crls(CRLFile),
 1499: 			[CRL | Acc]
 1500: 		end, [], CRLS).
 1501: 
 1502: 
 1503: %% TODO: If we implement policy support
 1504: %% Certificate policy tests need special handling. They can have several
 1505: %% sub tests and we need to check the outputs are correct.
 1506: 
 1507: certificate_policies_tests() ->
 1508:     %%{ "4.8", "Certificate Policies" },
 1509:     [{"4.8.1.1", "All Certificates Same Policy Test1", "-policy anyPolicy -explicit_policy", "True", ?NIST1, ?NIST1, 0},
 1510:      {"4.8.1.2", "All Certificates Same Policy Test1", "-policy ?NIST1BasicSelfIssuedCRLSigningKeyCACert.pem -explicit_policy", "True", ?NIST1, ?NIST1, 0},
 1511:      {"4.8.1.3", "All Certificates Same Policy Test1", "-policy ?NIST2 -explicit_policy", "True", ?NIST1, "<empty>", 43},
 1512:      {"4.8.1.4", "All Certificates Same Policy Test1", "-policy ?NIST1 -policy ?NIST2 -explicit_policy", "True", ?NIST1, ?NIST1, 0},
 1513:      {"4.8.2.1", "All Certificates No Policies Test2", "-policy anyPolicy", "False", "<empty>", "<empty>", 0},
 1514:      {"4.8.2.2", "All Certificates No Policies Test2", "-policy anyPolicy -explicit_policy", "True", "<empty>", "<empty>", 43},
 1515:      {"4.8.3.1", "Different Policies Test3", "-policy anyPolicy", "False", "<empty>", "<empty>", 0},
 1516:     {"4.8.3.2", "Different Policies Test3", "-policy anyPolicy -explicit_policy", "True", "<empty>", "<empty>", 43},
 1517:      {"4.8.3.3", "Different Policies Test3", "-policy ?NIST1 -policy ?NIST2 -explicit_policy", "True", "<empty>", "<empty>", 43},
 1518:      {"4.8.4", "Different Policies Test4", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1519:      {"4.8.5", "Different Policies Test5", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1520:      {"4.8.6.1", "Overlapping Policies Test6", "-policy anyPolicy", "True", ?NIST1, ?NIST1, 0},
 1521:      {"4.8.6.2", "Overlapping Policies Test6", "-policy ?NIST1", "True", ?NIST1, ?NIST1, 0},
 1522:      {"4.8.6.3", "Overlapping Policies Test6", "-policy ?NIST2", "True", ?NIST1, "<empty>", 43},
 1523:      {"4.8.7", "Different Policies Test7", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1524:      {"4.8.8", "Different Policies Test8", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1525:      {"4.8.9", "Different Policies Test9", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1526:      {"4.8.10.1", "All Certificates Same Policies Test10", "-policy ?NIST1", "True", "?NIST1:?NIST2", "?NIST1", 0},
 1527:      {"4.8.10.2", "All Certificates Same Policies Test10", "-policy ?NIST2", "True", "?NIST1:?NIST2", "?NIST2", 0},
 1528:      {"4.8.10.3", "All Certificates Same Policies Test10", "-policy anyPolicy", "True", "?NIST1:?NIST2", "?NIST1:?NIST2", 0},
 1529:      {"4.8.11.1", "All Certificates AnyPolicy Test11", "-policy anyPolicy", "True", "$apolicy", "$apolicy", 0},
 1530:     {"4.8.11.2", "All Certificates AnyPolicy Test11", "-policy ?NIST1", "True", "$apolicy", "?NIST1", 0},
 1531:      {"4.8.12", "Different Policies Test12", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1532:      {"4.8.13.1", "All Certificates Same Policies Test13", "-policy ?NIST1", "True", "?NIST1:?NIST2:?NIST3", "?NIST1", 0},
 1533:      {"4.8.13.2", "All Certificates Same Policies Test13", "-policy ?NIST2", "True", "?NIST1:?NIST2:?NIST3", "?NIST2", 0},
 1534:      {"4.8.13.3", "All Certificates Same Policies Test13", "-policy ?NIST3", "True", "?NIST1:?NIST2:?NIST3", "?NIST3", 0},
 1535:      {"4.8.14.1",       "AnyPolicy Test14", "-policy ?NIST1", "True", "?NIST1",         "?NIST1", 0},
 1536:      {"4.8.14.2",       "AnyPolicy Test14", "-policy ?NIST2", "True", "?NIST1",         "<empty>", 43},
 1537:      {"4.8.15", "User Notice Qualifier Test15", "-policy anyPolicy", "False", "?NIST1", "?NIST1", 0},
 1538:      {"4.8.16", "User Notice Qualifier Test16", "-policy anyPolicy", "False", "?NIST1", "?NIST1", 0},
 1539:     {"4.8.17", "User Notice Qualifier Test17", "-policy anyPolicy", "False", "?NIST1", "?NIST1", 0},
 1540:      {"4.8.18.1", "User Notice Qualifier Test18", "-policy ?NIST1", "True", "?NIST1:?NIST2", "?NIST1", 0},
 1541:      {"4.8.18.2", "User Notice Qualifier Test18", "-policy ?NIST2", "True", "?NIST1:?NIST2", "?NIST2", 0},
 1542:      {"4.8.19", "User Notice Qualifier Test19", "-policy anyPolicy", "False", "?NIST1", "?NIST1", 0},
 1543:      {"4.8.20", "CPS Pointer Qualifier Test20", "-policy anyPolicy -explicit_policy", "True", "?NIST1", "?NIST1", 0}].
 1544: require_explicit_policy_tests() ->
 1545:     %%{ "4.9", "Require Explicit Policy" },
 1546:     [{"4.9.1", "Valid RequireExplicitPolicy Test1", "-policy anyPolicy", "False", "<empty>", "<empty>", 0},
 1547:      {"4.9.2", "Valid RequireExplicitPolicy Test2", "-policy anyPolicy", "False", "<empty>", "<empty>", 0},
 1548:      {"4.9.3", "Invalid RequireExplicitPolicy Test3", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1549:      {"4.9.4", "Valid RequireExplicitPolicy Test4", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0},
 1550:      {"4.9.5", "Invalid RequireExplicitPolicy Test5", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1551:      {"4.9.6", "Valid Self-Issued requireExplicitPolicy Test6", "-policy anyPolicy", "False", "<empty>", "<empty>", 0},
 1552:      {"4.9.7", "Invalid Self-Issued requireExplicitPolicy Test7", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1553:      {"4.9.8", "Invalid Self-Issued requireExplicitPolicy Test8", "-policy anyPolicy", "True", "<empty>", "<empty>", 43}].
 1554: policy_mappings_tests() ->
 1555:     %%{ "4.10", "Policy Mappings" },
 1556:     [{"4.10.1.1", "Valid Policy Mapping Test1", "-policy ?NIST1", "True", "?NIST1", "?NIST1", 0},
 1557:      {"4.10.1.2", "Valid Policy Mapping Test1", "-policy ?NIST2", "True", "?NIST1", "<empty>", 43},
 1558:      {"4.10.1.3", "Valid Policy Mapping Test1", "-policy anyPolicy -inhibit_map", "True", "<empty>", "<empty>", 43},
 1559:      {"4.10.2.1", "Invalid Policy Mapping Test2", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1560:      {"4.10.2.2", "Invalid Policy Mapping Test2", "-policy anyPolicy -inhibit_map", "True", "<empty>", "<empty>", 43},
 1561:      {"4.10.3.1", "Valid Policy Mapping Test3", "-policy ?NIST1", "True", "?NIST2", "<empty>", 43},
 1562:      {"4.10.3.2", "Valid Policy Mapping Test3", "-policy ?NIST2", "True", "?NIST2", "?NIST2", 0},
 1563:      {"4.10.4", "Invalid Policy Mapping Test4", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1564:      {"4.10.5.1", "Valid Policy Mapping Test5", "-policy ?NIST1", "True", "?NIST1", "?NIST1", 0},
 1565:      {"4.10.5.2", "Valid Policy Mapping Test5", "-policy ?NIST6", "True", "?NIST1", "<empty>", 43},
 1566:      {"4.10.6.1", "Valid Policy Mapping Test6", "-policy ?NIST1", "True", "?NIST1", "?NIST1", 0},
 1567:      {"4.10.6.2", "Valid Policy Mapping Test6", "-policy ?NIST6", "True", "?NIST1", "<empty>", 43},
 1568:      { "4.10.7", "Invalid Mapping From anyPolicy Test7", 42 },
 1569:      { "4.10.8", "Invalid Mapping To anyPolicy Test8",   42 },
 1570:      {"4.10.9", "Valid Policy Mapping Test9", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0},
 1571:      {"4.10.10", "Invalid Policy Mapping Test10", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1572:      {"4.10.11", "Valid Policy Mapping Test11", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0},
 1573: 
 1574:      %% TODO: check notice display
 1575:      {"4.10.12.1", "Valid Policy Mapping Test12", "-policy ?NIST1", "True", "?NIST1:?NIST2", "?NIST1", 0},
 1576: 
 1577:      %% TODO: check notice display
 1578:      {"4.10.12.2", "Valid Policy Mapping Test12", "-policy ?NIST2", "True", "?NIST1:?NIST2", "?NIST2", 0},
 1579:      {"4.10.13", "Valid Policy Mapping Test13", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0},
 1580: 
 1581:      %% TODO: check notice display
 1582:      {"4.10.14", "Valid Policy Mapping Test14", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0}].
 1583: 
 1584: inhibit_policy_mapping_tests() ->
 1585:     %%{ "4.11", "Inhibit Policy Mapping" },
 1586:     [{"4.11.1", "Invalid inhibitPolicyMapping Test1", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1587:      {"4.11.2", "Valid inhibitPolicyMapping Test2", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0},
 1588:      {"4.11.3", "Invalid inhibitPolicyMapping Test3", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1589:      {"4.11.4", "Valid inhibitPolicyMapping Test4", "-policy anyPolicy", "True", "?NIST2", "?NIST2", 0},
 1590:      {"4.11.5", "Invalid inhibitPolicyMapping Test5", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1591:      {"4.11.6", "Invalid inhibitPolicyMapping Test6", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1592:      {"4.11.7", "Valid Self-Issued inhibitPolicyMapping Test7", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0},
 1593:      {"4.11.8", "Invalid Self-Issued inhibitPolicyMapping Test8", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1594:      {"4.11.9", "Invalid Self-Issued inhibitPolicyMapping Test9", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1595:      {"4.11.10", "Invalid Self-Issued inhibitPolicyMapping Test10", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1596:      {"4.11.11", "Invalid Self-Issued inhibitPolicyMapping Test11", "-policy anyPolicy", "True", "<empty>", "<empty>", 43}].
 1597: inhibit_any_policy_tests() ->
 1598:     %%{ "4.12", "Inhibit Any Policy" },
 1599:     [{"4.12.1", "Invalid inhibitAnyPolicy Test1", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1600:      {"4.12.2", "Valid inhibitAnyPolicy Test2", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0},
 1601:      {"4.12.3.1", "inhibitAnyPolicy Test3", "-policy anyPolicy", "True", "?NIST1", "?NIST1", 0},
 1602:      {"4.12.3.2", "inhibitAnyPolicy Test3", "-policy anyPolicy -inhibit_any", "True", "<empty>", "<empty>", 43},
 1603:      {"4.12.4", "Invalid inhibitAnyPolicy Test4", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1604:      {"4.12.5", "Invalid inhibitAnyPolicy Test5", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1605:      {"4.12.6", "Invalid inhibitAnyPolicy Test6", "-policy anyPolicy", "True", "<empty>", "<empty>", 43},
 1606:      {"4.12.7",  "Valid Self-Issued inhibitAnyPolicy Test7",      ok},
 1607:      {"4.12.8",  "Invalid Self-Issued inhibitAnyPolicy Test8",    43 },
 1608:      {"4.12.9",  "Valid Self-Issued inhibitAnyPolicy Test9",      ok},
 1609:      {"4.12.10", "Invalid Self-Issued inhibitAnyPolicy Test10",   43 }].