Bug 1045973 - sec_error_extension_value_invalid: mozilla::pkix does not accept certificates with x509v3 extensions in x509v1 or x509v2 certificates. r=keeler, a=sledru
authorRichard Barnes <rbarnes@mozilla.com>
Tue, 23 Sep 2014 16:48:54 -0400
changeset 216853 a4697303afa6
parent 216852 12a5b8d685b2
child 216854 371e802df4dc
push id3942
push userryanvm@gmail.com
push date2014-09-26 13:41 +0000
treeherdermozilla-beta@2b061899d368 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler, sledru
bugs1045973
milestone33.0
Bug 1045973 - sec_error_extension_value_invalid: mozilla::pkix does not accept certificates with x509v3 extensions in x509v1 or x509v2 certificates. r=keeler, a=sledru
security/manager/ssl/tests/unit/test_cert_version.js
security/manager/ssl/tests/unit/test_cert_version/generate.py
security/manager/ssl/tests/unit/test_cert_version/v1_self_signed.der
security/manager/ssl/tests/unit/test_cert_version/v1_self_signed_bc.der
security/manager/ssl/tests/unit/test_cert_version/v2_self_signed.der
security/manager/ssl/tests/unit/test_cert_version/v2_self_signed_bc.der
security/pkix/lib/pkixcert.cpp
--- a/security/manager/ssl/tests/unit/test_cert_version.js
+++ b/security/manager/ssl/tests/unit/test_cert_version.js
@@ -48,19 +48,19 @@ function run_test() {
   load_cert("v1_ca", "CTu,CTu,CTu");
   load_cert("v1_ca_bc", "CTu,CTu,CTu");
   load_cert("v2_ca", "CTu,CTu,CTu");
   load_cert("v2_ca_bc", "CTu,CTu,CTu");
   load_cert("v3_ca", "CTu,CTu,CTu");
   load_cert("v3_ca_missing_bc", "CTu,CTu,CTu");
 
   check_ok_ca(cert_from_file('v1_ca.der'));
-  check_ca_err(cert_from_file('v1_ca_bc.der'), SEC_ERROR_BAD_DER);
+  check_ok_ca(cert_from_file('v1_ca_bc.der'));
   check_ca_err(cert_from_file('v2_ca.der'), SEC_ERROR_CA_CERT_INVALID);
-  check_ca_err(cert_from_file('v2_ca_bc.der'), SEC_ERROR_BAD_DER);
+  check_ok_ca(cert_from_file('v2_ca_bc.der'));
   check_ok_ca(cert_from_file('v3_ca.der'));
   check_ca_err(cert_from_file('v3_ca_missing_bc.der'), SEC_ERROR_CA_CERT_INVALID);
 
   // Classic allows v1 and v2 certs to be CA certs in trust anchor positions and
   // intermediates when they have a v3 basic constraints extenstion (which
   // makes them invalid certs). Insanity only allows v1 certs to be CA in
   // anchor position (even if they have invalid encodings), v2 certs are not
   // considered CAs in any position.
@@ -77,423 +77,432 @@ function run_test() {
   // v1 intermediate with v1 trust anchor
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v1_int-v1_ca.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v1_int-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v1_int-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v1_int-v1_ca.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v1_ca.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v1_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v1_int-v1_ca.der'), ee_error);
 
-  // v1 intermediate with v3 extensions. CA is invalid.
-  check_ca_err(cert_from_file('v1_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v1_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v1_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v1_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v1_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
+  // v1 intermediate with v3 extensions.
+  check_ok_ca(cert_from_file('v1_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v1_ee-v1_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v1_bc_ee-v1_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v2_ee-v1_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v2_bc_ee-v1_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v3_missing_bc_ee-v1_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v3_bc_ee-v1_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v4_bc_ee-v1_int_bc-v1_ca.der'));
 
   // A v2 intermediate with a v1 CA
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v2_int-v1_ca.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v2_int-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v2_int-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v2_int-v1_ca.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v1_ca.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v1_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v2_int-v1_ca.der'), ee_error);
 
-  // A v2 intermediate with basic constraints (not allowed in mozilla::pkix)
-  check_ca_err(cert_from_file('v2_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v2_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v2_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v2_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v2_int_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
+  // A v2 intermediate with basic constraints
+  check_ok_ca(cert_from_file('v2_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v1_ee-v2_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v1_bc_ee-v2_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v2_ee-v2_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v2_bc_ee-v2_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v3_missing_bc_ee-v2_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v3_bc_ee-v2_int_bc-v1_ca.der'));
+  check_ok(cert_from_file('v4_bc_ee-v2_int_bc-v1_ca.der'));
 
   // Section is OK. A x509 v3 CA MUST have bc
   // http://tools.ietf.org/html/rfc5280#section-4.2.1.9
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v3_int_missing_bc-v1_ca.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v3_int_missing_bc-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v3_int_missing_bc-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v3_int_missing_bc-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v3_int_missing_bc-v1_ca.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v1_ca.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v1_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v1_ca.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v3_int_missing_bc-v1_ca.der'), ee_error);
 
   // It is valid for a v1 ca to sign a v3 intemediate.
   check_ok_ca(cert_from_file('v3_int-v1_ca.der'));
   check_ok(cert_from_file('v1_ee-v3_int-v1_ca.der'));
   check_ok(cert_from_file('v2_ee-v3_int-v1_ca.der'));
   check_ok(cert_from_file('v3_missing_bc_ee-v3_int-v1_ca.der'));
   check_ok(cert_from_file('v3_bc_ee-v3_int-v1_ca.der'));
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int-v1_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int-v1_ca.der'), SEC_ERROR_BAD_DER);
+  check_ok(cert_from_file('v1_bc_ee-v3_int-v1_ca.der'));
+  check_ok(cert_from_file('v2_bc_ee-v3_int-v1_ca.der'));
   check_ok(cert_from_file('v4_bc_ee-v3_int-v1_ca.der'));
 
   // The next groups change the v1 ca for a v1 ca with base constraints
   // (invalid trust anchor). The error pattern is the same as the groups
   // above
 
   // Using A v1 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v1_int-v1_ca_bc.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v1_int-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v1_int-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v1_int-v1_ca_bc.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v1_ca_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v1_int-v1_ca_bc.der'), ee_error);
 
-  // Using a v1 intermediate with v3 extenstions (invalid).
-  check_ca_err(cert_from_file('v1_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v1_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v1_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v1_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v1_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
+  // Using a v1 intermediate with v3 extenstions
+  check_ok_ca(cert_from_file('v1_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v1_ee-v1_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v1_bc_ee-v1_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v2_ee-v1_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v2_bc_ee-v1_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v3_missing_bc_ee-v1_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v3_bc_ee-v1_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v4_bc_ee-v1_int_bc-v1_ca_bc.der'));
 
   // Using v2 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v2_int-v1_ca_bc.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v2_int-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v2_int-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v2_int-v1_ca_bc.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v1_ca_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v2_int-v1_ca_bc.der'), ee_error);
 
-  // Using a v2 intermediate with basic constraints (invalid)
-  check_ca_err(cert_from_file('v2_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v2_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v2_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v2_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v2_int_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
+  // Using a v2 intermediate with basic constraints 
+  check_ok_ca(cert_from_file('v2_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v1_ee-v2_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v1_bc_ee-v2_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v2_ee-v2_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v2_bc_ee-v2_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v3_missing_bc_ee-v2_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v3_bc_ee-v2_int_bc-v1_ca_bc.der'));
+  check_ok(cert_from_file('v4_bc_ee-v2_int_bc-v1_ca_bc.der'));
 
   // Using a v3 intermediate that is missing basic constraints (invalid)
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v3_int_missing_bc-v1_ca_bc.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v3_int_missing_bc-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v3_int_missing_bc-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v3_int_missing_bc-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v3_int_missing_bc-v1_ca_bc.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v1_ca_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v1_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v3_int_missing_bc-v1_ca_bc.der'), ee_error);
 
   // these should pass assuming we are OK with v1 ca signing v3 intermediates
-  ca_error = SEC_ERROR_EXTENSION_VALUE_INVALID;
-  ee_error = SEC_ERROR_EXTENSION_VALUE_INVALID;
-  check_ca_err(cert_from_file('v3_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v3_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v3_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v3_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v3_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v3_int-v1_ca_bc.der'), SEC_ERROR_BAD_DER);
+  check_ok_ca(cert_from_file('v3_int-v1_ca_bc.der'));
+  check_ok(cert_from_file('v1_ee-v3_int-v1_ca_bc.der'));
+  check_ok(cert_from_file('v1_bc_ee-v3_int-v1_ca_bc.der'));
+  check_ok(cert_from_file('v2_ee-v3_int-v1_ca_bc.der'));
+  check_ok(cert_from_file('v2_bc_ee-v3_int-v1_ca_bc.der'));
+  check_ok(cert_from_file('v3_missing_bc_ee-v3_int-v1_ca_bc.der'));
+  check_ok(cert_from_file('v3_bc_ee-v3_int-v1_ca_bc.der'));
+  check_ok(cert_from_file('v4_bc_ee-v3_int-v1_ca_bc.der'));
 
 
   //////////////
   // v2 CA supersection
   //////////////////
 
   // v2 ca, v1 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v1_int-v2_ca.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v1_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v1_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v1_int-v2_ca.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v2_ca.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v1_int-v2_ca.der'), ee_error);
 
   // v2 ca, v1 intermediate with basic constraints (invalid)
-  check_ca_err(cert_from_file('v1_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v1_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v1_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v1_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v1_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
+  ca_error = SEC_ERROR_CA_CERT_INVALID;
+  ee_error = SEC_ERROR_CA_CERT_INVALID;
+  check_ca_err(cert_from_file('v1_int_bc-v2_ca.der'), ca_error);
+  check_cert_err(cert_from_file('v1_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v1_bc_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v3_bc_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v4_bc_ee-v1_int_bc-v2_ca.der'), ee_error);
 
   // v2 ca, v2 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v2_int-v2_ca.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v2_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v2_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v2_int-v2_ca.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v2_ca.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v2_int-v2_ca.der'), ee_error);
 
   // v2 ca, v2 intermediate with basic constraints (invalid)
-  check_ca_err(cert_from_file('v2_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v2_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v2_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v2_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v2_int_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
+  ca_error = SEC_ERROR_CA_CERT_INVALID;
+  ee_error = SEC_ERROR_CA_CERT_INVALID;
+  check_ca_err(cert_from_file('v1_int_bc-v2_ca.der'), ca_error);
+  check_cert_err(cert_from_file('v1_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v1_bc_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v3_bc_ee-v1_int_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v4_bc_ee-v1_int_bc-v2_ca.der'), ee_error);
 
   // v2 ca, v3 intermediate missing basic constraints
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v3_int_missing_bc-v2_ca.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v3_int_missing_bc-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v3_int_missing_bc-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v3_int_missing_bc-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v3_int_missing_bc-v2_ca.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v2_ca.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v3_int_missing_bc-v2_ca.der'), ee_error);
 
   // v2 ca, v3 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v3_int-v2_ca.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v3_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v3_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v3_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v3_int-v2_ca.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int-v2_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int-v2_ca.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v3_int-v2_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v3_int-v2_ca.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v3_int-v2_ca.der'), ee_error);
 
   // v2 ca, v1 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v1_int-v2_ca_bc.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v1_int-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v1_int-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v1_int-v2_ca_bc.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v2_ca_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v1_int-v2_ca_bc.der'), ee_error);
 
-  // v2 ca, v1 intermediate with bc (invalid)
-  check_ca_err(cert_from_file('v1_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v1_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v1_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v1_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v1_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
+  // v2 ca, v1 intermediate with bc
+  check_ok_ca(cert_from_file('v1_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v1_ee-v1_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v1_bc_ee-v1_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v2_ee-v1_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v2_bc_ee-v1_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v3_missing_bc_ee-v1_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v3_bc_ee-v1_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v4_bc_ee-v1_int_bc-v2_ca_bc.der'));
 
   // v2 ca, v2 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v2_int-v2_ca_bc.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v2_int-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v2_int-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v2_int-v2_ca_bc.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v2_ca_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v2_int-v2_ca_bc.der'), ee_error);
 
-  // v2 ca, v2 intermediate with bc (invalid)
-  check_ca_err(cert_from_file('v2_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v2_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v2_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v2_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v2_int_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
+  // v2 ca, v2 intermediate with bc
+  check_ok_ca(cert_from_file('v2_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v1_ee-v2_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v1_bc_ee-v2_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v2_ee-v2_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v2_bc_ee-v2_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v3_missing_bc_ee-v2_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v3_bc_ee-v2_int_bc-v2_ca_bc.der'));
+  check_ok(cert_from_file('v4_bc_ee-v2_int_bc-v2_ca_bc.der'));
 
   // v2 ca, invalid v3 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v3_int_missing_bc-v2_ca_bc.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v3_int_missing_bc-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v3_int_missing_bc-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v3_int_missing_bc-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v3_int_missing_bc-v2_ca_bc.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v2_ca_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v2_ca_bc.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v3_int_missing_bc-v2_ca_bc.der'), ee_error);
 
-  // v2 ca, valid v3 intermediate (is OK if we use 'classic' semantics)
-  check_ca_err(cert_from_file('v3_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v3_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v3_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v3_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v3_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v3_int-v2_ca_bc.der'), SEC_ERROR_BAD_DER);
+  // v2 ca, valid v3 intermediate
+  check_ok_ca(cert_from_file('v3_int-v2_ca_bc.der'));
+  check_ok(cert_from_file('v1_ee-v3_int-v2_ca_bc.der'));
+  check_ok(cert_from_file('v1_bc_ee-v3_int-v2_ca_bc.der'));
+  check_ok(cert_from_file('v2_ee-v3_int-v2_ca_bc.der'));
+  check_ok(cert_from_file('v2_bc_ee-v3_int-v2_ca_bc.der'));
+  check_ok(cert_from_file('v3_missing_bc_ee-v3_int-v2_ca_bc.der'));
+  check_ok(cert_from_file('v3_bc_ee-v3_int-v2_ca_bc.der'));
+  check_ok(cert_from_file('v4_bc_ee-v3_int-v2_ca_bc.der'));
 
   //////////////
   // v3 CA supersection
   //////////////////
 
   // v3 ca, v1 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v1_int-v3_ca.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v1_int-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v1_int-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v1_int-v3_ca.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v3_ca.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v3_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v1_int-v3_ca.der'), ee_error);
 
   // A v1 intermediate with v3 extensions
-  check_ca_err(cert_from_file('v1_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v1_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v1_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v1_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v1_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
+  check_ok_ca(cert_from_file('v1_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v1_ee-v1_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v1_bc_ee-v1_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v2_ee-v1_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v2_bc_ee-v1_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v3_missing_bc_ee-v1_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v3_bc_ee-v1_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v4_bc_ee-v1_int_bc-v3_ca.der'));
 
   // reject a v2 cert as intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v2_int-v3_ca.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v2_int-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v2_int-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v2_int-v3_ca.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v3_ca.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v3_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v2_int-v3_ca.der'), ee_error);
 
   // v2 intermediate with bc (invalid)
-  check_ca_err(cert_from_file('v2_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v2_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v2_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v2_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v2_int_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
+  check_ok_ca(cert_from_file('v2_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v1_ee-v2_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v1_bc_ee-v2_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v2_ee-v2_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v2_bc_ee-v2_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v3_missing_bc_ee-v2_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v3_bc_ee-v2_int_bc-v3_ca.der'));
+  check_ok(cert_from_file('v4_bc_ee-v2_int_bc-v3_ca.der'));
 
   // invalid v3 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v3_int_missing_bc-v3_ca.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v3_int_missing_bc-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v3_int_missing_bc-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v3_int_missing_bc-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v3_int_missing_bc-v3_ca.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v3_ca.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v3_ca.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v3_ca.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v3_int_missing_bc-v3_ca.der'), ee_error);
 
-  // I dont think that v3 intermediates should be allowed to sign v1 or v2
-  // certs, but other thanthat this  is what we usually get in the wild.
+  // v1/v2 end entity, v3 intermediate
   check_ok_ca(cert_from_file('v3_int-v3_ca.der'));
   check_ok(cert_from_file('v1_ee-v3_int-v3_ca.der'));
   check_ok(cert_from_file('v2_ee-v3_int-v3_ca.der'));
   check_ok(cert_from_file('v3_missing_bc_ee-v3_int-v3_ca.der'));
   check_ok(cert_from_file('v3_bc_ee-v3_int-v3_ca.der'));
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int-v3_ca.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int-v3_ca.der'), SEC_ERROR_BAD_DER);
+  check_ok(cert_from_file('v1_bc_ee-v3_int-v3_ca.der'));
+  check_ok(cert_from_file('v2_bc_ee-v3_int-v3_ca.der'));
   check_ok(cert_from_file('v4_bc_ee-v3_int-v3_ca.der'));
 
   // v3 CA, invalid v3 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v1_int-v3_ca_missing_bc.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v1_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v1_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v1_int-v3_ca_missing_bc.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v1_int-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v1_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v1_int-v3_ca_missing_bc.der'), ee_error);
 
-  // Int v1 with BC that is just invalid (classic fail insanity OK)
-  check_ca_err(cert_from_file('v1_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v1_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v1_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v1_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v1_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v1_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v1_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
+  // Int v1 with BC that is just invalid
+  ca_error = SEC_ERROR_CA_CERT_INVALID;
+  ee_error = SEC_ERROR_CA_CERT_INVALID;
+  check_ca_err(cert_from_file('v1_int_bc-v3_ca_missing_bc.der'), ca_error);
+  check_cert_err(cert_from_file('v1_ee-v1_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v1_bc_ee-v1_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_ee-v1_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v1_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v3_missing_bc_ee-v1_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v3_bc_ee-v1_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v4_bc_ee-v1_int_bc-v3_ca_missing_bc.der'), ee_error);
 
   // Good section (all fail)
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v2_int-v3_ca_missing_bc.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v2_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v2_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v2_int-v3_ca_missing_bc.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v2_int-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v2_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v2_int-v3_ca_missing_bc.der'), ee_error);
 
-  // v2 intermediate (even with basic constraints) is invalid
-  check_ca_err(cert_from_file('v2_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_ee-v2_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v1_bc_ee-v2_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_ee-v2_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v2_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v3_bc_ee-v2_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v4_bc_ee-v2_int_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
+  // v3 intermediate missing basic constraints is invalid
+  ca_error = SEC_ERROR_CA_CERT_INVALID;
+  ee_error = SEC_ERROR_CA_CERT_INVALID;
+  check_ca_err(cert_from_file('v2_int_bc-v3_ca_missing_bc.der'), ca_error);
+  check_cert_err(cert_from_file('v1_ee-v2_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v1_bc_ee-v2_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_ee-v2_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v2_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v3_missing_bc_ee-v2_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v3_bc_ee-v2_int_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v4_bc_ee-v2_int_bc-v3_ca_missing_bc.der'), ee_error);
 
   // v3 intermediate missing basic constraints is invalid
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v3_int_missing_bc-v3_ca_missing_bc.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v3_int_missing_bc-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v3_int_missing_bc-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v3_int_missing_bc-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v3_int_missing_bc-v3_ca_missing_bc.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v3_int_missing_bc-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v3_int_missing_bc-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v3_int_missing_bc-v3_ca_missing_bc.der'), ee_error);
 
   // With a v3 root missing bc and valid v3 intermediate
   ca_error = SEC_ERROR_CA_CERT_INVALID;
   ee_error = SEC_ERROR_CA_CERT_INVALID;
   check_ca_err(cert_from_file('v3_int-v3_ca_missing_bc.der'), ca_error);
   check_cert_err(cert_from_file('v1_ee-v3_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v2_ee-v3_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_missing_bc_ee-v3_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v3_bc_ee-v3_int-v3_ca_missing_bc.der'), ee_error);
-  check_cert_err(cert_from_file('v1_bc_ee-v3_int-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
-  check_cert_err(cert_from_file('v2_bc_ee-v3_int-v3_ca_missing_bc.der'), SEC_ERROR_BAD_DER);
+  check_cert_err(cert_from_file('v1_bc_ee-v3_int-v3_ca_missing_bc.der'), ee_error);
+  check_cert_err(cert_from_file('v2_bc_ee-v3_int-v3_ca_missing_bc.der'), ee_error);
   check_cert_err(cert_from_file('v4_bc_ee-v3_int-v3_ca_missing_bc.der'), ee_error);
 
   // self-signed
+  check_cert_err(cert_from_file('v1_self_signed.der'), SEC_ERROR_UNKNOWN_ISSUER);
+  check_cert_err(cert_from_file('v1_self_signed_bc.der'), SEC_ERROR_UNKNOWN_ISSUER);
+  check_cert_err(cert_from_file('v2_self_signed.der'), SEC_ERROR_UNKNOWN_ISSUER);
+  check_cert_err(cert_from_file('v2_self_signed_bc.der'), SEC_ERROR_UNKNOWN_ISSUER);
   check_cert_err(cert_from_file('v3_self_signed.der'), SEC_ERROR_UNKNOWN_ISSUER);
   check_cert_err(cert_from_file('v3_self_signed_bc.der'), SEC_ERROR_UNKNOWN_ISSUER);
   check_cert_err(cert_from_file('v4_self_signed.der'), SEC_ERROR_UNKNOWN_ISSUER);
   check_cert_err(cert_from_file('v4_self_signed_bc.der'), SEC_ERROR_UNKNOWN_ISSUER);
 }
--- a/security/manager/ssl/tests/unit/test_cert_version/generate.py
+++ b/security/manager/ssl/tests/unit/test_cert_version/generate.py
@@ -69,16 +69,25 @@ def generate_certs():
   [noise_file, pwd_file] = CertUtils.init_nss_db(db)
   generate_ca(db, srcdir, noise_file, "v1_ca", 1, False )
   generate_ca(db, srcdir, noise_file, "v1_ca_bc", 1, True)
   generate_ca(db, srcdir, noise_file, "v2_ca", 2, False )
   generate_ca(db, srcdir, noise_file, "v2_ca_bc", 2, True)
   generate_ca(db, srcdir, noise_file, "v3_ca", 3, True )
   generate_ca(db, srcdir, noise_file, "v3_ca_missing_bc", 3, False)
 
+
+  CertUtils.generate_self_signed_cert(db, srcdir, noise_file, "v1_self_signed",
+                                      1, False, False)
+  CertUtils.generate_self_signed_cert(db, srcdir, noise_file, "v1_self_signed_bc",
+                                      1, True, False)
+  CertUtils.generate_self_signed_cert(db, srcdir, noise_file, "v2_self_signed",
+                                      2, False, False)
+  CertUtils.generate_self_signed_cert(db, srcdir, noise_file, "v2_self_signed_bc",
+                                      2, True, False)
   CertUtils.generate_self_signed_cert(db, srcdir, noise_file, "v3_self_signed",
                                       3, False, False)
   CertUtils.generate_self_signed_cert(db, srcdir, noise_file, "v3_self_signed_bc",
                                       3, True, False)
   CertUtils.generate_self_signed_cert(db, srcdir, noise_file, "v4_self_signed",
                                       4, False, False);
   CertUtils.generate_self_signed_cert(db, srcdir, noise_file, "v4_self_signed_bc",
                                       4, True, False);
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f305f351ad43561d74e7256f5611c91c0fb08c32
GIT binary patch
literal 846
zc$_n6V)im<VlrZ4Wmur@&1JyL#;Mij(e|B}k&%^^!64I++klgeIh2J>m?<>aP}o2a
z#NiO;a!$<2Ov^9I%S<#BGY|m@vJ3P2=9lJ`BxdF*gk`3d8;TeRfyB9lxdVcI6+%*r
zOEUA)4aE&aL88n&d}W65#i==I@x__xd8sJ|a^k#(CI%KpMuuiamL_IV;=D%4TzWdC
ziBSnTAQ)L0n41{+8GzzkOihf83@dn|UNhRA7QWD~sHlBYGU-E^{XKJoXPK3g)HlRF
z5Quyv@U~RL)&2CVl5d-<BgMLWE);lk{`XxzjaPKnEfv+}{*&IlEnV_>@y=qM$M5xS
z9h5%%_>kc;u3$#>$pu|sR|dRY-n37g)1J{#sq57Q3EQTiuw8A^nr5Evnt!GXY}dBa
zm$9{<XRl!JdbaxIm2QmuOZN0FTeA9!waW3+Q*UXAH6^t?PCTMBwQK97=ztY^A<H%X
zthCB>abKInm%U(_zz5T^^OaLsRDNv#Yt<?^{axGcLowTnvkK>&N?5wwR!vV$%z)F1
zL$k1ZS<mX3%XZ6txN6onJ^HZ9(f0CFFY|4jSC=y}GcquuB^72+z)Y;j+7ztAZuD*T
zzwFOUsXVeP?oHr6_~ZATqMrSG%y&yi#`A1G{V#2H;nZ~I)Q+Io`QKW3e!mNP;1a*!
z-1<J5w+5ff7k)kV_sYrJc5TY0_m9tY*38-M`b;tQ%nHUcM;>1jG@Lm7)ZQH?KbqxB
zW*zHiDAYgTF=a8^WShjYwUrfnemVCzHI;Jm+g#|K5D?NCty#16zxkBrotF+uOPwj3
zbop5d!@R9lds%#ZzW!_76u8jr%fdskF8`)}QZ}9VH>=&rYjRJ|ae1yETzy}*1iXDG
zaBu1PA04(4bM`R3{_)j8g!R$88y9Rgm2oyDK3cTSa`NjWk<?48mXzl-PX1=@8(moO
F0syz&MaKXD
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7e59bfc49e396d46eb349e13626197242456670a
GIT binary patch
literal 867
zc$_n6VvaXxVsd9<Wmur@&1b;N#;Mij(e|B}k&%^^!63(w+klgeIh2J>m?<>aP}o2a
z#NiO;a!$<2Ov^9I%S<#BGY|m@vJ3P2=9lJ`BxdF*gk`3d8;TeRfyB9lxdVcI6+%*r
zOEUA)4W$euK%&e%f@OyB#i==I@x__xd8sM!Ny!Fs;=G0?1{Ov}hGs^VCYDj+yhg}e
zI=iNcQ3*LX7+D#Zn;7{SfZ|+CO^l2T2a3H8&C3?=d&6?^Z1H1570KDV9C)W~?c-5N
zxBPwcGK*hH+o^3~OooNidSaaO760Zo)_+fMn0zVl*#0{cW0l^iPVzeK&^pg(M))^2
z`Ft(Ih1<Uy_8jCq5pKZeZaR6*N@0PxPo^Cotj#zwWY+HyT)}%>Osbf{t2;R*i~ql&
z@Kq5z<<5-{J{WQxyZyQNd9#7W6>iVh|BRc&E-vy{R<r%-Asaip(2<3252w$aywqpn
ztIw({r1>w_NH8<)IQVI1Zm3>-<;<m%Yn|pT{q)pCLV_iv&-8m-P5s$~yKyDEJ)(qy
zK1_PsvQg?l5!YhHvJKp!Czg26p0hAtqx~G;gli79Ow5c7jEi{<AaNoq%)(^AfR=uk
zLE$u;{jRvu!^FK7mJ{v7>;6qBn|N~Z)dj3ae=a@q)S>&&PLBmzh2J&LFdd3MeE9Xg
zBTGKBM+6+^`hWCuwadSk6Fhggu@&A(kauEkIP4_h_U(b_t(^J4GI9<JcyRf7f4N$8
zp`vz1*LfMi)T=qGTw2|CY~6V#MD9mU51;#5%WH{>HVj){D9&!WrMrCp9A5FvCDS6`
z&KE7d!gJi>XS$sJ&CZ;A)45$!<WBEhpIm<8o8IMPU$U=0zo|aq*QS?p5AUxPbuYfw
zyC8JU0^Y4LU#6Msp3B@ezl}*f+p$KeX|9sQm8hu>>7VXf{AD<^T~_9z$)Z#NscmNO
SOzV_y?-rZs&R_qp!36+RAwfF;
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b61d8961ffed642d10cf31c3664f1092af5c5381
GIT binary patch
literal 719
zc$_n6VmfWm#JG6@GZP~t6Dz}l3LR|&UN%mxHjlRNyo`*jtPBR~hCBvbY|No7T*Ax&
z!M=v#2BIJyGY?;xQG9V~PFj3%W_n&~ih-Osuc3*7rIE3bfsvV!QIt5Z5i*x}gPItX
zkR8Fu%D~*j$j<;2=VEGNWMo()(3&rFm?6L7+Uoy*mMm*$+BfrL>&M%I*Yq+c@IHyL
zh;ayC^~}RhZ1<Tbo1XQTbVYwoos!)w$q{Mnw7AviCX0LJ+fsw9IkAq@1(dGMm^N{e
ztib;ryJ{SG&RrFHbWNe~M`-=}_gw*cT?U!2ziL0|cs8r=;D;;RkKSqe&AawfQS?BE
z#iorLjn=RE->UcIS3i%^$&Z2V?bBVix}AOJ)hbmir+D#HhE;os?414W*`LFVzJwoX
z?o^Pw!anQxfph9tUd7%`Xl~M**TFAfe3@@;?Xjl)y$^cX9$j6em7Q?p+U3Y3^HVB!
zRhPc{>|ee7RZYD$`+bA@GKO`pt8{wy9-C1i$;8aaz=#%2%%FggwUA{`nwW8T4U0(4
zD#nev5!T*QHKe=yO%8rM&R>x2Y0<bx&hXx!;M?3&1ov^Ll!rb~i19Og7SrhdI@#z!
zMAo%w^Rn~#r|BHok@-c>|Ld!){`kX}w;amj-&8ztCxb!r)FrQrLuW3}5#@0(iDJ;0
zmn_{O{?1ag&25HIb++RU<%z+vOTHX`b*EQ6-A60pLVN6oxonz=5A)T<d>OyA1fM+o
z*}!}5i-%rq`~Daow6nb-cJkDe@OSr(@`@FT1l<yOSW0E;qaVd})VNMnw4eEXFT+O9
zm$Cn)&!s(N(@c4FkzwwYvo{*H%lv$HD`MyTbIOty-a;;W*&hBk@?LH5<)vN%0B+|a
A#sB~S
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bc3ff47f27ecc0f34ef464ca74be24de37f7a513
GIT binary patch
literal 740
zc$_n6VtQcE#CT!>GZP~t6Dz}l3LSj|UN%mxHjlRNyo`*jtPBQPhCBvbY|No7T*Ax&
z!M=u41`;41Gml`IQG9V~PFj3%W_n&~N_<kXft)z6p^1T|k+G41k(rTMlsK;uGM6N?
zni!Rkox;e<z}&>h&j1wXVrpV!WVkZn#M?F2l0FM>e>O1H`5iRziI+Oxv)BK1=FZiA
zdh>61bo_N~uF5~G8dKGOrY`q1^ozdcapvOdOUqo=CcJmLVe7;3=IVqcZ@NX7UkIGH
z=VrHnxBm0Hsd|b=;S#!Qle+Ath^5M=UMM{McgoG;-HX3%i-=m0tW$lm;*`^)f_HaY
z-S&jPIch6uc;S4v@ZH&*{0o*Rxh#4WI(bWM`07`OR_^q<$#0Rje4S8@^b+qk$9zKk
z7KdB>mxz#MUhn$KgwdvAy{hqhJ+7HM_@0$+5)7F9r&{6ibC+VNJOBDt&X@af_RG0A
z%je#fOtr7>^!(Zx>~?weC1=s~t^RB8$)CHJRQ$Z(l8Kp-fpIaf0k;7sFbrjdS(pqM
z(Bh666i#YSmK!hr*7Ks+)}^ifP!;1>Z|&Q~N^<PxS0*m14Yq!yyJvMswknITsr8*U
z&6@$!X0~OvUl)41Z@PWdqu<Y1AGud}PJYYo9MCW3a=794!ySC<C(XJi6maGBH|I0$
z7Y^zk@c5MV-bYUGndrJVPWP&RPMGigza?T;oW;x~Yv0&qS8zWqWw$gwn)l7^L)Tf;
z!nS^$eL=U@#xOK5DQ*w{=>B%Am`OxhX2u?7@pOk34*Sd=fAcn~>)3WypZi8ccHyH-
zQWf2wHIw>N@7~SXCZ=Pr-7$lI@yhdGrt%~kIRs5CO4K?w;hImk{g3PzH-`r0Q&;yN
TI;FrM-D|aE$Exre$Gv6%4xBFb
--- a/security/pkix/lib/pkixcert.cpp
+++ b/security/pkix/lib/pkixcert.cpp
@@ -123,75 +123,70 @@ BackCert::Init()
   rv = der::ExpectTagAndGetTLV(tbsCertificate, der::SEQUENCE,
                                subjectPublicKeyInfo);
   if (rv != Success) {
     return rv;
   }
 
   static const uint8_t CSC = der::CONTEXT_SPECIFIC | der::CONSTRUCTED;
 
-  // RFC 5280 says: "These fields MUST only appear if the version is 2 or 3
-  // (Section 4.1.2.1). These fields MUST NOT appear if the version is 1."
-  if (version != der::Version::v1) {
+  // According to RFC 5280, all fields below this line are forbidden for
+  // certificate versions less than v3.  However, for compatibility reasons,
+  // we parse v1/v2 certificates in the same way as v3 certificates.  So if
+  // these fields appear in a v1 certificate, they will be used.
 
-    // Ignore issuerUniqueID if present.
-    if (tbsCertificate.Peek(CSC | 1)) {
-      rv = der::ExpectTagAndSkipValue(tbsCertificate, CSC | 1);
-      if (rv != Success) {
-        return rv;
-      }
+  // Ignore issuerUniqueID if present.
+  if (tbsCertificate.Peek(CSC | 1)) {
+    rv = der::ExpectTagAndSkipValue(tbsCertificate, CSC | 1);
+    if (rv != Success) {
+      return rv;
     }
+  }
 
-    // Ignore subjectUniqueID if present.
-    if (tbsCertificate.Peek(CSC | 2)) {
-      rv = der::ExpectTagAndSkipValue(tbsCertificate, CSC | 2);
-      if (rv != Success) {
-        return rv;
-      }
+  // Ignore subjectUniqueID if present.
+  if (tbsCertificate.Peek(CSC | 2)) {
+    rv = der::ExpectTagAndSkipValue(tbsCertificate, CSC | 2);
+    if (rv != Success) {
+      return rv;
     }
   }
 
-  // Extensions were added in v3, so only accept extensions in v3 certificates.
-  // v4 certificates are not defined but there are some certificates issued
-  // with v4 that expect v3 decoding. For compatibility reasons we handle them
-  // as v3 certificates.
-  if (version == der::Version::v3 || version == der::Version::v4) {
-    rv = der::OptionalExtensions(tbsCertificate, CSC | 3,
-                                 bind(&BackCert::RememberExtension, this, _1,
-                                      _2, _3, _4));
-    if (rv != Success) {
-      return rv;
-    }
-    // The Netscape Certificate Type extension is an obsolete
-    // Netscape-proprietary mechanism that we ignore in favor of the standard
-    // extensions. However, some CAs have issued certificates with the Netscape
-    // Cert Type extension marked critical. Thus, for compatibility reasons, we
-    // "understand" this extension by ignoring it when it is not critical, and
-    // by ensuring that the equivalent standardized extensions are present when
-    // it is marked critical, based on the assumption that the information in
-    // the Netscape Cert Type extension is consistent with the information in
-    // the standard extensions.
-    //
-    // Here is a mapping between the Netscape Cert Type extension and the
-    // standard extensions:
-    //
-    // Netscape Cert Type  |  BasicConstraints.cA  |  Extended Key Usage
-    // --------------------+-----------------------+----------------------
-    // SSL Server          |  false                |  id_kp_serverAuth
-    // SSL Client          |  false                |  id_kp_clientAuth
-    // S/MIME Client       |  false                |  id_kp_emailProtection
-    // Object Signing      |  false                |  id_kp_codeSigning
-    // SSL Server CA       |  true                 |  id_pk_serverAuth
-    // SSL Client CA       |  true                 |  id_kp_clientAuth
-    // S/MIME CA           |  true                 |  id_kp_emailProtection
-    // Object Signing CA   |  true                 |  id_kp_codeSigning
-    if (criticalNetscapeCertificateType.len > 0 &&
-        (basicConstraints.len == 0 || extKeyUsage.len == 0)) {
-      return Result::ERROR_UNKNOWN_CRITICAL_EXTENSION;
-    }
+  rv = der::OptionalExtensions(tbsCertificate, CSC | 3,
+                               bind(&BackCert::RememberExtension, this, _1,
+                                    _2, _3, _4));
+  if (rv != Success) {
+    return rv;
+  }
+
+  // The Netscape Certificate Type extension is an obsolete
+  // Netscape-proprietary mechanism that we ignore in favor of the standard
+  // extensions. However, some CAs have issued certificates with the Netscape
+  // Cert Type extension marked critical. Thus, for compatibility reasons, we
+  // "understand" this extension by ignoring it when it is not critical, and
+  // by ensuring that the equivalent standardized extensions are present when
+  // it is marked critical, based on the assumption that the information in
+  // the Netscape Cert Type extension is consistent with the information in
+  // the standard extensions.
+  //
+  // Here is a mapping between the Netscape Cert Type extension and the
+  // standard extensions:
+  //
+  // Netscape Cert Type  |  BasicConstraints.cA  |  Extended Key Usage
+  // --------------------+-----------------------+----------------------
+  // SSL Server          |  false                |  id_kp_serverAuth
+  // SSL Client          |  false                |  id_kp_clientAuth
+  // S/MIME Client       |  false                |  id_kp_emailProtection
+  // Object Signing      |  false                |  id_kp_codeSigning
+  // SSL Server CA       |  true                 |  id_pk_serverAuth
+  // SSL Client CA       |  true                 |  id_kp_clientAuth
+  // S/MIME CA           |  true                 |  id_kp_emailProtection
+  // Object Signing CA   |  true                 |  id_kp_codeSigning
+  if (criticalNetscapeCertificateType.len > 0 &&
+      (basicConstraints.len == 0 || extKeyUsage.len == 0)) {
+    return Result::ERROR_UNKNOWN_CRITICAL_EXTENSION;
   }
 
   return der::End(tbsCertificate);
 }
 
 Result
 BackCert::RememberExtension(Input& extnID, const SECItem& extnValue,
                             bool critical, /*out*/ bool& understood)