Blob Blame History Raw
From e06171a21b19b1f6f5ce1749cebe2ecf942da614 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Fri, 17 Mar 2017 16:45:18 -0700
Subject: [PATCH 01/11] Added Eclipse project files. Eclipse project file,
 classpath, settings have been added to automate cleanups and certain
 formattings which will simplify and standardize the development.

https://bugzilla.mozilla.org/show_bug.cgi?id=1347394
---
 .classpath                           |   7 +
 .gitignore                           |   1 +
 .project                             |  17 +++
 .settings/org.eclipse.jdt.core.prefs | 282 +++++++++++++++++++++++++++++++++++
 .settings/org.eclipse.jdt.ui.prefs   |  56 +++++++
 5 files changed, 363 insertions(+)
 create mode 100644 .classpath
 create mode 100644 .gitignore
 create mode 100644 .project
 create mode 100644 .settings/org.eclipse.jdt.core.prefs
 create mode 100644 .settings/org.eclipse.jdt.ui.prefs

diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..68f6f4f
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry excluding="samples/" kind="src" path=""/>
+	<classpathentry kind="src" path="samples"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+bin
diff --git a/.project b/.project
new file mode 100644
index 0000000..7f7adff
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>jss</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..d2fbe82
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,282 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=false
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=false
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=8
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=false
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=120
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..40b7812
--- /dev/null
+++ b/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,56 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_PKI Project Profile
+formatter_settings_version=12
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
-- 
2.9.3


From 8019c869865593a8fc078ca6dd555191711dad7b Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Fri, 17 Mar 2017 16:45:25 -0700
Subject: [PATCH 02/11] Cleaned up SSLSocket class. The SSLSocket class has
 been cleaned up using Eclipse to remove trailing white spaces and wildcards
 in import statements.

https://bugzilla.mozilla.org/show_bug.cgi?id=1347394
---
 org/mozilla/jss/ssl/SSLSocket.java | 179 +++++++++++++++++++------------------
 1 file changed, 90 insertions(+), 89 deletions(-)

diff --git a/org/mozilla/jss/ssl/SSLSocket.java b/org/mozilla/jss/ssl/SSLSocket.java
index f91b218..642a3e6 100644
--- a/org/mozilla/jss/ssl/SSLSocket.java
+++ b/org/mozilla/jss/ssl/SSLSocket.java
@@ -4,12 +4,13 @@
 
 package org.mozilla.jss.ssl;
 
-import java.lang.IllegalArgumentException;
-import java.net.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
 import java.net.SocketException;
 import java.net.SocketTimeoutException;
-import java.io.*;
-import java.io.IOException;
+import java.net.UnknownHostException;
 import java.util.Vector;
 
 /**
@@ -41,13 +42,13 @@ public class SSLSocket extends java.net.Socket {
     private boolean open = false;
     private boolean handshakeAsClient = true;
     private SocketBase base = new SocketBase();
-    static final public int SSL_REQUIRE_NEVER =  
+    static final public int SSL_REQUIRE_NEVER =
            org.mozilla.jss.ssl.SocketBase.SSL_REQUIRE_NEVER;
-    static final public int SSL_REQUIRE_ALWAYS = 
+    static final public int SSL_REQUIRE_ALWAYS =
            org.mozilla.jss.ssl.SocketBase.SSL_REQUIRE_ALWAYS;
-    static final public int SSL_REQUIRE_FIRST_HANDSHAKE = 
+    static final public int SSL_REQUIRE_FIRST_HANDSHAKE =
            org.mozilla.jss.ssl.SocketBase.SSL_REQUIRE_FIRST_HANDSHAKE;
-    static final public int SSL_REQUIRE_NO_ERROR = 
+    static final public int SSL_REQUIRE_NO_ERROR =
            org.mozilla.jss.ssl.SocketBase.SSL_REQUIRE_NO_ERROR;
     static final public int SSL_RENEGOTIATE_NEVER =
            org.mozilla.jss.ssl.SocketBase.SSL_RENEGOTIATE_NEVER;
@@ -411,12 +412,12 @@ public class SSLSocket extends java.net.Socket {
      */
     public native void setReceiveBufferSize(int size) throws SocketException;
 
-    /** 
+    /**
      * Returnst he size (in bytes) of the receive buffer.
      */
     public native int getReceiveBufferSize() throws SocketException;
 
-    /** 
+    /**
      * Closes this socket.
      */
     public void close() throws IOException {
@@ -488,7 +489,7 @@ public class SSLSocket extends java.net.Socket {
             l.handshakeCompleted(event);
         }
     }
-               
+
 
     /**
      * Enables SSL v2 on this socket. It is enabled  by default, unless the
@@ -534,10 +535,10 @@ public class SSLSocket extends java.net.Socket {
     static public void enableTLSDefault(boolean enable) throws SocketException{
         setSSLDefaultOption(SocketBase.SSL_ENABLE_TLS, enable);
     }
- 
+
     /**
-     * Enables Session tickets on this socket. It is disabled by default, 
-     * unless the default has been changed with 
+     * Enables Session tickets on this socket. It is disabled by default,
+     * unless the default has been changed with
      * <code>enableSessionTicketsDefault</code>.
      */
     public void enableSessionTickets(boolean enable) throws SocketException {
@@ -547,7 +548,7 @@ public class SSLSocket extends java.net.Socket {
     /**
      * Sets the default for Session Tickets for all new sockets.
      */
-    static public void enableSessionTicketsDefault(boolean enable) 
+    static public void enableSessionTicketsDefault(boolean enable)
         throws SocketException{
         setSSLDefaultOption(SocketBase.SSL_ENABLE_SESSION_TICKETS, enable);
     }
@@ -643,26 +644,26 @@ public class SSLSocket extends java.net.Socket {
 
     /**
      * Enable rollback detection for this socket.
-     * It is enabled by default, unless the default has been changed 
+     * It is enabled by default, unless the default has been changed
      * with <code>enableRollbackDetectionDefault</code>.
      */
-    public void enableRollbackDetection(boolean enable) 
-        throws SocketException 
+    public void enableRollbackDetection(boolean enable)
+        throws SocketException
     {
         base.enableRollbackDetection(enable);
     }
-    
+
     /**
      * Sets the default rollback detection for all new sockets.
      */
-    static void enableRollbackDetectionDefault(boolean enable) 
-        throws SocketException 
+    static void enableRollbackDetectionDefault(boolean enable)
+        throws SocketException
     {
         setSSLDefaultOption(SocketBase.SSL_ROLLBACK_DETECTION, enable);
     }
-    
+
     /**
-     * This option, enableStepDown, is concerned with the generation 
+     * This option, enableStepDown, is concerned with the generation
      * of step-down keys which are used with export suites.
      * If the server cert's public key is 512 bits or less
      * this option is ignored because step-down keys don't
@@ -673,15 +674,15 @@ public class SSLSocket extends java.net.Socket {
      * enable=false: don't generate step-down keys; disable
      * export cipher suites
      *
-     * This option is enabled by default; unless the default has  
+     * This option is enabled by default; unless the default has
      * been changed with <code>SSLSocket.enableStepDownDefault</code>.
      */
     public void enableStepDown(boolean enable) throws SocketException {
         base.enableStepDown(enable);
     }
     /**
-     * This option, enableStepDownDefault, is concerned with the  
-     * generation of step-down keys which are used with export suites. 
+     * This option, enableStepDownDefault, is concerned with the
+     * generation of step-down keys which are used with export suites.
      * This options will set the default for all sockets.
      * If the server cert's public key is 512 bits of less,
      * this option is ignored because step-down keys don't
@@ -694,92 +695,92 @@ public class SSLSocket extends java.net.Socket {
      *
      * This option is enabled by default for all sockets.
      */
-    static void enableStepDownDefault(boolean enable) 
-    throws SocketException 
+    static void enableStepDownDefault(boolean enable)
+    throws SocketException
     {
         setSSLDefaultOption(SocketBase.SSL_NO_STEP_DOWN, enable);
     }
 
     /**
-     * Enable simultaneous read/write by separate read and write threads 
+     * Enable simultaneous read/write by separate read and write threads
      * (full duplex) for this socket.
-     * It is disabled by default, unless the default has been changed 
+     * It is disabled by default, unless the default has been changed
      * with <code>enableFDXDefault</code>.
      */
-    public void enableFDX(boolean enable) 
-    throws SocketException 
+    public void enableFDX(boolean enable)
+    throws SocketException
     {
         base.enableFDX(enable);
     }
-    
+
     /**
-     * Sets the default to permit simultaneous read/write 
+     * Sets the default to permit simultaneous read/write
      * by separate read and write threads (full duplex)
      * for all new sockets.
      */
-    static void enableFDXDefault(boolean enable) 
-    throws SocketException 
+    static void enableFDXDefault(boolean enable)
+    throws SocketException
     {
         setSSLDefaultOption(SocketBase.SSL_ENABLE_FDX, enable);
     }
 
     /**
      * Enable sending v3 client hello in v2 format for this socket.
-     * It is enabled by default, unless the default has been changed 
+     * It is enabled by default, unless the default has been changed
      * with <code>enableV2CompatibleHelloDefault</code>.
      */
-    public void enableV2CompatibleHello(boolean enable) 
-    throws SocketException 
+    public void enableV2CompatibleHello(boolean enable)
+    throws SocketException
     {
         base.enableV2CompatibleHello(enable);
     }
-    
-    /**    
+
+    /**
      * Sets the default to send v3 client hello in v2 format
      * for all new sockets.
      */
-    static void enableV2CompatibleHelloDefault(boolean enable) 
-    throws SocketException 
+    static void enableV2CompatibleHelloDefault(boolean enable)
+    throws SocketException
     {
         setSSLDefaultOption(SocketBase.SSL_V2_COMPATIBLE_HELLO, enable);
     }
-    
+
     /**
      * @return a String listing the current SSLOptions for this SSLSocket.
      */
     public String getSSLOptions() {
         return base.getSSLOptions();
     }
-    
+
     /**
-     * 
-     * @param option 
-     * @return 0 for option disabled 1 for option enabled. 
+     *
+     * @param option
+     * @return 0 for option disabled 1 for option enabled.
      */
     static private native int getSSLDefaultOption(int option)
         throws SocketException;
 
     /**
-     * 
+     *
      * @return a String listing  the Default SSLOptions for all SSLSockets.
      */
     static public String getSSLDefaultOptions() {
         StringBuffer buf = new StringBuffer();
         try {
             buf.append("Default Options configured for all SSLSockets: ");
-            buf.append("\nSSL_ENABLE_SSL2" + 
+            buf.append("\nSSL_ENABLE_SSL2" +
                 ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SSL2) != 0)
                 ? "=on" :  "=off"));
-            buf.append("\nSSL_ENABLE_SSL3"  + 
-                ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SSL3) != 0) 
+            buf.append("\nSSL_ENABLE_SSL3"  +
+                ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SSL3) != 0)
                 ? "=on" :  "=off"));
-            buf.append("\nSSL_ENABLE_TLS"  + 
-                ((getSSLDefaultOption(SocketBase.SSL_ENABLE_TLS) != 0) 
+            buf.append("\nSSL_ENABLE_TLS"  +
+                ((getSSLDefaultOption(SocketBase.SSL_ENABLE_TLS) != 0)
                 ? "=on" :  "=off"));
             buf.append("\nSSL_ENABLE_SESSION_TICKETS"  +
                 ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SESSION_TICKETS)
                 != 0) ? "=on" :  "=off"));
-            buf.append("\nSSL_REQUIRE_CERTIFICATE"); 
+            buf.append("\nSSL_REQUIRE_CERTIFICATE");
             switch (getSSLDefaultOption(SocketBase.SSL_REQUIRE_CERTIFICATE)) {
                 case 0:
                     buf.append("=Never");
@@ -797,23 +798,23 @@ public class SSLSocket extends java.net.Socket {
                    buf.append("=Report JSS Bug this option has a status.");
                    break;
             } //end switch
-            buf.append("\nSSL_REQUEST_CERTIFICATE"  + 
-                ((getSSLDefaultOption(SocketBase.SSL_REQUEST_CERTIFICATE) != 0) 
+            buf.append("\nSSL_REQUEST_CERTIFICATE"  +
+                ((getSSLDefaultOption(SocketBase.SSL_REQUEST_CERTIFICATE) != 0)
                 ? "=on" :  "=off"));
-            buf.append("\nSSL_NO_CACHE"  + 
+            buf.append("\nSSL_NO_CACHE"  +
                 ((getSSLDefaultOption(SocketBase.SSL_NO_CACHE) != 0)
                 ? "=on" :  "=off"));
-            buf.append("\nSSL_ROLLBACK_DETECTION"  + 
+            buf.append("\nSSL_ROLLBACK_DETECTION"  +
                 ((getSSLDefaultOption(SocketBase.SSL_ROLLBACK_DETECTION) != 0)
                 ? "=on" :  "=off"));
-            buf.append("\nSSL_NO_STEP_DOWN"  + 
+            buf.append("\nSSL_NO_STEP_DOWN"  +
                 ((getSSLDefaultOption(SocketBase.SSL_NO_STEP_DOWN) != 0)
                 ? "=on" :  "=off"));
-            buf.append("\nSSL_ENABLE_FDX"  + 
+            buf.append("\nSSL_ENABLE_FDX"  +
                 ((getSSLDefaultOption(SocketBase.SSL_ENABLE_FDX) != 0)
                 ? "=on" :  "=off"));
-            buf.append("\nSSL_V2_COMPATIBLE_HELLO"  + 
-                ((getSSLDefaultOption(SocketBase.SSL_V2_COMPATIBLE_HELLO) != 0) 
+            buf.append("\nSSL_V2_COMPATIBLE_HELLO"  +
+                ((getSSLDefaultOption(SocketBase.SSL_V2_COMPATIBLE_HELLO) != 0)
                 ? "=on" :  "=off"));
             buf.append("\nSSL_ENABLE_SESSION_TICKETS"  +
                 ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SESSION_TICKETS)
@@ -845,7 +846,7 @@ public class SSLSocket extends java.net.Socket {
         }
         return buf.toString();
     }
-    
+
     /**
      *  Sets whether the socket requires client authentication from the remote
      *  peer. If requestClientAuth() has not already been called, this
@@ -863,19 +864,19 @@ public class SSLSocket extends java.net.Socket {
      *  Sets whether the socket requires client authentication from the remote
      *  peer. If requestClientAuth() has not already been called, this method
      *  will tell the socket to request client auth as well as requiring it.
-     *  This is only meaningful for the server end of the SSL connection. 
-     *  During the next handshake, the remote peer will be asked to 
+     *  This is only meaningful for the server end of the SSL connection.
+     *  During the next handshake, the remote peer will be asked to
      *  authenticate itself with the requirement that was set.
      *
-     *  @param mode One of:  SSLSocket.SSL_REQUIRE_NEVER, 
-     *                       SSLSocket.SSL_REQUIRE_ALWAYS, 
-     *                       SSLSocket.SSL_REQUIRE_FIRST_HANDSHAKE, 
+     *  @param mode One of:  SSLSocket.SSL_REQUIRE_NEVER,
+     *                       SSLSocket.SSL_REQUIRE_ALWAYS,
+     *                       SSLSocket.SSL_REQUIRE_FIRST_HANDSHAKE,
      *                       SSLSocket.SSL_REQUIRE_NO_ERROR
      */
     public void requireClientAuth(int mode)
             throws SocketException
     {
-        if (mode >= SocketBase.SSL_REQUIRE_NEVER && 
+        if (mode >= SocketBase.SSL_REQUIRE_NEVER &&
             mode <= SocketBase.SSL_REQUIRE_NO_ERROR) {
             base.requireClientAuth(mode);
         } else {
@@ -900,15 +901,15 @@ public class SSLSocket extends java.net.Socket {
      *  All subsequently created sockets will use this default setting
      *  This is only meaningful for the server end of the SSL connection.
      *
-     *  @param mode One of:  SSLSocket.SSL_REQUIRE_NEVER, 
-     *                       SSLSocket.SSL_REQUIRE_ALWAYS, 
-     *                       SSLSocket.SSL_REQUIRE_FIRST_HANDSHAKE, 
+     *  @param mode One of:  SSLSocket.SSL_REQUIRE_NEVER,
+     *                       SSLSocket.SSL_REQUIRE_ALWAYS,
+     *                       SSLSocket.SSL_REQUIRE_FIRST_HANDSHAKE,
      *                       SSLSocket.SSL_REQUIRE_NO_ERROR
      */
     static public void requireClientAuthDefault(int mode)
             throws SocketException
     {
-        if (mode >= SocketBase.SSL_REQUIRE_NEVER && 
+        if (mode >= SocketBase.SSL_REQUIRE_NEVER &&
             mode <= SocketBase.SSL_REQUIRE_NO_ERROR) {
             setSSLDefaultOption(SocketBase.SSL_REQUEST_CERTIFICATE, true);
             setSSLDefaultOptionMode(SocketBase.SSL_REQUIRE_CERTIFICATE,mode);
@@ -924,7 +925,7 @@ public class SSLSocket extends java.net.Socket {
      */
     public native void forceHandshake() throws SocketException;
 
-    /** 
+    /**
      * Determines whether this end of the socket is the client or the server
      *  for purposes of the SSL protocol. By default, it is the client.
      * @param b true if this end of the socket is the SSL slient, false
@@ -1031,7 +1032,7 @@ public class SSLSocket extends java.net.Socket {
         base.useCache(b);
     }
 
-    /** 
+    /**
      * Sets the default setting for use of the session cache.
      */
     public void useCacheDefault(boolean b) throws SocketException {
@@ -1090,7 +1091,7 @@ public class SSLSocket extends java.net.Socket {
         setSSLVersionRangeDefault(ssl_variant.getEnum(), range.getMinEnum(), range.getMaxEnum());
     }
 
-    /** 
+    /**
      * Sets SSL Version Range Default
      */
     private static native void setSSLVersionRangeDefault(int ssl_variant, int min, int max)
@@ -1102,13 +1103,13 @@ public class SSLSocket extends java.net.Socket {
         setSSLDefaultOption(option, on ? 1 : 0);
     }
 
-    /** 
+    /**
      * Sets SSL Default options that have simple enable/disable values.
      */
     private static native void setSSLDefaultOption(int option, int on)
         throws SocketException;
 
-    /** 
+    /**
      * Set SSL default options that have more modes than enable/disable.
      */
     private static native void setSSLDefaultOptionMode(int option, int mode)
@@ -1141,19 +1142,19 @@ public class SSLSocket extends java.net.Socket {
     native int socketAvailable()
         throws IOException;
 
-    int read(byte[] b, int off, int len) 
+    int read(byte[] b, int off, int len)
         throws IOException, SocketTimeoutException {
         synchronized (readLock) {
             synchronized (this) {
                 if ( isClosed ) { /* abort read if socket is closed */
                     throw new IOException(
-                        "Socket has been closed, and cannot be reused."); 
+                        "Socket has been closed, and cannot be reused.");
                 }
-                inRead = true;            
+                inRead = true;
             }
             int iRet;
             try {
-                iRet = socketRead(b, off, len, base.getTimeout()); 
+                iRet = socketRead(b, off, len, base.getTimeout());
             } catch (SocketTimeoutException ste) {
                 throw new SocketTimeoutException(
                     "SocketTimeoutException cannot read on socket");
@@ -1169,13 +1170,13 @@ public class SSLSocket extends java.net.Socket {
         }
     }
 
-    void write(byte[] b, int off, int len) 
+    void write(byte[] b, int off, int len)
         throws IOException, SocketTimeoutException {
         synchronized (writeLock) {
             synchronized (this) {
                 if ( isClosed ) { /* abort write if socket is closed */
                     throw new IOException(
-                        "Socket has been closed, and cannot be reused."); 
+                        "Socket has been closed, and cannot be reused.");
                 }
                 inWrite = true;
             }
@@ -1284,9 +1285,9 @@ public class SSLSocket extends java.net.Socket {
     }
 
      /**
-     * isFipsCipherSuite 
+     * isFipsCipherSuite
      *
-     *@return true if the ciphersuite isFIPS, false otherwise 
+     *@return true if the ciphersuite isFIPS, false otherwise
      */
     public static boolean isFipsCipherSuite(int ciphersuite) throws SocketException {
         return isFipsCipherSuiteNative(ciphersuite);
@@ -1364,12 +1365,12 @@ public class SSLSocket extends java.net.Socket {
 
     public final static int TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA    = 0x0062;
     public final static int TLS_RSA_EXPORT1024_WITH_RC4_56_SHA     = 0x0064;
- 
+
     public final static int TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA = 0x0063;
     public final static int TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA  = 0x0065;
     public final static int TLS_DHE_DSS_WITH_RC4_128_SHA            = 0x0066;
 
-// New TLS cipher suites in NSS 3.4 
+// New TLS cipher suites in NSS 3.4
     public final static int TLS_RSA_WITH_AES_128_CBC_SHA          =  0x002F;
     public final static int TLS_DH_DSS_WITH_AES_128_CBC_SHA       =  0x0030;
     public final static int TLS_DH_RSA_WITH_AES_128_CBC_SHA       =  0x0031;
-- 
2.9.3


From 0138f3f47e061c088ca231f9b177363beb2c2f62 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Fri, 17 Mar 2017 16:58:28 -0700
Subject: [PATCH 03/11] Reformatted cipher definitions in SSLSocket class. The
 cipher definitions in SSLSocket class have been moved to the top of the class
 and reformatted for better readability.

https://bugzilla.mozilla.org/show_bug.cgi?id=1347429
---
 org/mozilla/jss/ssl/SSLSocket.java | 289 ++++++++++++++++++-------------------
 1 file changed, 144 insertions(+), 145 deletions(-)

diff --git a/org/mozilla/jss/ssl/SSLSocket.java b/org/mozilla/jss/ssl/SSLSocket.java
index 642a3e6..ce39987 100644
--- a/org/mozilla/jss/ssl/SSLSocket.java
+++ b/org/mozilla/jss/ssl/SSLSocket.java
@@ -18,6 +18,150 @@ import java.util.Vector;
  */
 public class SSLSocket extends java.net.Socket {
 
+    /**
+     *
+     * Note the following cipher-suites constants are not all implemented.
+     * You need to call getImplementedCiphersuites.
+     *
+     */
+
+    public final static int SSL2_RC4_128_WITH_MD5                        = 0xFF01;
+    public final static int SSL2_RC4_128_EXPORT40_WITH_MD5               = 0xFF02;
+    public final static int SSL2_RC2_128_CBC_WITH_MD5                    = 0xFF03;
+    public final static int SSL2_RC2_128_CBC_EXPORT40_WITH_MD5           = 0xFF04;
+    public final static int SSL2_IDEA_128_CBC_WITH_MD5                   = 0xFF05;
+    public final static int SSL2_DES_64_CBC_WITH_MD5                     = 0xFF06;
+    public final static int SSL2_DES_192_EDE3_CBC_WITH_MD5               = 0xFF07;
+
+    public final static int SSL3_RSA_WITH_NULL_MD5                       = 0x0001;
+    public final static int SSL3_RSA_WITH_NULL_SHA                       = 0x0002;
+    public final static int SSL3_RSA_EXPORT_WITH_RC4_40_MD5              = 0x0003;
+    public final static int SSL3_RSA_WITH_RC4_128_MD5                    = 0x0004;
+    public final static int SSL3_RSA_WITH_RC4_128_SHA                    = 0x0005;
+    public final static int SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5          = 0x0006;
+    public final static int SSL3_RSA_WITH_IDEA_CBC_SHA                   = 0x0007;
+    public final static int SSL3_RSA_EXPORT_WITH_DES40_CBC_SHA           = 0x0008;
+    public final static int SSL3_RSA_WITH_DES_CBC_SHA                    = 0x0009;
+    public final static int SSL3_RSA_WITH_3DES_EDE_CBC_SHA               = 0x000a;
+
+    public final static int SSL3_DH_DSS_EXPORT_WITH_DES40_CBC_SHA        = 0x000b;
+    public final static int SSL3_DH_DSS_WITH_DES_CBC_SHA                 = 0x000c;
+    public final static int SSL3_DH_DSS_WITH_3DES_EDE_CBC_SHA            = 0x000d;
+    public final static int SSL3_DH_RSA_EXPORT_WITH_DES40_CBC_SHA        = 0x000e;
+    public final static int SSL3_DH_RSA_WITH_DES_CBC_SHA                 = 0x000f;
+    public final static int SSL3_DH_RSA_WITH_3DES_EDE_CBC_SHA            = 0x0010;
+
+    public final static int SSL3_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA       = 0x0011;
+    public final static int SSL3_DHE_DSS_WITH_DES_CBC_SHA                = 0x0012;
+    public final static int SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA           = 0x0013;
+    public final static int SSL3_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA       = 0x0014;
+    public final static int SSL3_DHE_RSA_WITH_DES_CBC_SHA                = 0x0015;
+    public final static int SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA           = 0x0016;
+
+    public final static int SSL3_DH_ANON_EXPORT_WITH_RC4_40_MD5          = 0x0017;
+    public final static int SSL3_DH_ANON_WITH_RC4_128_MD5                = 0x0018;
+    public final static int SSL3_DH_ANON_EXPORT_WITH_DES40_CBC_SHA       = 0x0019;
+    public final static int SSL3_DH_ANON_WITH_DES_CBC_SHA                = 0x001a;
+    public final static int SSL3_DH_ANON_WITH_3DES_EDE_CBC_SHA           = 0x001b;
+
+    /**
+     * @deprecated As of NSS 3.11, FORTEZZA is no longer supported.
+     * SSL3_FORTEZZA_DMS_WITH_NULL_SHA, SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA
+     * and SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA are placeholders for
+     * backward compatibility.
+     */
+    public final static int SSL3_FORTEZZA_DMS_WITH_NULL_SHA              = 0x001c;
+    public final static int SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA      = 0x001d;
+    public final static int SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA           = 0x001e;
+
+    public final static int SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA           = 0xfeff;
+    public final static int SSL_RSA_FIPS_WITH_DES_CBC_SHA                = 0xfefe;
+
+    public final static int TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA          = 0x0062;
+    public final static int TLS_RSA_EXPORT1024_WITH_RC4_56_SHA           = 0x0064;
+
+    public final static int TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA      = 0x0063;
+    public final static int TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA       = 0x0065;
+    public final static int TLS_DHE_DSS_WITH_RC4_128_SHA                 = 0x0066;
+    public final static int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256          = 0x0067;
+    public final static int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256          = 0x006B;
+
+    // New TLS cipher suites in NSS 3.4
+    public final static int TLS_RSA_WITH_AES_128_CBC_SHA                 = 0x002F;
+    public final static int TLS_DH_DSS_WITH_AES_128_CBC_SHA              = 0x0030;
+    public final static int TLS_DH_RSA_WITH_AES_128_CBC_SHA              = 0x0031;
+    public final static int TLS_DHE_DSS_WITH_AES_128_CBC_SHA             = 0x0032;
+    public final static int TLS_DHE_RSA_WITH_AES_128_CBC_SHA             = 0x0033;
+    public final static int TLS_DH_ANON_WITH_AES_128_CBC_SHA             = 0x0034;
+
+    public final static int TLS_RSA_WITH_AES_256_CBC_SHA                 = 0x0035;
+    public final static int TLS_DH_DSS_WITH_AES_256_CBC_SHA              = 0x0036;
+    public final static int TLS_DH_RSA_WITH_AES_256_CBC_SHA              = 0x0037;
+    public final static int TLS_DHE_DSS_WITH_AES_256_CBC_SHA             = 0x0038;
+    public final static int TLS_DHE_RSA_WITH_AES_256_CBC_SHA             = 0x0039;
+    public final static int TLS_DH_ANON_WITH_AES_256_CBC_SHA             = 0x003A;
+    public final static int TLS_RSA_WITH_NULL_SHA256                     = 0x003B;
+    public final static int TLS_RSA_WITH_AES_128_CBC_SHA256              = 0x003C;
+    public final static int TLS_RSA_WITH_AES_256_CBC_SHA256              = 0x003D;
+
+    public final static int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA            = 0x0041;
+    public final static int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA         = 0x0042;
+    public final static int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA         = 0x0043;
+    public final static int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA        = 0x0044;
+    public final static int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA        = 0x0045;
+    public final static int TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA        = 0x0046;
+
+    public final static int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA            = 0x0084;
+    public final static int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA         = 0x0085;
+    public final static int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA         = 0x0086;
+    public final static int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA        = 0x0087;
+    public final static int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA        = 0x0088;
+    public final static int TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA        = 0x0089;
+
+    public final static int TLS_RSA_WITH_SEED_CBC_SHA                    = 0x0096;
+
+    public final static int TLS_RSA_WITH_AES_128_GCM_SHA256              = 0x009C;
+    public final static int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256          = 0x009E;
+    public final static int TLS_DHE_DSS_WITH_AES_128_GCM_SHA256          = 0x00A2;
+
+    public final static int TLS_ECDH_ECDSA_WITH_NULL_SHA                 = 0xc001;
+    public final static int TLS_ECDH_ECDSA_WITH_RC4_128_SHA              = 0xc002;
+    public final static int TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA         = 0xc003;
+    public final static int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA          = 0xc004;
+    public final static int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA          = 0xc005;
+
+    public final static int TLS_ECDHE_ECDSA_WITH_NULL_SHA                = 0xc006;
+    public final static int TLS_ECDHE_ECDSA_WITH_RC4_128_SHA             = 0xc007;
+    public final static int TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA        = 0xc008;
+    public final static int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA         = 0xc009;
+    public final static int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA         = 0xc00a;
+
+    public final static int TLS_ECDH_RSA_WITH_NULL_SHA                   = 0xc00b;
+    public final static int TLS_ECDH_RSA_WITH_RC4_128_SHA                = 0xc00c;
+    public final static int TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA           = 0xc00d;
+    public final static int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA            = 0xc00e;
+    public final static int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA            = 0xc00f;
+
+    public final static int TLS_ECDHE_RSA_WITH_NULL_SHA                  = 0xc010;
+    public final static int TLS_ECDHE_RSA_WITH_RC4_128_SHA               = 0xc011;
+    public final static int TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA          = 0xc012;
+    public final static int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA           = 0xc013;
+    public final static int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA           = 0xc014;
+
+    public final static int TLS_ECDH_anon_WITH_NULL_SHA                  = 0xc015;
+    public final static int TLS_ECDH_anon_WITH_RC4_128_SHA               = 0xc016;
+    public final static int TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA          = 0xc017;
+    public final static int TLS_ECDH_anon_WITH_AES_128_CBC_SHA           = 0xc018;
+    public final static int TLS_ECDH_anon_WITH_AES_256_CBC_SHA           = 0xc019;
+
+    public final static int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256      = 0xc023;
+    public final static int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256        = 0xc027;
+
+    public final static int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256      = 0xc02B;
+    public final static int TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256       = 0xc02D;
+    public final static int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256        = 0xc02F;
+    public final static int TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256         = 0xc031;
+
     /*
      * Locking strategy of SSLSocket
      *
@@ -1303,149 +1447,4 @@ public class SSLSocket extends java.net.Socket {
      * <tt>TLS_RSA_WITH_AES_128_CBC_SHA</tt>).
      */
     public static native int[] getImplementedCipherSuites();
-
-    /**
-     *
-     * Note the following cipher-suites constants are not all implemented.
-     * You need to call getImplementedCiphersuites.
-     *
-     */
-
-    public final static int SSL2_RC4_128_WITH_MD5                  = 0xFF01;
-    public final static int SSL2_RC4_128_EXPORT40_WITH_MD5         = 0xFF02;
-    public final static int SSL2_RC2_128_CBC_WITH_MD5              = 0xFF03;
-    public final static int SSL2_RC2_128_CBC_EXPORT40_WITH_MD5     = 0xFF04;
-    public final static int SSL2_IDEA_128_CBC_WITH_MD5             = 0xFF05;
-    public final static int SSL2_DES_64_CBC_WITH_MD5               = 0xFF06;
-    public final static int SSL2_DES_192_EDE3_CBC_WITH_MD5         = 0xFF07;
-
-    public final static int SSL3_RSA_WITH_NULL_MD5                 = 0x0001;
-    public final static int SSL3_RSA_WITH_NULL_SHA                 = 0x0002;
-    public final static int SSL3_RSA_EXPORT_WITH_RC4_40_MD5        = 0x0003;
-    public final static int SSL3_RSA_WITH_RC4_128_MD5              = 0x0004;
-    public final static int SSL3_RSA_WITH_RC4_128_SHA              = 0x0005;
-    public final static int SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5    = 0x0006;
-    public final static int SSL3_RSA_WITH_IDEA_CBC_SHA             = 0x0007;
-    public final static int SSL3_RSA_EXPORT_WITH_DES40_CBC_SHA     = 0x0008;
-    public final static int SSL3_RSA_WITH_DES_CBC_SHA              = 0x0009;
-    public final static int SSL3_RSA_WITH_3DES_EDE_CBC_SHA         = 0x000a;
-
-    public final static int SSL3_DH_DSS_EXPORT_WITH_DES40_CBC_SHA  = 0x000b;
-    public final static int SSL3_DH_DSS_WITH_DES_CBC_SHA           = 0x000c;
-    public final static int SSL3_DH_DSS_WITH_3DES_EDE_CBC_SHA      = 0x000d;
-    public final static int SSL3_DH_RSA_EXPORT_WITH_DES40_CBC_SHA  = 0x000e;
-    public final static int SSL3_DH_RSA_WITH_DES_CBC_SHA           = 0x000f;
-    public final static int SSL3_DH_RSA_WITH_3DES_EDE_CBC_SHA      = 0x0010;
-
-    public final static int SSL3_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011;
-    public final static int SSL3_DHE_DSS_WITH_DES_CBC_SHA          = 0x0012;
-    public final static int SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA     = 0x0013;
-    public final static int SSL3_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014;
-    public final static int SSL3_DHE_RSA_WITH_DES_CBC_SHA          = 0x0015;
-    public final static int SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA     = 0x0016;
-
-    public final static int SSL3_DH_ANON_EXPORT_WITH_RC4_40_MD5    = 0x0017;
-    public final static int SSL3_DH_ANON_WITH_RC4_128_MD5          = 0x0018;
-    public final static int SSL3_DH_ANON_EXPORT_WITH_DES40_CBC_SHA = 0x0019;
-    public final static int SSL3_DH_ANON_WITH_DES_CBC_SHA          = 0x001a;
-    public final static int SSL3_DH_ANON_WITH_3DES_EDE_CBC_SHA     = 0x001b;
-
-    /**
-     * @deprecated As of NSS 3.11, FORTEZZA is no longer supported.
-     * SSL3_FORTEZZA_DMS_WITH_NULL_SHA, SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA
-     * and SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA are placeholders for
-     * backward compatibility.
-     */
-    public final static int SSL3_FORTEZZA_DMS_WITH_NULL_SHA        = 0x001c;
-    public final static int SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA= 0x001d;
-    public final static int SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA     = 0x001e;
-
-    public final static int SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA     = 0xfeff;
-    public final static int SSL_RSA_FIPS_WITH_DES_CBC_SHA          = 0xfefe;
-
-    public final static int TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA    = 0x0062;
-    public final static int TLS_RSA_EXPORT1024_WITH_RC4_56_SHA     = 0x0064;
-
-    public final static int TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA = 0x0063;
-    public final static int TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA  = 0x0065;
-    public final static int TLS_DHE_DSS_WITH_RC4_128_SHA            = 0x0066;
-
-// New TLS cipher suites in NSS 3.4
-    public final static int TLS_RSA_WITH_AES_128_CBC_SHA          =  0x002F;
-    public final static int TLS_DH_DSS_WITH_AES_128_CBC_SHA       =  0x0030;
-    public final static int TLS_DH_RSA_WITH_AES_128_CBC_SHA       =  0x0031;
-    public final static int TLS_DHE_DSS_WITH_AES_128_CBC_SHA      =  0x0032;
-    public final static int TLS_DHE_RSA_WITH_AES_128_CBC_SHA      =  0x0033;
-    public final static int TLS_DH_ANON_WITH_AES_128_CBC_SHA      =  0x0034;
-
-    public final static int TLS_RSA_WITH_AES_256_CBC_SHA          =  0x0035;
-    public final static int TLS_DH_DSS_WITH_AES_256_CBC_SHA       =  0x0036;
-    public final static int TLS_DH_RSA_WITH_AES_256_CBC_SHA       =  0x0037;
-    public final static int TLS_DHE_DSS_WITH_AES_256_CBC_SHA      =  0x0038;
-    public final static int TLS_DHE_RSA_WITH_AES_256_CBC_SHA      =  0x0039;
-    public final static int TLS_DH_ANON_WITH_AES_256_CBC_SHA      =  0x003a;
-    public final static int TLS_RSA_WITH_NULL_SHA256              =  0x003b;
-    public final static int TLS_RSA_WITH_AES_128_CBC_SHA256       =  0x003c;
-    public final static int TLS_RSA_WITH_AES_256_CBC_SHA256       =  0x003d;
-
-    public final static int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA     =  0x0041;
-    public final static int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA  =  0x0042;
-    public final static int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA  =  0x0043;
-    public final static int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA =  0x0044;
-    public final static int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA =  0x0045;
-    public final static int TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA =  0x0046;
-
-    public final static int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256   =  0x0067;
-    public final static int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256   =  0x006b;
-
-    public final static int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA     =  0x0084;
-    public final static int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA  =  0x0085;
-    public final static int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA  =  0x0086;
-    public final static int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA =  0x0087;
-    public final static int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA =  0x0088;
-    public final static int TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA =  0x0089;
-
-    public final static int TLS_RSA_WITH_SEED_CBC_SHA             =  0x0096;
-
-    public final static int TLS_RSA_WITH_AES_128_GCM_SHA256       =  0x009c;
-    public final static int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256   =  0x009e;
-    public final static int TLS_DHE_DSS_WITH_AES_128_GCM_SHA256   =  0x00A2;
-
-    public final static int TLS_ECDH_ECDSA_WITH_NULL_SHA          =  0xc001;
-    public final static int TLS_ECDH_ECDSA_WITH_RC4_128_SHA       =  0xc002;
-    public final static int TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA  =  0xc003;
-    public final static int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA   =  0xc004;
-    public final static int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA   =  0xc005;
-
-    public final static int TLS_ECDHE_ECDSA_WITH_NULL_SHA         =  0xc006;
-    public final static int TLS_ECDHE_ECDSA_WITH_RC4_128_SHA      =  0xc007;
-    public final static int TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA =  0xc008;
-    public final static int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA  =  0xc009;
-    public final static int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA  =  0xc00a;
-
-    public final static int TLS_ECDH_RSA_WITH_NULL_SHA            =  0xc00b;
-    public final static int TLS_ECDH_RSA_WITH_RC4_128_SHA         =  0xc00c;
-    public final static int TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA    =  0xc00d;
-    public final static int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA     =  0xc00e;
-    public final static int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA     =  0xc00f;
-
-    public final static int TLS_ECDHE_RSA_WITH_NULL_SHA           =  0xc010;
-    public final static int TLS_ECDHE_RSA_WITH_RC4_128_SHA        =  0xc011;
-    public final static int TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA   =  0xc012;
-    public final static int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA    =  0xc013;
-    public final static int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA    =  0xc014;
-
-    public final static int TLS_ECDH_anon_WITH_NULL_SHA           =  0xc015;
-    public final static int TLS_ECDH_anon_WITH_RC4_128_SHA        =  0xc016;
-    public final static int TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA   =  0xc017;
-    public final static int TLS_ECDH_anon_WITH_AES_128_CBC_SHA    =  0xc018;
-    public final static int TLS_ECDH_anon_WITH_AES_256_CBC_SHA    =  0xc019;
-
-    public final static int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xc023;
-    public final static int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 =  0xc027;
-    public final static int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xc02b;
-    public final static int TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256  = 0xc02D;
-    public final static int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 =  0xc02f;
-    public final static int TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256    = 0xc031;
 }
-
-- 
2.9.3


From 71f8cd5a15610690f6e8f226fc081b10f9dd9cb6 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Fri, 17 Mar 2017 16:59:11 -0700
Subject: [PATCH 04/11] Added annotations for deprecated SSL 3.0 ciphers. Some
 SSL 3.0 ciphers have deprecated according to this list:
 https://github.com/nss-dev/nss/blob/master/lib/ssl/sslproto.h

The deprecated cipher definitions have been marked accordingly
in the SSLSocket class. The replacement cipher definitions (if
any) have been added with the same cipher IDs.

https://bugzilla.mozilla.org/show_bug.cgi?id=1347429
---
 org/mozilla/jss/ssl/SSLSocket.java | 152 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 149 insertions(+), 3 deletions(-)

diff --git a/org/mozilla/jss/ssl/SSLSocket.java b/org/mozilla/jss/ssl/SSLSocket.java
index ce39987..2e1ac54 100644
--- a/org/mozilla/jss/ssl/SSLSocket.java
+++ b/org/mozilla/jss/ssl/SSLSocket.java
@@ -33,45 +33,166 @@ public class SSLSocket extends java.net.Socket {
     public final static int SSL2_DES_64_CBC_WITH_MD5                     = 0xFF06;
     public final static int SSL2_DES_192_EDE3_CBC_WITH_MD5               = 0xFF07;
 
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_NULL_MD5.
+     */
+    @Deprecated
     public final static int SSL3_RSA_WITH_NULL_MD5                       = 0x0001;
+    public final static int TLS_RSA_WITH_NULL_MD5                        = 0x0001;
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_NULL_SHA.
+     */
+    @Deprecated
     public final static int SSL3_RSA_WITH_NULL_SHA                       = 0x0002;
+    public final static int TLS_RSA_WITH_NULL_SHA                        = 0x0002;
+
     public final static int SSL3_RSA_EXPORT_WITH_RC4_40_MD5              = 0x0003;
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_RC4_128_MD5.
+     */
+    @Deprecated
     public final static int SSL3_RSA_WITH_RC4_128_MD5                    = 0x0004;
+    public final static int TLS_RSA_WITH_RC4_128_MD5                     = 0x0004;
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_RC4_128_SHA.
+     */
+    @Deprecated
     public final static int SSL3_RSA_WITH_RC4_128_SHA                    = 0x0005;
+    public final static int TLS_RSA_WITH_RC4_128_SHA                     = 0x0005;
+
     public final static int SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5          = 0x0006;
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_IDEA_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_RSA_WITH_IDEA_CBC_SHA                   = 0x0007;
+    public final static int TLS_RSA_WITH_IDEA_CBC_SHA                    = 0x0007;
+
     public final static int SSL3_RSA_EXPORT_WITH_DES40_CBC_SHA           = 0x0008;
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_RSA_WITH_DES_CBC_SHA                    = 0x0009;
+    public final static int TLS_RSA_WITH_DES_CBC_SHA                     = 0x0009;
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_RSA_WITH_3DES_EDE_CBC_SHA               = 0x000a;
+    public final static int TLS_RSA_WITH_3DES_EDE_CBC_SHA                = 0x000a;
 
     public final static int SSL3_DH_DSS_EXPORT_WITH_DES40_CBC_SHA        = 0x000b;
+
+    /**
+     * @deprecated Replaced with TLS_DH_DSS_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_DH_DSS_WITH_DES_CBC_SHA                 = 0x000c;
+    public final static int TLS_DH_DSS_WITH_DES_CBC_SHA                  = 0x000c;
+
+    /**
+     * @deprecated Replaced with TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_DH_DSS_WITH_3DES_EDE_CBC_SHA            = 0x000d;
+    public final static int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA             = 0x000d;
+
     public final static int SSL3_DH_RSA_EXPORT_WITH_DES40_CBC_SHA        = 0x000e;
+
+    /**
+     * @deprecated Replaced with TLS_DH_RSA_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_DH_RSA_WITH_DES_CBC_SHA                 = 0x000f;
+    public final static int TLS_DH_RSA_WITH_DES_CBC_SHA                  = 0x000f;
+
+    /**
+     * @deprecated Replaced with TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_DH_RSA_WITH_3DES_EDE_CBC_SHA            = 0x0010;
+    public final static int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA             = 0x0010;
 
     public final static int SSL3_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA       = 0x0011;
+
+    /**
+     * @deprecated Replaced with TLS_DHE_DSS_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_DHE_DSS_WITH_DES_CBC_SHA                = 0x0012;
+    public final static int TLS_DHE_DSS_WITH_DES_CBC_SHA                 = 0x0012;
+
+    /**
+     * @deprecated Replaced with TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA           = 0x0013;
+    public final static int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA            = 0x0013;
+
     public final static int SSL3_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA       = 0x0014;
+
+    /**
+     * @deprecated Replaced with TLS_DHE_RSA_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_DHE_RSA_WITH_DES_CBC_SHA                = 0x0015;
+    public final static int TLS_DHE_RSA_WITH_DES_CBC_SHA                 = 0x0015;
+
+    /**
+     * @deprecated Replaced with TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA           = 0x0016;
+    public final static int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA            = 0x0016;
 
     public final static int SSL3_DH_ANON_EXPORT_WITH_RC4_40_MD5          = 0x0017;
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_RC4_128_MD5.
+     */
+    @Deprecated
     public final static int SSL3_DH_ANON_WITH_RC4_128_MD5                = 0x0018;
+    public final static int TLS_DH_anon_WITH_RC4_128_MD5                 = 0x0018;
+
     public final static int SSL3_DH_ANON_EXPORT_WITH_DES40_CBC_SHA       = 0x0019;
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_DH_ANON_WITH_DES_CBC_SHA                = 0x001a;
+    public final static int TLS_DH_anon_WITH_DES_CBC_SHA                 = 0x001a;
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
     public final static int SSL3_DH_ANON_WITH_3DES_EDE_CBC_SHA           = 0x001b;
+    public final static int TLS_DH_anon_WITH_3DES_EDE_CBC_SHA            = 0x001b;
 
     /**
      * @deprecated As of NSS 3.11, FORTEZZA is no longer supported.
-     * SSL3_FORTEZZA_DMS_WITH_NULL_SHA, SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA
-     * and SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA are placeholders for
-     * backward compatibility.
      */
+    @Deprecated
     public final static int SSL3_FORTEZZA_DMS_WITH_NULL_SHA              = 0x001c;
+
+    /**
+     * @deprecated As of NSS 3.11, FORTEZZA is no longer supported.
+     */
+    @Deprecated
     public final static int SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA      = 0x001d;
+
+    /**
+     * @deprecated As of NSS 3.11, FORTEZZA is no longer supported.
+     */
+    @Deprecated
     public final static int SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA           = 0x001e;
 
     public final static int SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA           = 0xfeff;
@@ -92,14 +213,27 @@ public class SSLSocket extends java.net.Socket {
     public final static int TLS_DH_RSA_WITH_AES_128_CBC_SHA              = 0x0031;
     public final static int TLS_DHE_DSS_WITH_AES_128_CBC_SHA             = 0x0032;
     public final static int TLS_DHE_RSA_WITH_AES_128_CBC_SHA             = 0x0033;
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_AES_128_CBC_SHA.
+     */
+    @Deprecated
     public final static int TLS_DH_ANON_WITH_AES_128_CBC_SHA             = 0x0034;
+    public final static int TLS_DH_anon_WITH_AES_128_CBC_SHA             = 0x0034;
 
     public final static int TLS_RSA_WITH_AES_256_CBC_SHA                 = 0x0035;
     public final static int TLS_DH_DSS_WITH_AES_256_CBC_SHA              = 0x0036;
     public final static int TLS_DH_RSA_WITH_AES_256_CBC_SHA              = 0x0037;
     public final static int TLS_DHE_DSS_WITH_AES_256_CBC_SHA             = 0x0038;
     public final static int TLS_DHE_RSA_WITH_AES_256_CBC_SHA             = 0x0039;
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_AES_256_CBC_SHA.
+     */
+    @Deprecated
     public final static int TLS_DH_ANON_WITH_AES_256_CBC_SHA             = 0x003A;
+    public final static int TLS_DH_anon_WITH_AES_256_CBC_SHA             = 0x003A;
+
     public final static int TLS_RSA_WITH_NULL_SHA256                     = 0x003B;
     public final static int TLS_RSA_WITH_AES_128_CBC_SHA256              = 0x003C;
     public final static int TLS_RSA_WITH_AES_256_CBC_SHA256              = 0x003D;
@@ -109,14 +243,26 @@ public class SSLSocket extends java.net.Socket {
     public final static int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA         = 0x0043;
     public final static int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA        = 0x0044;
     public final static int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA        = 0x0045;
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA.
+     */
+    @Deprecated
     public final static int TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA        = 0x0046;
+    public final static int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA        = 0x0046;
 
     public final static int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA            = 0x0084;
     public final static int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA         = 0x0085;
     public final static int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA         = 0x0086;
     public final static int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA        = 0x0087;
     public final static int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA        = 0x0088;
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA.
+     */
+    @Deprecated
     public final static int TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA        = 0x0089;
+    public final static int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA        = 0x0089;
 
     public final static int TLS_RSA_WITH_SEED_CBC_SHA                    = 0x0096;
 
-- 
2.9.3


From 7027cbab0757376f4719674173206df0cdadd592 Mon Sep 17 00:00:00 2001
From: "Endi S. Edewata" <edewata@redhat.com>
Date: Tue, 21 Mar 2017 13:09:37 -0700
Subject: [PATCH 05/11] Added SSLSocketListener. The SSLSocket has been
 modified to support SSLSocketListener which will be invoked when an SSL alert
 has been sent or received, also when an SSL handshake has been completed.

https://bugzilla.mozilla.org/show_bug.cgi?id=1348856
---
 org/mozilla/jss/ssl/SSLAlertDescription.java |  64 ++++++++++++++
 org/mozilla/jss/ssl/SSLAlertEvent.java       |  39 +++++++++
 org/mozilla/jss/ssl/SSLAlertLevel.java       |  29 +++++++
 org/mozilla/jss/ssl/SSLSocket.java           |  53 ++++++++----
 org/mozilla/jss/ssl/SSLSocketListener.java   |  11 +++
 org/mozilla/jss/ssl/callbacks.c              | 119 +++++++++++++++++++++++++++
 org/mozilla/jss/ssl/common.c                 |  19 +++++
 org/mozilla/jss/ssl/jssl.h                   |   8 ++
 org/mozilla/jss/util/java_ids.h              |   8 ++
 9 files changed, 332 insertions(+), 18 deletions(-)
 create mode 100644 org/mozilla/jss/ssl/SSLAlertDescription.java
 create mode 100644 org/mozilla/jss/ssl/SSLAlertEvent.java
 create mode 100644 org/mozilla/jss/ssl/SSLAlertLevel.java
 create mode 100644 org/mozilla/jss/ssl/SSLSocketListener.java

diff --git a/org/mozilla/jss/ssl/SSLAlertDescription.java b/org/mozilla/jss/ssl/SSLAlertDescription.java
new file mode 100644
index 0000000..c2ed060
--- /dev/null
+++ b/org/mozilla/jss/ssl/SSLAlertDescription.java
@@ -0,0 +1,64 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.jss.ssl;
+
+public enum SSLAlertDescription {
+
+    // see lib/ssl/ssl3prot.h in NSS
+    CLOSE_NOTIFY                    (0),
+    END_OF_EARLY_DATA               (1), // TLS 1.3
+    UNEXPECTED_MESSAGE              (10),
+    BAD_RECORD_MAC                  (20),
+    DECRYPTION_FAILED               (21), // RFC 5246
+    RECORD_OVERFLOW                 (22), // TLS only
+    DECOMPRESSION_FAILURE           (30),
+    HANDSHAKE_FAILURE               (40),
+    NO_CERTIFICATE                  (41), // SSL3 only, NOT TLS
+    BAD_CERTIFICATE                 (42),
+    UNSUPPORTED_CERTIFICATE         (43),
+    CERTIFICATE_REVOKED             (44),
+    CERTIFICATE_EXPIRED             (45),
+    CERTIFICATE_UNKNOWN             (46),
+    ILLEGAL_PARAMETER               (47),
+
+    // All alerts below are TLS only.
+    UNKNOWN_CA                      (48),
+    ACCESS_DENIED                   (49),
+    DECODE_ERROR                    (50),
+    DECRYPT_ERROR                   (51),
+    EXPORT_RESTRICTION              (60),
+    PROTOCOL_VERSION                (70),
+    INSUFFICIENT_SECURITY           (71),
+    INTERNAL_ERROR                  (80),
+    INAPPROPRIATE_FALLBACK          (86), // could also be sent for SSLv3
+    USER_CANCELED                   (90),
+    NO_RENEGOTIATION                (100),
+
+    // Alerts for client hello extensions
+    MISSING_EXTENSION               (109),
+    UNSUPPORTED_EXTENSION           (110),
+    CERTIFICATE_UNOBTAINABLE        (111),
+    UNRECOGNIZED_NAME               (112),
+    BAD_CERTIFICATE_STATUS_RESPONSE (113),
+    BAD_CERTIFICATE_HASH_VALUE      (114),
+    NO_APPLICATION_PROTOCOL         (120);
+
+    private int id;
+
+    private SSLAlertDescription(int id) {
+        this.id = id;
+    }
+
+    public int getID() {
+        return id;
+    }
+
+    public static SSLAlertDescription valueOf(int id) {
+        for (SSLAlertDescription description : SSLAlertDescription.class.getEnumConstants()) {
+            if (description.id == id) return description;
+        }
+        return null;
+    }
+}
diff --git a/org/mozilla/jss/ssl/SSLAlertEvent.java b/org/mozilla/jss/ssl/SSLAlertEvent.java
new file mode 100644
index 0000000..bfa42e1
--- /dev/null
+++ b/org/mozilla/jss/ssl/SSLAlertEvent.java
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.jss.ssl;
+
+import java.util.EventObject;
+
+public class SSLAlertEvent extends EventObject {
+
+    private static final long serialVersionUID = 1L;
+
+    int level;
+    int description;
+
+    public SSLAlertEvent(SSLSocket socket) {
+        super(socket);
+    }
+
+    public SSLSocket getSocket() {
+        return (SSLSocket)getSource();
+    }
+
+    public int getLevel() {
+        return level;
+    }
+
+    public void setLevel(int level) {
+        this.level = level;
+    }
+
+    public int getDescription() {
+        return description;
+    }
+
+    public void setDescription(int description) {
+        this.description = description;
+    }
+}
diff --git a/org/mozilla/jss/ssl/SSLAlertLevel.java b/org/mozilla/jss/ssl/SSLAlertLevel.java
new file mode 100644
index 0000000..f7f44f2
--- /dev/null
+++ b/org/mozilla/jss/ssl/SSLAlertLevel.java
@@ -0,0 +1,29 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.jss.ssl;
+
+public enum SSLAlertLevel {
+
+    // see lib/ssl/ssl3prot.h in NSS
+    WARNING (1),
+    FATAL   (2);
+
+    private int id;
+
+    private SSLAlertLevel(int id) {
+        this.id = id;
+    }
+
+    public int getID() {
+        return id;
+    }
+
+    public static SSLAlertLevel valueOf(int id) {
+        for (SSLAlertLevel level : SSLAlertLevel.class.getEnumConstants()) {
+            if (level.id == id) return level;
+        }
+        return null;
+    }
+}
diff --git a/org/mozilla/jss/ssl/SSLSocket.java b/org/mozilla/jss/ssl/SSLSocket.java
index 2e1ac54..0dd39fd 100644
--- a/org/mozilla/jss/ssl/SSLSocket.java
+++ b/org/mozilla/jss/ssl/SSLSocket.java
@@ -11,7 +11,8 @@ import java.net.InetAddress;
 import java.net.SocketException;
 import java.net.SocketTimeoutException;
 import java.net.UnknownHostException;
-import java.util.Vector;
+import java.util.ArrayList;
+import java.util.Collection;
 
 /**
  * SSL client socket.
@@ -349,6 +350,9 @@ public class SSLSocket extends java.net.Socket {
     static final public int SSL_RENEGOTIATE_TRANSITIONAL  =
            org.mozilla.jss.ssl.SocketBase.SSL_RENEGOTIATE_TRANSITIONAL;
 
+    private Collection<SSLSocketListener> socketListeners = new ArrayList<>();
+    private Collection<SSLHandshakeCompletedListener> handshakeCompletedListeners = new ArrayList<>();
+
     /**
      * For sockets that get created by accept().
      */
@@ -749,38 +753,51 @@ public class SSLSocket extends java.net.Socket {
     ////////////////////////////////////////////////////////////////////
     // SSL-specific stuff
     ////////////////////////////////////////////////////////////////////
-    private Vector handshakeCompletedListeners = new Vector();
+
+    public void addSocketListener(SSLSocketListener listener) {
+        socketListeners.add(listener);
+        addHandshakeCompletedListener(listener);
+    }
+
+    public void removeSocketListener(SSLSocketListener listener) {
+        socketListeners.remove(listener);
+        removeHandshakeCompletedListener(listener);
+    }
+
+    private void fireAlertReceivedEvent(SSLAlertEvent event) {
+        for (SSLSocketListener listener : socketListeners) {
+            listener.alertReceived(event);
+        }
+    }
+
+    private void fireAlertSentEvent(SSLAlertEvent event) {
+        for (SSLSocketListener listener : socketListeners) {
+            listener.alertSent(event);
+        }
+    }
 
     /**
      * Adds a listener to be notified when an SSL handshake completes.
      */
-    public void addHandshakeCompletedListener(SSLHandshakeCompletedListener l) {
-        handshakeCompletedListeners.addElement(l);
+    public void addHandshakeCompletedListener(SSLHandshakeCompletedListener listener) {
+        handshakeCompletedListeners.add(listener);
     }
 
     /**
      * Removes a previously registered listener for handshake completion.
      */
-    public void removeHandshakeCompletedListener(
-            SSLHandshakeCompletedListener l) {
-        handshakeCompletedListeners.removeElement(l);
+    public void removeHandshakeCompletedListener(SSLHandshakeCompletedListener listener) {
+        handshakeCompletedListeners.remove(listener);
     }
 
     private void notifyAllHandshakeListeners() {
-        SSLHandshakeCompletedEvent event =
-            new SSLHandshakeCompletedEvent(this);
-
-        /* XXX NOT THREAD SAFE */
-        int i;
-        for( i=0; i < handshakeCompletedListeners.size(); ++i) {
-            SSLHandshakeCompletedListener l =
-                (SSLHandshakeCompletedListener)
-                 handshakeCompletedListeners.elementAt(i);
-            l.handshakeCompleted(event);
+        SSLHandshakeCompletedEvent event = new SSLHandshakeCompletedEvent(this);
+
+        for (SSLHandshakeCompletedListener listener : handshakeCompletedListeners) {
+            listener.handshakeCompleted(event);
         }
     }
 
-
     /**
      * Enables SSL v2 on this socket. It is enabled  by default, unless the
      * default has been changed with <code>enableSSL2Default</code>.
diff --git a/org/mozilla/jss/ssl/SSLSocketListener.java b/org/mozilla/jss/ssl/SSLSocketListener.java
new file mode 100644
index 0000000..e653f66
--- /dev/null
+++ b/org/mozilla/jss/ssl/SSLSocketListener.java
@@ -0,0 +1,11 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.jss.ssl;
+
+public interface SSLSocketListener extends SSLHandshakeCompletedListener {
+
+    public void alertReceived(SSLAlertEvent event);
+    public void alertSent(SSLAlertEvent event);
+}
diff --git a/org/mozilla/jss/ssl/callbacks.c b/org/mozilla/jss/ssl/callbacks.c
index d691363..0738e79 100644
--- a/org/mozilla/jss/ssl/callbacks.c
+++ b/org/mozilla/jss/ssl/callbacks.c
@@ -271,6 +271,125 @@ loser:
     return rv;
 }
 
+void
+JSSL_AlertReceivedCallback(const PRFileDesc *fd, void *arg, const SSLAlert *alert)
+{
+    JSSL_SocketData *socket = (JSSL_SocketData*) arg;
+
+    jint rc;
+    JNIEnv *env;
+    jclass socketClass, eventClass;
+    jmethodID eventConstructor, eventSetLevel, eventSetDescription;
+    jobject event;
+    jmethodID fireEvent;
+
+    PR_ASSERT(socket != NULL);
+    PR_ASSERT(socket->socketObject != NULL);
+
+    rc = (*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL);
+    PR_ASSERT(rc == JNI_OK);
+    PR_ASSERT(env != NULL);
+
+    /* SSLAlertEvent event = new SSLAlertEvent(socket); */
+
+    socketClass = (*env)->FindClass(env, SSLSOCKET_CLASS);
+    PR_ASSERT(socketClass != NULL);
+
+    eventClass = (*env)->FindClass(env, SSL_ALERT_EVENT_CLASS);
+    PR_ASSERT(eventClass != NULL);
+
+    eventConstructor = (*env)->GetMethodID(env, eventClass, "<init>", "(L" SSLSOCKET_CLASS ";)V");
+    PR_ASSERT(eventConstructor != NULL);
+
+    event = (*env)->NewObject(env, eventClass, eventConstructor, socket->socketObject);
+    PR_ASSERT(event != NULL);
+
+    /* event.setLevel(level); */
+
+    eventSetLevel = (*env)->GetMethodID(env, eventClass, "setLevel", "(I)V");
+    PR_ASSERT(eventSetLevel != NULL);
+
+    (*env)->CallVoidMethod(env, event, eventSetLevel, (int)alert->level);
+
+    /* event.setDescription(description); */
+
+    eventSetDescription = (*env)->GetMethodID(env, eventClass, "setDescription", "(I)V");
+    PR_ASSERT(eventSetDescription != NULL);
+
+    (*env)->CallVoidMethod(env, event, eventSetDescription, alert->description);
+
+    /* socket.fireAlertReceivedEvent(event); */
+
+    fireEvent = (*env)->GetMethodID(env,
+        socketClass,
+        "fireAlertReceivedEvent",
+        "(L" SSL_ALERT_EVENT_CLASS ";)V");
+    PR_ASSERT(fireEvent != NULL);
+
+    (*env)->CallVoidMethod(env, socket->socketObject, fireEvent, event);
+
+    (*JSS_javaVM)->DetachCurrentThread(JSS_javaVM);
+}
+
+void
+JSSL_AlertSentCallback(const PRFileDesc *fd, void *arg, const SSLAlert *alert)
+{
+    JSSL_SocketData *socket = (JSSL_SocketData*) arg;
+
+    jint rc;
+    JNIEnv *env;
+    jclass socketClass, eventClass;
+    jmethodID eventConstructor, eventSetLevel, eventSetDescription;
+    jobject event;
+    jmethodID fireEvent;
+
+    PR_ASSERT(socket != NULL);
+    PR_ASSERT(socket->socketObject != NULL);
+
+    rc = (*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL);
+    PR_ASSERT(rc == JNI_OK);
+    PR_ASSERT(env != NULL);
+
+    /* SSLAlertEvent event = new SSLAlertEvent(socket); */
+
+    socketClass = (*env)->FindClass(env, SSLSOCKET_CLASS);
+    PR_ASSERT(socketClass != NULL);
+
+    eventClass = (*env)->FindClass(env, SSL_ALERT_EVENT_CLASS);
+    PR_ASSERT(eventClass != NULL);
+
+    eventConstructor = (*env)->GetMethodID(env, eventClass, "<init>", "(L" SSLSOCKET_CLASS ";)V");
+    PR_ASSERT(eventConstructor != NULL);
+
+    event = (*env)->NewObject(env, eventClass, eventConstructor, socket->socketObject);
+    PR_ASSERT(event != NULL);
+
+    /* event.setLevel(level); */
+
+    eventSetLevel = (*env)->GetMethodID(env, eventClass, "setLevel", "(I)V");
+    PR_ASSERT(eventSetLevel != NULL);
+
+    (*env)->CallVoidMethod(env, event, eventSetLevel, (int)alert->level);
+
+    /* event.setDescription(description); */
+
+    eventSetDescription = (*env)->GetMethodID(env, eventClass, "setDescription", "(I)V");
+    PR_ASSERT(eventSetDescription != NULL);
+
+    (*env)->CallVoidMethod(env, event, eventSetDescription, alert->description);
+
+    /* socket.fireAlertSentEvent(event); */
+
+    fireEvent = (*env)->GetMethodID(env,
+        socketClass,
+        "fireAlertSentEvent",
+        "(L" SSL_ALERT_EVENT_CLASS ";)V");
+    PR_ASSERT(fireEvent != NULL);
+
+    (*env)->CallVoidMethod(env, socket->socketObject, fireEvent, event);
+
+    (*JSS_javaVM)->DetachCurrentThread(JSS_javaVM);
+}
 
 void
 JSSL_HandshakeCallback(PRFileDesc *fd, void *arg)
diff --git a/org/mozilla/jss/ssl/common.c b/org/mozilla/jss/ssl/common.c
index be35c57..84a4332 100644
--- a/org/mozilla/jss/ssl/common.c
+++ b/org/mozilla/jss/ssl/common.c
@@ -261,6 +261,7 @@ JSSL_SocketData*
 JSSL_CreateSocketData(JNIEnv *env, jobject sockObj, PRFileDesc* newFD,
         PRFilePrivate *priv)
 {
+    SECStatus status;
     JSSL_SocketData *sockdata = NULL;
 
     /* make a JSSL_SocketData structure */
@@ -297,6 +298,24 @@ JSSL_CreateSocketData(JNIEnv *env, jobject sockObj, PRFileDesc* newFD,
     sockdata->socketObject = NEW_WEAK_GLOBAL_REF(env, sockObj);
     if( sockdata->socketObject == NULL ) goto finish;
 
+    /* registering alert received callback */
+
+    status = SSL_AlertReceivedCallback(sockdata->fd, JSSL_AlertReceivedCallback, sockdata);
+
+    if (status != SECSuccess) {
+        JSSL_throwSSLSocketException(env, "Unable to install alert received callback");
+        goto finish;
+    }
+
+    /* registering alert sent callback */
+
+    status = SSL_AlertSentCallback(sockdata->fd, JSSL_AlertSentCallback, sockdata);
+
+    if (status != SECSuccess) {
+        JSSL_throwSSLSocketException(env, "Unable to install alert sent callback");
+        goto finish;
+    }
+
 finish:
     if( (*env)->ExceptionOccurred(env) != NULL ) {
         if( sockdata != NULL ) {
diff --git a/org/mozilla/jss/ssl/jssl.h b/org/mozilla/jss/ssl/jssl.h
index 616c755..571c2a4 100644
--- a/org/mozilla/jss/ssl/jssl.h
+++ b/org/mozilla/jss/ssl/jssl.h
@@ -5,6 +5,8 @@
 #ifndef ORG_MOZILLA_JSS_SSL_JSSL_H
 #define ORG_MOZILLA_JSS_SSL_JSSL_H
 
+#include <ssl.h>
+
 struct JSSL_SocketData {
     PRFileDesc *fd;
     jobject socketObject; /* weak global ref */
@@ -26,6 +28,12 @@ JSSL_JavaCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig,
              PRBool isServer);
 
 void
+JSSL_AlertReceivedCallback(const PRFileDesc *fd, void *client_data, const SSLAlert *alert);
+
+void
+JSSL_AlertSentCallback(const PRFileDesc *fd, void *client_data, const SSLAlert *alert);
+
+void
 JSSL_HandshakeCallback(PRFileDesc *fd, void *arg);
 
 SECStatus
diff --git a/org/mozilla/jss/util/java_ids.h b/org/mozilla/jss/util/java_ids.h
index 3ceebaa..7ec9ea9 100644
--- a/org/mozilla/jss/util/java_ids.h
+++ b/org/mozilla/jss/util/java_ids.h
@@ -285,6 +285,11 @@ PR_BEGIN_EXTERN_C
 #define SUPPORTS_IPV6_SIG "()Z"
 
 /*
+ * SSLAlertEvent
+ */
+#define SSL_ALERT_EVENT_CLASS "org/mozilla/jss/ssl/SSLAlertEvent"
+
+/*
  * SSLCertificateApprovalCallback
  */
 #define SSLCERT_APP_CB_APPROVE_NAME "approve"
@@ -300,8 +305,11 @@ PR_BEGIN_EXTERN_C
 /*
  * SSLSocket
  */
+#define SSLSOCKET_CLASS "org/mozilla/jss/ssl/SSLSocket"
+
 #define SSLSOCKET_HANDSHAKE_NOTIFIER_NAME "notifyAllHandshakeListeners"
 #define SSLSOCKET_HANDSHAKE_NOTIFIER_SIG "()V"
+
 #define SSLSOCKET_PROXY_FIELD "sockProxy"
 #define SSLSOCKET_PROXY_SIG "Lorg/mozilla/jss/ssl/SocketProxy;"
 
-- 
2.9.3


From 1a83476dbbd54c87ffcf54fac7fdfa093812997f Mon Sep 17 00:00:00 2001
From: "Endi S. Edewata" <edewata@redhat.com>
Date: Tue, 21 Mar 2017 13:21:43 -0700
Subject: [PATCH 06/11] Added SSLCipher enumeration. The cipher constants in
 SSLSocket have been copied and converted into SSLCipher enumeration. The
 enumeration provides a mechanism to convert between cipher ID and cipher
 constant, also a flag to indicate whether it is an ECC cipher.

https://bugzilla.mozilla.org/show_bug.cgi?id=1349278
---
 org/mozilla/jss/ssl/SSLCipher.java | 328 +++++++++++++++++++++++++++++++++++++
 1 file changed, 328 insertions(+)
 create mode 100644 org/mozilla/jss/ssl/SSLCipher.java

diff --git a/org/mozilla/jss/ssl/SSLCipher.java b/org/mozilla/jss/ssl/SSLCipher.java
new file mode 100644
index 0000000..30acdd7
--- /dev/null
+++ b/org/mozilla/jss/ssl/SSLCipher.java
@@ -0,0 +1,328 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.jss.ssl;
+
+/**
+ * SSL cipher.
+ */
+public enum SSLCipher {
+
+    /**
+     *
+     * Note the following cipher-suites constants are not all implemented.
+     * You need to call SSLSocket.getImplementedCiphersuites().
+     *
+     */
+
+    SSL2_RC4_128_WITH_MD5                        (0xFF01),
+    SSL2_RC4_128_EXPORT40_WITH_MD5               (0xFF02),
+    SSL2_RC2_128_CBC_WITH_MD5                    (0xFF03),
+    SSL2_RC2_128_CBC_EXPORT40_WITH_MD5           (0xFF04),
+    SSL2_IDEA_128_CBC_WITH_MD5                   (0xFF05),
+    SSL2_DES_64_CBC_WITH_MD5                     (0xFF06),
+    SSL2_DES_192_EDE3_CBC_WITH_MD5               (0xFF07),
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_NULL_MD5.
+     */
+    @Deprecated
+    SSL3_RSA_WITH_NULL_MD5                       (0x0001),
+    TLS_RSA_WITH_NULL_MD5                        (0x0001),
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_NULL_SHA.
+     */
+    @Deprecated
+    SSL3_RSA_WITH_NULL_SHA                       (0x0002),
+    TLS_RSA_WITH_NULL_SHA                        (0x0002),
+
+    SSL3_RSA_EXPORT_WITH_RC4_40_MD5              (0x0003),
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_RC4_128_MD5.
+     */
+    @Deprecated
+    SSL3_RSA_WITH_RC4_128_MD5                    (0x0004),
+    TLS_RSA_WITH_RC4_128_MD5                     (0x0004),
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_RC4_128_SHA.
+     */
+    @Deprecated
+    SSL3_RSA_WITH_RC4_128_SHA                    (0x0005),
+    TLS_RSA_WITH_RC4_128_SHA                     (0x0005),
+
+    SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5          (0x0006),
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_IDEA_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_RSA_WITH_IDEA_CBC_SHA                   (0x0007),
+    TLS_RSA_WITH_IDEA_CBC_SHA                    (0x0007),
+
+    SSL3_RSA_EXPORT_WITH_DES40_CBC_SHA           (0x0008),
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_RSA_WITH_DES_CBC_SHA                    (0x0009),
+    TLS_RSA_WITH_DES_CBC_SHA                     (0x0009),
+
+    /**
+     * @deprecated Replaced with TLS_RSA_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_RSA_WITH_3DES_EDE_CBC_SHA               (0x000a),
+    TLS_RSA_WITH_3DES_EDE_CBC_SHA                (0x000a),
+
+    SSL3_DH_DSS_EXPORT_WITH_DES40_CBC_SHA        (0x000b),
+
+    /**
+     * @deprecated Replaced with TLS_DH_DSS_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_DH_DSS_WITH_DES_CBC_SHA                 (0x000c),
+    TLS_DH_DSS_WITH_DES_CBC_SHA                  (0x000c),
+
+    /**
+     * @deprecated Replaced with TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_DH_DSS_WITH_3DES_EDE_CBC_SHA            (0x000d),
+    TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA             (0x000d),
+
+    SSL3_DH_RSA_EXPORT_WITH_DES40_CBC_SHA        (0x000e),
+
+    /**
+     * @deprecated Replaced with TLS_DH_RSA_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_DH_RSA_WITH_DES_CBC_SHA                 (0x000f),
+    TLS_DH_RSA_WITH_DES_CBC_SHA                  (0x000f),
+
+    /**
+     * @deprecated Replaced with TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_DH_RSA_WITH_3DES_EDE_CBC_SHA            (0x0010),
+    TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA             (0x0010),
+
+    SSL3_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA       (0x0011),
+
+    /**
+     * @deprecated Replaced with TLS_DHE_DSS_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_DHE_DSS_WITH_DES_CBC_SHA                (0x0012),
+    TLS_DHE_DSS_WITH_DES_CBC_SHA                 (0x0012),
+
+    /**
+     * @deprecated Replaced with TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA           (0x0013),
+    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA            (0x0013),
+
+    SSL3_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA       (0x0014),
+
+    /**
+     * @deprecated Replaced with TLS_DHE_RSA_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_DHE_RSA_WITH_DES_CBC_SHA                (0x0015),
+    TLS_DHE_RSA_WITH_DES_CBC_SHA                 (0x0015),
+
+    /**
+     * @deprecated Replaced with TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA           (0x0016),
+    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA            (0x0016),
+
+    SSL3_DH_ANON_EXPORT_WITH_RC4_40_MD5          (0x0017),
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_RC4_128_MD5.
+     */
+    @Deprecated
+    SSL3_DH_ANON_WITH_RC4_128_MD5                (0x0018),
+    TLS_DH_anon_WITH_RC4_128_MD5                 (0x0018),
+
+    SSL3_DH_ANON_EXPORT_WITH_DES40_CBC_SHA       (0x0019),
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_DES_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_DH_ANON_WITH_DES_CBC_SHA                (0x001a),
+    TLS_DH_anon_WITH_DES_CBC_SHA                 (0x001a),
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_3DES_EDE_CBC_SHA.
+     */
+    @Deprecated
+    SSL3_DH_ANON_WITH_3DES_EDE_CBC_SHA           (0x001b),
+    TLS_DH_anon_WITH_3DES_EDE_CBC_SHA            (0x001b),
+
+    /**
+     * @deprecated As of NSS 3.11, FORTEZZA is no longer supported.
+     */
+    @Deprecated
+    SSL3_FORTEZZA_DMS_WITH_NULL_SHA              (0x001c),
+
+    /**
+     * @deprecated As of NSS 3.11, FORTEZZA is no longer supported.
+     */
+    @Deprecated
+    SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA      (0x001d),
+
+    /**
+     * @deprecated As of NSS 3.11, FORTEZZA is no longer supported.
+     */
+    @Deprecated
+    SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA           (0x001e),
+
+    SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA           (0xfeff),
+    SSL_RSA_FIPS_WITH_DES_CBC_SHA                (0xfefe),
+
+    TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA          (0x0062),
+    TLS_RSA_EXPORT1024_WITH_RC4_56_SHA           (0x0064),
+
+    TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA      (0x0063),
+    TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA       (0x0065),
+    TLS_DHE_DSS_WITH_RC4_128_SHA                 (0x0066),
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256          (0x0067),
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256          (0x006B),
+
+    // New TLS cipher suites in NSS 3.4
+    TLS_RSA_WITH_AES_128_CBC_SHA                 (0x002F),
+    TLS_DH_DSS_WITH_AES_128_CBC_SHA              (0x0030),
+    TLS_DH_RSA_WITH_AES_128_CBC_SHA              (0x0031),
+    TLS_DHE_DSS_WITH_AES_128_CBC_SHA             (0x0032),
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA             (0x0033),
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_AES_128_CBC_SHA.
+     */
+    @Deprecated
+    TLS_DH_ANON_WITH_AES_128_CBC_SHA             (0x0034),
+    TLS_DH_anon_WITH_AES_128_CBC_SHA             (0x0034),
+
+    TLS_RSA_WITH_AES_256_CBC_SHA                 (0x0035),
+    TLS_DH_DSS_WITH_AES_256_CBC_SHA              (0x0036),
+    TLS_DH_RSA_WITH_AES_256_CBC_SHA              (0x0037),
+    TLS_DHE_DSS_WITH_AES_256_CBC_SHA             (0x0038),
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA             (0x0039),
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_AES_256_CBC_SHA.
+     */
+    @Deprecated
+    TLS_DH_ANON_WITH_AES_256_CBC_SHA             (0x003A),
+    TLS_DH_anon_WITH_AES_256_CBC_SHA             (0x003A),
+
+    TLS_RSA_WITH_NULL_SHA256                     (0x003B),
+    TLS_RSA_WITH_AES_128_CBC_SHA256              (0x003C),
+    TLS_RSA_WITH_AES_256_CBC_SHA256              (0x003D),
+
+    TLS_RSA_WITH_CAMELLIA_128_CBC_SHA            (0x0041),
+    TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA         (0x0042),
+    TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA         (0x0043),
+    TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA        (0x0044),
+    TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA        (0x0045),
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA.
+     */
+    @Deprecated
+    TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA        (0x0046),
+    TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA        (0x0046),
+
+    TLS_RSA_WITH_CAMELLIA_256_CBC_SHA            (0x0084),
+    TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA         (0x0085),
+    TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA         (0x0086),
+    TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA        (0x0087),
+    TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA        (0x0088),
+
+    /**
+     * @deprecated Replaced with TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA.
+     */
+    @Deprecated
+    TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA        (0x0089),
+    TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA        (0x0089),
+
+    TLS_RSA_WITH_SEED_CBC_SHA                    (0x0096),
+
+    TLS_RSA_WITH_AES_128_GCM_SHA256              (0x009C),
+    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256          (0x009E),
+    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256          (0x00A2),
+
+    TLS_ECDH_ECDSA_WITH_NULL_SHA                 (0xc001, true),
+    TLS_ECDH_ECDSA_WITH_RC4_128_SHA              (0xc002, true),
+    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA         (0xc003, true),
+    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA          (0xc004, true),
+    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA          (0xc005, true),
+
+    TLS_ECDHE_ECDSA_WITH_NULL_SHA                (0xc006, true),
+    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA             (0xc007, true),
+    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA        (0xc008, true),
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA         (0xc009, true),
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA         (0xc00a, true),
+
+    TLS_ECDH_RSA_WITH_NULL_SHA                   (0xc00b, true),
+    TLS_ECDH_RSA_WITH_RC4_128_SHA                (0xc00c, true),
+    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA           (0xc00d, true),
+    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA            (0xc00e, true),
+    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA            (0xc00f, true),
+
+    TLS_ECDHE_RSA_WITH_NULL_SHA                  (0xc010, true),
+    TLS_ECDHE_RSA_WITH_RC4_128_SHA               (0xc011, true),
+    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA          (0xc012, true),
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA           (0xc013, true),
+    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA           (0xc014, true),
+
+    TLS_ECDH_anon_WITH_NULL_SHA                  (0xc015, true),
+    TLS_ECDH_anon_WITH_RC4_128_SHA               (0xc016, true),
+    TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA          (0xc017, true),
+    TLS_ECDH_anon_WITH_AES_128_CBC_SHA           (0xc018, true),
+    TLS_ECDH_anon_WITH_AES_256_CBC_SHA           (0xc019, true),
+
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256      (0xc023, true),
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256        (0xc027, true),
+
+    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256      (0xc02B, true),
+    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256       (0xc02D, true),
+    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256        (0xc02F, true),
+    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256         (0xc031, true);
+
+    private int id;
+    private boolean ecc;
+
+    private SSLCipher(int id) {
+        this.id = id;
+    }
+
+    private SSLCipher(int id, boolean ecc) {
+        this.id = id;
+        this.ecc = ecc;
+    }
+
+    public int getID() {
+        return id;
+    }
+
+    public boolean isECC() {
+        return ecc;
+    }
+
+    public static SSLCipher valueOf(int id) {
+        for (SSLCipher cipher : SSLCipher.class.getEnumConstants()) {
+            if (cipher.id == id) return cipher;
+        }
+        return null;
+    }
+}
-- 
2.9.3


From 5c09c644caf9849dd1602dc6df56c0691a2d25f8 Mon Sep 17 00:00:00 2001
From: "Endi S. Edewata" <edewata@redhat.com>
Date: Wed, 22 Mar 2017 19:17:19 -0700
Subject: [PATCH 07/11] Replaced Password.readPasswordFromConsole()
 implementation.

The native implementation of Password.readPasswordFromConsole() has
been replaced with platform independent code using System.console()
which does not cause a problem if the program is interrupted while
waiting for password input.

https://bugzilla.mozilla.org/show_bug.cgi?id=1349349
---
 org/mozilla/jss/util/Password.java |  24 +++--
 org/mozilla/jss/util/jssutil.c     | 212 -------------------------------------
 2 files changed, 17 insertions(+), 219 deletions(-)

diff --git a/org/mozilla/jss/util/Password.java b/org/mozilla/jss/util/Password.java
index 9e6a3bb..47bc8a1 100644
--- a/org/mozilla/jss/util/Password.java
+++ b/org/mozilla/jss/util/Password.java
@@ -5,6 +5,7 @@
 package org.mozilla.jss.util;
 
 import java.io.CharConversionException;
+import java.io.Console;
 
 /**
  * Stores a password.  <code>clear</code> should be
@@ -114,7 +115,7 @@ public class Password implements PasswordCallback, Cloneable,
      * for example using <code>wipeChars</code>.
      */
     public synchronized char[] getCharCopy() {
-        return (char[]) password.clone();
+        return password.clone();
     }
 
     /**
@@ -125,7 +126,7 @@ public class Password implements PasswordCallback, Cloneable,
      * for example using <code>wipeChars</code>.
      */
     synchronized byte[] getByteCopy() {
-        return charToByte( (char[]) password.clone() );
+        return charToByte( password.clone() );
     }
 
     /**
@@ -150,11 +151,11 @@ public class Password implements PasswordCallback, Cloneable,
     public synchronized Object clone() {
         Password dolly = new Password();
 
-        dolly.password = (char[]) password.clone();
+        dolly.password = password.clone();
         dolly.cleared = cleared;
         return dolly;
     }
-          
+
 
     /**
      * The finalizer clears the sensitive information before releasing
@@ -230,9 +231,18 @@ public class Password implements PasswordCallback, Cloneable,
      *      <code>&lt;enter&gt;</code>).
 	 * @return The password the user entered at the command line.
  	 */
-	public synchronized static native Password readPasswordFromConsole()
-        throws PasswordCallback.GiveUpException;
-        
+	public static Password readPasswordFromConsole() throws PasswordCallback.GiveUpException {
+
+	    Console console = System.console();
+	    char[] password = console.readPassword();
+
+	    if (password == null || password.length == 0) {
+	        throw new PasswordCallback.GiveUpException();
+	    }
+
+	    return new Password(password);
+        }
+
     // The password, stored as a char[] so we can clear it.  Passwords
     // should never be stored in Strings because Strings can't be cleared.
     private char[] password;
diff --git a/org/mozilla/jss/util/jssutil.c b/org/mozilla/jss/util/jssutil.c
index 609eeb3..0d19a84 100644
--- a/org/mozilla/jss/util/jssutil.c
+++ b/org/mozilla/jss/util/jssutil.c
@@ -462,218 +462,6 @@ JSS_wipeCharArray(char* array)
 	}
 }
 
-/***********************************************************************
- * platform-dependent definitions for getting passwords from console.
- ***********************************************************************/
-
-#ifdef XP_UNIX
-
-#include <termios.h>
-#include <unistd.h>
-#define GETCH getchar
-#define PUTCH putchar
-
-#else
-
-#include <conio.h>
-#define GETCH _getch
-#define PUTCH _putch
-
-#endif
-
-/***********************************************************************
- * g e t P W F r o m C o n s o l e
- *
- * Does platform-dependent stuff to retrieve a char* from the console.
- * Retrieves up to the first newline character, but does not return
- * the newline. Maximum length is 200 chars.
- * Stars (*) are echoed to the screen.  Backspacing works.
- * WARNING: This function is NOT thread-safe!!! This should be OK because
- * the Java method that calls it is synchronized.
- *
- * RETURNS
- *      The password in a buffer owned by the caller, or NULL if the
- *      user did not enter a password (just hit <enter>).
- */
-static char* getPWFromConsole()
-{
-    int c;
-    char *ret;
-    int i;
-    char buf[200];  /* no buffer overflow: we bail after 200 chars */
-    int length=200;
-#ifdef XP_UNIX 
-    int fd = fileno(stdin);
-    struct termios save_tio;
-    struct termios tio;
-#endif
-
-
-    /*
-     * In Win32, the default is for _getch to not echo and to not be buffered.
-     * In UNIX, we have to set this explicitly.
-     */
-#ifdef XP_UNIX
-    if ( isatty(fd) ) {
-        tcgetattr(fd, &save_tio);
-        tio = save_tio;
-        tio.c_lflag &= ~(ECHO|ICANON);   /* no echo, non-canonical mode */
-        tio.c_cc[VMIN] = 1;     /* 1 char at a time */
-        tio.c_cc[VTIME] = 0;    /* wait forever */
-        tcsetattr(fd, TCSAFLUSH, &tio);
-    } else {
-        /* no reading from a file allowed. Windows enforces this automatically*/
-        return NULL;
-    }
-#endif
-
-    /*
-     * Retrieve up to length characters, or the first newline character.
-     */
-    for(i=0; i < length-1; i++) {
-        PR_ASSERT(i >= 0);
-        c = GETCH();
-        if( c == '\b' ) {
-            /*
-             * backspace.  Back up the buffer and the cursor.
-             */
-            if( i==0 ) {
-                /* backspace is first char, do nothing */
-                i--;
-            } else {
-                /* backspace is not first char, backup one */
-                i -= 2;
-                PUTCH('\b'); PUTCH(' '); PUTCH('\b');
-            }
-        } else if( c == '\r' || c == '\n' ) {
-            /* newline, we're done */
-            break;
-        } else {
-            /* normal password char.  Echo an asterisk. */
-            buf[i] = c;
-            PUTCH('*');
-        }
-    }
-    buf[i] = '\0';
-    PUTCH('\n');
-
-    /*
-     * Restore the saved terminal settings.
-     */
-#ifdef XP_UNIX
-    tcsetattr(fd, TCSAFLUSH, &save_tio);
-#endif
-
-    /* If password is empty, return NULL to signal the user giving up */
-    if(buf[0] == '\0') {
-        ret = NULL;
-    } else {
-        ret = PL_strdup(buf);
-    }
-
-    /* Clear the input buffer */
-    memset(buf, 0, length);
-
-    return ret;
-}
-
-
-/***********************************************************************
- * Class:     org_mozilla_jss_util_Password
- * Method:    readPasswordFromConsole
- * Signature: ()Lorg/mozilla/jss/util/Password;
- */
-JNIEXPORT jobject JNICALL Java_org_mozilla_jss_util_Password_readPasswordFromConsole
-  (JNIEnv *env, jclass clazz)
-{
-    char *pw=NULL;
-    int pwlen;
-    jclass pwClass;
-    jmethodID pwConstructor;
-    jcharArray pwCharArray=NULL;
-    jchar *pwChars=NULL;
-    jobject password=NULL;
-    jboolean pwIsCopy;
-    int i;
-
-    /***************************************************
-     * Get JNI IDs
-     ***************************************************/
-    pwClass = (*env)->FindClass(env, PASSWORD_CLASS_NAME);
-    if(pwClass == NULL) {
-        ASSERT_OUTOFMEM(env);
-        goto finish;
-    }
-    pwConstructor = (*env)->GetMethodID(env,
-                                        pwClass,
-                                        PLAIN_CONSTRUCTOR,
-                                        PASSWORD_CONSTRUCTOR_SIG);
-    if(pwConstructor == NULL) {
-        ASSERT_OUTOFMEM(env);
-        goto finish;
-    }
-
-    /***************************************************
-     * Get the password from the console
-     ***************************************************/
-    pw = getPWFromConsole();
-
-    if(pw == NULL) {
-        JSS_throw(env, GIVE_UP_EXCEPTION);
-        goto finish;
-    }
-    pwlen = strlen(pw);
-    PR_ASSERT(pwlen > 0);
-
-    /***************************************************
-     * Put the password into a char array
-     ***************************************************/
-    pwCharArray = (*env)->NewCharArray(env, pwlen);
-    if(pwCharArray == NULL) {
-        ASSERT_OUTOFMEM(env);
-        goto finish;
-    }
-    pwChars = (*env)->GetCharArrayElements(env, pwCharArray, &pwIsCopy);
-    if(pwChars == NULL) {
-        ASSERT_OUTOFMEM(env);
-        goto finish;
-    }
-    for(i=0; i < pwlen; i++) {
-        /* YUK! Only works for ASCII. */
-        pwChars[i] = pw[i];
-    }
-
-    if( pwIsCopy ) {
-        /* copy back the changes */
-        (*env)->ReleaseCharArrayElements(env, pwCharArray, pwChars, JNI_COMMIT);
-        /* clear the copy */
-        memset(pwChars, 0, pwlen);
-        /* release the copy */
-        (*env)->ReleaseCharArrayElements(env, pwCharArray, pwChars, JNI_ABORT);
-    } else {
-        /* pwChars is not a copy, so this should be a no-op, but we include
-         * it anyway */
-        (*env)->ReleaseCharArrayElements(env, pwCharArray, pwChars, 0);
-    }
-    pwChars = NULL;
-
-    /***************************************************
-     * Construct a new Password from the char array
-     ***************************************************/
-    password = (*env)->NewObject(env, pwClass, pwConstructor, pwCharArray);
-    if(password == NULL) {
-        ASSERT_OUTOFMEM(env);
-        goto finish;
-    }
-
-finish:
-    if(pw != NULL) {
-        memset(pw, 0, strlen(pw));
-        PR_Free(pw);
-    }
-    return password;
-}
-
 #ifdef DEBUG
 static int debugLevel = JSS_TRACE_VERBOSE;
 #else
-- 
2.9.3


From bee3bc6cfef28f39b8abb1fd7e8505e5a9880716 Mon Sep 17 00:00:00 2001
From: Matthew Harmsen <mharmsen@redhat.com>
Date: Thu, 23 Mar 2017 10:48:29 -0700
Subject: [PATCH 08/11] Bug 1349831 - Revise top-level README file, r=emaldona

---
 README | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 110 insertions(+), 24 deletions(-)

diff --git a/README b/README
index 4ceb0fd..cfc0244 100644
--- a/README
+++ b/README
@@ -4,8 +4,8 @@
 
 (1) Prepare a work area
 
-    (a) For upstream builds which checkout and utilize the current NSPR and NSS
-        source repositories: 
+    (a) For upstream builds which checkout and utilize
+        the current NSPR and NSS source repositories:
 
         # mkdir sandbox
         # cd sandbox
@@ -20,13 +20,20 @@
           cd jss; hg pull -u -v; cd ..
         )
 
-    (b) Alternatively, for upstream builds which use the NSPR and NSS installed 
-        on the system:
+    (b) Alternatively, for upstream builds which use
+        the NSPR and NSS installed on the system:
 
         # mkdir sandbox
         # cd sandbox
         # export USE_INSTALLED_NSPR=1
         # export USE_INSTALLED_NSS=1
+        # export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1
+        # export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1
+        # export NSPR_INCLUDE_DIR=`/usr/bin/pkg-config --cflags-only-I nspr | sed 's/-I//'`
+        # export NSPR_LIB_DIR=`/usr/bin/pkg-config --libs-only-L nspr | sed 's/-L//'`
+        # export NSS_INCLUDE_DIR=`/usr/bin/pkg-config --cflags-only-I nss | sed 's/-I//'`
+        # export NSS_LIB_DIR=`/usr/bin/pkg-config --libs-only-L nss | sed 's/-L//'`
+        # export XCFLAGS="-g"
         # hg clone https://hg.mozilla.org/projects/jss
         # cd ..
 
@@ -41,9 +48,32 @@
     # export JAVA_HOME=/etc/alternatives/java_sdk_1.8.0_openjdk
     # export USE_64=1
 
-    NOTE:  JSS will now attempt to verify whether or not these two environment
-           variables have been set (JAVA_HOME is mandatory; USE_64 is mandatory
-           on 64-bit platforms when building 64-bit).
+    NOTE:  JSS will now attempt to verify whether or not these two
+           environment variables have been set (JAVA_HOME is mandatory;
+           USE_64 is mandatory on 64-bit platforms when building 64-bit).
+
+    The following steps are optional, and left to the discretion of the user:
+
+        Debug vs. Optimized jar files:
+
+            By default, JSS will be built as a debuggable jar
+            (xpclass_dbg.jar - generally recommended for test builds);
+            to create an optimized jar (xpclass.jar), set the following
+            environment variable:
+
+                # export BUILD_OPT=1
+
+        Beta vs. Non-Beta builds:
+
+            Finally, by default, JSS is not built as a "beta" release (as
+            specified in 'org/mozilla/jss/util/jssver.h'):
+
+                #define JSS_BETA     PR_FALSE
+
+            If a "beta" version of JSS is desired, reset this #define (as
+            specified in 'org/mozilla/jss/util/jssver.h') to:
+
+                #define JSS_BETA     PR_TRUE
 
 
 (3) Build JSS
@@ -52,30 +82,88 @@
     # make clean all
     # cd ../..
 
-    (or you can run "# script -c 'make clean all' typescript.build')
+    (or you can run "# script -c 'make clean all' typescript.build")
 
     NOTE: When build method (1)(a) is being utilized, if nss has not been
           built, it will now automatically be built before jss; if nss has
           already been built, only jss will be built/re-built.
 
 
-(4) Run JSS Tests
+(4) Install JSS on the System (Optional)
 
-    # cd sandbox/jss
-    # make test_jss
-    # cd ../..
+    If JSS already exists on the system, run something similar to the
+    following command(s):
+
+        # sudo mv /usr/lib/java/jss4.jar /usr/lib/java/jss4.jar.orig
+
+        If the platform is 32-bit Linux:
+
+            # sudo mv /usr/lib/jss/libjss4.so /usr/lib/jss/libjss4.so.orig
+
+        else if the platform is 64-bit Linux:
+
+            # sudo mv /usr/lib64/jss/libjss4.so /usr/lib64/jss/libjss4.so.orig
+
+    If BUILD_OPT is undefined (default Debuggable Jar):
+
+        # sudo cp sandbox/dist/xpclass_dbg.jar /usr/lib/java/jss4.jar
+
+    else if BUILD_OPT is defined (Optimized Jar):
 
-    (or you can run "# script -c 'make test_jss' typescript.tests)
+        # sudo cp sandbox/dist/xpclass.jar /usr/lib/java/jss4.jar
+
+    # sudo chown root:root /usr/lib/java/jss4.jar
+    # sudo chmod 644 /usr/lib/java/jss4.jar
+
+    # sudo cp sandbox/jss/lib/Linux*.OBJ/libjss4.so /usr/lib64/jss/libjss4.so
+    # sudo chown root:root /usr/lib64/jss/libjss4.so
+    # sudo chmod 755 /usr/lib64/jss/libjss4.so
+
+
+(5) Run JSS Tests (Optional, but only if build method (1)(a) was utilized)
+
+    If build method (1)(a) is being utilized, it is possible to run the
+    built-in JSS tests:
+
+        # cd sandbox/jss
+        # make test_jss
+        # cd ../..
+
+        (or you can run "# script -c 'make test_jss' typescript.tests")
 
     NOTE: This command is currently only available on Linux and Macintosh
-          platforms; currenty JSS must be built via 'make clean all' before
+          platforms when method (1)(a) has been utilized to build JSS
+          since the tests are dependent upon the work area as setup in
+          this method; currenty JSS must be built via 'make clean all' before
           execution of this command (e.g. - build is separate from test).
 
 
-(5) Known Issues
+(6) Restoration of non-Test-Only Systems (Optional)
+
+    If step (4) above was run, and the system is being used for purposes
+    other than test, the user may wish to restore the original system JSS
+    by running the following commands:
+
+        # sudo mv /usr/lib/java/jss4.jar.orig /usr/lib/java/jss4.jar
+
+        If the platform is 32-bit Linux:
+
+            # sudo mv /usr/lib/jss/libjss4.so.orig /usr/lib/jss/libjss4.so
+
+        else if the platform is 64-bit Linux:
+
+            # sudo mv /usr/lib64/jss/libjss4.so.orig /usr/lib64/jss/libjss4.so
+
+        NOTE:  For this procedure, no ownership or permission changes should
+               be necessary.
+
+
+(7) Known Issues
 
     * Mozilla Bug #1346410 - Load JSS libraries appropriately
 
+    NOTE:  This issue should not occur unless step (4) above was skipped.
+
     Testing failures were found while working on Bug 1346410 when loading the
     JSS libraries to meet requirements of certain operating systems.  Our
     investigation revealed that due to the nature of the changes made via this
@@ -83,16 +171,14 @@
     that a failure may be encountered on one or more of the HMAC algorithms
     causing these two tests to fail.  On 64-bit Linux, for example, the
     workaround for this issue is to perform the following steps before
-    re-running the tests: 
+    re-running the tests:
+
+        (a) Install the new JSS builds by executing step (4) above
+
+        (b) Execute the following commands:
 
-        # sudo mv /usr/lib64/jss/libjss4.so /usr/lib64/jss/libjss4.so.orig
-        # sudo cp -p
-          sandbox/dist/Linux3.10_x86_64_cc_glibc_PTH_64_DBG.OBJ/lib/libjss4.so
-          /usr/lib64/jss/libjss4.so
-        # sudo chown root:root /usr/lib64/jss/libjss4.so
-        # sudo chmod 755 /usr/lib64/jss/libjss4.so
-        # cd sandbox/jss; make test_jss
+            # cd sandbox/jss; make test_jss
 
     NOTE:  If the system is being used for purposes other than test, the user
-           may wish to restore 'libjss4.so.orig' back to 'libjss4.so'.
+           may wish to restore the original JSS by executing step (6) above.
 
-- 
2.9.3


From 382d6611ee2208c0bbe03afac33b96bf7a34047a Mon Sep 17 00:00:00 2001
From: Matthew Harmsen <mharmsen@redhat.com>
Date: Thu, 23 Mar 2017 10:52:15 -0700
Subject: [PATCH 09/11] Bug 1349836 - Changes to JSS Version Block, r=emaldona

---
 lib/manifest.mn                    | 4 ++--
 manifest.mn                        | 8 ++------
 org/mozilla/jss/CryptoManager.c    | 4 ++--
 org/mozilla/jss/CryptoManager.java | 4 ++--
 org/mozilla/jss/JSSProvider.java   | 4 ++--
 org/mozilla/jss/util/jssver.h      | 5 ++---
 6 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/lib/manifest.mn b/lib/manifest.mn
index d37cb68..6f03301 100644
--- a/lib/manifest.mn
+++ b/lib/manifest.mn
@@ -7,11 +7,11 @@
 #/* The VERSION Strings should be updated in the following           */
 #/* files everytime a new release of JSS is generated:               */
 #/*                                                                  */
+#/* lib/manifest.mn                                                  */
+#/* org/mozilla/jss/CryptoManager.c                                  */
 #/* org/mozilla/jss/CryptoManager.java                               */
 #/* org/mozilla/jss/JSSProvider.java                                 */
 #/* org/mozilla/jss/util/jssver.h                                    */
-#/* lib/manifest.mn                                                  */
-#/* jss/manifest.mn                                                  */
 #/*                                                                  */
 #/********************************************************************/
 
diff --git a/manifest.mn b/manifest.mn
index 9338108..07cabce 100644
--- a/manifest.mn
+++ b/manifest.mn
@@ -12,18 +12,14 @@ MODULE = jss
 #/* The VERSION Strings should be updated in the following           */
 #/* files everytime a new release of JSS is generated:               */
 #/*                                                                  */
+#/* lib/manifest.mn                                                  */
+#/* org/mozilla/jss/CryptoManager.c                                  */
 #/* org/mozilla/jss/CryptoManager.java                               */
 #/* org/mozilla/jss/JSSProvider.java                                 */
 #/* org/mozilla/jss/util/jssver.h                                    */
-#/* lib/manifest.mn                                                  */
-#/* mozilla/security/jss/manifest.mn                                 */
 #/*                                                                  */
 #/********************************************************************/
 
-IMPORTS =	nss/NSS_3_12_RTM \
-			nspr20/v4.7 \
-			$(NULL)
-
 DIRS =  coreconf \
         org     \
         lib     \
diff --git a/org/mozilla/jss/CryptoManager.c b/org/mozilla/jss/CryptoManager.c
index 3eb9ae7..56e66b2 100644
--- a/org/mozilla/jss/CryptoManager.c
+++ b/org/mozilla/jss/CryptoManager.c
@@ -49,11 +49,11 @@ const char * jss_sccsid() {
 /* The VERSION Strings should be updated in the following           */
 /* files everytime a new release of JSS is generated:               */
 /*                                                                  */
+/* lib/manifest.mn                                                  */
+/* org/mozilla/jss/CryptoManager.c                                  */
 /* org/mozilla/jss/CryptoManager.java                               */
 /* org/mozilla/jss/JSSProvider.java                                 */
 /* org/mozilla/jss/util/jssver.h                                    */
-/* lib/manifest.mn                                                  */
-/* mozilla/security/jss/manifest.mn                                 */
 /*                                                                  */
 /********************************************************************/
 
diff --git a/org/mozilla/jss/CryptoManager.java b/org/mozilla/jss/CryptoManager.java
index 9cc50d9..9e5503d 100644
--- a/org/mozilla/jss/CryptoManager.java
+++ b/org/mozilla/jss/CryptoManager.java
@@ -1449,11 +1449,11 @@ public final class CryptoManager implements TokenSupplier
     /* The VERSION Strings should be updated in the following           */
     /* files everytime a new release of JSS is generated:               */
     /*                                                                  */
+    /* lib/manifest.mn                                                  */
+    /* org/mozilla/jss/CryptoManager.c                                  */
     /* org/mozilla/jss/CryptoManager.java                               */
     /* org/mozilla/jss/JSSProvider.java                                 */
     /* org/mozilla/jss/util/jssver.h                                    */
-    /* lib/manifest.mn                                                  */
-    /* jss/manifest.mn                                                  */
     /*                                                                  */
     /********************************************************************/
 
diff --git a/org/mozilla/jss/JSSProvider.java b/org/mozilla/jss/JSSProvider.java
index 687e88b..a8205ab 100644
--- a/org/mozilla/jss/JSSProvider.java
+++ b/org/mozilla/jss/JSSProvider.java
@@ -9,11 +9,11 @@ public final class JSSProvider extends java.security.Provider {
     /* The VERSION Strings should be updated in the following           */
     /* files everytime a new release of JSS is generated:               */
     /*                                                                  */
+    /* lib/manifest.mn                                                  */
+    /* org/mozilla/jss/CryptoManager.c                                  */
     /* org/mozilla/jss/CryptoManager.java                               */
     /* org/mozilla/jss/JSSProvider.java                                 */
     /* org/mozilla/jss/util/jssver.h                                    */
-    /* lib/manifest.mn                                                  */
-    /* jss/manifest.mn                                                  */
     /*                                                                  */
     /********************************************************************/
     /* QUESTION: When do we change MINOR and PATCH to 4 and 0? */
diff --git a/org/mozilla/jss/util/jssver.h b/org/mozilla/jss/util/jssver.h
index bd8a492..df67620 100644
--- a/org/mozilla/jss/util/jssver.h
+++ b/org/mozilla/jss/util/jssver.h
@@ -17,12 +17,11 @@
 /* The VERSION Strings should be updated in the following           */
 /* files everytime a new release of JSS is generated:               */
 /*                                                                  */
-/* org/mozilla/jss/CryptoManager.java                               */
+/* lib/manifest.mn                                                  */
 /* org/mozilla/jss/CryptoManager.c                                  */
+/* org/mozilla/jss/CryptoManager.java                               */
 /* org/mozilla/jss/JSSProvider.java                                 */
 /* org/mozilla/jss/util/jssver.h                                    */
-/* lib/manifest.mn                                                  */
-/* jss/manifest.mn                                                  */
 /*                                                                  */
 /********************************************************************/
 
-- 
2.9.3


From 434c9d5253d6f1e32c4f29cf66cb43d8ca7bf569 Mon Sep 17 00:00:00 2001
From: Christina Fu <cfu@redhat.com>
Date: Sat, 25 Mar 2017 12:08:51 -0400
Subject: [PATCH 10/11] Bug 1337092 CMC conformance update: Implement required
 ASN.1 code for RFC5272+, r=jmagne

From: Christina Fu <cfu@redhat.com>
Date: Thu, 16 Mar 2017 09:54:01 -0700
Subject: [PATCH] bugzilla.mozilla#1337092 cmc RFC5272 ASN.1
This patch provides the required ASN.1 code for updating cmc to RFC5272,
as well as adding some needed missing controls from earlier rfc 2797.
The major cmc control structures added are: IdentityProofV2, EncryptedPOP,
DecryptedPOP, PopLinkWitnessV2, CMCStatusInfoV2 and their underelying
support structures.
---
 org/mozilla/jss/asn1/OBJECT_IDENTIFIER.java     |  21 ++
 org/mozilla/jss/crypto/HMACAlgorithm.java       |   2 +-
 org/mozilla/jss/pkix/cmc/BodyPartReference.java | 198 +++++++++++++++
 org/mozilla/jss/pkix/cmc/CMCStatusInfoV2.java   | 270 ++++++++++++++++++++
 org/mozilla/jss/pkix/cmc/DecryptedPOP.java      | 165 ++++++++++++
 org/mozilla/jss/pkix/cmc/EncryptedPOP.java      | 185 ++++++++++++++
 org/mozilla/jss/pkix/cmc/ExtendedFailInfo.java  | 145 +++++++++++
 org/mozilla/jss/pkix/cmc/IdentityProofV2.java   | 163 ++++++++++++
 org/mozilla/jss/pkix/cmc/OtherInfo.java         | 150 ++++++++---
 org/mozilla/jss/pkix/cmc/OtherReqMsg.java       | 167 ++++++++++++
 org/mozilla/jss/pkix/cmc/PopLinkWitnessV2.java  | 163 ++++++++++++
 org/mozilla/jss/pkix/cmc/RevokeRequest.java     | 323 ++++++++++++++++++++++++
 org/mozilla/jss/pkix/cmc/TaggedRequest.java     |  78 +++++-
 org/mozilla/jss/pkix/cmmf/RevRequest.java       |   3 +
 org/mozilla/jss/pkix/crmf/CertRequest.java      |   7 +
 15 files changed, 1995 insertions(+), 45 deletions(-)
 create mode 100644 org/mozilla/jss/pkix/cmc/BodyPartReference.java
 create mode 100644 org/mozilla/jss/pkix/cmc/CMCStatusInfoV2.java
 create mode 100644 org/mozilla/jss/pkix/cmc/DecryptedPOP.java
 create mode 100644 org/mozilla/jss/pkix/cmc/EncryptedPOP.java
 create mode 100644 org/mozilla/jss/pkix/cmc/ExtendedFailInfo.java
 create mode 100644 org/mozilla/jss/pkix/cmc/IdentityProofV2.java
 create mode 100644 org/mozilla/jss/pkix/cmc/OtherReqMsg.java
 create mode 100644 org/mozilla/jss/pkix/cmc/PopLinkWitnessV2.java
 create mode 100644 org/mozilla/jss/pkix/cmc/RevokeRequest.java

diff --git a/org/mozilla/jss/asn1/OBJECT_IDENTIFIER.java b/org/mozilla/jss/asn1/OBJECT_IDENTIFIER.java
index 399b555..d55dcfc 100644
--- a/org/mozilla/jss/asn1/OBJECT_IDENTIFIER.java
+++ b/org/mozilla/jss/asn1/OBJECT_IDENTIFIER.java
@@ -140,6 +140,27 @@ public class OBJECT_IDENTIFIER implements ASN1Value {
     id_cmc_idPOPLinkWitness = id_cmc.subBranch(23);
     public static final OBJECT_IDENTIFIER
     id_cmc_idConfirmCertAcceptance = id_cmc.subBranch(24);
+    // rfc 5272
+    public static final OBJECT_IDENTIFIER
+    id_cmc_statusInfoV2 = id_cmc.subBranch(25);
+    public static final OBJECT_IDENTIFIER
+    id_cmc_trustedAnchors = id_cmc.subBranch(26);
+    public static final OBJECT_IDENTIFIER
+    id_cmc_authData = id_cmc.subBranch(27);
+    public static final OBJECT_IDENTIFIER
+    id_cmc_batchRequests = id_cmc.subBranch(28);
+    public static final OBJECT_IDENTIFIER
+    id_cmc_batchResponses = id_cmc.subBranch(29);
+    public static final OBJECT_IDENTIFIER
+    id_cmc_publishCert = id_cmc.subBranch(30);
+    public static final OBJECT_IDENTIFIER
+    id_cmc_modCertTemplate = id_cmc.subBranch(31);
+    public static final OBJECT_IDENTIFIER
+    id_cmc_controlProcessed = id_cmc.subBranch(32);
+    public static final OBJECT_IDENTIFIER
+    id_cmc_popLinkWitnessV2 = id_cmc.subBranch(33);
+    public static final OBJECT_IDENTIFIER
+    id_cmc_identityProofV2 = id_cmc.subBranch(34);
 
     public static final OBJECT_IDENTIFIER
     id_cct = PKIX.subBranch( 12 );
diff --git a/org/mozilla/jss/crypto/HMACAlgorithm.java b/org/mozilla/jss/crypto/HMACAlgorithm.java
index aec57c8..24ed2ea 100644
--- a/org/mozilla/jss/crypto/HMACAlgorithm.java
+++ b/org/mozilla/jss/crypto/HMACAlgorithm.java
@@ -34,7 +34,7 @@ public class HMACAlgorithm extends DigestAlgorithm {
      * @exception NoSuchAlgorithmException If no registered HMAC algorithm
      *  has the given OID.
      */
-    public static DigestAlgorithm fromOID(OBJECT_IDENTIFIER oid)
+    public static HMACAlgorithm fromOID(OBJECT_IDENTIFIER oid)
         throws NoSuchAlgorithmException
     {
         Object alg = oidMap.get(oid);
diff --git a/org/mozilla/jss/pkix/cmc/BodyPartReference.java b/org/mozilla/jss/pkix/cmc/BodyPartReference.java
new file mode 100644
index 0000000..e7358dc
--- /dev/null
+++ b/org/mozilla/jss/pkix/cmc/BodyPartReference.java
@@ -0,0 +1,198 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Security Services for Java.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+package org.mozilla.jss.pkix.cmc;
+
+import org.mozilla.jss.util.Assert;
+import org.mozilla.jss.asn1.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.BitSet;
+
+/**
+ * CMC <i>BodyPartReference</i>:
+ * <pre>
+ *      BodyPartReference::= CHOICE { 
+ *          bodyPartID       BodyPartID
+ *          bodyPartPath     SEQUENCE SIZE (1..MAX) OF BodyPartID, 
+ *     } 
+ *
+ * @author Christina Fu (cfu)
+ * </pre>
+ */
+public class BodyPartReference implements ASN1Value {
+    public static final INTEGER BODYIDMAX = new INTEGER("4294967295");
+
+    /**
+     * The type of BodyPartReference.
+     */
+    public static class Type {
+        private Type() { }
+
+        static Type BodyPartID = new Type();
+        static Type BodyPartPath = new Type();
+    }
+    public static Type BodyPartID = Type.BodyPartID;
+    public static Type BodyPartPath = Type.BodyPartPath;
+
+    ///////////////////////////////////////////////////////////////////////
+    // Members
+    ///////////////////////////////////////////////////////////////////////
+    private Type type;
+    private INTEGER bodyPartID;
+    private SEQUENCE bodyPartPath; 
+
+    ///////////////////////////////////////////////////////////////////////
+    // Constructors
+    ///////////////////////////////////////////////////////////////////////
+
+    private BodyPartReference() { }
+
+    /**
+     * @param type The type of the BodyPartReference
+     * @param bodyPartID A BodyPartID. 
+     * @param bodyPartPath The sequence of bodyPartIDs.
+     */
+    public BodyPartReference(Type type,
+            INTEGER bodyPartID,
+            SEQUENCE bodyPartPath) {
+        this.bodyPartID = bodyPartID;
+        this.bodyPartPath = bodyPartPath;
+    }
+
+    /**
+     * Adds a BodyPartID to the bodyPartPath SEQUENCE.
+     */
+    public void addBodyPartId(int id) {
+        INTEGER id1 = new INTEGER(id);
+        Assert._assert(id1.compareTo(BODYIDMAX) <= 0);
+        bodyPartPath.addElement( id1 );
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // member access
+    ///////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns the type of BodyPartReference: <ul>
+     * <li><code>BodyPartID</code>
+     * <li><code>BodyPartPath</code>
+     * </ul>
+     */
+    public Type getType() {
+        return type;
+    }
+
+    public INTEGER getBodyPartID() {
+        return bodyPartID;
+    }
+
+    public SEQUENCE getBodyPartPath() {
+        return bodyPartPath;
+    }
+    ///////////////////////////////////////////////////////////////////////
+    // decoding/encoding
+    ///////////////////////////////////////////////////////////////////////
+
+    public Tag getTag() {
+        //return the subType's tag
+        if (type == BodyPartID ) {
+            return INTEGER.TAG;
+        } else {
+            Assert._assert( type == BodyPartPath);
+            return SEQUENCE.TAG;
+        }
+    }
+
+    public void encode(OutputStream ostream) throws IOException {
+        if (type == BodyPartID ) {
+            bodyPartID.encode(ostream);
+        } else {
+            Assert._assert( type == BodyPartPath);
+            bodyPartPath.encode(ostream);
+        }
+    }
+
+    public void encode(Tag implicitTag, OutputStream ostream)
+        throws IOException
+    {
+        encode(ostream);
+    }
+
+    private static final Template templateInstance = new Template();
+    public static Template getTemplate() {
+        return templateInstance;
+    }
+
+
+    /**
+     * A Template for decoding a BodyPartReference.
+     */
+    public static class Template implements ASN1Template {
+
+        private CHOICE.Template choicet;
+
+        public Template() {
+            choicet = new CHOICE.Template();
+            choicet.addElement( INTEGER.getTemplate() );
+            choicet.addElement( new SEQUENCE.OF_Template(INTEGER.getTemplate()) );
+        }
+
+        public boolean tagMatch(Tag tag) {
+            return choicet.tagMatch(tag);
+        }
+
+        public ASN1Value decode(InputStream istream)
+                throws InvalidBERException, IOException {
+            CHOICE c = (CHOICE) choicet.decode(istream);
+
+            if( c.getTag().equals(INTEGER.TAG) ) {
+                return new BodyPartReference(BodyPartID, (INTEGER) c.getValue() , null);
+            } else {
+                Assert._assert( c.getTag().equals(SEQUENCE.TAG) );
+                return new BodyPartReference(BodyPartPath, null, (SEQUENCE) c.getValue());
+            }
+        }
+
+        public ASN1Value decode(Tag implicitTag, InputStream istream)
+                throws InvalidBERException, IOException {
+            //A CHOICE cannot be implicitly tagged
+            return decode(istream);
+        }
+    }
+}
diff --git a/org/mozilla/jss/pkix/cmc/CMCStatusInfoV2.java b/org/mozilla/jss/pkix/cmc/CMCStatusInfoV2.java
new file mode 100644
index 0000000..9b6aeb9
--- /dev/null
+++ b/org/mozilla/jss/pkix/cmc/CMCStatusInfoV2.java
@@ -0,0 +1,270 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Security Services for Java.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+package org.mozilla.jss.pkix.cmc;
+
+import org.mozilla.jss.util.Assert;
+import org.mozilla.jss.asn1.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.BitSet;
+
+/**
+ * CMCStatusInfoV2 replaces CMCStatusInfo in rfc 5272
+ * CMC <i>CMCStatusInfoV2</i>:
+ * <pre>
+ *     CMCStatusInfoV2 ::= SEQUENCE { 
+ *          cMCStatus           CMCStatus, 
+ *          bodyList            SEQUENCE SIZE (1..MAX)
+ *                                       BodyPartReference,
+ *          statusString        UTF8String OPTIONAL, 
+ *          otherInfo           CHOICE {  // defined in updated OtherInfo
+ *            failInfo            CMCFailInfo, 
+ *            pendInfo            PendInfo,
+ *            extendedFailInfo       SEQUENCE {
+ *              failInfoOID            OBJECT IDENTIFIER,
+ *              failInfoValue          AttributeValue
+ *            } OPTIONAL 
+ *         }
+ *     } 
+ *     PendInfo ::= SEQUENCE { 
+ *          pendToken           OCTET STRING, 
+ *          pendTime            GeneralizedTime 
+ *     }
+ *
+ * @author Christina Fu (cfu)
+ * </pre>
+ */
+public class CMCStatusInfoV2 implements ASN1Value {
+    public static final INTEGER BODYIDMAX = new INTEGER("4294967295");
+
+    ///////////////////////////////////////////////////////////////////////
+    // Members
+    ///////////////////////////////////////////////////////////////////////
+    private INTEGER status;
+    private SEQUENCE bodyList; 
+    private UTF8String statusString;
+    private OtherInfo otherInfo;
+
+    // CMCStatus constants
+    public static final int SUCCESS = 0;
+    public static final int RESERVED = 1;
+    public static final int FAILED = 2;
+    public static final int PENDING = 3;
+    public static final int NOSUPPORT = 4;
+    public static final int CONFIRM_REQUIRED = 5;
+    public static final int POP_REQUIRED = 6;
+    public static final int PARTIAL = 7;
+
+    public static final String[] STATUS = {"success",
+                                           "reserved",
+                                           "failed",
+                                           "pending",
+                                           "not supported",
+                                           "confirm required",
+                                           "pop required",
+                                           "partial"};
+
+    ///////////////////////////////////////////////////////////////////////
+    // Constructors
+    ///////////////////////////////////////////////////////////////////////
+
+    private CMCStatusInfoV2() { }
+
+    /**
+     * @param status A CMCStatus constant.
+     * @param bodyList The sequence of BodyPartReference.
+     */
+    public CMCStatusInfoV2(int status, SEQUENCE bodyList) {
+        this.status = new INTEGER(status);
+        this.bodyList = bodyList;
+        this.statusString = null;
+        this.otherInfo = null;
+    }
+
+    /**
+     * @param status A CMCStatus constant.
+     * @param bodyList The sequence of BodyPartReference.
+     * @param statusString A String.
+     * @param otherInfo The OtherInfo choice.
+     */
+    public CMCStatusInfoV2(int status, SEQUENCE bodyList, String
+                         statusString, OtherInfo otherInfo) {
+        this.status = new INTEGER(status);
+        this.bodyList = bodyList;
+        if (statusString != null){
+            try {
+                this.statusString = new UTF8String(statusString);
+            } catch (Exception e){}
+        } else
+            this.statusString = null;
+        this.otherInfo = otherInfo;
+    }
+
+    /**
+     * Create a CMCStatusInfoV2 from decoding.
+     * @param status A CMCStatus constant.
+     * @param bodyList The sequence of BodyPartReference.
+     * @param statusString A UTF8String.
+     * @param otherInfo A CHOICE.
+     */
+    public CMCStatusInfoV2(INTEGER status, SEQUENCE bodyList, UTF8String
+                         statusString, OtherInfo otherInfo) {
+        this.status = status;
+        this.bodyList = bodyList;
+        this.statusString = statusString;
+        this.otherInfo = otherInfo;
+    }
+
+    /**
+     * Sets the <code>statusString</code> field. May be null, since this
+     *  field is optional.
+     */
+    public void setStatusString(String statusString) {
+        if (statusString != null){
+            try {
+                this.statusString = new UTF8String(statusString);
+            } catch (Exception e){}
+        } else{
+            this.statusString = null;
+        }
+    }
+
+    /**
+     * Adds a BodyPartID to the bodyList SEQUENCE.
+     */
+    public void addBodyPartID(int id) {
+        INTEGER id1 = new INTEGER(id);
+        Assert._assert(id1.compareTo(BODYIDMAX) <= 0);
+        bodyList.addElement( id1 );
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // member access
+    ///////////////////////////////////////////////////////////////////////
+    public int getStatus() {
+        return status.intValue();
+    }
+    
+    public SEQUENCE getBodyList() {
+        return bodyList;
+    }
+
+    public String getStatusString() {
+        if (statusString != null)
+            return statusString.toString();
+        return null;
+    }
+
+    public OtherInfo getOtherInfo() {
+        return otherInfo;
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // decoding/encoding
+    ///////////////////////////////////////////////////////////////////////
+
+    public static final Tag TAG = SEQUENCE.TAG;
+    public Tag getTag() {
+        return TAG;
+    }
+
+    public void encode(OutputStream ostream) throws IOException {
+        encode(TAG, ostream);
+    }
+
+    public void encode(Tag implicitTag, OutputStream ostream)
+        throws IOException
+    {
+        SEQUENCE seq = new SEQUENCE();
+
+        seq.addElement(status);
+        seq.addElement(bodyList);
+        if( statusString != null ) {
+            seq.addElement( statusString );
+        }
+
+        if ( otherInfo != null) {
+            seq.addElement( otherInfo );
+        }
+
+        seq.encode(implicitTag, ostream);
+    }
+
+    private static final Template templateInstance = new Template();
+    public static Template getTemplate() {
+        return templateInstance;
+    }
+
+
+    public static class Template implements ASN1Template {
+
+        private SEQUENCE.Template seqt;
+
+        public Template() {
+            seqt = new SEQUENCE.Template();
+            seqt.addElement( INTEGER.getTemplate() );
+            seqt.addElement( new SEQUENCE.OF_Template(INTEGER.getTemplate()) );
+            seqt.addOptionalElement( UTF8String.getTemplate());
+
+            seqt.addOptionalElement( OtherInfo.getTemplate() );
+        }
+
+        public boolean tagMatch(Tag tag) {
+            return TAG.equals(tag);
+        }
+
+        public ASN1Value decode(InputStream istream)
+                throws InvalidBERException, IOException {
+            return decode(TAG, istream);
+        }
+
+        public ASN1Value decode(Tag implicitTag, InputStream istream)
+                throws InvalidBERException, IOException {
+
+            CMCStatusInfoV2 psi;
+            SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+            return new CMCStatusInfoV2((INTEGER)seq.elementAt(0),
+                                     (SEQUENCE)seq.elementAt(1),
+                                     (UTF8String)seq.elementAt(2),
+                                     (OtherInfo)seq.elementAt(3));
+        }
+    }
+}
+
diff --git a/org/mozilla/jss/pkix/cmc/DecryptedPOP.java b/org/mozilla/jss/pkix/cmc/DecryptedPOP.java
new file mode 100644
index 0000000..14013aa
--- /dev/null
+++ b/org/mozilla/jss/pkix/cmc/DecryptedPOP.java
@@ -0,0 +1,165 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Security Services for Java.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.jss.pkix.cmc;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import java.io.*;
+
+/**
+ * CMC <i>DecryptedPOP</i>:
+ * <pre>
+ *     DecryptedPOP ::= SEQUENCE {
+ *         bodyPartID      BodyPartID,
+ *         thePOPAlgID     AlgorithmIdentifier,
+ *         thePOP         OCTET STRING
+ *     }
+ * </pre>
+ *
+ * @author Christina Fu (cfu)
+ */
+public class DecryptedPOP implements ASN1Value {
+
+    ///////////////////////////////////////////////////////////////////////
+    // members and member access
+    ///////////////////////////////////////////////////////////////////////
+    private INTEGER bodyPartID;
+    private AlgorithmIdentifier thePOPAlgID;
+    private OCTET_STRING thePOP;
+    private SEQUENCE sequence;  // for DER encoding
+
+    /**
+     * Returns the <code>bodyPartID</code> field.
+     */
+    public INTEGER getBodyPartID() {
+        return bodyPartID;
+    }
+
+    public AlgorithmIdentifier getThePOPAlgID() {
+        return thePOPAlgID;
+    }
+
+    public OCTET_STRING getWitness() {
+        return thePOP;
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // constructors
+    ///////////////////////////////////////////////////////////////////////
+    private DecryptedPOP() { }
+
+    public DecryptedPOP(
+            INTEGER bodyPartID,
+            AlgorithmIdentifier thePOPAlgID,
+            OCTET_STRING thePOP)
+    {
+        if( bodyPartID==null || thePOPAlgID==null ||
+                thePOP==null ) {
+            throw new IllegalArgumentException("DecryptedPOP constructor"
+                +" parameter is null");
+        }
+
+        this.bodyPartID = bodyPartID;
+        this.thePOPAlgID = thePOPAlgID;
+        this.thePOP = thePOP;
+
+        sequence = new SEQUENCE();
+        sequence.addElement(bodyPartID);
+        sequence.addElement(thePOPAlgID);
+        sequence.addElement(thePOP);
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // DER encoding
+    ///////////////////////////////////////////////////////////////////////
+
+    private static final Tag TAG = SEQUENCE.TAG;
+
+    public Tag getTag() {
+        return TAG;
+    }
+
+    public void encode(OutputStream ostream) throws IOException {
+        sequence.encode(ostream);
+    }
+
+    public void encode(Tag implicitTag, OutputStream ostream)
+            throws IOException {
+        sequence.encode(implicitTag, ostream);
+    }
+
+    private static final Template templateInstance = new Template();
+    public static Template getTemplate() {
+        return templateInstance;
+    }
+
+    /**
+     * A Template for decoding BER-encoded DecryptedPOP items.
+     */
+    public static class Template implements ASN1Template {
+
+        private SEQUENCE.Template seqt;
+
+        public Template() {
+            seqt = new SEQUENCE.Template();
+
+            seqt.addElement( INTEGER.getTemplate() );
+            seqt.addElement( AlgorithmIdentifier.getTemplate() );
+            seqt.addElement( OCTET_STRING.getTemplate() );
+        }
+
+        public boolean tagMatch(Tag tag) {
+            return TAG.equals(tag);
+        }
+
+        public ASN1Value decode(InputStream istream)
+                throws InvalidBERException, IOException {
+            return decode(TAG, istream);
+        }
+
+        public ASN1Value decode(Tag implicitTag, InputStream istream)
+                throws InvalidBERException, IOException {
+
+            SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+            return new DecryptedPOP(
+                            (INTEGER) seq.elementAt(0),
+                            (AlgorithmIdentifier) seq.elementAt(1),
+                            (OCTET_STRING) seq.elementAt(2) );
+        }
+    }
+}
diff --git a/org/mozilla/jss/pkix/cmc/EncryptedPOP.java b/org/mozilla/jss/pkix/cmc/EncryptedPOP.java
new file mode 100644
index 0000000..58a3f4c
--- /dev/null
+++ b/org/mozilla/jss/pkix/cmc/EncryptedPOP.java
@@ -0,0 +1,185 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Security Services for Java.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.jss.pkix.cmc;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.cms.*;
+import java.io.*;
+
+/**
+ * CMC <i>EncryptedPOP</i>:
+ * <pre>
+ *     EncryptedPOP ::= SEQUENCE {
+ *         request       TaggedRequest,
+ *         cms             ContentInfo,
+ *         thePOPAlgID     AlgorithmIdentifier,
+ *         witnessAlgID    AlgorithmIdentifier,
+ *         witness         OCTET STRING
+ *     }
+ * </pre>
+ *
+ * @author Christina Fu (cfu)
+ */
+public class EncryptedPOP implements ASN1Value {
+
+    ///////////////////////////////////////////////////////////////////////
+    // members and member access
+    ///////////////////////////////////////////////////////////////////////
+    private TaggedRequest request;
+    private ContentInfo cms;
+    private AlgorithmIdentifier thePOPAlgID;
+    private AlgorithmIdentifier witnessAlgID;
+    private OCTET_STRING witness;
+    private SEQUENCE sequence;  // for DER encoding
+
+    public TaggedRequest getRequest() {
+        return request;
+    }
+
+    public ContentInfo getContentInfo() {
+        return cms;
+    }
+
+    public AlgorithmIdentifier getThePOPAlgID() {
+        return thePOPAlgID;
+    }
+
+    public AlgorithmIdentifier getWitnessAlgID() {
+        return witnessAlgID;
+    }
+
+    public OCTET_STRING getWitness() {
+        return witness;
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // constructors
+    ///////////////////////////////////////////////////////////////////////
+    private EncryptedPOP() { }
+
+    public EncryptedPOP(
+            TaggedRequest request,
+            ContentInfo cms,
+            AlgorithmIdentifier thePOPAlgID,
+            AlgorithmIdentifier witnessAlgID,
+            OCTET_STRING witness)
+    {
+        if( request==null || cms==null || thePOPAlgID==null || witnessAlgID==null ||
+                witness==null ) {
+            throw new IllegalArgumentException("EncryptedPOP constructor"
+                +" parameter is null");
+        }
+
+        this.request = request;
+        this.cms = cms;
+        this.thePOPAlgID = thePOPAlgID;
+        this.witnessAlgID = witnessAlgID;
+        this.witness = witness;
+
+        sequence = new SEQUENCE();
+        sequence.addElement(request);
+        sequence.addElement(cms);
+        sequence.addElement(thePOPAlgID);
+        sequence.addElement(witnessAlgID);
+        sequence.addElement(witness);
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // DER encoding
+    ///////////////////////////////////////////////////////////////////////
+
+    private static final Tag TAG = SEQUENCE.TAG;
+
+    public Tag getTag() {
+        return TAG;
+    }
+
+    public void encode(OutputStream ostream) throws IOException {
+        sequence.encode(ostream);
+    }
+
+    public void encode(Tag implicitTag, OutputStream ostream)
+            throws IOException {
+        sequence.encode(implicitTag, ostream);
+    }
+
+    private static final Template templateInstance = new Template();
+    public static Template getTemplate() {
+        return templateInstance;
+    }
+
+    /**
+     * A Template for decoding BER-encoded EncryptedPOP items.
+     */
+    public static class Template implements ASN1Template {
+
+        private SEQUENCE.Template seqt;
+
+        public Template() {
+            seqt = new SEQUENCE.Template();
+
+            seqt.addElement( TaggedRequest.getTemplate() );
+            seqt.addElement( ContentInfo.getTemplate() );
+            seqt.addElement( AlgorithmIdentifier.getTemplate() );
+            seqt.addElement( AlgorithmIdentifier.getTemplate() );
+            seqt.addElement( OCTET_STRING.getTemplate() );
+        }
+
+        public boolean tagMatch(Tag tag) {
+            return TAG.equals(tag);
+        }
+
+        public ASN1Value decode(InputStream istream)
+                throws InvalidBERException, IOException {
+            return decode(TAG, istream);
+        }
+
+        public ASN1Value decode(Tag implicitTag, InputStream istream)
+                throws InvalidBERException, IOException {
+
+            SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+            return new EncryptedPOP(
+                            (TaggedRequest) seq.elementAt(0),
+                            (ContentInfo) seq.elementAt(1),
+                            (AlgorithmIdentifier) seq.elementAt(2),
+                            (AlgorithmIdentifier) seq.elementAt(3),
+                            (OCTET_STRING) seq.elementAt(4) );
+        }
+    }
+}
diff --git a/org/mozilla/jss/pkix/cmc/ExtendedFailInfo.java b/org/mozilla/jss/pkix/cmc/ExtendedFailInfo.java
new file mode 100644
index 0000000..34a10a8
--- /dev/null
+++ b/org/mozilla/jss/pkix/cmc/ExtendedFailInfo.java
@@ -0,0 +1,145 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Security Services for Java.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.jss.pkix.cmc;
+
+import org.mozilla.jss.asn1.*;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import org.mozilla.jss.util.Assert;
+
+/**
+ * ExtendedFailInfo per rfc 5272
+ *    It is to be used in CMCStatusInfoV2 as a CHOICE of otherInfo
+ *
+ * <pre>
+ *      ExtendedFailInfo ::= SEQUENCE {
+ *          failInfoOID        OBJECT IDENTIFIER,
+ *          failInfoValue       ANY DEFINED BY failInfoOID }
+ * </pre>
+ *
+ * @author Christina Fu (cfu)
+ */
+public class ExtendedFailInfo implements ASN1Value {
+
+    private OBJECT_IDENTIFIER failInfoOID;
+    private ANY failInfoValue;
+
+    public static final Tag TAG = SEQUENCE.TAG;
+    public Tag getTag() {
+        return TAG;
+    }
+
+    private ExtendedFailInfo() { }
+
+    public ExtendedFailInfo(OBJECT_IDENTIFIER failInfoOID, ASN1Value failInfoValue) {
+        this.failInfoOID = failInfoOID;
+        if( failInfoValue instanceof ANY ) {
+            this.failInfoValue = (ANY) failInfoValue;
+        } else {
+            byte[] encoded = ASN1Util.encode(failInfoValue);
+            try {
+              this.failInfoValue = (ANY) ASN1Util.decode(ANY.getTemplate(), encoded);
+            } catch( InvalidBERException e ) {
+              Assert.notReached("InvalidBERException while decoding as ANY");
+            }
+        }
+    }
+
+    public OBJECT_IDENTIFIER getOID() {
+        return failInfoOID;
+    }
+
+    /**
+     * Returns the failInfoValue of this ExtendedFailInfo, encoded as an ANY.
+     */
+    public ANY getValue() {
+        return failInfoValue;
+    }
+
+    public void encode(OutputStream ostream) throws IOException {
+        encode(TAG, ostream);
+    }
+
+    public void encode(Tag implicit, OutputStream ostream)
+        throws IOException
+    {
+        SEQUENCE seq = new SEQUENCE();
+        seq.addElement(failInfoOID);
+        seq.addElement(failInfoValue);
+
+        seq.encode(implicit, ostream);
+    }
+
+    private static final Template templateInstance = new Template();
+    public static Template getTemplate() {
+        return templateInstance;
+    }
+
+    /**
+     * A Template for decoding an ExtendedFailInfo.
+     */
+    public static class Template implements ASN1Template {
+
+        public boolean tagMatch(Tag tag) {
+            return TAG.equals(tag);
+        }
+
+        public ASN1Value decode(InputStream istream)
+            throws IOException, InvalidBERException
+        {
+            return decode(TAG, istream);
+        }
+
+        public ASN1Value decode(Tag implicit, InputStream istream)
+            throws IOException, InvalidBERException
+        {
+            SEQUENCE.Template seqt = new SEQUENCE.Template();
+
+            seqt.addElement( new OBJECT_IDENTIFIER.Template()   );
+            seqt.addElement( new ANY.Template()                 );
+
+            SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream);
+
+            // The template should have enforced this
+            Assert._assert(seq.size() == 2);
+
+            return new ExtendedFailInfo( (OBJECT_IDENTIFIER) seq.elementAt(0),
+                                            seq.elementAt(1) );
+        }
+    }
+
+}
diff --git a/org/mozilla/jss/pkix/cmc/IdentityProofV2.java b/org/mozilla/jss/pkix/cmc/IdentityProofV2.java
new file mode 100644
index 0000000..f0daaaa
--- /dev/null
+++ b/org/mozilla/jss/pkix/cmc/IdentityProofV2.java
@@ -0,0 +1,163 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Security Services for Java.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.jss.pkix.cmc;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import java.io.*;
+
+/**
+ * CMC <i>IdentityProofV2</i>:
+ *   per rfc 5272
+ * <pre>
+ *     IdentityProofV2 ::= SEQUENCE {
+ *         hashAlgID      AlgorithmIdentifier,
+ *         macAlgId       AlgorithmIdentifier,
+ *         witness        OCTET STRING
+ *     }
+ * </pre>
+ *
+ * @author Christina Fu (cfu)
+ */
+public class IdentityProofV2 implements ASN1Value {
+
+    ///////////////////////////////////////////////////////////////////////
+    // members and member access
+    ///////////////////////////////////////////////////////////////////////
+    private AlgorithmIdentifier hashAlgID;
+    private AlgorithmIdentifier macAlgId;
+    private OCTET_STRING witness;
+    private SEQUENCE sequence;  // for DER encoding
+
+    public AlgorithmIdentifier getHashAlgID() {
+        return hashAlgID;
+    }
+
+    public AlgorithmIdentifier getMacAlgId() {
+        return macAlgId;
+    }
+
+    public OCTET_STRING getWitness() {
+        return witness;
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // constructors
+    ///////////////////////////////////////////////////////////////////////
+    private IdentityProofV2() { }
+
+    public IdentityProofV2(
+            AlgorithmIdentifier hashAlgID,
+            AlgorithmIdentifier macAlgId,
+            OCTET_STRING witness)
+    {
+        if(  hashAlgID==null || macAlgId==null ||
+                witness==null ) {
+            throw new IllegalArgumentException("IdentityProofV2 constructor"
+                +" parameter is null");
+        }
+
+        this.hashAlgID = hashAlgID;
+        this.macAlgId = macAlgId;
+        this.witness = witness;
+
+        sequence = new SEQUENCE();
+        sequence.addElement(hashAlgID);
+        sequence.addElement(macAlgId);
+        sequence.addElement(witness);
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // DER encoding
+    ///////////////////////////////////////////////////////////////////////
+
+    private static final Tag TAG = SEQUENCE.TAG;
+
+    public Tag getTag() {
+        return TAG;
+    }
+
+    public void encode(OutputStream ostream) throws IOException {
+        sequence.encode(ostream);
+    }
+
+    public void encode(Tag implicitTag, OutputStream ostream)
+            throws IOException {
+        sequence.encode(implicitTag, ostream);
+    }
+
+    private static final Template templateInstance = new Template();
+    public static Template getTemplate() {
+        return templateInstance;
+    }
+
+    /**
+     * A Template for decoding BER-encoded IdentityProofV2 items.
+     */
+    public static class Template implements ASN1Template {
+
+        private SEQUENCE.Template seqt;
+
+        public Template() {
+            seqt = new SEQUENCE.Template();
+
+            seqt.addElement( AlgorithmIdentifier.getTemplate() );
+            seqt.addElement( AlgorithmIdentifier.getTemplate() );
+            seqt.addElement( OCTET_STRING.getTemplate() );
+        }
+
+        public boolean tagMatch(Tag tag) {
+            return TAG.equals(tag);
+        }
+
+        public ASN1Value decode(InputStream istream)
+                throws InvalidBERException, IOException {
+            return decode(TAG, istream);
+        }
+
+        public ASN1Value decode(Tag implicitTag, InputStream istream)
+                throws InvalidBERException, IOException {
+
+            SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+            return new IdentityProofV2(
+                            (AlgorithmIdentifier) seq.elementAt(0),
+                            (AlgorithmIdentifier) seq.elementAt(1),
+                            (OCTET_STRING) seq.elementAt(2) );
+        }
+    }
+}
diff --git a/org/mozilla/jss/pkix/cmc/OtherInfo.java b/org/mozilla/jss/pkix/cmc/OtherInfo.java
index b93c193..3c83932 100644
--- a/org/mozilla/jss/pkix/cmc/OtherInfo.java
+++ b/org/mozilla/jss/pkix/cmc/OtherInfo.java
@@ -9,13 +9,20 @@ import java.io.*;
 import org.mozilla.jss.util.Assert;
 
 /**
- * CMCStatusInfo <i>OtherInfo</i>:
+ * CMCStatusInfoV2 <i>OtherInfo</i>:
+ *
  * <pre>
  *   OtherInfo ::= CHOICE { 
  *       failInfo INTEGER, 
- *       pendInfo PendInfo 
- *   } 
+ *       pendInfo PendInfo,
+ *       extendedFailInfo       SEQUENCE {  // ExtendedFailInfo
+ *           failInfoOID            OBJECT IDENTIFIER,
+ *           failInfoValue          AttributeValue
+ *       } OPTIONAL
+ *   }
  * </pre>
+ *
+ * @author Christina Fu (cfu) - updated for rfc5272
  */
 public class OtherInfo implements ASN1Value {
     // CMCFailInfo constants
@@ -32,20 +39,23 @@ public class OtherInfo implements ASN1Value {
     public static final int NO_KEY_REUSE = 10;
     public static final int INTERNAL_CA_ERROR = 11;
     public static final int TRY_LATER = 12;
+    public static final int authDataFail = 13;
 
-    public static final String[] FAIL_INFO = {"bad algorithm",
-												"bad message check",
-												"bad request",
-												"bad time",
-												"bad certificate id",
-												"unsupported extensions",
-												"must archive keys",
-												"bad identity",
-												"POP required",
-												"POP failed",
-												"no key reuse",
-												"internal ca error",
-												"try later"};
+    public static final String[] FAIL_INFO = {
+            "bad algorithm",
+            "bad message check",
+            "bad request",
+            "bad time",
+            "bad certificate id",
+            "unsupported extensions",
+            "must archive keys",
+            "bad identity",
+            "POP required",
+            "POP failed",
+            "no key reuse",
+            "internal ca error",
+            "try later",
+            "authenticated data fail"};
     /**
      * The type of OtherInfo.
      */
@@ -54,9 +64,11 @@ public class OtherInfo implements ASN1Value {
 
         static Type FAIL = new Type();
         static Type PEND = new Type();
+        static Type EXTENDED = new Type();
     }
     public static Type FAIL = Type.FAIL;
     public static Type PEND = Type.PEND;
+    public static Type EXTENDED = Type.EXTENDED;
 
     ///////////////////////////////////////////////////////////////////////
     // members and member access
@@ -65,6 +77,7 @@ public class OtherInfo implements ASN1Value {
     private Type type;
     private INTEGER failInfo; // if type == FAIL
     private PendInfo pendInfo; // if type == PEND
+    private ExtendedFailInfo extendedFailInfo; // if type == EXTENDED
 
     ///////////////////////////////////////////////////////////////////////
     // Constructors
@@ -73,17 +86,76 @@ public class OtherInfo implements ASN1Value {
     // no default constructor
     public OtherInfo() { }
 
-    /** 
+    /**
      * Constructs a OtherInfo from its components.
      *
      * @param type The type of the otherInfo.
      * @param failInfo the CMCFailInfo code.
      * @param pendInfo the pending information.
+     *
+     * Note: kept for backward compatibility for now; new code don't use
      */
     public OtherInfo(Type type, INTEGER failInfo, PendInfo pendInfo) {
+        if (type == null) {
+            throw new IllegalArgumentException("OtherInfo constructor"
+                +" parameter is null");
+        }
+
+        if ( type == FAIL ) {
+            if (failInfo == null) {
+                throw new IllegalArgumentException("OtherInfo constructor"
+                    +" parameter failInfo is null");
+            }
+        } else {
+            Assert._assert( type == PEND );
+            if (pendInfo == null) {
+                throw new IllegalArgumentException("OtherInfo constructor"
+                    +" parameter pendInfo is null");
+            }
+        }
+        this.type = type;
+        this.failInfo = failInfo;
+        this.pendInfo = pendInfo;
+    }
+
+    /** 
+     * Constructs a OtherInfo from its components.
+     *
+     * @param type The type of the otherInfo.
+     * @param failInfo the CMCFailInfo code.
+     * @param pendInfo the pending information.
+     * @param extendedFailInfo the extendedFailInfo information.
+     */
+    public OtherInfo(Type type,
+            INTEGER failInfo,
+            PendInfo pendInfo,
+            ExtendedFailInfo extendedFailInfo) {
+        if (type == null) {
+            throw new IllegalArgumentException("OtherInfo constructor"
+                +" parameter is null");
+        }
+
+        if ( type == FAIL ) {
+            if (failInfo == null) {
+                throw new IllegalArgumentException("OtherInfo constructor"
+                    +" parameter failInfo is null");
+            }
+        } else if ( type == PEND ) {
+            if (pendInfo == null) {
+                throw new IllegalArgumentException("OtherInfo constructor"
+                    +" parameter pendInfo is null");
+            }
+        } else {
+            Assert._assert( type == EXTENDED );
+            if (extendedFailInfo == null) {
+                throw new IllegalArgumentException("OtherInfo constructor"
+                    +" parameter extendedFailInfo is null");
+            }
+        }
         this.type = type;
         this.failInfo = failInfo;
         this.pendInfo = pendInfo;
+        this.extendedFailInfo = extendedFailInfo;
     }
 
     ///////////////////////////////////////////////////////////////////////
@@ -94,6 +166,7 @@ public class OtherInfo implements ASN1Value {
      * Returns the type of OtherInfo: <ul>
      * <li><code>FAIL</code>
      * <li><code>PEND</code>
+     * <li><code>EXTENDED</code>
      * </ul>
      */
     public Type getType() {
@@ -116,17 +189,27 @@ public class OtherInfo implements ASN1Value {
         return pendInfo;
     }
 
+    /**
+     * If type == EXTENDED, returns the extendedFailInfo field. Otherwise,
+     * returns null.
+     */
+    public ExtendedFailInfo getExtendedFailInfo() {
+        return extendedFailInfo;
+    }
+
     ///////////////////////////////////////////////////////////////////////
     // DER decoding/encoding
     ///////////////////////////////////////////////////////////////////////
 
     public Tag getTag() {
-		// return the subType's tag
+        // return the subType's tag
         if( type == FAIL ) {
             return INTEGER.TAG;
-        } else {
-            Assert._assert( type == PEND );
+        } else if( type == PEND ){
             return PendInfo.TAG;
+        } else {
+            Assert._assert( type == EXTENDED );
+            return ExtendedFailInfo.TAG;
         }
     }
 
@@ -134,16 +217,18 @@ public class OtherInfo implements ASN1Value {
 
         if( type == FAIL ) {
             failInfo.encode(ostream);
-        } else {
-            Assert._assert( type == PEND );
+        } else if( type == PEND ){
             pendInfo.encode(ostream);
+        } else {
+            Assert._assert( type == EXTENDED );
+            extendedFailInfo.encode(ostream);
         }
     }
 
     public void encode(Tag implicitTag, OutputStream ostream)
             throws IOException {
-			//Assert.notReached("A CHOICE cannot be implicitly tagged " +implicitTag.getNum());
-			encode(ostream);
+            //Assert.notReached("A CHOICE cannot be implicitly tagged " +implicitTag.getNum());
+            encode(ostream);
     }
 
     private static final Template templateInstance = new Template();
@@ -162,6 +247,7 @@ public class OtherInfo implements ASN1Value {
             choicet = new CHOICE.Template();
             choicet.addElement( INTEGER.getTemplate() );
             choicet.addElement( PendInfo.getTemplate() );
+            choicet.addElement( ExtendedFailInfo.getTemplate() );
         }
 
         public boolean tagMatch(Tag tag) {
@@ -173,17 +259,19 @@ public class OtherInfo implements ASN1Value {
             CHOICE c = (CHOICE) choicet.decode(istream);
 
             if( c.getTag().equals(INTEGER.TAG) ) {
-                return new OtherInfo(FAIL, (INTEGER) c.getValue() , null);
+                return new OtherInfo(FAIL, (INTEGER) c.getValue() , null, null);
+            } else if( c.getTag().equals(PendInfo.TAG) ) {
+                return new OtherInfo(PEND, null, (PendInfo) c.getValue(), null);
             } else {
-                Assert._assert( c.getTag().equals(PendInfo.TAG) );
-                return new OtherInfo(PEND, null, (PendInfo) c.getValue());
+                Assert._assert( c.getTag().equals(ExtendedFailInfo.TAG) );
+                return new OtherInfo(EXTENDED, null, null, (ExtendedFailInfo) c.getValue());
             }
         }
 
         public ASN1Value decode(Tag implicitTag, InputStream istream)
                 throws InvalidBERException, IOException {
-				//Assert.notReached("A CHOICE cannot be implicitly tagged");
-				return decode(istream);
-		}
-	}
+                //Assert.notReached("A CHOICE cannot be implicitly tagged");
+                return decode(istream);
+        }
+    }
 }
diff --git a/org/mozilla/jss/pkix/cmc/OtherReqMsg.java b/org/mozilla/jss/pkix/cmc/OtherReqMsg.java
new file mode 100644
index 0000000..d1100b4
--- /dev/null
+++ b/org/mozilla/jss/pkix/cmc/OtherReqMsg.java
@@ -0,0 +1,167 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Security Services for Java.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.jss.pkix.cmc;
+
+import org.mozilla.jss.asn1.*;
+import java.io.*;
+
+/**
+ * CMC <i>OtherReqMsg</i>.
+ * <pre>
+ * OtherReqMsg is to be used by the "orm" field of the TaggedRequest per
+ *     definition in RFC 5272.
+ *
+ * OtherReqMsg ::= SEQUENCE {
+ *      bodyPartID      BodyPartID,
+ *      requestMessageType    Object Identifier,
+ *      requestMessageValue   ANY defined by requestMessageType}
+ * </pre>
+ *
+ * @author Christina Fu (cfu)
+ */
+public class OtherReqMsg implements ASN1Value {
+
+    ///////////////////////////////////////////////////////////////////////
+    // Members and member access
+    ///////////////////////////////////////////////////////////////////////
+    private INTEGER bodyPartID;
+    private OBJECT_IDENTIFIER requestMessageType;
+    private ANY requestMessageValue;
+    private SEQUENCE sequence;
+
+    /**
+     * Returns the <code>bodyPartID</code> field.
+     */
+    public INTEGER getBodyPartID() {
+        return bodyPartID;
+    }
+
+    /**
+     * Returns the <code>requestMessageType</code> field.
+     */
+    public OBJECT_IDENTIFIER getOtherReqMsgType() {
+        return requestMessageType;
+    }
+
+    /**
+     * Returns the <code>requestMessageValue</code> field.
+     */
+    public ANY getOtherReqMsgValue() {
+        return requestMessageValue;
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // Constructors
+    ///////////////////////////////////////////////////////////////////////
+    private OtherReqMsg() { }
+
+    /**
+     * Constructs a new <code>OtherReqMsg</code> from its components.
+     */
+    public OtherReqMsg(INTEGER bodyPartID, OBJECT_IDENTIFIER requestMessageType,
+            ANY requestMessageValue) {
+        if (bodyPartID == null || requestMessageType == null
+                || requestMessageValue == null) {
+            throw new IllegalArgumentException(
+                "parameter to OtherReqMsg constructor is null");
+        }
+        sequence = new SEQUENCE();
+
+        this.bodyPartID = bodyPartID;
+        sequence.addElement(bodyPartID);
+
+        this.requestMessageType = requestMessageType;
+        sequence.addElement(requestMessageType);
+
+        this.requestMessageValue = requestMessageValue;
+        sequence.addElement(requestMessageValue);
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // encoding/decoding
+    ///////////////////////////////////////////////////////////////////////
+    private static final Tag TAG = SEQUENCE.TAG;
+    public Tag getTag() {
+        return TAG;
+    }
+
+    public void encode(OutputStream ostream) throws IOException {
+        sequence.encode(ostream);
+    }
+
+    public void encode(Tag implicitTag, OutputStream ostream)
+            throws IOException {
+        sequence.encode(implicitTag, ostream);
+    }
+
+    private static final Template templateInstance = new Template();
+    public static Template getTemplate() {
+        return templateInstance;
+    }
+
+    /**
+     * A Template for decoding a <code>OtherReqMsg</code>.
+     */
+    public static class Template implements ASN1Template {
+        private SEQUENCE.Template seqt;
+
+        public Template() {
+            seqt = new SEQUENCE.Template();
+            seqt.addElement(INTEGER.getTemplate());
+            seqt.addElement(OBJECT_IDENTIFIER.getTemplate());
+            seqt.addElement(ANY.getTemplate());
+        }
+
+        public boolean tagMatch(Tag tag) {
+            return TAG.equals(tag);
+        }
+
+        public ASN1Value decode(InputStream istream)
+                throws InvalidBERException, IOException {
+            return decode(TAG, istream);
+        }
+
+        public ASN1Value decode(Tag implicitTag, InputStream istream)
+                throws InvalidBERException, IOException {
+            SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+            return new OtherReqMsg((INTEGER)seq.elementAt(0),
+                                (OBJECT_IDENTIFIER)seq.elementAt(1),
+                                (ANY)seq.elementAt(2));
+        }
+    }
+}
diff --git a/org/mozilla/jss/pkix/cmc/PopLinkWitnessV2.java b/org/mozilla/jss/pkix/cmc/PopLinkWitnessV2.java
new file mode 100644
index 0000000..637c316
--- /dev/null
+++ b/org/mozilla/jss/pkix/cmc/PopLinkWitnessV2.java
@@ -0,0 +1,163 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Security Services for Java.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.jss.pkix.cmc;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+import java.io.*;
+
+/**
+ * CMC <i>PopLinkWitnessV2</i>:
+ *   per rfc 5272
+ * <pre>
+ *     PopLinkWitnessV2 ::= SEQUENCE {
+ *         keyGenAlgorithm     AlgorithmIdentifier,
+ *         macAlgorithm       AlgorithmIdentifier,
+ *         witness        OCTET STRING
+ *     }
+ * </pre>
+ *
+ * @author Christina Fu (cfu)
+ */
+public class PopLinkWitnessV2 implements ASN1Value {
+
+    ///////////////////////////////////////////////////////////////////////
+    // members and member access
+    ///////////////////////////////////////////////////////////////////////
+    private AlgorithmIdentifier keyGenAlgorithm;
+    private AlgorithmIdentifier macAlgorithm;
+    private OCTET_STRING witness;
+    private SEQUENCE sequence;  // for DER encoding
+
+    public AlgorithmIdentifier getKeyGenAlgorithm() {
+        return keyGenAlgorithm;
+    }
+
+    public AlgorithmIdentifier getMacAlgorithm() {
+        return macAlgorithm;
+    }
+
+    public OCTET_STRING getWitness() {
+        return witness;
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // constructors
+    ///////////////////////////////////////////////////////////////////////
+    private PopLinkWitnessV2() { }
+
+    public PopLinkWitnessV2(
+            AlgorithmIdentifier keyGenAlgorithm,
+            AlgorithmIdentifier macAlgorithm,
+            OCTET_STRING witness)
+    {
+        if(  keyGenAlgorithm==null || macAlgorithm==null ||
+                witness==null ) {
+            throw new IllegalArgumentException("PopLinkWitnessV2 constructor"
+                +" parameter is null");
+        }
+
+        this.keyGenAlgorithm = keyGenAlgorithm;
+        this.macAlgorithm = macAlgorithm;
+        this.witness = witness;
+
+        sequence = new SEQUENCE();
+        sequence.addElement(keyGenAlgorithm);
+        sequence.addElement(macAlgorithm);
+        sequence.addElement(witness);
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // DER encoding
+    ///////////////////////////////////////////////////////////////////////
+
+    private static final Tag TAG = SEQUENCE.TAG;
+
+    public Tag getTag() {
+        return TAG;
+    }
+
+    public void encode(OutputStream ostream) throws IOException {
+        sequence.encode(ostream);
+    }
+
+    public void encode(Tag implicitTag, OutputStream ostream)
+            throws IOException {
+        sequence.encode(implicitTag, ostream);
+    }
+
+    private static final Template templateInstance = new Template();
+    public static Template getTemplate() {
+        return templateInstance;
+    }
+
+    /**
+     * A Template for decoding BER-encoded PopLinkWitnessV2 items.
+     */
+    public static class Template implements ASN1Template {
+
+        private SEQUENCE.Template seqt;
+
+        public Template() {
+            seqt = new SEQUENCE.Template();
+
+            seqt.addElement( AlgorithmIdentifier.getTemplate() );
+            seqt.addElement( AlgorithmIdentifier.getTemplate() );
+            seqt.addElement( OCTET_STRING.getTemplate() );
+        }
+
+        public boolean tagMatch(Tag tag) {
+            return TAG.equals(tag);
+        }
+
+        public ASN1Value decode(InputStream istream)
+                throws InvalidBERException, IOException {
+            return decode(TAG, istream);
+        }
+
+        public ASN1Value decode(Tag implicitTag, InputStream istream)
+                throws InvalidBERException, IOException {
+
+            SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+            return new PopLinkWitnessV2(
+                            (AlgorithmIdentifier) seq.elementAt(0),
+                            (AlgorithmIdentifier) seq.elementAt(1),
+                            (OCTET_STRING) seq.elementAt(2) );
+        }
+    }
+}
diff --git a/org/mozilla/jss/pkix/cmc/RevokeRequest.java b/org/mozilla/jss/pkix/cmc/RevokeRequest.java
new file mode 100644
index 0000000..d8444b6
--- /dev/null
+++ b/org/mozilla/jss/pkix/cmc/RevokeRequest.java
@@ -0,0 +1,323 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Security Services for Java.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.jss.pkix.cmc;
+
+import org.mozilla.jss.asn1.*;
+import java.io.*;
+
+/**
+ * CMC <i>RevokeRequest</i>.
+ * <pre>
+ * RevokeRequest ::= SEQUENCE {
+ *      issuerName      Name,
+ *      serialNumber    INTEGER,
+ *      reason          CRLReason,
+ *      invalidityDate  GeneralizedTime OPTIONAL,
+ *      passphrase    OCTET STRING OPTIONAL,
+ *      comment         UTF8String OPTIONAL }
+ * </pre>
+ *
+ * For maintenance and conformance reasons, this code is brought over
+ * and mildly updated and renamed from cmmf/RevRequest during the process
+ * of CMC update to rfc 5272
+ * @author Christina Fu (cfu)
+ */
+public class RevokeRequest implements ASN1Value {
+
+    ///////////////////////////////////////////////////////////////////////
+    // Constants
+    ///////////////////////////////////////////////////////////////////////
+
+    /**
+     * A <code>CRLReason</code>, which can be used in the <code>reason</code>
+     *  field.
+     */
+    public static final ENUMERATED unspecified = new ENUMERATED(0);
+    /**
+     * A <code>CRLReason</code>, which can be used in the <code>reason</code>
+     *  field.
+     */
+    public static final ENUMERATED keyCompromise = new ENUMERATED(1);
+    /**
+     * A <code>CRLReason</code>, which can be used in the <code>reason</code>
+     *  field.
+     */
+    public static final ENUMERATED cACompromise = new ENUMERATED(2);
+    /**
+     * A <code>CRLReason</code>, which can be used in the <code>reason</code>
+     *  field.
+     */
+    public static final ENUMERATED affiliationChanged = new ENUMERATED(3);
+    /**
+     * A <code>CRLReason</code>, which can be used in the <code>reason</code>
+     *  field.
+     */
+    public static final ENUMERATED superseded = new ENUMERATED(4);
+    /**
+     * A <code>CRLReason</code>, which can be used in the <code>reason</code>
+     *  field.
+     */
+    public static final ENUMERATED cessationOfOperation = new ENUMERATED(5);
+    /**
+     * A <code>CRLReason</code>, which can be used in the <code>reason</code>
+     *  field.
+     */
+    public static final ENUMERATED certificateHold = new ENUMERATED(6);
+    /**
+     * A <code>CRLReason</code>, which can be used in the <code>reason</code>
+     *  field.
+     */
+    public static final ENUMERATED removeFromCRL = new ENUMERATED(8);
+    /**
+     * A <code>CRLReason</code>, which can be used in the <code>reason</code>
+     *  field.
+     */
+    public static final ENUMERATED privilegeWithdrawn = new ENUMERATED(9);
+    /**
+     * A <code>CRLReason</code>, which can be used in the <code>reason</code>
+     *  field.
+     */
+    public static final ENUMERATED aACompromise = new ENUMERATED(10);
+
+
+    ///////////////////////////////////////////////////////////////////////
+    // Members and member access
+    ///////////////////////////////////////////////////////////////////////
+    private ANY issuerName;
+    private INTEGER serialNumber;
+    private ENUMERATED reason;
+    private GeneralizedTime invalidityDate; // may be null
+    private OCTET_STRING passphrase; // may be null
+    private UTF8String comment; // may be null
+    private SEQUENCE sequence;
+
+    /**
+     * Returns the <code>issuerName</code> field as an ANY.
+     */
+    public ANY getIssuerName() {
+        return issuerName;
+    }
+
+    /**
+     * Returns the <code>serialNumber</code> field.
+     */
+    public INTEGER getSerialNumber() {
+        return serialNumber;
+    }
+
+    /**
+     * Returns the <code>reason</code> field, which should indicate the
+     *  reason for the revocation.  The currently supported reasons are:
+     * <pre>
+     * CRLReason ::= ENUMERATED {
+     *      unspecified             (0),
+     *      keyCompromise           (1),
+     *      cACompromise            (2),
+     *      affiliationChanged      (3),
+     *      superseded              (4),
+     *      cessationOfOperation    (5),
+     *      certificateHold         (6),
+     *      removeFromCRL           (8),
+     *      privilegeWithdrawn      (9),
+     *      aACompromise            (10) }
+     * </pre>
+     * These are all defined as constants in this class.
+     */
+    public ENUMERATED getReason() {
+        return reason;
+    }
+
+    /**
+     * Returns the <tt>invalidityDate</tt> field. Returns <tt>null</tt>
+     * if the field is not present.
+     */
+    public GeneralizedTime getInvalidityDate() {
+        return invalidityDate;
+    }
+
+    /**
+     * Returns the <code>passphrase</code> field.  Returns
+     *  <code>null</code> if the field is not present.
+     */
+    public OCTET_STRING getSharedSecret() {
+        return passphrase;
+    }
+
+    /**
+     * Returns the <code>comment</code> field.  Returns <code>null</code>
+     * if the field is not present.
+     */
+    public UTF8String getComment() {
+        return comment;
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // Constructors
+    ///////////////////////////////////////////////////////////////////////
+
+    private RevokeRequest() { }
+
+
+    /**
+     * Constructs a new <code>RevokeRequest</code> from its components,
+     *  omitting the <tt>invalidityDate</tt> field.
+     *
+     * @deprecated This constructor is obsolete now that
+     *      <tt>invalidityDate</tt> has been added to the class.
+     *
+     * @param issuerName The <code>issuerName</code> field.
+     * @param serialNumber The <code>serialNumber</code> field.
+     * @param reason The <code>reason</code> field.  The constants defined
+     *      in this class may be used.
+     * @param passphrase The <code>passphrase</code> field.  This field is
+     *      optional, so <code>null</code> may be used.
+     * @param comment The <code>comment</code> field.  This field is optional,
+     *      so <code>null</code> may be used.
+     */
+    public RevokeRequest(ANY issuerName, INTEGER serialNumber,
+                    ENUMERATED reason, OCTET_STRING passphrase,
+                    UTF8String comment)
+    {
+        this(issuerName, serialNumber, reason, null, passphrase, comment);
+    }
+
+    /**
+     * Constructs a new <code>RevokeRequest</code> from its components.
+     *
+     * @param issuerName The <code>issuerName</code> field.
+     * @param serialNumber The <code>serialNumber</code> field.
+     * @param reason The <code>reason</code> field.  The constants defined
+     *      in this class may be used.
+     * @param invalidityDate The suggested value for the Invalidity Date
+     *      CRL extension. This field is optional, so <tt>null</tt> may be
+     *      used.
+     * @param passphrase The <code>passphrase</code> field.  This field is
+     *      optional, so <code>null</code> may be used.
+     * @param comment The <code>comment</code> field.  This field is optional,
+     *      so <code>null</code> may be used.
+     */
+    public RevokeRequest(ANY issuerName, INTEGER serialNumber,
+                    ENUMERATED reason, GeneralizedTime invalidityDate,
+                    OCTET_STRING passphrase, UTF8String comment)
+    {
+        if( issuerName==null || serialNumber==null || reason==null ) {
+            throw new IllegalArgumentException(
+                "parameter to RevokeRequest constructor is null");
+        }
+        sequence = new SEQUENCE();
+
+        this.issuerName = issuerName;
+        sequence.addElement(issuerName);
+
+        this.serialNumber = serialNumber;
+        sequence.addElement(serialNumber);
+
+        this.reason = reason;
+        sequence.addElement(reason);
+
+        this.invalidityDate = invalidityDate;
+        sequence.addElement(invalidityDate);
+
+        this.passphrase = passphrase;
+        sequence.addElement(passphrase);
+
+        this.comment = comment;
+        sequence.addElement(comment);
+    }
+
+
+    ///////////////////////////////////////////////////////////////////////
+    // encoding/decoding
+    ///////////////////////////////////////////////////////////////////////
+
+    private static final Tag TAG = SEQUENCE.TAG;
+    public Tag getTag() {
+        return TAG;
+    }
+
+    public void encode(OutputStream ostream) throws IOException {
+        sequence.encode(ostream);
+    }
+
+    public void encode(Tag implicitTag, OutputStream ostream)
+            throws IOException {
+        sequence.encode(implicitTag, ostream);
+    }
+
+
+
+    /**
+     * A Template class for decoding a <code>RevokeRequest</code>.
+     */
+    public static class Template implements ASN1Template {
+
+        private SEQUENCE.Template seqt;
+
+        public Template() {
+            seqt = new SEQUENCE.Template();
+            seqt.addElement(ANY.getTemplate());
+            seqt.addElement(INTEGER.getTemplate());
+            seqt.addElement(ENUMERATED.getTemplate());
+            seqt.addOptionalElement(GeneralizedTime.getTemplate());
+            seqt.addOptionalElement(OCTET_STRING.getTemplate());
+            seqt.addOptionalElement(UTF8String.getTemplate());
+        }
+
+        public boolean tagMatch(Tag tag) {
+            return TAG.equals(tag);
+        }
+
+        public ASN1Value decode(InputStream istream)
+                throws InvalidBERException, IOException {
+            return decode(TAG, istream);
+        }
+
+        public ASN1Value decode(Tag implicitTag, InputStream istream)
+                throws InvalidBERException, IOException {
+            
+            SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream);
+
+            return new RevokeRequest(  (ANY) seq.elementAt(0),
+                                    (INTEGER) seq.elementAt(1),
+                                    (ENUMERATED) seq.elementAt(2),
+                                    (GeneralizedTime) seq.elementAt(3),
+                                    (OCTET_STRING) seq.elementAt(4),
+                                    (UTF8String) seq.elementAt(5) );
+
+        }
+    }
+}
diff --git a/org/mozilla/jss/pkix/cmc/TaggedRequest.java b/org/mozilla/jss/pkix/cmc/TaggedRequest.java
index e616660..e71b57c 100644
--- a/org/mozilla/jss/pkix/cmc/TaggedRequest.java
+++ b/org/mozilla/jss/pkix/cmc/TaggedRequest.java
@@ -15,6 +15,11 @@ import org.mozilla.jss.util.Assert;
  *   TaggedRequest ::= CHOICE { 
  *       tcr               [0] TaggedCertificationRequest, 
  *       crm               [1] CertReqMsg 
+ *       orm               [2] SEQUENCE {
+ *            bodyPartID            BodyPartID,
+ *            requestMessageType    OBJECT IDENTIFIER,
+ *            requestMessageValue   ANY DEFINED BY requestMessageType
+ *       } // added for rfc 5272; defined in OtherReqMsg
  *   } 
  * </pre>
  */
@@ -27,9 +32,11 @@ public class TaggedRequest implements ASN1Value {
 
         static Type PKCS10 = new Type();
         static Type CRMF = new Type();
+        static Type OTHER = new Type();
     }
     public static Type PKCS10 = Type.PKCS10;
     public static Type CRMF = Type.CRMF;
+    public static Type OTHER = Type.OTHER;
 
     ///////////////////////////////////////////////////////////////////////
     // members and member access
@@ -38,6 +45,7 @@ public class TaggedRequest implements ASN1Value {
     private Type type;
     private TaggedCertificationRequest tcr; // if type == PKCS10
     private CertReqMsg crm; // if type == CRMF
+    private OtherReqMsg orm; // if type == OTHER
 
     ///////////////////////////////////////////////////////////////////////
     // Constructors
@@ -48,7 +56,7 @@ public class TaggedRequest implements ASN1Value {
 
     /** 
      * Constructs a TaggedRequest from its components.
-     *
+     *   kept for backward compatibility for now
      * @param type The type of the request.
      * @param tcr Tagged pkcs10 request.
      * @param crm CRMF request.
@@ -59,6 +67,24 @@ public class TaggedRequest implements ASN1Value {
         this.crm = crm;
     }
 
+    /** 
+     * Constructs a TaggedRequest from its components.
+     *   rfc 5272
+     * @param type The type of the request.
+     * @param tcr Tagged pkcs10 request.
+     * @param crm CRMF request.
+     * @param orm OTHER request.
+     */
+    public TaggedRequest(Type type,
+            TaggedCertificationRequest tcr,
+            CertReqMsg crm,
+            OtherReqMsg orm) {
+        this.type = type;
+        this.tcr = tcr;
+        this.crm = crm;
+        this.orm = orm;
+    }
+
     ///////////////////////////////////////////////////////////////////////
     // accessors
     ///////////////////////////////////////////////////////////////////////
@@ -67,6 +93,7 @@ public class TaggedRequest implements ASN1Value {
      * Returns the type of TaggedRequest: <ul>
      * <li><code>PKCS10</code>
      * <li><code>CRMF</code>
+     * <li><code>OTHER</code>
      * </ul>
      */
     public Type getType() {
@@ -89,6 +116,14 @@ public class TaggedRequest implements ASN1Value {
         return crm;
     }
 
+    /**
+     * If type == OTHER, returns the orm field. Otherwise,
+     * returns null.
+     */
+    public OtherReqMsg getOrm() {
+        return orm;
+    }
+
     ///////////////////////////////////////////////////////////////////////
     // DER decoding/encoding
     ///////////////////////////////////////////////////////////////////////
@@ -96,9 +131,11 @@ public class TaggedRequest implements ASN1Value {
     public Tag getTag() {
         if( type == PKCS10 ) {
             return Tag.get(0);
-        } else {
-            Assert._assert( type == CRMF );
+        } else if( type == CRMF ){
             return Tag.get(1);
+        } else {
+            Assert._assert( type == OTHER );
+            return Tag.get(2);
         }
     }
 
@@ -109,12 +146,17 @@ public class TaggedRequest implements ASN1Value {
             // a CHOICE must be explicitly tagged
             //EXPLICIT e = new EXPLICIT( Tag.get(0), tcr );
             //e.encode(ostream);
-        } else {
-            Assert._assert( type == CRMF );
+        } else if( type == CRMF ) {
             crm.encode(Tag.get(1), ostream);
             // a CHOICE must be explicitly tagged
             //EXPLICIT e = new EXPLICIT( Tag.get(1), crm );
             //e.encode(ostream);
+        } else {
+            Assert._assert( type == OTHER );
+            orm.encode(Tag.get(2), ostream);
+            // a CHOICE must be explicitly tagged
+            //EXPLICIT e = new EXPLICIT( Tag.get(2), orm );
+            //e.encode(ostream);
         }
     }
 
@@ -142,12 +184,16 @@ public class TaggedRequest implements ASN1Value {
 
             //EXPLICIT.Template et = new EXPLICIT.Template(
             //    Tag.get(0), TaggedCertificationRequest.getTemplate() );
-			//choicet.addElement( et );
+            //choicet.addElement( et );
             choicet.addElement( Tag.get(0), TaggedCertificationRequest.getTemplate() );
             //et = new EXPLICIT.Template(
             //    Tag.get(1), CertReqMsg.getTemplate() );
-			//choicet.addElement( et );
+            //choicet.addElement( et );
             choicet.addElement( Tag.get(1), CertReqMsg.getTemplate() );
+            //et = new EXPLICIT.Template(
+            //    Tag.get(2), CertReqMsg.getTemplate() );
+            //choicet.addElement( et );
+            choicet.addElement( Tag.get(2), OtherReqMsg.getTemplate() );
         }
 
         public boolean tagMatch(Tag tag) {
@@ -161,15 +207,21 @@ public class TaggedRequest implements ASN1Value {
             if( c.getTag().equals(Tag.get(0)) ) {
                 //EXPLICIT e = (EXPLICIT) c.getValue();
                 //return new TaggedRequest(PKCS10,
-				//						 (TaggedCertificationRequest)
-				//						 e.getContent(), null );
+                //            (TaggedCertificationRequest)
+                //            e.getContent(), null );
                 return new TaggedRequest(PKCS10, (TaggedCertificationRequest) c.getValue() , null);
+            } if( c.getTag().equals(Tag.get(1)) ) {
+                //EXPLICIT e = (EXPLICIT) c.getValue();
+                //return new TaggedRequest(CRMF,
+                //            (CertReqMsg)
+                //            e.getContent(), null );
+                return new TaggedRequest(CRMF, null, (CertReqMsg) c.getValue() , null);
             } else {
-                Assert._assert( c.getTag().equals(Tag.get(1)) );
+                Assert._assert( c.getTag().equals(Tag.get(2)) );
                 //EXPLICIT e = (EXPLICIT) c.getValue();
-                //return new TaggedRequest(CRMF, null,
-				//						 (CertReqMsg) e.getContent() );
-                return new TaggedRequest(CRMF, null, (CertReqMsg) c.getValue());
+                //return new TaggedRequest(OTHER, null,
+                //            (CertReqMsg) e.getContent() );
+                return new TaggedRequest(OTHER, null, null, (OtherReqMsg) c.getValue());
             }
         }
 
diff --git a/org/mozilla/jss/pkix/cmmf/RevRequest.java b/org/mozilla/jss/pkix/cmmf/RevRequest.java
index 3fd1342..578548b 100644
--- a/org/mozilla/jss/pkix/cmmf/RevRequest.java
+++ b/org/mozilla/jss/pkix/cmmf/RevRequest.java
@@ -18,6 +18,9 @@ import java.io.*;
  *      sharedSecret    OCTET STRING OPTIONAL,
  *      comment         UTF8String OPTIONAL }
  * </pre>
+ * For maintenance and conformance reasons, this code has been brought
+ * over and renamed to cmc/RevokeRequest during the CMC update to rfc 5272.
+ * All new code should use cmc/RevokeRequest instead
  */
 public class RevRequest implements ASN1Value {
 
diff --git a/org/mozilla/jss/pkix/crmf/CertRequest.java b/org/mozilla/jss/pkix/crmf/CertRequest.java
index ee0868c..90aab0d 100644
--- a/org/mozilla/jss/pkix/crmf/CertRequest.java
+++ b/org/mozilla/jss/pkix/crmf/CertRequest.java
@@ -57,6 +57,13 @@ public class CertRequest implements ASN1Value {
     }
 
     /**
+     * Returns the <i>controls</i> field.
+     */
+    public SEQUENCE getControls() {
+        return controls;
+    }
+
+    /**
      * Returns the number of optional Controls in the cert request.
      * The number may be zero.
      */
-- 
2.9.3


From 9462edf264ae6da5aad113b293af9f5345542caa Mon Sep 17 00:00:00 2001
From: Elio Maldonado <emaldona@redhat.com>
Date: Mon, 27 Mar 2017 12:01:30 -0700
Subject: [PATCH 11/11] Bug 1350130 - Missing
 CryptoManager.verifyCertificateNowCUNative() implementation, r=edewata

---
 org/mozilla/jss/PK11Finder.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/org/mozilla/jss/PK11Finder.c b/org/mozilla/jss/PK11Finder.c
index a488c4f..9e234e6 100644
--- a/org/mozilla/jss/PK11Finder.c
+++ b/org/mozilla/jss/PK11Finder.c
@@ -1554,6 +1554,68 @@ finish:
 }
 
 /***********************************************************************
+ * CryptoManager.verifyCertificateNow
+ *
+ * Called by java_org_mozilla_jss_CryptoManager_verifyCertificateNowCUNative
+ */
+SECStatus verifyCertificateNow(JNIEnv *env, jobject self, jstring nickString,
+        jboolean checkSig, jint required_certificateUsage,
+         SECCertificateUsage *currUsage)
+{
+    SECStatus         rv    = SECFailure;
+    SECCertificateUsage      certificateUsage;
+    CERTCertificate   *cert=NULL;
+    char *nickname=NULL;
+
+    nickname = (char *) (*env)->GetStringUTFChars(env, nickString, NULL);
+    if( nickname == NULL ) {
+         goto finish;
+    }
+
+    certificateUsage = required_certificateUsage;
+
+    cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname);
+
+    if (cert == NULL) {
+        JSS_throw(env, OBJECT_NOT_FOUND_EXCEPTION);
+        goto finish;
+    } else {
+    /* 0 for certificateUsage in call to CERT_VerifyCertificateNow will
+     * retrieve the current valid usage into currUsage
+     */
+        rv = CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert,
+            checkSig, certificateUsage, NULL, currUsage );
+        if ((rv == SECSuccess) && certificateUsage == 0x0000) {
+            if (*currUsage == 
+                ( certUsageUserCertImport |
+                certUsageVerifyCA |
+                certUsageProtectedObjectSigner |
+                certUsageAnyCA )) {
+
+              /* the cert is good for nothing 
+                 The folllowing usages cannot be verified:
+                   certUsageAnyCA
+                   certUsageProtectedObjectSigner
+                   certUsageUserCertImport
+                   certUsageVerifyCA
+                    (0x0b80) */
+                rv =SECFailure;
+            }
+        }
+    }
+
+finish:
+    if(nickname != NULL) {
+      (*env)->ReleaseStringUTFChars(env, nickString, nickname);
+    }
+    if(cert != NULL) {
+       CERT_DestroyCertificate(cert);
+    }
+
+    return rv;
+}
+
+/***********************************************************************
  * CryptoManager.verifyCertificateNowNative
  *
  * Returns JNI_TRUE if success, JNI_FALSE otherwise
@@ -1604,6 +1666,31 @@ finish:
 }
 
 /***********************************************************************
+ * CryptoManager.verifyCertificateNowCUNative
+ *
+ * Returns jint which contains bits in SECCertificateUsage that reflects
+ * the cert usage(s) that the cert is good for
+ * if the cert is good for nothing, returned value is
+ *                 (0x0b80):
+ *                 certUsageUserCertImport |
+ *                 certUsageVerifyCA |
+ *                 certUsageProtectedObjectSigner |
+ *                 certUsageAnyCA
+ */
+JNIEXPORT jint JNICALL
+Java_org_mozilla_jss_CryptoManager_verifyCertificateNowCUNative(JNIEnv *env,
+        jobject self, jstring nickString, jboolean checkSig)
+{
+    SECStatus VARIABLE_MAY_NOT_BE_USED rv    = SECFailure;
+    SECCertificateUsage      currUsage = 0x0000;
+
+    rv = verifyCertificateNow(env, self, nickString, checkSig, 0, &currUsage);
+    /* rv is ignored */
+
+    return currUsage;
+}
+
+/***********************************************************************
  * CryptoManager.verifyCertificateNowNative2
  *
  * Verify a certificate that exists in the given cert database,
-- 
2.9.3