pax_global_header00006660000000000000000000000064136210642000014504gustar00rootroot0000000000000052 comment=8cab3e04a644e8dddd0cad84621c2ad33cf0dcb6 jss-4.6.3/000077500000000000000000000000001362106420000123155ustar00rootroot00000000000000jss-4.6.3/.classpath000066400000000000000000000012021362106420000142730ustar00rootroot00000000000000 jss-4.6.3/.copr/000077500000000000000000000000001362106420000133365ustar00rootroot00000000000000jss-4.6.3/.copr/Makefile000066400000000000000000000002441362106420000147760ustar00rootroot00000000000000srpm: dnf install -y git ./build.sh --with-timestamp --with-commit-id srpm if [[ "${outdir}" != "" ]]; then \ mv ${HOME}/build/jss/SRPMS/* ${outdir}; \ fi jss-4.6.3/.github/000077500000000000000000000000001362106420000136555ustar00rootroot00000000000000jss-4.6.3/.github/workflows/000077500000000000000000000000001362106420000157125ustar00rootroot00000000000000jss-4.6.3/.github/workflows/optional.yml000066400000000000000000000032611362106420000202640ustar00rootroot00000000000000name: Optional Tests on: push: branches: - master pull_request: branches: - master jobs: pkcs11check: runs-on: ubuntu-latest steps: - name: Clone the repository uses: actions/checkout@v2 - name: Build and Run the Docker Image run: bash tools/run_container.sh "pkcs11check" || echo "::warning ::Job exited with status $?" debian_jdk11: runs-on: ubuntu-latest steps: - name: Clone the repository uses: actions/checkout@v2 - name: Build and Run the Docker Image run: bash tools/run_container.sh "debian_jdk11" || echo "::warning ::Job exited with status $?" ubuntu_jdk8: runs-on: ubuntu-latest steps: - name: Clone the repository uses: actions/checkout@v2 - name: Build and Run the Docker Image run: bash tools/run_container.sh "ubuntu_jdk8" || echo "::warning ::Job exited with status $?" fedora_latest_jdk11: runs-on: ubuntu-latest steps: - name: Clone the repository uses: actions/checkout@v2 - name: Build and Run the Docker Image run: bash tools/run_container.sh "fedora_latest_jdk11" || echo "::warning ::Job exited with status $?" fedora_rawhide: runs-on: ubuntu-latest steps: - name: Clone the repository uses: actions/checkout@v2 - name: Build and Run the Docker Image run: bash tools/run_container.sh "fedora_rawhide" || echo "::warning ::Job exited with status $?" fedora_sandbox: runs-on: ubuntu-latest steps: - name: Clone the repository uses: actions/checkout@v2 - name: Build and Run the Docker Image run: bash tools/run_container.sh "fedora_sandbox" || echo "::warning ::Job exited with status $?" jss-4.6.3/.github/workflows/required.yml000066400000000000000000000010211362106420000202470ustar00rootroot00000000000000name: Required Tests on: push: branches: - master pull_request: branches: - master jobs: fedora30: runs-on: ubuntu-latest steps: - name: Clone the repository uses: actions/checkout@v2 - name: Build and Run the Docker Image run: bash tools/run_container.sh "fedora_30" fedora31: runs-on: ubuntu-latest steps: - name: Clone the repository uses: actions/checkout@v2 - name: Build and Run the Docker Image run: bash tools/run_container.sh "fedora_31" jss-4.6.3/.gitignore000066400000000000000000000002171362106420000143050ustar00rootroot00000000000000bin *.OBJ/ # CMake build directory build/ # These files are automatically generated from their .in equivalents org/mozilla/jss/util/jssver.h jss-4.6.3/.hgignore000066400000000000000000000000621362106420000141160ustar00rootroot00000000000000syntax: glob *~ *OPT.OBJ/* *DBG.OBJ/* *DBG.OBJD/* jss-4.6.3/.project000066400000000000000000000005521362106420000137660ustar00rootroot00000000000000 jss org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature jss-4.6.3/.settings/000077500000000000000000000000001362106420000142335ustar00rootroot00000000000000jss-4.6.3/.settings/org.eclipse.jdt.core.prefs000066400000000000000000000561231362106420000212240ustar00rootroot00000000000000eclipse.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 jss-4.6.3/.settings/org.eclipse.jdt.ui.prefs000066400000000000000000000052561362106420000207120ustar00rootroot00000000000000eclipse.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 jss-4.6.3/CMakeLists.txt000066400000000000000000000047461362106420000150700ustar00rootroot00000000000000# This is the CMakeLists.txt for the JSS Project. project(jss) # Required cmake version; set a 3.0.2 since that's the version of the # documentation I referenced. cmake_minimum_required(VERSION 3.0.2) # Source our custom CMake modules; this includes NSS and NSPR modules from # PKI and the JSSConfig and JSSCommon modules. set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) # Define optional variables and conditionals. if (DEFINED ENV{CHECK_DEPRECATION}) set(CHECK_DEPRECATION_ENV TRUE) endif() option(CHECK_DEPRECATION "When enabled, utilize the deprecation checking functionality of the java compiler." ${CHECK_DEPRECATION_ENV}) if (CHECK_DEPRECATION) list(APPEND JSS_JAVAC_FLAGS "-Xlint:deprecation") endif() if (DEFINED ENV{FIPS_ENABLED}) set(FIPS_ENABLED_ENV TRUE) endif() option(FIPS_ENABLED "When enabled, disable certain tests which don't work in FIPS mode. This should only be specified when the host system is in FIPS mode." ${FIPS_ENABLED_ENV}) if (DEFINED ENV{SANDBOX}) set(SANDBOX_ENV TRUE) endif() option(SANDBOX "When enabled, expect to find nss and nspr from the parent (sandbox) directory instead of using the system-installed versions of the libraries." ${SANDBOX_ENV}) if (DEFINED ENV{TEST_VALGRIND}) set(TEST_VALGRIND_ENV TRUE) endif() option(TEST_VALGRIND "When enabled, run the entire test suite under Valgrind. This will be noisy as JSS can't clean up NSS initialization and the JVM itself leaks." ${TEST_VALGRIND_ENV}) # Build a debug build by default when no type is specified on the command line if(NOT (DEFINED CMAKE_BUILD_TYPE)) set(CMAKE_BUILD_TYPE "Debug") endif() # Find NSPR and NSS Libraries. find_package(NSPR REQUIRED) find_package(NSS REQUIRED) # Find Java and JNI packages; this sets CMake wariables like # Java_JAVAC_EXECUTABLE. find_package(Java REQUIRED) find_package(JNI REQUIRED) # Shims for older CMake versions without useful features. include(Shims) # Since we found Java, include UseJava to provide the find_jar function. include(UseJava) # This include is required for the macro check_symbol_exists in jss_config() include(CheckSymbolExists) # Load JSSConfig module; this defines the jss_config() macro which defines # JSS-specific configuration values. include(JSSConfig) # Load JSSCommon module; this defines the jss_build() macros which defines # the JSS build procedure. include(JSSCommon) # Load JSSTests module; this defines the jss_tests() macro which defines the # JSS test procedure. include(JSSTests) jss_config() jss_build() jss_tests() jss-4.6.3/MPL-1.1.txt000066400000000000000000000622331362106420000140110ustar00rootroot00000000000000 MOZILLA PUBLIC LICENSE Version 1.1 --------------- 1. Definitions. 1.0.1. "Commercial Use" means distribution or otherwise making the Covered Code available to a third party. 1.1. "Contributor" means each entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. 1.3. "Covered Code" means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. 1.4. "Electronic Distribution Mechanism" means a mechanism generally accepted in the software development community for the electronic transfer of data. 1.5. "Executable" means Covered Code in any form other than Source Code. 1.6. "Initial Developer" means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. 1.7. "Larger Work" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. 1.8. "License" means this document. 1.8.1. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. B. Any new file that contains any part of the Original Code or previous Modifications. 1.10. "Original Code" means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. 1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.11. "Source Code" means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. 1.12. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. Source Code License. 2.1. The Initial Developer Grant. The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and (b) under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). (c) the licenses granted in this Section 2.1(a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. 2.2. Contributor Grant. Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first makes Commercial Use of the Covered Code. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Application of License. The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. 3.2. Availability of Source Code. Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. 3.3. Description of Modifications. You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. 3.4. Intellectual Property Matters (a) Third Party Claims. If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. (b) Contributor APIs. If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the LEGAL file. (c) Representations. Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. 3.5. Required Notices. You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice. If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.6. Distribution of Executable Versions. You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.7. Larger Works. You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. 4. Inability to Comply Due to Statute or Regulation. If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Application of this License. This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. 6. Versions of the License. 6.1. New Versions. Netscape Communications Corporation ("Netscape") may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. 6.2. Effect of New Versions. Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License. 6.3. Derivative Works. If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL", "NPL" or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) 7. DISCLAIMER OF WARRANTY. COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 8. TERMINATION. 8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 8.2. If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant") alleging that: (a) such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. (b) any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. 8.3. If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. 8.4. In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination. 9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 10. U.S. GOVERNMENT END USERS. The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. 11. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. 12. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. 13. MULTIPLE-LICENSED CODE. Initial Developer may designate portions of the Covered Code as "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the NPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A. EXHIBIT A -Mozilla Public License. ``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 Initial Developer of the Original Code is ________________________. Portions created by ______________________ are Copyright (C) ______ _______________________. All Rights Reserved. Contributor(s): ______________________________________. Alternatively, the contents of this file may be used under the terms of the _____ license (the "[___] License"), in which case the provisions of [______] License are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the [____] License and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the [___] License. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the [___] License." [NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source Code files of the Original Code. You should use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications.] jss-4.6.3/README.md000066400000000000000000000053301362106420000135750ustar00rootroot00000000000000Network Security Services for Java (JSS) ======================================== Overview -------- **Network Security Services for Java** is a Java interface to [NSS](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS). JSS supports most of the security standards and encryption technologies supported by NSS. JSS also provides a pure Java interface for ASN.1 types and BER/DER encoding. * Website: http://www.dogtagpki.org/wiki/JSS * Issues: https://pagure.io/jss/issues * Archive: https://github.com/dogtagpki/jss-archive * Javadocs: https://dogtagpki.github.io/jss **NOTICE:** As of JSS version 4.5.1, the legacy build instructions will not work; the build system has been completely replaced with CMake. Dependencies ------------ This project has the following dependencies: - [NSPR](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSPR) - [NSS](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS) - Minimum version: 3.30 - A c and c++ compiler such as [gcc](ttps://gcc.gnu.org/) - [zlib](https://zlib.net/) - [OpenJDK 1.8.0 or newer](https://openjdk.java.net/) - [CMake](https://cmake.org/) - [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/) - [JavaEE JAXB](https://github.com/eclipse-ee4j/jaxb-ri) - [SLF4J](https://www.slf4j.org/) - [JUnit 4](https://junit.org/junit4/) To install these dependencies on Fedora, execute the following: sudo dnf install apache-commons-lang gcc-c++ java-devel jpackage-utils \ slf4j zlib-devel glassfish-jaxb-api nss-tools nss-devel \ cmake junit To install these dependencies on Debian, execute the following: sudo apt-get install build-essential libcommons-lang-java libnss3-dev \ libslf4j-java default-jdk pkg-config zlib1g-dev \ libjaxb-api-java libnss3-tools cmake zip unzip \ junit4 Building -------- To build JSS and make a best effort to detect environment variables: git clone https://github.com/dogtagpki/jss cd jss/build && cmake .. make all test Alternatively, to build a RPM distribution of JSS: git clone https://github.com/dogtagpki/jss cd jss ./build.sh To view more detailed instructions for building JSS, please refer to the build documentation: [`docs/building.md`](docs/building.md). Contributing ------------ We welcome all contributions to JSS! If you're looking for help getting started, check out our [documentation](docs/contributing.md), or if you want to contact us, check out the following forums: - The [pki-devel mailing list](https://www.redhat.com/mailman/listinfo/pki-devel). - The `#dogtag-pki` IRC channel on [Freenode](https://freenode.net/). jss-4.6.3/build.sh000077500000000000000000000212701362106420000137550ustar00rootroot00000000000000#!/bin/bash -e # BEGIN COPYRIGHT BLOCK # (C) 2018 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK NAME=jss SCRIPT_PATH="$(readlink -f "$0")" SCRIPT_NAME="$(basename "$SCRIPT_PATH")" SRC_DIR="$(dirname "$SCRIPT_PATH")" WORK_DIR="$HOME/build/$NAME" SOURCE_TAG= SPEC_TEMPLATE= WITH_TIMESTAMP= WITH_COMMIT_ID= DIST= VERBOSE= DEBUG= usage() { echo "Usage: $SCRIPT_NAME [OPTIONS] " echo echo "Options:" echo " --work-dir= Working directory (default: $WORK_DIR)." echo " --source-tag= Generate RPM sources from a source tag." echo " --spec= Use the specified RPM spec." echo " --with-timestamp Append timestamp to release number." echo " --with-commit-id Append commit ID to release number." echo " --dist= Distribution name (e.g. fc28)." echo " -v,--verbose Run in verbose mode." echo " --debug Run in debug mode." echo " --help Show help message." echo echo "Target:" echo " src Generate RPM sources." echo " spec Generate RPM spec." echo " srpm Build SRPM package." echo " rpm Build RPM packages (default)." } generate_rpm_sources() { TARBALL="$NAME-$VERSION${_PHASE}.tar.gz" if [ "$SOURCE_TAG" != "" ] ; then if [ "$VERBOSE" = true ] ; then echo "Generating $TARBALL from $SOURCE_TAG tag" fi git -C "$SRC_DIR" \ archive \ --format=tar.gz \ --prefix "$NAME-$VERSION${_PHASE}/" \ -o "$WORK_DIR/SOURCES/$TARBALL" \ $SOURCE_TAG if [ "$SOURCE_TAG" != "HEAD" ] ; then TAG_ID="$(git -C "$SRC_DIR" rev-parse $SOURCE_TAG)" HEAD_ID="$(git -C "$SRC_DIR" rev-parse HEAD)" if [ "$TAG_ID" != "$HEAD_ID" ] ; then generate_patch fi fi return fi if [ "$VERBOSE" = true ] ; then echo "Generating $TARBALL" fi tar czf "$WORK_DIR/SOURCES/$TARBALL" \ --transform "s,^./,$NAME-$VERSION${_PHASE}/," \ --exclude .git \ --exclude bin \ -C "$SRC_DIR" \ . } generate_patch() { PATCH="$NAME-$VERSION-$RELEASE.patch" if [ "$VERBOSE" = true ] ; then echo "Generating $PATCH for all changes since $SOURCE_TAG tag" fi git -C "$SRC_DIR" \ format-patch \ --stdout \ $SOURCE_TAG \ > "$WORK_DIR/SOURCES/$PATCH" } generate_rpm_spec() { RPM_SPEC="$NAME.spec" if [ "$VERBOSE" = true ] ; then echo "Generating $RPM_SPEC" fi # hard-code timestamp commands="s/%{?_timestamp}/${_TIMESTAMP}/g" # hard-code commit ID commands="${commands}; s/%{?_commit_id}/${_COMMIT_ID}/g" # hard-code phase commands="${commands}; s/%{?_phase}/${_PHASE}/g" # hard-code patch if [ "$PATCH" != "" ] ; then commands="${commands}; s/# Patch: jss-VERSION-RELEASE.patch/Patch: $PATCH/g" fi sed "$commands" "$SPEC_TEMPLATE" > "$WORK_DIR/SPECS/$RPM_SPEC" # rpmlint "$WORK_DIR/SPECS/$RPM_SPEC" } while getopts v-: arg ; do case $arg in v) VERBOSE=true ;; -) LONG_OPTARG="${OPTARG#*=}" case $OPTARG in work-dir=?*) WORK_DIR="$(readlink -f "$LONG_OPTARG")" ;; source-tag=?*) SOURCE_TAG="$LONG_OPTARG" ;; spec=?*) SPEC_TEMPLATE="$LONG_OPTARG" ;; with-timestamp) WITH_TIMESTAMP=true ;; with-commit-id) WITH_COMMIT_ID=true ;; dist=?*) DIST="$LONG_OPTARG" ;; verbose) VERBOSE=true ;; debug) VERBOSE=true DEBUG=true ;; help) usage exit ;; '') break # "--" terminates argument processing ;; work-dir* | source-tag* | spec* | dist*) echo "ERROR: Missing argument for --$OPTARG option" >&2 exit 1 ;; *) echo "ERROR: Illegal option --$OPTARG" >&2 exit 1 ;; esac ;; \?) exit 1 # getopts already reported the illegal option ;; esac done # remove parsed options and args from $@ list shift $((OPTIND-1)) if [ "$#" -lt 1 ] ; then BUILD_TARGET=rpm else BUILD_TARGET=$1 fi if [ "$DEBUG" = true ] ; then echo "WORK_DIR: $WORK_DIR" echo "BUILD_TARGET: $BUILD_TARGET" fi if [ "$BUILD_TARGET" != "src" ] && [ "$BUILD_TARGET" != "spec" ] && [ "$BUILD_TARGET" != "srpm" ] && [ "$BUILD_TARGET" != "rpm" ] ; then echo "ERROR: Invalid build target: $BUILD_TARGET" >&2 exit 1 fi if [ "$SPEC_TEMPLATE" = "" ] ; then SPEC_TEMPLATE="$SRC_DIR/$NAME.spec" fi VERSION="$(rpmspec -P "$SPEC_TEMPLATE" | grep "^Version:" | awk '{print $2;}')" if [ "$DEBUG" = true ] ; then echo "VERSION: $VERSION" fi RELEASE="$(rpmspec -P "$SPEC_TEMPLATE" --undefine dist | grep "^Release:" | awk '{print $2;}')" if [ "$DEBUG" = true ] ; then echo "RELEASE: $RELEASE" fi spec=$(<"$SPEC_TEMPLATE") regex=$'%global *_phase *([^\n]+)' if [[ $spec =~ $regex ]] ; then _PHASE="${BASH_REMATCH[1]}" fi if [ "$DEBUG" = true ] ; then echo "PHASE: ${_PHASE}" fi if [ "$WITH_TIMESTAMP" = true ] ; then TIMESTAMP="$(date +"%Y%m%d%H%M%S")" _TIMESTAMP=".$TIMESTAMP" fi if [ "$DEBUG" = true ] ; then echo "TIMESTAMP: $TIMESTAMP" fi if [ "$WITH_COMMIT_ID" = true ]; then COMMIT_ID="$(git -C "$SRC_DIR" rev-parse --short=8 HEAD)" _COMMIT_ID=".$COMMIT_ID" fi if [ "$DEBUG" = true ] ; then echo "COMMIT_ID: $COMMIT_ID" fi echo "Building $NAME-$VERSION-$RELEASE${_TIMESTAMP}${_COMMIT_ID}" ################################################################################ # Initialize working directory ################################################################################ if [ "$VERBOSE" = true ] ; then echo "Initializing $WORK_DIR" fi mkdir -p "$WORK_DIR" cd "$WORK_DIR" rm -rf BUILD rm -rf RPMS rm -rf SOURCES rm -rf SPECS rm -rf SRPMS mkdir BUILD mkdir RPMS mkdir SOURCES mkdir SPECS mkdir SRPMS ################################################################################ # Generate RPM sources ################################################################################ generate_rpm_sources echo "RPM sources:" find "$WORK_DIR/SOURCES" -type f -printf " %p\\n" if [ "$BUILD_TARGET" = "src" ] ; then exit fi ################################################################################ # Generate RPM spec ################################################################################ generate_rpm_spec echo "RPM spec:" find "$WORK_DIR/SPECS" -type f -printf " %p\\n" if [ "$BUILD_TARGET" = "spec" ] ; then exit fi ################################################################################ # Build source package ################################################################################ OPTIONS=() OPTIONS+=(--quiet) OPTIONS+=(--define "_topdir ${WORK_DIR}") if [ "$WITH_TIMESTAMP" = true ] ; then OPTIONS+=(--define "_timestamp ${_TIMESTAMP}") fi if [ "$WITH_COMMIT_ID" = true ] ; then OPTIONS+=(--define "_commit_id ${_COMMIT_ID}") fi if [ "$DIST" != "" ] ; then OPTIONS+=(--define "dist .$DIST") fi if [ "$DEBUG" = true ] ; then echo rpmbuild -bs "${OPTIONS[@]}" "$WORK_DIR/SPECS/$RPM_SPEC" fi # build SRPM with user-provided options rpmbuild -bs "${OPTIONS[@]}" "$WORK_DIR/SPECS/$RPM_SPEC" rc=$? if [ $rc != 0 ]; then echo "ERROR: Unable to build SRPM package" exit 1 fi SRPM="$(find "$WORK_DIR/SRPMS" -type f)" echo "SRPM package:" echo " $SRPM" if [ "$BUILD_TARGET" = "srpm" ] ; then exit fi ################################################################################ # Build binary packages ################################################################################ OPTIONS=() if [ "$VERBOSE" = true ] ; then OPTIONS+=(--define "_verbose 1") fi OPTIONS+=(--define "_topdir ${WORK_DIR}") if [ "$DEBUG" = true ] ; then echo rpmbuild --rebuild "${OPTIONS[@]}" "$SRPM" fi # rebuild RPM with hard-coded options in SRPM rpmbuild --rebuild "${OPTIONS[@]}" "$SRPM" rc=$? if [ $rc != 0 ]; then echo "ERROR: Unable to build RPM packages" exit 1 fi # install SRPM to restore sources and spec file removed during rebuild rpm -i --define "_topdir $WORK_DIR" "$SRPM" # flatten folder find "$WORK_DIR/RPMS" -mindepth 2 -type f -exec mv -i '{}' "$WORK_DIR/RPMS" ';' # remove empty subfolders find "$WORK_DIR/RPMS" -mindepth 1 -type d -delete echo "RPM packages:" find "$WORK_DIR/RPMS" -type f -printf " %p\\n" jss-4.6.3/build/000077500000000000000000000000001362106420000134145ustar00rootroot00000000000000jss-4.6.3/build/.gitkeep000066400000000000000000000000001362106420000150330ustar00rootroot00000000000000jss-4.6.3/cmake/000077500000000000000000000000001362106420000133755ustar00rootroot00000000000000jss-4.6.3/cmake/FindNSPR.cmake000066400000000000000000000055741362106420000157750ustar00rootroot00000000000000# - Try to find NSPR # Once done this will define # # NSPR_FOUND - system has NSPR # NSPR_INCLUDE_DIRS - the NSPR include directory # NSPR_LIBRARIES - Link these to use NSPR # NSPR_DEFINITIONS - Compiler switches required for using NSPR # # Copyright (c) 2010 Andreas Schneider # # Redistribution and use is allowed according to the terms of the New # BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # if (SANDBOX) # Bypass the cache: we want to use files from the directory above. set(NSS_FOUND TRUE) # Read the internal build directory from the dist directory set(DIST_DIR "${CMAKE_SOURCE_DIR}/../dist") file(READ "${DIST_DIR}/latest" LATEST_BUILD) string(STRIP "${LATEST_BUILD}" LATEST_BUILD) message(STATUS "NSS sandbox build directory: ${LATEST_BUILD}") # Directly set the NSS include and library directories set(NSPR_INCLUDE_DIRS "${DIST_DIR}/${LATEST_BUILD}/include/nspr") set(NSPR_LIBRARIES "${DIST_DIR}/${LATEST_BUILD}/lib") list(APPEND JSS_LD_FLAGS "-Wl,-rpath,${DIST_DIR}/${LATEST_BUILD}/lib") elseif (NSPR_LIBRARIES AND NSPR_INCLUDE_DIRS) # in cache already set(NSPR_FOUND TRUE) else (NSPR_LIBRARIES AND NSPR_INCLUDE_DIRS) find_package(PkgConfig) if (PKG_CONFIG_FOUND) pkg_check_modules(_NSPR nspr) endif (PKG_CONFIG_FOUND) find_path(NSPR_INCLUDE_DIR NAMES nspr.h PATHS ${_NSPR_INCLUDEDIR} /usr/include /usr/local/include /opt/local/include /sw/include PATH_SUFFIXES nspr4 nspr ) find_library(PLDS4_LIBRARY NAMES plds4 PATHS ${_NSPR_LIBDIR} /usr/lib /usr/local/lib /opt/local/lib /sw/lib ) find_library(PLC4_LIBRARY NAMES plc4 PATHS ${_NSPR_LIBDIR} /usr/lib /usr/local/lib /opt/local/lib /sw/lib ) find_library(NSPR4_LIBRARY NAMES nspr4 PATHS ${_NSPR_LIBDIR} /usr/lib /usr/local/lib /opt/local/lib /sw/lib ) set(NSPR_INCLUDE_DIRS ${NSPR_INCLUDE_DIR} ) if(PLDS4_LIBRARY) get_filename_component(PLDS4_LIBRARY "${PLDS4_LIBRARY}" DIRECTORY) set(NSPR_LIBRARIES ${NSPR_LIBRARIES} ${PLDS4_LIBRARY} ) endif() if(PLC4_LIBRARY) get_filename_component(PLC4_LIBRARY "${PLC4_LIBRARY}" DIRECTORY) set(NSPR_LIBRARIES ${NSPR_LIBRARIES} ${PLC4_LIBRARY} ) endif() if(NSPR4_LIBRARY) get_filename_component(NSPR4_LIBRARY "${NSPR4_LIBRARY}" DIRECTORY) set(NSPR_LIBRARIES ${NSPR_LIBRARIES} ${NSPR4_LIBRARY} ) endif() list(REMOVE_DUPLICATES NSPR_LIBRARIES) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(NSPR DEFAULT_MSG NSPR_LIBRARIES NSPR_INCLUDE_DIRS) # show the NSPR_INCLUDE_DIRS and NSPR_LIBRARIES variables only in the advanced view mark_as_advanced(NSPR_INCLUDE_DIRS NSPR_LIBRARIES) endif() jss-4.6.3/cmake/FindNSS.cmake000066400000000000000000000062441362106420000156510ustar00rootroot00000000000000# - Try to find NSS # Once done this will define # # NSS_FOUND - system has NSS # NSS_INCLUDE_DIRS - the NSS include directory # NSS_LIBRARIES - Link these to use NSS # NSS_DEFINITIONS - Compiler switches required for using NSS # # Copyright (c) 2010 Andreas Schneider # # Redistribution and use is allowed according to the terms of the New # BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # if (SANDBOX) # Bypass the cache: we want to use files from the directory above. set(NSS_FOUND TRUE) # Read the internal build directory from the dist directory set(DIST_DIR "${CMAKE_SOURCE_DIR}/../dist") file(READ "${DIST_DIR}/latest" LATEST_BUILD) string(STRIP "${LATEST_BUILD}" LATEST_BUILD) message(STATUS "NSS sandbox build directory: ${LATEST_BUILD}") # Directly set the NSS include and library directories set(NSS_INCLUDE_DIRS "${DIST_DIR}/public/nss") set(NSS_LIBRARIES "${DIST_DIR}/${LATEST_BUILD}/lib") list(APPEND JSS_LD_FLAGS "-Wl,-rpath,${DIST_DIR}/${LATEST_BUILD}/lib") elseif (NSS_LIBRARIES AND NSS_INCLUDE_DIRS) # in cache already set(NSS_FOUND TRUE) else (NSS_LIBRARIES AND NSS_INCLUDE_DIRS) find_package(PkgConfig) if (PKG_CONFIG_FOUND) pkg_check_modules(_NSS nss) endif (PKG_CONFIG_FOUND) find_path(NSS_INCLUDE_DIR NAMES nss.h PATHS ${_NSS_INCLUDEDIR} /usr/include /usr/local/include /opt/local/include /sw/include PATH_SUFFIXES nss3 nss ) find_library(SSL3_LIBRARY NAMES ssl3 PATHS ${_NSS_LIBDIR} /usr/lib /usr/local/lib /opt/local/lib /sw/lib ) find_library(SMIME3_LIBRARY NAMES smime3 PATHS ${_NSS_LIBDIR} /usr/lib /usr/local/lib /opt/local/lib /sw/lib ) find_library(NSS3_LIBRARY NAMES nss3 PATHS ${_NSS_LIBDIR} /usr/lib /usr/local/lib /opt/local/lib /sw/lib ) find_library(NSSUTIL3_LIBRARY NAMES nssutil3 PATHS ${_NSS_LIBDIR} /usr/lib /usr/local/lib /opt/local/lib /sw/lib ) set(NSS_INCLUDE_DIRS ${NSS_INCLUDE_DIR} ) if(SSL3_LIBRARY) get_filename_component(SSL3_LIBRARY "${SSL3_LIBRARY}" DIRECTORY) set(NSS_LIBRARIES ${NSS_LIBRARIES} ${SSL3_LIBRARY} ) endif() if(SMIME3_LIBRARY) get_filename_component(SMIME3_LIBRARY "${SMIME3_LIBRARY}" DIRECTORY) set(NSS_LIBRARIES ${NSS_LIBRARIES} ${SMIME3_LIBRARY} ) endif() if(NSS3_LIBRARY) get_filename_component(NSS3_LIBRARY "${NSS3_LIBRARY}" DIRECTORY) set(NSS_LIBRARIES ${NSS_LIBRARIES} ${NSS3_LIBRARY} ) endif() if(NSSUTIL3_LIBRARY) get_filename_component(NSSUTIL3_LIBRARY "${NSSUTIL3_LIBRARY}" DIRECTORY) set(NSS_LIBRARIES ${NSS_LIBRARIES} ${NSSUTIL3_LIBRARY} ) endif() list(REMOVE_DUPLICATES NSS_LIBRARIES) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(NSS DEFAULT_MSG NSS_LIBRARIES NSS_INCLUDE_DIRS) # show the NSS_INCLUDE_DIRS and NSS_LIBRARIES variables only in the advanced view mark_as_advanced(NSS_INCLUDE_DIRS NSS_LIBRARIES) endif() jss-4.6.3/cmake/JSSCommon.cmake000066400000000000000000000226151362106420000162150ustar00rootroot00000000000000# Core of JSS building # Build JSS; high level flow macro(jss_build) # "set(..)" in CMake defines a globally-scoped variable (or more # precisely, a variable that exists in all scopes _after_ this one) # by default. These are three helpful globs of files for dependencies: # all java, headers, and c source files. Note that org/*.java differs # from the bash-style glob in that it matches all files which begin with # "org" and end with ".java". This includes, e.g., # "org/mozilla/jss/CryptoManager.java". Because these globs are computed # at cmake time (prior to the make step) incremental builds are not # possible; each time the build directory should be removed and recreated # prior to building again. jss_build_globs() # To build JSS, we need: # 1. To build the Java files. # 2. To copy the headers for compilation. # 3. To build the library. # 4. To build the jar. # 5. To build the javadocs. jss_build_java() jss_build_includes() jss_build_c() jss_build_jars() jss_build_javadocs() endmacro() macro(jss_build_globs) file(GLOB_RECURSE _JAVA_SOURCES org/*.java) foreach(_JAVA_SOURCE ${_JAVA_SOURCES}) if(${_JAVA_SOURCE} MATCHES "mozilla/jss/tests/") list(APPEND JAVA_TEST_SOURCES "${_JAVA_SOURCE}") else() list(APPEND JAVA_SOURCES "${_JAVA_SOURCE}") endif() endforeach() # Write the Java sources to a file to reduce the size of the javac # command line. list(SORT JAVA_SOURCES) list(SORT JAVA_TEST_SOURCES) jss_list_join(JAVA_SOURCES "\n" JAVA_SOURCES_CONTENTS) jss_list_join(JAVA_TEST_SOURCES "\n" JAVA_TEST_SOURCES_CONTENTS) file(WRITE "${JAVA_SOURCES_FILE}" "${JAVA_SOURCES_CONTENTS}") file(WRITE "${JAVA_TEST_SOURCES_FILE}" "${JAVA_TEST_SOURCES_CONTENTS}") file(GLOB_RECURSE _C_HEADERS org/*.h) foreach(_C_HEADER ${_C_HEADERS}) if(${_C_HEADER} MATCHES "mozilla/jss/tests/") list(APPEND C_TEST_HEADERS "${_C_HEADER}") else() list(APPEND C_HEADERS "${_C_HEADER}") endif() endforeach() file(GLOB_RECURSE _C_SOURCES org/*.c) # We exclude any C files in the tests directory because they shouldn't # contribute to our library. They should instead be built as part of the # test suite and probably be built as stand alone binaries which link # against libjss4.so (at most). foreach(_C_SOURCE ${_C_SOURCES}) if(${_C_SOURCE} MATCHES "mozilla/jss/tests/") list(APPEND C_TEST_SOURCES "${_C_SOURCE}") else() list(APPEND C_SOURCES "${_C_SOURCE}") endif() endforeach() endmacro() # Build all Java sources into classes and generate JNI headers macro(jss_build_java) # Create a fake, pseudo-target for generate_java -- we have to have some # status for when the build finishes for the add_custom_target to depend # on, but it also must be the last-thing created; thus, we touch # ${JNI_OUTPUTS} after the javac command finishes. set(JNI_OUTPUTS "${TARGETS_OUTPUT_DIR}/finished_generate_java") set(TESTS_JNI_OUTPUTS "${TARGETS_OUTPUT_DIR}/finished_tests_generate_java") # We frequently use the add_custom_command + add_custom_target wrapper due # to a quirk of CMake. This is documented more extensively in the # following links: # https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/ # https://gitlab.kitware.com/cmake/community/wikis/FAQ#how-can-i-add-a-dependency-to-a-source-file-which-is-generated-in-a-subdirectory add_custom_command( OUTPUT "${JNI_OUTPUTS}" COMMAND ${Java_JAVAC_EXECUTABLE} ${JSS_JAVAC_FLAGS} -d ${CLASSES_OUTPUT_DIR} -h ${JNI_OUTPUT_DIR} @${JAVA_SOURCES_FILE} COMMAND touch "${JNI_OUTPUTS}" DEPENDS ${JAVA_SOURCES} ) add_custom_command( OUTPUT "${TESTS_JNI_OUTPUTS}" COMMAND ${Java_JAVAC_EXECUTABLE} ${JSS_TEST_JAVAC_FLAGS} -d ${TESTS_CLASSES_OUTPUT_DIR} -h ${TESTS_JNI_OUTPUT_DIR} @${JAVA_TEST_SOURCES_FILE} COMMAND touch "${TESTS_JNI_OUTPUTS}" DEPENDS ${JAVA_TEST_SOURCES} ) add_custom_target( generate_java ALL DEPENDS ${JNI_OUTPUTS} ${TESTS_JNI_OUTPUTS} ) endmacro() # "Build" all includes by copying them to a common directory macro(jss_build_includes) # Note that file(COPY ...) operations are performed at "CMake" run time, # (equivalent to configure time), so CMake needs to be reconfigured every # time a new header file is added. This is most easily done by removing # the build directory and recreating it. This also applies to all other # build steps as the globs are computed at configure time as well. foreach(C_HEADER ${C_HEADERS}) file(COPY "${C_HEADER}" DESTINATION ${INCLUDE_OUTPUT_DIR}) endforeach() foreach(C_TEST_HEADER ${C_TEST_HEADERS}) file(COPY "${C_TEST_HEADER}" DESTINATION ${TESTS_INCLUDE_OUTPUT_DIR}) endforeach() add_custom_target( generate_includes ) endmacro() # Compile a single C file macro(jss_build_c_file C_FILE C_OUTPUT C_TARGET C_DIR) # C files can be built in parallel. This macro builds each file wrapped in # add_custom_command+add_custom_target so parallel builds work. Note that # each build depends on generate_java and generate_includes to have # finished, else many headers wouldn't exist. add_custom_command( OUTPUT "${C_OUTPUT}" COMMAND ${CMAKE_C_COMPILER} -fPIC ${JSS_C_FLAGS} -o ${C_OUTPUT} -c ${C_FILE} WORKING_DIRECTORY ${C_DIR} DEPENDS ${C_FILE} DEPENDS generate_java DEPENDS generate_includes ) add_custom_target( "generate_c_${C_TARGET}" DEPENDS "${C_OUTPUT}" ${C_HEADERS} ) endmacro() # Compile all C source files and build libjss library macro(jss_build_c) foreach(C_SOURCE ${C_SOURCES}) get_filename_component(C_TARGET ${C_SOURCE} NAME_WE) get_filename_component(C_DIR ${C_SOURCE} DIRECTORY) set(C_OUTPUT "${LIB_OUTPUT_DIR}/${C_TARGET}.o") jss_build_c_file("${C_SOURCE}" "${C_OUTPUT}" "${C_TARGET}" "${C_DIR}") list(APPEND C_OUTPUTS "${C_OUTPUT}") endforeach() # Combine all C targets here into a single pseudo-target for parallel # builds. add_custom_target( generate_c ALL DEPENDS ${C_OUTPUTS} ) # We generate two libraries: build/lib/libjss.so and build/libjss.so: # the former is for testing and is unversioned, so all symbols are public # and can thus be tested; the latter is for releases and is versioned, # limiting which symbols are made public. We only need to make the JNI # symbols public as libjss.so should only be used from Java in conjunction # with jss.jar. add_custom_command( OUTPUT "${JSS_SO_PATH}" "${JSS_TESTS_SO_PATH}" COMMAND ${CMAKE_C_COMPILER} -o ${JSS_TESTS_SO_PATH} ${LIB_OUTPUT_DIR}/*.o ${JSS_LD_FLAGS} ${JSS_LIBRARY_FLAGS} COMMAND ${CMAKE_C_COMPILER} -o ${JSS_SO_PATH} ${LIB_OUTPUT_DIR}/*.o ${JSS_LD_FLAGS} ${JSS_VERSION_SCRIPT} ${JSS_LIBRARY_FLAGS} DEPENDS generate_c ) # Add a target for anything depending on the library existing. add_custom_target( generate_so ALL DEPENDS ${JSS_SO_PATH} ${JSS_TESTS_SO_PATH} ) endmacro() # Build the jar by combining the java classes from generate_java step macro(jss_build_jars) # Note that build/MANIFEST.MF is generated by JSSConfig.cmake's # jss_config_version macro. Further, this doesn't yet build a reproducible # JAR. add_custom_command( OUTPUT "${JSS_BUILD_JAR_PATH}" COMMAND "${Java_JAR_EXECUTABLE}" cmf "${CMAKE_BINARY_DIR}/MANIFEST.MF" ${JSS_BUILD_JAR_PATH} org/* WORKING_DIRECTORY "${CLASSES_OUTPUT_DIR}" DEPENDS generate_java ) add_custom_command( OUTPUT "${JSS_TESTS_JAR_PATH}" COMMAND "${Java_JAR_EXECUTABLE}" cmf "${CMAKE_BINARY_DIR}/MANIFEST.MF" ${JSS_TESTS_JAR_PATH} org/* WORKING_DIRECTORY "${TESTS_CLASSES_OUTPUT_DIR}" DEPENDS generate_java ) add_custom_target( generate_build_jar DEPENDS "${JSS_BUILD_JAR_PATH}" ) add_custom_command( OUTPUT "${JSS_JAR_PATH}" COMMAND "${PROJECT_SOURCE_DIR}/tools/reproducible_jar.sh" "${JSS_BUILD_JAR_PATH}" "${REPRODUCIBLE_TEMP_DIR}" "${JSS_JAR_PATH}" DEPENDS generate_build_jar ) add_custom_target( generate_jar ALL DEPENDS "${JSS_JAR_PATH}" "${JSS_TESTS_JAR_PATH}" ) endmacro() # Build javadocs from the source files macro(jss_build_javadocs) # Add another pseudo-target here as well -- javadocs create a lot of # output, but anything which depends on the javadocs existing should # depend on the javadoc target. set(JAVADOCS_OUTPUTS "${TARGETS_OUTPUT_DIR}/finished_generate_javadocs") add_custom_command( OUTPUT ${JAVADOCS_OUTPUTS} COMMAND "${Java_JAVADOC_EXECUTABLE}" -overview "${PROJECT_SOURCE_DIR}/tools/javadoc/overview.html" -windowtitle "${JSS_WINDOW_TITLE}" -notimestamp -breakiterator -classpath ${JAVAC_CLASSPATH} -sourcepath ${PROJECT_SOURCE_DIR} -d ${DOCS_OUTPUT_DIR} @${JAVA_SOURCES_FILE} COMMAND touch "${JAVADOCS_OUTPUTS}" DEPENDS ${JAVA_SOURCES} ) add_custom_target( javadoc DEPENDS ${JAVADOCS_OUTPUTS} ) # For compliance with GNU Make standard targets add_custom_target( html DEPENDS javadoc ) endmacro() jss-4.6.3/cmake/JSSConfig.cmake000066400000000000000000000322551362106420000161730ustar00rootroot00000000000000macro(jss_config) # Set the current JSS release number. Arguments are: # MAJOR MINOR PATCH BETA # When BETA is zero, it isn't a beta release. jss_config_version(4 6 3 0) # Configure output directories jss_config_outputs() # Configure flags for compiling and linking jss_config_cflags() jss_config_ldflags() # Configure java-related flags jss_config_java() # Template auto-generated files jss_config_template() # Check symbols to see what tests we run jss_config_symbols() endmacro() macro(jss_config_version MAJOR MINOR PATCH BETA) # This sets the JSS Version for use in CMake and propagates it to the # necessary source locations. These are: # # org/mozilla/jss/util/jssver.h{.in,} # lib/MANIFEST.MF.in -> build/MANIFEST.MF # # On a build, these automatically get generated with the correct versions # included. Note that all "sets" are of global scope, so these variables # can be used anywhere that is necessary. Some uses are for setting the # version number in the library and jar file, etc. # Define variables from passed arguments set(JSS_VERSION_MAJOR "${MAJOR}") set(JSS_VERSION_MINOR "${MINOR}") set(JSS_VERSION_PATCH "${PATCH}") set(JSS_VERSION_BETA "${BETA}") set(JSS_VERSION "${JSS_VERSION_MAJOR}.${JSS_VERSION_MINOR}.${JSS_VERSION_PATCH}") set(JSS_VERSION_MANIFEST "${JSS_VERSION_MAJOR}.${JSS_VERSION_MINOR}") set(JSS_VERSION_STR "JSS_${JSS_VERSION_MAJOR}_${JSS_VERSION_MINOR}") if(${PATCH} GREATER 0) set(JSS_VERSION_MANIFEST "${JSS_VERSION_MANIFEST}.${JSS_VERSION_PATCH}") set(JSS_VERSION_STR "${JSS_VERSION_STR}_${JSS_VERSION_PATCH}") endif() if(${BETA} GREATER 0) set(JSS_VERSION "${JSS_VERSION} beta ${JSS_VERSION_BETA}") set(JSS_VERSION_STR "${JSS_VERSION_STR}_b${JSS_VERSION_BETA}") endif() endmacro() macro(jss_config_outputs) # Global variables representing various output files; note that these # directories are created at the end of this macro. set(CLASSES_OUTPUT_DIR "${CMAKE_BINARY_DIR}/classes/jss") set(DOCS_OUTPUT_DIR "${CMAKE_BINARY_DIR}/docs") set(LIB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/lib") set(BIN_OUTPUT_DIR "${CMAKE_BINARY_DIR}/bin") set(INCLUDE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/include/jss") set(JNI_OUTPUT_DIR "${CMAKE_BINARY_DIR}/include/jss/_jni") # This folder is for pseudo-locations for CMake targets set(TARGETS_OUTPUT_DIR "${CMAKE_BINARY_DIR}/.targets") set(JAVA_SOURCES_FILE "${TARGETS_OUTPUT_DIR}/java.sources") set(JAVA_TEST_SOURCES_FILE "${TARGETS_OUTPUT_DIR}/java-test.sources") # These folders are for the NSS DBs created during testing set(RESULTS_DATA_OUTPUT_DIR "${CMAKE_BINARY_DIR}/results/data") set(RESULTS_NSSDB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/results/nssdb") set(RESULTS_NSSDB_FIPS_OUTPUT_DIR "${CMAKE_BINARY_DIR}/results/fips") # This is a temporary location for building the reproducible jar set(REPRODUCIBLE_TEMP_DIR "${CMAKE_BINARY_DIR}/reproducible") set(JSS_BUILD_JAR "staging.jar") set(JSS_JAR "jss${JSS_VERSION_MAJOR}.jar") set(JSS_SO "libjss${JSS_VERSION_MAJOR}.so") set(JSS_BUILD_JAR_PATH "${CMAKE_BINARY_DIR}/${JSS_BUILD_JAR}") set(JSS_JAR_PATH "${CMAKE_BINARY_DIR}/${JSS_JAR}") set(JSS_SO_PATH "${CMAKE_BINARY_DIR}/${JSS_SO}") # These options are for the test suite and mirror their non-tests # counterparts. Note that JSS_TESTS_SO is the same as JSS_SO, but # JSS_TESTS_SO_PATH differs -- one is "unversioned" and lacks a # version script so we can test internal methods. set(TESTS_CLASSES_OUTPUT_DIR "${CMAKE_BINARY_DIR}/classes/tests") set(TESTS_INCLUDE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/include/tests") set(TESTS_JNI_OUTPUT_DIR "${CMAKE_BINARY_DIR}/include/jss/_jni") set(JSS_TESTS_JAR "tests-jss${JSS_VERSION_MAJOR}.jar") set(JSS_TESTS_SO "${JSS_SO}") set(JSS_TESTS_JAR_PATH "${CMAKE_BINARY_DIR}/${JSS_TESTS_JAR}") set(JSS_TESTS_SO_PATH "${LIB_OUTPUT_DIR}/${JSS_TESTS_SO}") # Create the *_OUTPUT_DIR locations. file(MAKE_DIRECTORY "${CLASSES_OUTPUT_DIR}") file(MAKE_DIRECTORY "${DOCS_OUTPUT_DIR}") file(MAKE_DIRECTORY "${LIB_OUTPUT_DIR}") file(MAKE_DIRECTORY "${BIN_OUTPUT_DIR}") file(MAKE_DIRECTORY "${INCLUDE_OUTPUT_DIR}") file(MAKE_DIRECTORY "${JNI_OUTPUT_DIR}") file(MAKE_DIRECTORY "${TARGETS_OUTPUT_DIR}") file(MAKE_DIRECTORY "${TESTS_CLASSES_OUTPUT_DIR}") file(MAKE_DIRECTORY "${TESTS_INCLUDE_OUTPUT_DIR}") file(MAKE_DIRECTORY "${TESTS_JNI_OUTPUT_DIR}") endmacro() macro(jss_config_cflags) # We check that the C compiler can handle each of the C flags below include(CheckCCompilerFlag) # This list of C flags was taken from the original build scripts for # debug and release builds. if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") list(APPEND JSS_RAW_C_FLAGS "-Og") list(APPEND JSS_RAW_C_FLAGS "-ggdb") list(APPEND JSS_RAW_C_FLAGS "-DDEBUG") list(APPEND JSS_RAW_C_FLAGS "-DFORCE_PR_ASSERT") else() list(APPEND JSS_RAW_C_FLAGS "-O2") endif() list(APPEND JSS_RAW_C_FLAGS "-Wall") list(APPEND JSS_RAW_C_FLAGS "-std=gnu99") list(APPEND JSS_RAW_C_FLAGS "-Wno-cast-function-type") list(APPEND JSS_RAW_C_FLAGS "-Wno-unused-parameter") list(APPEND JSS_RAW_C_FLAGS "-Wno-unknown-warning-option") list(APPEND JSS_RAW_C_FLAGS "-Werror-implicit-function-declaration") list(APPEND JSS_RAW_C_FLAGS "-Wno-switch") list(APPEND JSS_RAW_C_FLAGS "-I${INCLUDE_OUTPUT_DIR}") foreach(JNI_INCLUDE_DIR ${JNI_INCLUDE_DIRS}) list(APPEND JSS_RAW_C_FLAGS "-I${JNI_INCLUDE_DIR}") endforeach() foreach(NSPR_INCLUDE_DIR ${NSPR_INCLUDE_DIRS}) list(APPEND JSS_RAW_C_FLAGS "-I${NSPR_INCLUDE_DIR}") endforeach() foreach(NSS_INCLUDE_DIR ${NSS_INCLUDE_DIRS}) list(APPEND JSS_RAW_C_FLAGS "-I${NSS_INCLUDE_DIR}") endforeach() foreach(NSPR_LIBRARY ${NSPR_LIBRARIES}) list(APPEND JSS_RAW_C_FLAGS "-L${NSPR_LIBRARY}") endforeach() foreach(NSS_LIBRARY ${NSS_LIBRARIES}) list(APPEND JSS_RAW_C_FLAGS "-L${NSS_LIBRARY}") endforeach() foreach(JSS_RAW_C_FLAG ${JSS_RAW_C_FLAGS}) # Validate that each of our desired CFLAGS is supported by the # compiler, or well, at least the compiler doesn't immediately # error on it. :) check_c_compiler_flag(${JSS_RAW_C_FLAG} HAVE_C_FLAG) if(${HAVE_C_FLAG}) list(APPEND JSS_C_FLAGS "${JSS_RAW_C_FLAG}") endif() endforeach() # Handle passed-in C flags as well; assume they are valid. separate_arguments(PASSED_C_FLAGS UNIX_COMMAND "${CMAKE_C_FLAGS}") foreach(PASSED_C_FLAG ${PASSED_C_FLAGS}) list(INSERT JSS_C_FLAGS 0 "${PASSED_C_FLAG}") endforeach() message(STATUS "JSS C FLAGS: ${JSS_C_FLAGS}") endmacro() macro(jss_config_ldflags) # This list of C linker flags was taken from the original build scripts # for debug and release builds. We lack a "check_c_linker_flag" macro, # so no effort is made to validate these flags. list(APPEND JSS_LD_FLAGS "-lsmime3") list(APPEND JSS_LD_FLAGS "-lssl3") list(APPEND JSS_LD_FLAGS "-lnss3") list(APPEND JSS_LD_FLAGS "-lnssutil3") list(APPEND JSS_LD_FLAGS "-lplc4") list(APPEND JSS_LD_FLAGS "-lplds4") list(APPEND JSS_LD_FLAGS "-lnspr4") list(APPEND JSS_LD_FLAGS "-lpthread") list(APPEND JSS_LD_FLAGS "-ldl") separate_arguments(PASSED_LD_FLAGS UNIX_COMMAND "${CMAKE_SHARED_LINKER_FLAGS}") foreach(PASSED_LD_FLAG ${PASSED_LD_FLAGS}) list(INSERT JSS_LD_FLAGS 0 "${PASSED_LD_FLAG}") endforeach() # This set of flags is specific to building the libjss library. list(APPEND JSS_LIBRARY_FLAGS "-shared") list(APPEND JSS_LIBRARY_FLAGS "-Wl,-z,defs") list(APPEND JSS_LIBRARY_FLAGS "-Wl,-soname") list(APPEND JSS_LIBRARY_FLAGS "-Wl,${JSS_SO}") set(JSS_VERSION_SCRIPT "-Wl,--version-script,${PROJECT_SOURCE_DIR}/lib/jss.map") message(STATUS "JSS LD FLAGS: ${JSS_LD_FLAGS}") message(STATUS "JSS LIBRARY FLAGS: ${JSS_LIBRARY_FLAGS}") endmacro() macro(jss_config_java) # Find various JARs required by JSS build and test suite find_jar( SLF4J_API_JAR NAMES api slf4j/api slf4j-api ) find_jar( LANG_JAR NAMES apache-commons-lang commons-lang ) find_jar( JAXB_JAR NAMES jaxb-api ) find_jar( SLF4J_JDK14_JAR NAMES jdk14 slf4j/jdk14 slf4j-jdk14 ) find_jar( JUNIT4_JAR NAMES junit4 junit ) find_jar( HAMCREST_JAR NAMES hamcrest/core hamcrest-core ) # Validate that we've found the required JARs if(SLF4J_API_JAR STREQUAL "SLF4J_API_JAR-NOTFOUND") message(FATAL_ERROR "Required dependency sfl4j-api.jar not found by find_jar!") endif() if(LANG_JAR STREQUAL "LANG_JAR-NOTFOUND") message(FATAL_ERROR "Required dependency apache-commons-lang.jar not found by find_jar!") endif() if(JAXB_JAR STREQUAL "JAXB_JAR-NOTFOUND") message(FATAL_ERROR "Required dependency javaee-jaxb-api.jar not found by find_jar!") endif() if(SLF4J_JDK14_JAR STREQUAL "SLF4J_JDK14_JAR-NOTFOUND") message(WARNING "Test dependency sfl4j-jdk14.jar not found by find_jar! Tests might not run properly.") endif() if(JUNIT4_JAR STREQUAL "JUNIT4_JAR-NOTFOUND") message(FATAL_ERROR "Test dependency junit4.jar not found by find_jar! Tests will not compile.") endif() if(HAMCREST_JAR STREQUAL "HAMCREST_JAR-NOTFOUND") message(WARNING "Test dependency hamcrest/core.jar not found by find_jar! Tests might not run properly.") endif() # Set class paths set(JAVAC_CLASSPATH "${SLF4J_API_JAR}:${LANG_JAR}:${JAXB_JAR}") set(TEST_CLASSPATH "${JSS_JAR_PATH}:${JSS_TESTS_JAR_PATH}:${JAVAC_CLASSPATH}:${SLF4J_JDK14_JAR}:${JUNIT4_JAR}:${HAMCREST_JAR}") message(STATUS "javac classpath: ${JAVAC_CLASSPATH}") message(STATUS "tests classpath: ${TEST_CLASSPATH}") # Set compile flags for JSS list(APPEND JSS_JAVAC_FLAGS "-classpath") list(APPEND JSS_JAVAC_FLAGS "${JAVAC_CLASSPATH}") list(APPEND JSS_JAVAC_FLAGS "-sourcepath") list(APPEND JSS_JAVAC_FLAGS "${PROJECT_SOURCE_DIR}") # Ensure we're compatible with JDK 8 list(APPEND JSS_JAVAC_FLAGS "-target") list(APPEND JSS_JAVAC_FLAGS "1.8") list(APPEND JSS_JAVAC_FLAGS "-source") list(APPEND JSS_JAVAC_FLAGS "1.8") # Handle passed-in javac flags as well; assume they are valid. separate_arguments(PASSED_JAVAC_FLAGS UNIX_COMMAND "$ENV{JAVACFLAGS}") foreach(PASSED_JAVAC_FLAG ${PASSED_JAVAC_FLAGS}) list(APPEND JSS_JAVAC_FLAGS "${PASSED_JAVAC_FLAG}") endforeach() if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") list(APPEND JSS_JAVAC_FLAGS "-g") else() list(APPEND JSS_JAVAC_FLAGS "-O") endif() # Set compile flags for JSS test suite list(APPEND JSS_TEST_JAVAC_FLAGS "-classpath") list(APPEND JSS_TEST_JAVAC_FLAGS "${JAVAC_CLASSPATH}:${JUNIT4_JAR}") list(APPEND JSS_TEST_JAVAC_FLAGS "-sourcepath") list(APPEND JSS_TEST_JAVAC_FLAGS "${PROJECT_SOURCE_DIR}") # Ensure we're compatible with JDK 8 list(APPEND JSS_TEST_JAVAC_FLAGS "-target") list(APPEND JSS_TEST_JAVAC_FLAGS "1.8") list(APPEND JSS_TEST_JAVAC_FLAGS "-source") list(APPEND JSS_TEST_JAVAC_FLAGS "1.8") # Handle passed-in javac flags as well; assume they are valid. separate_arguments(PASSED_JAVAC_FLAGS UNIX_COMMAND "$ENV{JAVACFLAGS}") foreach(PASSED_JAVAC_FLAG ${PASSED_JAVAC_FLAGS}) list(APPEND JSS_TEST_JAVAC_FLAGS "${PASSED_JAVAC_FLAG}") endforeach() if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") list(APPEND JSS_TEST_JAVAC_FLAGS "-g") else() list(APPEND JSS_TEST_JAVAC_FLAGS "-O") endif() message(STATUS "JSS JAVAC FLAGS: ${JSS_JAVAC_FLAGS}") message(STATUS "JSS TEST JAVAC FLAGS: ${JSS_TEST_JAVAC_FLAGS}") # Variables for javadoc building. set(JSS_WINDOW_TITLE "JSS: Java Security Services") set(JSS_BASE_PORT 2876) math(EXPR JSS_TEST_PORT_CLIENTAUTH ${JSS_BASE_PORT}+0) math(EXPR JSS_TEST_PORT_CLIENTAUTH_FIPS ${JSS_BASE_PORT}+1) endmacro() macro(jss_config_template) # Template files configure_file( "${PROJECT_SOURCE_DIR}/org/mozilla/jss/util/jssver.h.in" "${PROJECT_SOURCE_DIR}/org/mozilla/jss/util/jssver.h" ) configure_file( "${PROJECT_SOURCE_DIR}/lib/MANIFEST.MF.in" "${CMAKE_BINARY_DIR}/MANIFEST.MF" ) configure_file( "${PROJECT_SOURCE_DIR}/tools/run_test.sh.in" "${CMAKE_BINARY_DIR}/run_test.sh" ) endmacro() macro(jss_config_symbols) list(APPEND CMAKE_REQUIRED_INCLUDES ${NSPR_INCLUDE_DIRS}) list(APPEND CMAKE_REQUIRED_INCLUDES ${NSS_INCLUDE_DIRS}) jss_list_join(JSS_C_FLAGS " " CMAKE_REQUIRED_FLAGS) check_symbol_exists("CKM_AES_CMAC" "nspr.h;nss.h;pkcs11t.h" HAVE_NSS_CMAC) if(NOT HAVE_NSS_CMAC) message(WARNING "Your NSS version doesn't support CMAC; some features of JSS won't work.") endif() check_symbol_exists("CKM_SP800_108_COUNTER_KDF" "nspr.h;nss.h;pkcs11t.h" HAVE_NSS_KBKDF) if(NOT HAVE_NSS_KBKDF) message(WARNING "Your NSS version doesn't support NIST SP800-108 KBKDF; some features of JSS won't work.") endif() endmacro() jss-4.6.3/cmake/JSSTests.cmake000066400000000000000000000442201362106420000160630ustar00rootroot00000000000000macro(jss_tests) enable_testing() jss_tests_compile() # Common variables used as arguments to several tests set(JSS_TEST_DIR "${PROJECT_SOURCE_DIR}/org/mozilla/jss/tests") set(PASSWORD_FILE "${JSS_TEST_DIR}/passwords") set(DB_PWD "m1oZilla") # Create directories for test cases: # - results/data # - results/nssdb # - results/fips jss_test_exec( NAME "Clean_Data_Dir" COMMAND "cmake" "-E" "remove_directory" "${RESULTS_DATA_OUTPUT_DIR}" ) jss_test_exec( NAME "Create_Data_Dir" COMMAND "cmake" "-E" "make_directory" "${RESULTS_DATA_OUTPUT_DIR}" DEPENDS "Clean_Data_Dir" ) jss_test_exec( NAME "TestBufferPRFD" COMMAND "${BIN_OUTPUT_DIR}/TestBufferPRFD" ) # Rather than creating our results directories earlier in JSSConfig, # create them here so that the test suite can be rerun multiple times. jss_test_exec( NAME "Clean_Setup_DBs" COMMAND "cmake" "-E" "remove_directory" "${RESULTS_NSSDB_OUTPUT_DIR}" ) jss_test_exec( NAME "Create_Setup_DBs" COMMAND "cmake" "-E" "make_directory" "${RESULTS_NSSDB_OUTPUT_DIR}" DEPENDS "Clean_Setup_DBs" ) jss_test_java( NAME "Setup_DBs" COMMAND "org.mozilla.jss.tests.SetupDBs" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Create_Setup_DBs" ) # Various FIPS related tests depend on FIPS being enabled; since this # affects the entire NSS DB, create a separate database for them. jss_test_exec( NAME "Clean_FIPS_Setup_DBs" COMMAND "cmake" "-E" "remove_directory" "${RESULTS_NSSDB_FIPS_OUTPUT_DIR}" ) jss_test_exec( NAME "Create_FIPS_Setup_DBs" COMMAND "cmake" "-E" "make_directory" "${RESULTS_NSSDB_FIPS_OUTPUT_DIR}" DEPENDS "Clean_FIPS_Setup_DBs" ) jss_test_java( NAME "Setup_FIPS_DBs" COMMAND "org.mozilla.jss.tests.SetupDBs" "${RESULTS_NSSDB_FIPS_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Create_FIPS_Setup_DBs" ) jss_test_java( NAME "Test_UTF-8_Converter" COMMAND "org.mozilla.jss.tests.UTF8ConverterTest" ) jss_test_java( NAME "JSS_DER_Encoding_of_Enumeration_regression_test" COMMAND "org.mozilla.jss.tests.EnumerationZeroTest" ) jss_test_java( NAME "JSS_Test_DER_Encoding_Functionality" COMMAND "org.mozilla.jss.tests.DEROutputStreamTests" ) jss_test_java( NAME "JSS_Test_Empty_DER_Value" COMMAND "org.mozilla.jss.tests.EmptyDerValue" ) jss_test_java( NAME "BigObjectIdentifier" COMMAND "org.mozilla.jss.tests.BigObjectIdentifier" ) jss_test_java( NAME "JSS_Test_PR_FileDesc" COMMAND "org.mozilla.jss.tests.TestPRFD" ) jss_test_java( NAME "JSS_Test_Raw_SSL" COMMAND "org.mozilla.jss.tests.TestRawSSL" "${RESULTS_NSSDB_OUTPUT_DIR}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "JSS_Test_Buffer" COMMAND "org.mozilla.jss.tests.TestBuffer" ) if ((${Java_VERSION_MAJOR} EQUAL 1) AND (${Java_VERSION_MINOR} LESS 9)) jss_test_java( NAME "Test_PKCS11Constants.java_for_Sun_compatibility" COMMAND "org.mozilla.jss.tests.TestPKCS11Constants" ) endif() jss_test_java( NAME "JUnit_BMPStringTest" COMMAND "org.junit.runner.JUnitCore" "org.mozilla.jss.tests.BMPStringTest" ) jss_test_java( NAME "JUnit_IA5StringTest" COMMAND "org.junit.runner.JUnitCore" "org.mozilla.jss.tests.IA5StringTest" ) jss_test_java( NAME "JUnit_PrintableStringTest" COMMAND "org.junit.runner.JUnitCore" "org.mozilla.jss.tests.PrintableStringTest" ) jss_test_java( NAME "JUnit_TeletexStringTest" COMMAND "org.junit.runner.JUnitCore" "org.mozilla.jss.tests.TeletexStringTest" ) jss_test_java( NAME "JUnit_UniversalStringTest" COMMAND "org.junit.runner.JUnitCore" "org.mozilla.jss.tests.UniversalStringTest" ) jss_test_java( NAME "JUnit_UTF8StringTest" COMMAND "org.junit.runner.JUnitCore" "org.mozilla.jss.tests.UTF8StringTest" ) jss_test_exec( NAME "buffer_size_1" COMMAND "${BIN_OUTPUT_DIR}/buffer_size_1" DEPENDS "generate_c_buffer_size_1" ) jss_test_exec( NAME "buffer_size_4" COMMAND "${BIN_OUTPUT_DIR}/buffer_size_4" DEPENDS "generate_c_buffer_size_4" ) jss_test_java( NAME "JUnit_ChainSortingTest" COMMAND "org.junit.runner.JUnitCore" "org.mozilla.jss.tests.ChainSortingTest" ) jss_test_java( NAME "Generate_known_RSA_cert_pair" COMMAND "org.mozilla.jss.tests.GenerateTestCert" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" "20" "localhost" "SHA-256/RSA" "CA_RSA" "Server_RSA" "Client_RSA" DEPENDS "Setup_DBs" ) jss_test_java( NAME "Generate_known_ECDSA_cert_pair" COMMAND "org.mozilla.jss.tests.GenerateTestCert" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" "30" "localhost" "SHA-256/EC" "CA_ECDSA" "Server_ECDSA" "Client_ECDSA" DEPENDS "Generate_known_RSA_cert_pair" ) jss_test_java( NAME "Generate_known_DSS_cert_pair" COMMAND "org.mozilla.jss.tests.GenerateTestCert" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" "40" "localhost" "SHA-1/DSA" "CA_DSS" "Server_DSS" "Client_DSS" DEPENDS "Generate_known_ECDSA_cert_pair" ) jss_test_exec( NAME "Create_PKCS11_cert_to_PKCS12_rsa.pfx" COMMAND "pk12util" "-o" "${RESULTS_NSSDB_OUTPUT_DIR}/rsa.pfx" "-n" "CA_RSA" "-d" "${RESULTS_NSSDB_OUTPUT_DIR}" "-K" "${DB_PWD}" "-W" "${DB_PWD}" DEPENDS "Generate_known_RSA_cert_pair" ) jss_test_exec( NAME "Create_PKCS11_cert_to_PKCS12_ecdsa.pfx" COMMAND "pk12util" "-o" "${RESULTS_NSSDB_OUTPUT_DIR}/ecdsa.pfx" "-n" "CA_ECDSA" "-d" "${RESULTS_NSSDB_OUTPUT_DIR}" "-K" "${DB_PWD}" "-W" "${DB_PWD}" DEPENDS "Generate_known_ECDSA_cert_pair" ) jss_test_exec( NAME "Create_PKCS11_cert_to_PKCS12_dss.pfx" COMMAND "pk12util" "-o" "${RESULTS_NSSDB_OUTPUT_DIR}/dss.pfx" "-n" "CA_DSS" "-d" "${RESULTS_NSSDB_OUTPUT_DIR}" "-K" "${DB_PWD}" "-W" "${DB_PWD}" DEPENDS "Generate_known_DSS_cert_pair" ) jss_test_java( NAME "List_CA_certs" COMMAND "org.mozilla.jss.tests.ListCACerts" "${RESULTS_NSSDB_OUTPUT_DIR}" DEPENDS "Generate_known_DSS_cert_pair" ) jss_test_java( NAME "SSLClientAuth" COMMAND "org.mozilla.jss.tests.SSLClientAuth" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" "${JSS_TEST_PORT_CLIENTAUTH}" "50" DEPENDS "List_CA_certs" ) jss_test_java( NAME "Key_Generation" COMMAND "org.mozilla.jss.tests.TestKeyGen" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "Digest" COMMAND "org.mozilla.jss.tests.DigestTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "HMAC" COMMAND "org.mozilla.jss.tests.CrossHMACTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "KeyWrapping" COMMAND "org.mozilla.jss.tests.JCAKeyWrap" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "Mozilla_JSS_JCA_Signature" COMMAND "org.mozilla.jss.tests.JCASigTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "Mozilla_JSS_NSS_Signature" COMMAND "org.mozilla.jss.tests.SigTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "JSS_Signature_test" COMMAND "org.mozilla.jss.tests.SigTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "Secret_Decoder_Ring" COMMAND "org.mozilla.jss.tests.TestSDR" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "List_cert_by_certnick" COMMAND "org.mozilla.jss.tests.ListCerts" "${RESULTS_NSSDB_OUTPUT_DIR}" "Server_RSA" DEPENDS "Setup_DBs" ) jss_test_java( NAME "Verify_cert_by_certnick" COMMAND "org.mozilla.jss.tests.VerifyCert" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" "Server_RSA" DEPENDS "Setup_DBs" ) jss_test_java( NAME "Secret_Key_Generation" COMMAND "org.mozilla.jss.tests.SymKeyGen" "${RESULTS_NSSDB_OUTPUT_DIR}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "Symmetric_Key_Deriving" COMMAND "org.mozilla.jss.tests.SymKeyDeriving" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "X509CertTest" COMMAND "org.mozilla.jss.tests.X509CertTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "List_CA_certs" ) jss_test_java( NAME "KeyStoreTest" COMMAND "org.mozilla.jss.tests.KeyStoreTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" getAliases DEPENDS "List_CA_certs" "X509CertTest" "Secret_Key_Generation" "Symmetric_Key_Deriving" "SSLClientAuth" ) jss_test_java( NAME "JSSProvider" COMMAND "org.mozilla.jss.tests.JSSProvider" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "List_CA_certs" "X509CertTest" "Secret_Key_Generation" "Symmetric_Key_Deriving" "SSLClientAuth" ) if(NOT FIPS_ENABLED) jss_test_java( NAME "Key_Factory" COMMAND "org.mozilla.jss.tests.KeyFactoryTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) jss_test_java( NAME "HMAC_Unwrap" COMMAND "org.mozilla.jss.tests.HmacTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) if(HAVE_NSS_CMAC) jss_test_java( NAME "CMAC_Test" COMMAND "org.mozilla.jss.tests.TestCmac" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) endif() if(HAVE_NSS_KBKDF) jss_test_java( NAME "KBKDF_Test" COMMAND "org.mozilla.jss.tests.TestKBKDF" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Setup_DBs" ) endif() jss_test_java( NAME "Mozilla_JSS_Secret_Key_Generation" COMMAND "org.mozilla.jss.tests.JCASymKeyGen" "${RESULTS_NSSDB_OUTPUT_DIR}" DEPENDS "Setup_DBs" ) # SSL Engine related tests jss_test_exec( NAME "TestBufferPRFDSSL_RSA" COMMAND "${BIN_OUTPUT_DIR}/TestBufferPRFDSSL" "${RESULTS_NSSDB_OUTPUT_DIR}" "${DB_PWD}" "Server_RSA" DEPENDS "List_CA_certs" "generate_c_TestBufferPRFDSSL" ) jss_test_exec( NAME "TestBufferPRFDSSL_ECDSA" COMMAND "${BIN_OUTPUT_DIR}/TestBufferPRFDSSL" "${RESULTS_NSSDB_OUTPUT_DIR}" "${DB_PWD}" "Server_ECDSA" DEPENDS "List_CA_certs" "generate_c_TestBufferPRFDSSL" ) jss_test_java( NAME "JSS_Test_BufferPRFD" COMMAND "org.mozilla.jss.tests.TestBufferPRFD" "${RESULTS_NSSDB_OUTPUT_DIR}" "${DB_PWD}" DEPENDS "List_CA_certs" ) # FIPS-related tests jss_test_java( NAME "Enable_FipsMODE" COMMAND "org.mozilla.jss.tests.FipsTest" "${RESULTS_NSSDB_FIPS_OUTPUT_DIR}" "enable" DEPENDS "Setup_FIPS_DBs" ) jss_test_java( NAME "check_FipsMODE" COMMAND "org.mozilla.jss.tests.FipsTest" "${RESULTS_NSSDB_FIPS_OUTPUT_DIR}" "chkfips" DEPENDS "Enable_FipsMODE" ) # The current version of NSS features partial support for TLS 1.3 in # FIPS mode. if (NOT SANDBOX) jss_test_java( NAME "SSLClientAuth_FIPSMODE" COMMAND "org.mozilla.jss.tests.SSLClientAuth" "${RESULTS_NSSDB_FIPS_OUTPUT_DIR}" "${PASSWORD_FILE}" "${JSS_TEST_PORT_CLIENTAUTH_FIPS}" "60" DEPENDS "Enable_FipsMODE" ) endif() jss_test_java( NAME "HMAC_FIPSMODE" COMMAND "org.mozilla.jss.tests.CrossHMACTest" "${RESULTS_NSSDB_FIPS_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Enable_FipsMODE" ) jss_test_java( NAME "KeyWrapping_FIPSMODE" COMMAND "org.mozilla.jss.tests.JCAKeyWrap" "${RESULTS_NSSDB_FIPS_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Enable_FipsMODE" ) jss_test_java( NAME "Mozilla_JSS_JCA_Signature_FIPSMODE" COMMAND "org.mozilla.jss.tests.JCASigTest" "${RESULTS_NSSDB_FIPS_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Enable_FipsMODE" ) jss_test_java( NAME "JSS_Signature_test_FipsMODE" COMMAND "org.mozilla.jss.tests.SigTest" "${RESULTS_NSSDB_FIPS_OUTPUT_DIR}" "${PASSWORD_FILE}" DEPENDS "Enable_FipsMODE" ) # Since we need to disable FIPS mode _after_ all FIPS-mode tests have # run, we have to add a strict dependency from Disable_FipsMODE onto all # FIPS-related checks. jss_test_java( NAME "Disable_FipsMODE" COMMAND "org.mozilla.jss.tests.FipsTest" "${RESULTS_NSSDB_FIPS_OUTPUT_DIR}" "disable" DEPENDS "check_FipsMODE" "SSLClientAuth_FIPSMODE" "HMAC_FIPSMODE" "KeyWrapping_FIPSMODE" "Mozilla_JSS_JCA_Signature_FIPSMODE" "JSS_Signature_test_FipsMODE" ) endif() jss_test_java( NAME "JUnit_GenericValueConverterTest" COMMAND "org.junit.runner.JUnitCore" "org.mozilla.jss.tests.GenericValueConverterTest" ) jss_test_java( NAME "JUnit_IA5StringConverterTest" COMMAND "org.junit.runner.JUnitCore" "org.mozilla.jss.tests.IA5StringConverterTest" ) jss_test_java( NAME "JUnit_PrintableConverterTest" COMMAND "org.junit.runner.JUnitCore" "org.mozilla.jss.tests.PrintableConverterTest" ) # For compliance with several add_custom_target( check DEPENDS test ) endmacro() macro(jss_tests_compile) jss_tests_compile_c("${PROJECT_SOURCE_DIR}/org/mozilla/jss/tests/buffer_size_1.c" "${BIN_OUTPUT_DIR}/buffer_size_1" "buffer_size_1") jss_tests_compile_c("${PROJECT_SOURCE_DIR}/org/mozilla/jss/tests/buffer_size_4.c" "${BIN_OUTPUT_DIR}/buffer_size_4" "buffer_size_4") jss_tests_compile_c("${PROJECT_SOURCE_DIR}/org/mozilla/jss/tests/TestBufferPRFD.c" "${BIN_OUTPUT_DIR}/TestBufferPRFD" "TestBufferPRFD") jss_tests_compile_c("${PROJECT_SOURCE_DIR}/org/mozilla/jss/tests/TestBufferPRFDSSL.c" "${BIN_OUTPUT_DIR}/TestBufferPRFDSSL" "TestBufferPRFDSSL") endmacro() macro(jss_tests_compile_c C_FILE C_OUTPUT C_TARGET) # Generate the target executable from C_FILE add_custom_command( OUTPUT "${C_OUTPUT}" COMMAND ${CMAKE_C_COMPILER} ${JSS_C_FLAGS} -o ${C_OUTPUT} ${C_FILE} -L${LIB_OUTPUT_DIR} -ljss4 ${JSS_LD_FLAGS} WORKING_DIRECTORY ${C_DIR} DEPENDS "${C_FILE}" DEPENDS "${JSS_TESTS_SO_PATH}" DEPENDS generate_java DEPENDS generate_includes ) add_custom_target( "generate_c_${C_TARGET}" DEPENDS "${C_OUTPUT}" ) add_dependencies("generate_so" "generate_c_${C_TARGET}") endmacro() function(jss_test_java) set(TEST_FLAGS "NAME") set(TEST_ARGS "COMMAND" "DEPENDS") cmake_parse_arguments(TEST_JAVA "" "${TEST_FLAGS}" "${TEST_ARGS}" ${ARGN}) list(APPEND EXEC_COMMAND "${Java_JAVA_EXECUTABLE}") list(APPEND EXEC_COMMAND "-classpath") list(APPEND EXEC_COMMAND "${TEST_CLASSPATH}") list(APPEND EXEC_COMMAND "-ea") list(APPEND EXEC_COMMAND "-Djava.library.path=${CMAKE_BINARY_DIR}") if(CMAKE_BUILD_TYPE STREQUAL "Debug") list(APPEND EXEC_COMMAND "-Djava.util.logging.config.file=${PROJECT_SOURCE_DIR}/tools/logging.properties") endif() set(EXEC_COMMAND "${EXEC_COMMAND};${TEST_JAVA_COMMAND}") if(TEST_JAVA_DEPENDS) jss_test_exec( NAME "${TEST_JAVA_NAME}" COMMAND "${EXEC_COMMAND}" DEPENDS ${TEST_JAVA_DEPENDS} LIBRARY "java" ) else() jss_test_exec( NAME "${TEST_JAVA_NAME}" COMMAND "${EXEC_COMMAND}" LIBRARY "java" ) endif() endfunction() macro(jss_test_exec) # Usage: # # jss_test_exec( # NAME TEST_NAME # COMMAND TEST_COMMAND # [DEPENDS [TEST_DEPENDS TEST_DEPENDS...]] # # Note that TEST_COMMAND can be a list by quoting the list: # # jss_test_exec("NAME" "ARG1" "ARG2" "...") set(TEST_FLAGS "NAME" "LIBRARY") set(TEST_ARGS "COMMAND" "DEPENDS") cmake_parse_arguments(TEST_EXEC "" "${TEST_FLAGS}" "${TEST_ARGS}" ${ARGN}) if(TEST_VALGRIND) list(INSERT TEST_EXEC_COMMAND 0 "valgrind" "--track-origins=yes" "--leak-check=full") endif() add_test( NAME "${TEST_EXEC_NAME}" COMMAND ${TEST_EXEC_COMMAND} ) list(APPEND LD_LIBRARY ${NSS_LIBRARIES}) list(APPEND LD_LIBRARY ${NSPR_LIBRARIES}) # If we are calling a java program, use the versioned library to ensure # that any new JNI calls are made visible. if(TEST_EXEC_LIBRARY AND (TEST_EXEC_LIBRARY STREQUAL "java")) list(APPEND LD_LIBRARY "${CMAKE_BINARY_DIR}") list(REMOVE_DUPLICATES LD_LIBRARY) jss_list_join(LD_LIBRARY ":" LD_LIBRARY_PATH) set_tests_properties( "${TEST_EXEC_NAME}" PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" ) else() list(APPEND LD_LIBRARY "${LIB_OUTPUT_DIR}") list(REMOVE_DUPLICATES LD_LIBRARY) jss_list_join(LD_LIBRARY ":" LD_LIBRARY_PATH) set_tests_properties( "${TEST_EXEC_NAME}" PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" ) endif() if(TEST_EXEC_DEPENDS) set_tests_properties( "${TEST_EXEC_NAME}" PROPERTIES DEPENDS "${TEST_EXEC_DEPENDS}" ) endif() endmacro() jss-4.6.3/cmake/Shims.cmake000066400000000000000000000010241362106420000154570ustar00rootroot00000000000000# LIST(JOIN ...) was introduced in CMake verison 3.12 macro(jss_list_join LIST_ SEPARATOR_ VAR_) if(${CMAKE_VERSION} VERSION_LESS "3.12.0") set("${VAR_}" "") foreach(ELEMENT ${${LIST_}}) set("${VAR_}" "${${VAR_}}${SEPARATOR_}${ELEMENT}") endforeach() string(LENGTH "${SEPARATOR_}" JSS_LIST_JOIN_SEPARATOR_LENGTH) string(SUBSTRING "${${VAR_}}" ${JSS_LIST_JOIN_SEPARATOR_LENGTH} -1 "${VAR_}") else() list(JOIN ${LIST_} ${SEPARATOR_} ${VAR_}) endif() endmacro() jss-4.6.3/docs/000077500000000000000000000000001362106420000132455ustar00rootroot00000000000000jss-4.6.3/docs/build_system.md000066400000000000000000000124211362106420000162720ustar00rootroot00000000000000# Build System This document describes the CMake build system and various locations used by CMake. ## Overview The new build system relies on CMake to build JSS. Most of the functionality is located under the `cmake/` directory in the root of the project. JSS is built in five stages: 1. Classes are built from Java source and JNI headers are generated. This is done in a single pass of the `javac` compiler. All Java source files under `org/` are currently compiled to the `build/classes/` folder. 2. Any C header files are moved to the `build/includes/` folder. 3. C source files are compiled to objects and linked to form `libjss4.so`, excluding any C source files in `org/mozilla/jss/tests`. If any exist, they'll be compiled at a later stage for `ctest`. This step is dependent on steps 1 and 2. 4. Build the JAR archive from compiled Java classes. Note that at this time, all classes in `build/classes/` are compiled into one JAR; in the future, a white list might be applied and testing classes separated out into a different JAR. This is dependent on step 1. 5. (Optionally) build Javadocs. This requires the user to build the `javadoc` target. The test suite is also generated using CMake in `cmake/JSSTests.cmake`. This allows JSS to run its test in parallel. ## `CMakeLists.txt` This is a file required by CMake for all CMake projects; it defines how the project is built. We use it as a high-level overview of CMake: options are defined, environment variables are read, modules are imported, and JSS is built and tested through here. JSS uses a direct approach to building: as a single call to `javac` suffices to build all of our classes and JNI headers, we don't need a recursive structure to build. This lets us have only one `CMakeLists.txt` in the root of our project. ## `cmake/` This directory contains two sets of files: dependencies and core modules. The non-standard CMake dependencies currently include the `FindNSPR` and `FindNSS` modules: these allow CMake to find NSPR and NSS system libraries and were imported from PKI. The core modules include `JSSConfig`, which sets useful variables for use within CMake, `JSSCommon`, which controls building JSS, and `JSSTests`, which sets up the JSS test suite within CTest. ### Available CMake Options Our CMake generator currently understands the following options when configuring the build system. Each option can either be specified on the CMake command line with `-D=` syntax, or in the environment. - `CHECK_DEPRECATION` -- enable `-Xlint:deprecation` when compiling JSS to check for use of deprecated APIs. - `FIPS_ENABLED` -- disable certain test cases which are known to fail in FIPS mode for various reasons. These usually include tests which try to disable FIPS mode, use unsupported ciphers, or too small of key sizes. Note that NSS must still be built with FIPS mode support enabled. - `SANDBOX` -- support building sandboxed builds to test changes to NSPR or NSS alongside changes to JSS. This assumes you have the following directory structure: ``` sandbox/ sandbox/nspr sandbox/nss sandbox/dist sandbox/jss ``` Note that `sandbox` can be replaced by any directory name. The `sandbox/dist` folder is automatically created by NSS upon build. Please first build NSS (according to current instructions) and then build JSS. - `TEST_VALGRIND` -- run the entire test suite under Valgrind. This option is quite slow. By default it passes two arguments: `--track-origins=yes` and `--leak-check=full`. Modify `cmake/JSSTests.cmake` (macro: `jss_test_exec`) to change these options. ### Adding a Test Case To add a new test case, add an entry to `cmake/JSSTests.cmake`. There's two useful helpers macros `jss_test_exec` and `jss_test_java`. `jss_test_exec` takes a `NAME` parameter (to use to identify the test case in output and when running particular tests), a `COMMAND` to execute, and an optional set of dependencies (`DEPENDS ...`) on other tests. We use this because `add_test` doesn't itself handle dependencies or set environment variables (we need to inject `LD_LIBRARY_PATH` to handle testing our built `libjss4.so`). `jss_test_java` is a wrapper over `jss_test_exec` which handles setting up the JVM and passing required arguments to it (`-classpath`, `-enableasserts`, etc.). Pass only the class you wish to execute and any arguments to it as the COMMAND field. (e.g., `COMMAND "org.mozilla.jss.tests.TestBuffer"`). There are a few useful variables defined: - `JSS_TEST_DIR` -- directory to the souce code where the tests are contained. - `PASSWORD_FILE` -- password for the NSS DB tokens. - `DB_PWD` -- password for the NSS DB internal (default) token. - `RESULTS_DATA_OUTPUT_DIR` -- directory to write test results to. - `RESULTS_NSSDB_OUTPUT_DIR` -- path of the non-FIPS NSS DB. - `RESULTS_NSSDB_FIPS_OUTPUT_DIR` -- path of the FIPS NSS DB. Note that, on a FIPS-enabled machine, `RESULTS_NSSDB_FIPS_OUTPUT_DIR` is unused and `RESULTS_NSSDB_OUTPUT_DIR` is actually placed in FIPS mode. For tests which would fail in FIPS mode, place them in the `if(NOT FIPS_ENABLED)` block. ## `lib/` This includes a few templated files including `jss.map`, the linker script which contains a versioned API of JSS, and `MANIFEST.MF.in`, JSS's Jar manifest file. jss-4.6.3/docs/building.md000066400000000000000000000047611362106420000153740ustar00rootroot00000000000000# Building JSS As of version 4.5.1, JSS has moved to a CMake build system. This is a modern alternative to our legacy build system and gives us a standard framework for building and testing JSS. This also allows us to support parallel builds and tests; to take advantage of this, specify the `-j` flag when using `make` or `ctest`. Please make sure the required dependencies are installed prior to building (see: [`docs/dependencies`](dependencies.md)). ## In-Source Build To build JSS from the source release, use `cmake`; JSS behaves much like a regular CMake project. ### Building JSS To build JSS using CMake: cd jss/build cmake .. make all To later rebuild from scratch, remove the build directory and recreate it. This ensures that any new dependencies are reflected in the build system. cd jss rm -rf build && mkdir build && cd build cmake .. make all ### Building Documentation Optionally, build the javadocs: cd jss/build make javadoc ### Testing To run the test suite: cd jss/build make test Note that the test suite currently doesn't handling re-running without clearing the results directory. To re-run the test suite: cd jss/build rm -rf results mkdir -p results/tests results/fips make test Alternatively, use CTest to run the test suite: ctest --output-on-failure Helpful flags for ctest are `--verbose` and `--output-log`; for more information, read `man ctest`. ### Installation To install JSS, place `jss4.jar` and `libjss4.so` in places where the system can find them. We recommend the following locations on a 64-bit system: cd jss/build sudo cp jss4.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 libjss4.so /usr/lib64/jss/libjss4.so sudo chown root:root /usr/lib64/jss/libjss4.so sudo chmod 755 /usr/lib64/jss/libjss4.so To uninstall, simply remove the created files (`/usr/lib/java/jss4.jar` and `/usr/lib64/jss/libjss4.so`). Note that the preferred way to install JSS is from your distribution or via an RPM built with `build.sh`. ## RPM Builds To build a RPM release, please ensure all dependencies are installed: sudo dnf install rpm-build cd jss && sudo dnf builddep --spec jss.spec Then, issue a build using the `build.sh` interface: ./build.sh This will build RPMS and place them in `$HOME/build/jss` by default. For more information about this build script, refer to its help text: ./build.sh --help jss-4.6.3/docs/ci.md000066400000000000000000000022201362106420000141560ustar00rootroot00000000000000# Containers and Continuous Integration JSS uses [Travis CI](https://travis-ci.org/dogtagpki/jss) for PR gating. We use Linux containers to ensure a consistent build environment and to allow us to test locally and in Travis on various platforms. ## Running CI Locally The Docker images are built in Travis using the Dockerfiles in `tools/Dockerfiles`; they are not pushed to DockerHub or similar platforms at this time. To test locally, we recommend using the provided container tool, `tools/run_container.sh`. For a brief example: ```bash cd /path/to/sandbox/jss ./tools/run_container.sh fedora_28 ``` Note that this requires either Buildah and Podman or Docker to be installed. For more extensive documentation, please refer to the [Buildah](https://github.com/containers/buildah/blob/master/docs/) and [Podman docs](https://github.com/containers/libpod/tree/master/docs) and the code in the `tools/run_container.sh` script. ## Skipping CI To skip running CI for a given commit (e.g., for updating documentation), append `[skip ci]` to the commit summary. Note that the `ubuntu_jdk8` image does not affect build status; it is included for reference only. jss-4.6.3/docs/contributing.md000066400000000000000000000046231362106420000163030ustar00rootroot00000000000000# Contributing to JSS We welcome all contributions to JSS and thank you in advance for them! Below are a few ways of contributing to JSS. ## Filing a Downstream Issue If you're using JSS as shipped by a distribution, we recommend filing an issue downstream first. In the case of a [RHCS](https://www.redhat.com/en/technologies/cloud-computing/certificate-system), [RHEL](https://www.redhat.com/en/technologies/cloud-computing/certificate-system), or [Fedora](https://getfedora.org/) release, the correct bugtracker is the [Red Hat Bugzilla](https://bugzilla.redhat.com/) instance. If you don't hear a response at the appropriate downstream tracker or if you think the issue exists upstream as well, feel free to file an upstream issue. ## Filing an Upstream Issue Most of the [Dogtag](https://github.com/dogtagpki) software (the new home of JSS) uses Fedora's [pagure.io](https://pagure.io/) for bug tracking; JSS's issue tracker can be found [there](https://pagure.io/jss/issues) as well. Note that this requires a Fedora account to create bugs. If this isn't of interest to you, feel free to file an issue on [GitHub](https://github.com/dogtagpki/jss/issues) instead; it will still get read and responded to. ## Opening a Pull Request If you'd like to contribute code to JSS, feel free to open a pull request against JSS. We'd recommend filing an issue (see above) if you'd like to introduce major change to JSS. This gives us a place to discuss the changes before they are proposed. Please fork the repository and make your changes in a new branch; before proposing the pull request, rebase your branch against upstream master. To test JSS locally, follow the [build instructions](building.md). Additionally, it is possible to run the CI container instances locally; follow directions in the [CI Overview](ci.md). We'd suggest making sure a Fedora build passes (e.g., `fedora_28`) and the `stylecheck` image passes as well. Then, feel free to open a PR. If you're looking for more information, we suggest reading about the [GitHub Flow](https://guides.github.com/introduction/flow/index.html) and reaching out to the developers if you need any assistance. ## Contacting Us If you wish to discuss contributing to JSS or an issue, there are a few forums of discussion: - The [pki-devel mailing list](https://www.redhat.com/mailman/listinfo/pki-devel). - The `#dogtag-pki` IRC channel on [Freenode](https://freenode.net/). Thanks! jss-4.6.3/docs/dependencies.md000066400000000000000000000043671362106420000162270ustar00rootroot00000000000000# Dependencies ## Build-time Dependencies This project has the following dependencies: - [NSPR](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSPR) - [NSS](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS) - A c and c++ compiler such as [gcc](ttps://gcc.gnu.org/) - [zlib](https://zlib.net/) - [OpenJDK 1.8.0 or newer](http://openjdk.java.net/) - [CMake](https://cmake.org/) - [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/) - [JavaEE JAXB](https://github.com/eclipse-ee4j/jaxb-ri) - [SLF4J](https://www.slf4j.org/) Additionally, a zipping and unzipping program is required to create reproducible builds. To install these dependencies on Fedora, execute the following: sudo dnf install apache-commons-lang gcc-c++ java-devel jpackage-utils \ slf4j zlib-devel glassfish-jaxb-api nss-tools nss-devel \ cmake junit To install these dependencies on Debian, execute the following: sudo apt-get install build-essential libcommons-lang-java libnss3-dev \ libslf4j-java default-jdk pkg-config zlib1g-dev \ libjaxb-api-java libnss3-tools cmake zip unzip \ junit4 ## Test Suite Dependencies: In addition to the dependencies above, the test suite requires the following additional packages: - [SLF4J's JDK14 package](https://www.slf4j.org/api/org/slf4j/impl/JDK14LoggerAdapter.html) - [NSS's pk12util](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Reference/NSS_tools_:_pk12util) - [JUnit 4](https://junit.org/junit4/) To install these dependencies on Fedora, execute the following: sudo dnf install nss nss-tools slf4j-jdk14 junit To install these dependencies on Debian, execute the following: sudo apt-get install libnss3 libnss3-tools libslf4j-java \ junit4 ## Run-time Dependencies At run time, the following JARs are required to be specified on the `CLASSPATH` of anyone wishing to use JSS: - `jss4.jar` - `slf4j-api.jar` - `apache-commons-lang.jar` - `jaxb-api.jar` Note that these should already be installed when building JSS. For more information, please refer to our documentation on using JSS: [`docs/using_jss.md`](using_jss.md). jss-4.6.3/docs/gh_pages.md000066400000000000000000000021751362106420000153510ustar00rootroot00000000000000# GitHub Pages JSS uses the GitHub pages functionality to host our generated javadocs. This allows developers to browse our documentation online without pulling down the JSS sources. Periodically, this documentation will need to be updated and will mirror the latest contents of master. To do so: 1. Checkout the master branch and make sure it is up to date with `upstream`: ``` cd sandbox/jss git remote add upstream https://github.com/dogtagpki/jss git fetch --all git checkout upstream/master ``` 2. Build the javadocs; note that they are placed in `../dist/jssdocs`: ``` export JAVA_HOME=/etc/alternatives/java_sdk_1.8.0_openjdk export USE_64=1 make javadoc ``` 3. Copy the new-docs into the gh-pages branch: ``` git clean -xdf && git checkout gh-pages rm -rf javadoc && cp ../dist/jssdoc javadoc -rv git add javadoc && git commit -m "Update javadocs from master at $(date '+%Y-%m-%d %H:%M')" && git push origin gh-pages ``` 4. Open a PR against `dogtagpki/jss` with the updates. This will get reviewed, merged, and then automatically propagated to GitHub Pages. jss-4.6.3/docs/legacy_building.md000066400000000000000000000151211362106420000167100ustar00rootroot00000000000000# Legacy Build Instructions These instructions have been preserved from the README; if you are referring to specific parts of the build instructions, they have been moved here. Build/Test Instructions ----------------------- ### 1. Prepare a work area (a) For upstream builds which checkout and utilize the current NSPR and NSS source repositories: ``` # mkdir sandbox # cd sandbox # hg clone https://hg.mozilla.org/projects/nspr # hg clone https://hg.mozilla.org/projects/nss # git clone git@github.com:dogtagpki/jss.git # cd .. ``` There is no need to clone every time. For additional builds, simply use: ``` # cd nspr # hg pull -u -v # cd .. # cd nss # hg pull -u -v # cd .. # cd jss # git pull -v # cd .. ```` (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" # git clone https://hg.mozilla.org/projects/jss # cd .. ``` There is no need to clone every time. For additional builds, simply use: ``` # cd jss # git pull -v # cd .. ``` ### 2. Prepare an interactive shell for building ``` # 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). The following steps are optional, and left to the discretion of the user: #### Normal vs. Optimized builds By default, JSS will be built as a normal binaries. To create an optimized build, 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 To build JSS, execute the following commands: ``` # cd sandbox/jss # make clean all # cd ../.. ``` 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. Install JSS on the System (Optional) 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 ``` Then install the new JSS binaries: ``` # 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 when method (1)(a) has been utilized to build JSS since the tests are dependent upon the work area as setup in this method; currently JSS must be built via 'make clean all' before execution of this command (e.g. - build is separate from test). ### 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. Tagging the Source Code for a Release During development, several releases may be made. Consequently, it is good practice to create a "regular tag" to the source code at these various points in time using the following format: ``` # git tag -m "message" JSS___ ``` where: * major = JSS Major Version Number * minor = JSS Minor Version Number * YYYY = 4-digit year (e. g. - 2017) * MM = 2-digit month (e. g. - 01, ..., 12) * DD = 2-digit day of the month (e. g. - 01, ..., 31) For example: ``` # git rev-parse HEAD b3e864205ff0... # git tag -m "Added tag JSS_4_4_20170328 for changeset b3e864205ff0" JSS_4_4_20170328 ``` At the appropriate time, a new major.minor version may be created. At this time, it is important to create a maintenance branch for any future changes to the previous major.minor version: For example: ``` # git rev-parse HEAD f00f00f00f00... # git checkout -b JSS_4_4_BRANCH ``` ### 8. Known Issues Some of the known issues are: * 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 patch and its interaction with the HMAC Tests (both non-FIPS and FIPS), 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: * Install the new JSS builds by executing step (4) above * Execute the following commands: ``` # cd sandbox/jss # make test_jss ``` NOTE: If the system is being used for purposes other than test, the user may wish to restore the original JSS by executing step (6) above. jss-4.6.3/docs/pkcs11_constants.md000066400000000000000000000123501362106420000167660ustar00rootroot00000000000000# PKCS11Constants As of release 4.5.1, JSS now ships with a set of constants that enable JSS to work on JDK versions greater than 8. In particular, JDK 9+ introduced the concepts of Modules to Java, allowing previously exported classes to be restricted. This resulted in the complete removal of all `sun.*` classes; previously, these internal implementation details were exposed by the JDK. These changes are documented more at the following locations: - https://www.oracle.com/technetwork/java/faq-sun-packages-142232.html - https://www.oracle.com/corporate/features/understanding-java-9-modules.html - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=875589 - https://wiki.debian.org/Java/Java9Pitfalls As a replacement, we built a utility to convert NSS's header files (`pkcs11t.h` and `pkcs11n.h`) to Java. The following sections describe this system. ## Regenerating PKCS11Constants.java There are a few cases where updating PKCS11Constants.java is necessary: - If NSS updates either of the two header files. - If certain constants need to be excluded. - If new constants need to be included. In the former case, the CI job or container build of `pkcs11checks` will fail, notifying us that this will need to be updated. To do so, first make sure the system's NSS is up to date: dnf update --refresh dnf install nss-dev Then, validate the location of the NSS header files; on Fedora, this location is `/usr/include/nss3`: ls /usr/include/nss3/pkcs11{t,n}.h Lastly, run the utility: python3 ./tools/build_pkcs11_constants.py --system \ --pkcs11t /usr/include/nss3/pkcs11t.h \ --pkcs11n /usr/include/nss3/pkcs11n.h \ --output org/mozilla/jss/pkcs11/PKCS11Constants.java While not required, it is suggested to use the `--system` flag to ensure the values of `PKCS11Constants.java` are the same as the installed NSS values. After this, rebuild JSS and run the test suite on a JDK8 machine: source ./tools/autoenv.sh cd build && cmake .. && make clean all check This will trigger the interoperability tests against the Sun values. ## `tools/build_pkcs11_constants.py` This utility generates the `PKCS11Constants.java` from the contents of the NSS header files. It has the following flags: -h / --help :: display the help text associated with the script --pkcs11t :: path to the pkcs11t.h header file from a NSS distribution; this header file contains the general PKCS11 constants --pkcs11n :: path to the pkcs11n.h header file from a NSS distribution; this header file contains NSS and Netscape-specific PKCS11 Constants -o / --output :: path to output the generated Java file to -s / --system :: assume the provided headers are from the system-installed NSS; perform extended sanity checks by compiling the parsed values and checking them against the NSS values -v / --verbose :: generate extended debug information in the form of comments in the generated file; this includes information about parsing, resolution, and if applicable, the output of the system checks The code of this program is heavily documented and is roughly organized from more specific methods to more general methods (e.g., `main`). A few things are of particular note: - This program attempts to verify correctness by ensuring that the internal representation of a constant is as a Python `int`; this ensures that we correctly parsed the value token and that, when we write the output, the value doesn't depend on any other constants. - This program treats all `#define`-d constants as if they were of a numeric type, with all values being written as hex encoded longs. - This program preserves the original ordering of constants, with constants in `pkcs11t.h` appearing before constants in `pkcs11n.h`. - This program currently parses only parenthesis in a token's value, but not curly braces or square braces; the latter two shouldn't be present in most numeric types. Any failure to parse as a numeric type is a parse error which fails the script. For more information about this script, please refer to the comments therein. ## Java Test Included in the test suite when run on a JDK8 machine is a test called [`TestPKCS11Constants`](../org/mozilla/jss/tests/TestPKCS11Constants.java). This uses reflection to compare the values of the PKCS11Constants.java provided by JSS and the version provided by Sun, reporting constants in four categories: 1. Those which are "OK", i.e., present in both Sun and JSS with the same value. 2. Those which are "JSS only", i.e., the constant name does not exist in the Sun distribution. These are not treated as errors. 3. Those which are "Sun only", i.e., the constant name does not exist in the JSS distribution. These are not treated as errors. 4. Those which are "not OK", i.e., present in both Sun and JSS but with different values associated to them. This is not an error. Information about all constants is written to stdout during testing; please manually review the "JSS only" and "Sun only" cases to see if any results are unexpected. jss-4.6.3/docs/repo_archive.md000066400000000000000000000016071362106420000162410ustar00rootroot00000000000000# JSS Archive At the time of migration to GitHub, JSS had collected a significant number of branches. Because these branches may be of historical importance, it has been decided to archive them in a separate repository. This allows us to prune the main repository while persisting this information. For more information on this decision, please refer to the [RFC](https://pagure.io/jss/issue/25). To view the JSS archive, navigate to the [`jss-archive`](https://github.com/dogtagpki/jss-archive) repository. Because this repository has the same commits as the `jss` repository, it is possible to use both together: ``` cd /path/to/jss git remote add jss-archive https://github.com/dogtagpki/jss-archive git fetch jss-archive ``` At this point, all prior branches and tags will be synchronized with your current repository. To checkout a retired branch: ``` git checkout jss-archive/BRANCH_NAME ``` jss-4.6.3/docs/usage/000077500000000000000000000000001362106420000143515ustar00rootroot00000000000000jss-4.6.3/docs/usage/kbkdf.md000066400000000000000000000354471362106420000157710ustar00rootroot00000000000000# KBKDF - Documentation ## About KBKDF KBKDF is defined in [NIST's SP800-108][sp800-108]: Key Based Key Derivation Functions. These are a collection of three KDFs based on MACing primitives: 1. Counter Mode in 5.1, 2. Feedback Mode in 5.2, and 3. Double Pipeline Mode in 5.3. These KDFs see usage in GlobalPlatform's Secure Channel Protocol 03, Kerberos, and other places. This KDF is implemented using [PKCS#11 v3.0][pkcs11-kbkdf]; refer to that document for additional information about using this KDF. ## Using KBKDF KBKDF usage is available from the `Mozilla-JSS` provider through the javax [`KeyGenerator`][key-generator] interface. There are two categories of KDF implementations: 1. `CKO_SECRET_KEY` keys, which cannot be extracted when the system is running in FIPS mode or when the key lives on an HSM, and 2. `CKO_DATA_OBJECT` keys, which can always be extract. The latter category is suitable for generating SCP03 challenges, but shouldn't be used with cryptographic operations. They have the "Data" suffix in the provider list. ### Constructing a KBKDF `KeyGenerator` To construct a KBKDF generator, get the instance via the provider interface: ```java import javax.crypto.KeyGenerator; KeyGenerator kg = KeyGenerator.getInstance("", "Mozilla-JSS"); ``` Where name depends on the choice of KBKDF: | KeyGenerator Name | Mode | Data | Parameter Class | |-------------------|----------|------|----------------------------------------------| | KbkdfCounter | Counter | no | [KBKDFCounterParams][kbkdf-counter-params] | | KbkdfCounterData | Counter | yes | [KBKDFCounterParams][kbkdf-counter-params] | | KbkdfFeedback | Feedback | no | [KBKDFFeedbackParams][kbkdf-feedback-params] | | KbkdfFeedbackData | Feedback | yes | [KBKDFFeedbackParams][kbkdf-feedback-params] | | KbkdfPipeline | Pipeline | no | [KBKDFPipelineParams][kbkdf-pipeline-params] | | KbkdfPipelineData | Pipeline | yes | [KBKDFPipelineParams][kbkdf-pipeline-params] | Various aliases for these KeyGenerators also exist; this allows for greater compatibility with existing systems which implement this KDF. These exist because the [Java Cryptography Architecture][jca] doesn't specify canonical names for these KDFs. ### Construct a KBKDF Parameter Specification Each KBKDF mode has its own parameter specification class, which must be used with a `KeyGenerator` of only that type. These classes are given in the above table and exist in the [`org.mozilla.jss.crypto`][jss-crypto] package. Each parameter spec derives from [`KBKDFParameterSpec`][kbkdf-spec]. These arguments are: | Name | Description | Modes | Setter | |-------------------------|--------------------------------------|----------|-----------------------------------------------------------------------------------------------------| | PRF | PRF used during KBKDF (HMAC or CMAC) | All | [`setPRF`][kbkdf-spec-set-prf] | | PRF Key | Key used for the PRF | All | [`setPRFKey`][kbkdf-spec-set-prf-key] | | Derived Algorithm | Algorithm of the primary derived key | All | [`setDerivedKeyAlgorithm`][kbkdf-spec-set-derived-algo] | | Key Size | Size of the primary derived key | All | [`setKeySize`][kbkdf-spec-set-key-size] | | Initial Value | Initial chaining value | Feedback | [`setInitialValue`][kbkdf-spec-set-iv] | | PRF Data Parameters | Parameters to control PRF input | All | [`setParameters`][kbkdf-spec-set-params] / [`addParameter`][kbkdf-spec-add-param] | | Additional Derived Keys | Additional keys to derive | All | [`setAdditionalDerivedKeys`][kbkdf-spec-set-keys] / [`addAdditionalDerivedKey`][kbkdf-spec-add-key] | Note: the methods and fields inherited from `NativeEnclosure` shouldn't be called by the KBKDF user during normal usage. #### Using Algorithms When using this KBKDF, both the PRF and the derived key's algorithm must be specified. In both cases, the user has a choice: either use the [PKCS#11 Constant][jss-pkcs11-constants] for the algorithm, or use the algorithm as specified in the [PKCS#11 Algorithm][jss-pkcs11-algorithm] enumeration. For example, the following are equivalent: ```java import org.mozilla.jss.pkcs11.PKCS11Constants; KBKDFCounterParams params = new KBDKFCounterParams(); params.setPRF(PKCS11Constants.CKM_AES_CMAC); ``` and ```java import org.mozilla.jss.crypto.PKCS11Algorithm; KBKDFCounterParams params = new KBKDFCounterParams(); params.setPRF(PKCS11Algorithm.CKM_AES_CMAC); ``` The latter gives a little more type safety and ensures that the specified algorithm is understood and implemented by JSS; otherwise, they're equivalent. #### Constructing KDF PRF Input Stream (Data) Parameters The core of PKCS#11's KBKDF implementation allows great flexibility in crafting the input stream to the underlying PRF invocation. This allows for a wide range of usages (including in SCP03), assuming some care is taken in ensuring the resulting KBKDF is secure from length extension attacks. See NIST S800-108 for more details regarding concerns. PKCS#11 v3.0 defines four types of input parameters: | Name | Description | |-----------------------------|------------------------------------------------------------| | KBKDFByteArrayParam | A static array of bytes to add to the PRF input stream | | KBKDFDKMLengthParam | A structure for encoding and calculating KDF output length | | KBKDFIterationVariableParam | Either an incrementing counter or a chaining value | | KBKDFOptionalCounterParam | (In Feedback and Pipeline Modes); an optional counter | Please refer to [section 2.42.2 Mechanism Parameters][pkcs11-kbkdf-params] for more information about correct usage of each parameter, how they correlate to names in NIST SP800-108, and with which KDF modes each parameter can be used. #### Deriving Additional Keys PKCS#11 v3.0 defines a way of extracting additional keys from the derived key material. See [section 2.42.6 Deriving Additional Keys][pkcs11-kbkdf-adk] for a comprehensive reference. The `CK_DERIVED_KEY` PKCS#11 structure is mirrored in the `KBKDFDerivedKey` class. Add PKCS#11 Attributes to the derived key, specify it in the KDF parameter. After `kg.generateKey(...)` has been called, `getKey(...)` will return the additional key. ### Example KBKDF Usage Putting this all together, the following is a short example of how to use the KBKDF to derive a single key for the SCP03 protocol. ```java public SymmetricKey kbkdfDeriveSCP03Key(SymmetricKey master, byte[] context, byte kdfConstant, int kdfOutputSizeBytes) { KeyGenerator kg = KeyGenerator.getInstance("KbkdfCounter", "Mozilla-JSS"); KBKDFCounterParams kcp = new KBKDFCounterParams(); kcp.setPRF(PKCS11Algorithm.CKM_AES_CMAC); kcp.setPRFKey(master); kcp.setKeySize(kdfOutputSizeBytes); byte[] label = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, kdfConstant }; kcp.addParameter(new KBKDFByteArrayParam(label)); byte[] separator = new byte[] { 0x00 }; kcp.addParameter(new KBKDFByteArrayParam(separator)); KBKDFDataParameter length = new KBKDFDKMLengthParam( // How to calculate the length, were there multiple derived keys. PKCS11Constants.CK_SP800_108_DKM_LENGTH_SUM_OF_SEGMENTS, // This length is big endian, so littleEndian == false. false, // How many bits to encode the length. SCP03 requires two bytes. 2*8 ); kcp.addParameter(length); KBKDFDataParameter counter = new KBKDFIterationVariableParam(false, 1*8); kcp.addParameter(counter); kcp.addParameter(new KBKDFByteArrayParam(context)); kcp.setDerivedKeyAlgorithm(PKCS11Algorithm.CKM_AES_CBC); kg.init(kcp); return kg.generateKey(); } ``` ## Design of KBKDF Unlike past key generation mechanisms, the `CKM_SP800_108_*` PKCS#11 mechs require extensive mechanism parameters. Under Java, these take the form of [`java.security.spec.AlgorithmParameterSpec`][alg-param-spec] implementations, but this leaves much to be desired when bridging the JNI gap. Our approach involved creating new extensions to the [`NativeProxy`][native-proxy] class: the [`NativeEnclosure`][native-enclosure]. Unlike a `NativeProxy` -- whose scope is implicit, a `NativeEnclosure` formalizes and specifies the exact scope of a C pointer. In particular, a `NativeProxy` instance could be created at any time by the JNI code; it is then given to Java to handle usage and cleanup. Additionally, a `NativeProxy` instance doesn't exist until it is created by C code. Contrasting with that, we need our parameter specifications to exist prior to the creation of the `NativeProxy` instance -- so we can populate them -- but we still need to capture the creation, use, and destruction of the underlying `NativeProxy`. This leads to two NativeEnclosure methods: - `acquireNativeResources(...)` to trigger an allocation of the `NativeProxy`, storing it on the `mPointer` member, and - `releaseNativeResources(...)` to trigger freeing it. These get wrapped in `open(...)` and `close(...)` respective, allowing us to implement the [`java.lang.AutoCloseable`][auto-close] class. This lets us use the parameters in the `KeyGenerator` as following: prior to the call (via JNI) to `PK11_DeriveKey(...)`. We call `open(...)` and handle any issues creating the `CK_SP800_108_KDF_PARAMS` or `CK_SP800_108_FEEDBACK_KDF_PARAMS` pointer. We pass this pointer directly to `PK11_DeriveKey(...)`, and when we're done, call `close(...)` to handle freeing it. Thus, we incur only a single allocation and free when we're ready to use the parameter, and the complexities of handling the JNI translation are hidden from the programmer wishing to use it. [alg-param-spec]: https://docs.oracle.com/javase/8/docs/api/java/security/spec/AlgorithmParameterSpec.html "java.security.spec.AlgorithmParameterSpec" [auto-close]: https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html "java.lang.AutoCloseable" [jca]: https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html "Java Cryptography Architecture Reference Guide" [jss-crypto]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/package-summary.html "org.mozilla.jss.crypto.*" [jss-pkcs11-algorithm]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/PKCS11Algorithm.html "org.mozilla.jss.crypto.PKCS11Algorithm" [jss-pkcs11-constants]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/pkcs11/PKCS11Constants.html "org.mozilla.jss.pkcs11.PKCS11Constants" [kbkdf-counter-params]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFCounterParams.html "org.mozilla.jss.crypto.KBKDFCounterParams" [kbkdf-feedback-params]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFFeedbackParams.html "org.mozilla.jss.crypto.KBKDFFeedbackParams" [kbkdf-pipeline-params]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFPipelineParams.html "org.mozilla.jss.crypto.KBKDFPipelineParams" [kbkdf-spec]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFParameterSpec.html "org.mozilla.jss.crypto.KBKDFParameterSpec" [kbkdf-spec-set-prf]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFParameterSpec.html#setPRF-org.mozilla.jss.crypto.PKCS11Algorithm- "org.mozilla.jss.crypto.KBKDFParameterSpec setPRF(...)" [kbkdf-spec-set-prf-key]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFParameterSpec.html#setPRFKey-javax.crypto.SecretKey- "org.mozilla.jss.crypto.KBKDFParameterSpec setPRFKey(...)" [kbkdf-spec-set-derived-algo]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFParameterSpec.html#setDerivedKeyAlgorithm-org.mozilla.jss.crypto.PKCS11Algorithm- "org.mozilla.jss.crypto.KBKDFParameterSpec setDerivedKeyAlgorithm(...)" [kbkdf-spec-set-key-size]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFParameterSpec.html#setKeySize-int- "org.mozilla.jss.crypto.KBKDFParameterSpec setKeySize(...)" [kbkdf-spec-set-iv]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFFeedbackParams.html [kbkdf-spec-set-params]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFParameterSpec.html#setParameters-org.mozilla.jss.crypto.KBKDFDataParameter:A- "org.mozilla.jss.crypto.KBKDFParameterSpec setParameters(...)" [kbkdf-spec-add-param]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFParameterSpec.html#addParameter-org.mozilla.jss.crypto.KBKDFDataParameter- "org.mozilla.jss.crypto.KBKDFParameterSpec addParameter(...)" [kbkdf-spec-set-keys]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFParameterSpec.html#setAdditionalDerivedKeys-org.mozilla.jss.crypto.KBKDFDerivedKey:A- "org.mozilla.jss.crypto.KBKDFParameterSpec setAdditionalDerivedKeys(...)" [kbkdf-spec-add-key]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/crypto/KBKDFParameterSpec.html#addAdditionalDerivedKey-org.mozilla.jss.crypto.KBKDFDerivedKey- "org.mozilla.jss.crypto.KBKDFParameterSpec addAdditionalDerivedKey(...)" [key-generator]: https://docs.oracle.com/javase/8/docs/api/javax/crypto/KeyGenerator.html "javax.crypto.KeyGenerator" [native-enclosure]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/util/NativeEnclosure.html "org.mozilla.jss.util.NativeEnclosure" [native-proxy]: https://dogtagpki.github.io/jss/master/javadocs/org/mozilla/jss/util/NativeProxy.html "org.mozilla.jss.util.NativeProxy" [pkcs11-kbkdf]: https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.0/csprd01/pkcs11-curr-v3.0-csprd01.html#_Toc437440585 "PKCS#11 v3.0: SP 800-108 Key Derivation" [pkcs11-kbkdf-params]: https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.0/csprd01/pkcs11-curr-v3.0-csprd01.html#_Toc8118473 "PKCS#11 v3.0: SP 800-108 Key Derivation: 2.42.2 Mechanism Parameters" [pkcs11-kbkdf-adk]: https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.0/csprd01/pkcs11-curr-v3.0-csprd01.html#_Toc8118477 "PKCS#11 v3.0: SP 800-108 Key Derivation: 2.42.6 Deriving Additional Keys" [sp800-108]: https://csrc.nist.gov/publications/detail/sp/800-108/final "Recommendation for Key Derivation using Pseudorandom Functions (Revised)" jss-4.6.3/docs/using_jss.md000066400000000000000000000030351362106420000155740ustar00rootroot00000000000000# Using JSS Please make sure `libjss4.so` is included in your library path or set it via the `LD_LIBRARY_PATH` environment variable. See `man 8 ld.so` for more information. Alternatively, this can be done by setting `-Djava.library.path` to the directory with `libjss4.so` on the command line of all Java programs using JSS. Note that without `libjss4.so`, using JSS in nearly any capacity will fail. ## Classpath Dependencies To use JSS in your project after installation, you'll need to ensure the following dependencies are available in your `CLASSPATH`: - `jss4.jar` -- provided by the `jss` package and installed to `/usr/lib/java/jss4.jar`. - `slf4j-api.jar` -- provided by the `slf4j` package and installed to `/usr/share/java/slf4j/slf4j-api.jar`. - `apache-commons-lang.jar` -- provided by the `apache-commons-lang` package and installed to `/usr/share/java/apache-commons-lang.jar`. - `jaxb-api.jar` -- provided by the `glassfish-jaxb-api` package and installed to `/usr/share/java/jaxb-api.jar`. Note that the above paths and packages are for Fedora; for a list of packages in Debian, please see the [dependencies document](dependencies.md). Note that paths might differ between various platforms and versions of Fedora. ## Developing against JSS We recommend referring to the javadoc distribution generated when JSS was installed. On Fedora-like systems, this is provided by the `jss-javadoc` package; for an online version tracking master, please refer to our [live instance](https://dogtagpki.github.io/jss/javadoc/index.html). jss-4.6.3/gpl.txt000066400000000000000000000431031362106420000136410ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. jss-4.6.3/jss.html000066400000000000000000000060261362106420000140060ustar00rootroot00000000000000 Netscape Security Services for Java

Netscape Security Services for Java

Netscape Security Services for Java (JSS) is an interface allowing Java applications to use the Secure Sockets Layer protocol. The interface is implemented with the FIPS-validated Netscape Security Services library. It consists of a system-dependent dynamic library (libjss.so on UNIX, jss.dll on Windows) and a ZIP file (jss.zip) containing system-independent Java classes. These classes are compatible with JDK 1.1 or later using the native thread implementation (not green threads).

Building Applications with JSS

To construct Java applications that use JSS, you must:
  • Call the JSS classes from your application.
  • When compiling your application, put jss.zip in your CLASSPATH.
  • When running your application, put libjss.so in your LD_LIBRARY_PATH (on UNIX) or jss.dll in your PATH (on Windows), and put jss.zip in your CLASSPATH.

Programming with JSS

Before the SSL classes can be used, NSSInit.initialize must be called to open the security databases and initialize the random number generator. NSSInit.setPasswordCallback may be called to change the password callback; the default is to prompt for passwords on the command line.

The files in the examples directory illustrate the use of JSS in an application:

SSLClient.java
An example of an SSL client application.
SSLServer.java
An example of an SSL server application. To run, it requires certificate and key databases that contain a certificate called "SSLServer". The sample cert7.db and key3.db files, also in the examples directory, can be used for this purpose. When SSLServer is run, it will ask for a password for the "Internal Key Storage Token", which is the key database. The password for the example key3.db file is "netscape".
These classes are in the org.mozilla.jss.ssl package. The .class files must be put in the subdirectory org/mozilla/jss/ssl of a CLASSPATH entry in order to be located by the Java virtual machine.

Javadoc for the JSS Classes

jss-4.6.3/jss.spec000066400000000000000000000115521362106420000137740ustar00rootroot00000000000000################################################################################ Name: jss ################################################################################ Summary: Java Security Services (JSS) URL: http://www.dogtagpki.org/wiki/JSS License: MPLv1.1 or GPLv2+ or LGPLv2+ Version: 4.6.3 Release: 1%{?_timestamp}%{?_commit_id}%{?dist} # global _phase -a1 # To generate the source tarball: # $ git clone https://github.com/dogtagpki/jss.git # $ cd jss # $ git tag v4.5. # $ git push origin v4.5. # Then go to https://github.com/dogtagpki/jss/releases and download the source # tarball. Source: https://github.com/dogtagpki/%{name}/archive/v%{version}%{?_phase}/%{name}-%{version}%{?_phase}.tar.gz # To create a patch for all changes since a version tag: # $ git format-patch \ # --stdout \ # \ # > jss-VERSION-RELEASE.patch # Patch: jss-VERSION-RELEASE.patch ################################################################################ # Build Dependencies ################################################################################ # autosetup BuildRequires: git BuildRequires: make BuildRequires: cmake BuildRequires: gcc-c++ BuildRequires: nspr-devel >= 4.13.1 BuildRequires: nss-devel >= 3.30 BuildRequires: nss-tools >= 3.30 BuildRequires: java-devel BuildRequires: jpackage-utils BuildRequires: slf4j BuildRequires: glassfish-jaxb-api %if 0%{?rhel} && 0%{?rhel} <= 7 # no slf4j-jdk14 %else BuildRequires: slf4j-jdk14 %endif BuildRequires: apache-commons-lang BuildRequires: junit Requires: nss >= 3.30 Requires: java-headless Requires: jpackage-utils Requires: slf4j Requires: glassfish-jaxb-api %if 0%{?rhel} && 0%{?rhel} <= 7 # no slf4j-jdk14 %else Requires: slf4j-jdk14 %endif Requires: apache-commons-lang Conflicts: ldapjdk < 4.20 Conflicts: idm-console-framework < 1.2 Conflicts: tomcatjss < 7.3.4 Conflicts: pki-base < 10.6.5 %description Java Security Services (JSS) is a java native interface which provides a bridge for java-based applications to use native Network Security Services (NSS). This only works with gcj. Other JREs require that JCE providers be signed. ################################################################################ %package javadoc ################################################################################ Summary: Java Security Services (JSS) Javadocs Group: Documentation Requires: jss = %{version}-%{release} %description javadoc This package contains the API documentation for JSS. ################################################################################ %prep %autosetup -n %{name}-%{version}%{?_phase} -p 1 -S git ################################################################################ %build %set_build_flags [ -z "$JAVA_HOME" ] && export JAVA_HOME=%{_jvmdir}/java # Enable compiler optimizations export BUILD_OPT=1 # Generate symbolic info for debuggers CFLAGS="-g $RPM_OPT_FLAGS" export CFLAGS # Check if we're in FIPS mode modutil -dbdir /etc/pki/nssdb -chkfips true | grep -q enabled && export FIPS_ENABLED=1 # The Makefile is not thread-safe rm -rf build && mkdir -p build && cd build %cmake \ -DJAVA_HOME=%{java_home} \ -DJAVA_LIB_INSTALL_DIR=%{_jnidir} \ .. %{__make} all %{__make} javadoc ctest --output-on-failure ################################################################################ %install # There is no install target so we'll do it by hand # jars install -d -m 0755 $RPM_BUILD_ROOT%{_jnidir} install -m 644 build/jss4.jar ${RPM_BUILD_ROOT}%{_jnidir}/jss4.jar # We have to use the name libjss4.so because this is dynamically # loaded by the jar file. install -d -m 0755 $RPM_BUILD_ROOT%{_libdir}/jss install -m 0755 build/libjss4.so ${RPM_BUILD_ROOT}%{_libdir}/jss/ pushd ${RPM_BUILD_ROOT}%{_libdir}/jss ln -fs %{_jnidir}/jss4.jar jss4.jar popd # javadoc install -d -m 0755 $RPM_BUILD_ROOT%{_javadocdir}/%{name}-%{version} cp -rp build/docs/* $RPM_BUILD_ROOT%{_javadocdir}/%{name}-%{version} cp -p jss.html $RPM_BUILD_ROOT%{_javadocdir}/%{name}-%{version} cp -p *.txt $RPM_BUILD_ROOT%{_javadocdir}/%{name}-%{version} # No ldconfig is required since this library is loaded by Java itself. ################################################################################ %files %defattr(-,root,root,-) %doc jss.html MPL-1.1.txt gpl.txt lgpl.txt %{_libdir}/* %{_jnidir}/* ################################################################################ %files javadoc %defattr(-,root,root,-) %{_javadocdir}/%{name}-%{version}/ ################################################################################ %changelog * Tue May 29 2018 Dogtag PKI Team 4.5.0-0 - To list changes in since : $ git log --pretty=oneline --abbrev-commit --no-decorate .. jss-4.6.3/lgpl.txt000066400000000000000000000635041362106420000140240ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! jss-4.6.3/lib/000077500000000000000000000000001362106420000130635ustar00rootroot00000000000000jss-4.6.3/lib/MANIFEST.MF.in000066400000000000000000000005041362106420000151210ustar00rootroot00000000000000Manifest-Version: 1.0 Name: org/mozilla/jss/ Specification-Title: Network Security Services for Java (JSS) Specification-Version: ${JSS_VERSION_MANIFEST} Specification-Vendor: Mozilla Foundation Implementation-Title: org.mozilla.jss Implementation-Version: ${JSS_VERSION_MANIFEST} Implementation-Vendor: Mozilla Foundation jss-4.6.3/lib/jss.map000066400000000000000000000477211362106420000143740ustar00rootroot00000000000000# # 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/. # OK, this file is meant to support Linux's Version Script. For more # information, see: # ftp://ftp.gnu.org/pub/old-gnu/Manuals/ld-2.9.1/html_node/ld_25.html JSS_3.0 { # JSS 3.0 release global: Java_org_mozilla_jss_crypto_EncryptionAlgorithm_getIVLength; Java_org_mozilla_jss_crypto_PQGParams_generateNative__I; Java_org_mozilla_jss_crypto_PQGParams_generateNative__II; Java_org_mozilla_jss_crypto_PQGParams_paramsAreValidNative; Java_org_mozilla_jss_DatabaseCloser_closeDatabases; Java_org_mozilla_jss_CryptoManager_FIPSEnabled; Java_org_mozilla_jss_CryptoManager_buildCertificateChainNative; Java_org_mozilla_jss_CryptoManager_enableFIPS; Java_org_mozilla_jss_CryptoManager_exportCertsToPKCS7; Java_org_mozilla_jss_CryptoManager_findCertByIssuerAndSerialNumberNative; Java_org_mozilla_jss_CryptoManager_findCertByNicknameNative; Java_org_mozilla_jss_CryptoManager_findCertsByNicknameNative; Java_org_mozilla_jss_CryptoManager_findPrivKeyByCertNative; Java_org_mozilla_jss_CryptoManager_getCACerts; Java_org_mozilla_jss_CryptoManager_getPermCerts; Java_org_mozilla_jss_CryptoManager_importCRLNative; Java_org_mozilla_jss_CryptoManager_importCertPackageNative; Java_org_mozilla_jss_CryptoManager_importCertToPermNative; Java_org_mozilla_jss_CryptoManager_initializeAllNative; Java_org_mozilla_jss_CryptoManager_putModulesInVector; Java_org_mozilla_jss_CryptoManager_setNativePasswordCallback; Java_org_mozilla_jss_pkcs11_CertProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_CipherContextProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PK11Module_getLibraryName; Java_org_mozilla_jss_pkcs11_PK11Module_getName; Java_org_mozilla_jss_pkcs11_PK11Module_putTokensInVector; Java_org_mozilla_jss_pkcs11_ModuleProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PK11Cert_getEncoded; Java_org_mozilla_jss_pkcs11_PK11Cert_getIssuerDNString; Java_org_mozilla_jss_pkcs11_PK11Cert_getNickname; Java_org_mozilla_jss_pkcs11_PK11Cert_getOwningToken; Java_org_mozilla_jss_pkcs11_PK11Cert_getPublicKey; Java_org_mozilla_jss_pkcs11_PK11Cert_getSerialNumberByteArray; Java_org_mozilla_jss_pkcs11_PK11Cert_getSubjectDNString; Java_org_mozilla_jss_pkcs11_PK11Cert_getTrust; Java_org_mozilla_jss_pkcs11_PK11Cert_getUniqueID; Java_org_mozilla_jss_pkcs11_PK11Cert_getVersion; Java_org_mozilla_jss_pkcs11_PK11Cert_setTrust; Java_org_mozilla_jss_pkcs11_PK11Cipher_finalizeContext; Java_org_mozilla_jss_pkcs11_PK11Cipher_initContext; Java_org_mozilla_jss_pkcs11_PK11Cipher_updateContext; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapPrivWithSym; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymWithPriv; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymWithSym; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapPrivWithSym; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapSymWithPub; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapSymWithSym; Java_org_mozilla_jss_pkcs11_PK11MessageDigest_digest; Java_org_mozilla_jss_pkcs11_PK11MessageDigest_initDigest; Java_org_mozilla_jss_pkcs11_PK11MessageDigest_initHMAC; Java_org_mozilla_jss_pkcs11_PK11MessageDigest_update; Java_org_mozilla_jss_pkcs11_PK11PrivKey_getKeyType; Java_org_mozilla_jss_pkcs11_PK11PrivKey_getOwningToken; Java_org_mozilla_jss_pkcs11_PK11PrivKey_getStrength; Java_org_mozilla_jss_pkcs11_PK11PrivKey_getUniqueID; Java_org_mozilla_jss_pkcs11_PK11PrivKey_verifyKeyIsOnToken; Java_org_mozilla_jss_pkcs11_PK11PubKey_DSAFromRaw; Java_org_mozilla_jss_pkcs11_PK11PubKey_RSAFromRaw; Java_org_mozilla_jss_pkcs11_PK11PubKey_getEncoded; Java_org_mozilla_jss_pkcs11_PK11PubKey_getKeyType; Java_org_mozilla_jss_pkcs11_PK11PubKey_verifyKeyIsOnToken; Java_org_mozilla_jss_pkcs11_PK11SymKey_getKeyData; Java_org_mozilla_jss_pkcs11_PK11SymKey_getKeyType; Java_org_mozilla_jss_pkcs11_PK11SymKey_getOwningToken; Java_org_mozilla_jss_pkcs11_PK11SymKey_getStrength; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPair; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPair; Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generateNormal; Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE; Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE_1IV; Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_nativeClone; Java_org_mozilla_jss_pkcs11_PrivateKeyProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PublicKeyProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_SymKeyProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PK11Token_PWInitable; Java_org_mozilla_jss_pkcs11_PK11Token_SSOPasswordIsCorrect; Java_org_mozilla_jss_pkcs11_PK11Token_changePassword; Java_org_mozilla_jss_pkcs11_PK11Token_doesAlgorithm; Java_org_mozilla_jss_pkcs11_PK11Token_generatePK10; Java_org_mozilla_jss_pkcs11_PK11Token_getLoginMode; Java_org_mozilla_jss_pkcs11_PK11Token_getLoginTimeoutMinutes; Java_org_mozilla_jss_pkcs11_PK11Token_getName; Java_org_mozilla_jss_pkcs11_PK11Token_initPassword; Java_org_mozilla_jss_pkcs11_PK11Token_isLoggedIn; Java_org_mozilla_jss_pkcs11_PK11Token_isPresent; Java_org_mozilla_jss_pkcs11_PK11Token_isWritable; Java_org_mozilla_jss_pkcs11_PK11Token_logout; Java_org_mozilla_jss_pkcs11_PK11Token_nativeLogin; Java_org_mozilla_jss_pkcs11_PK11Token_passwordIsInitialized; Java_org_mozilla_jss_pkcs11_PK11Token_setLoginMode; Java_org_mozilla_jss_pkcs11_PK11Token_setLoginTimeoutMinutes; Java_org_mozilla_jss_pkcs11_PK11Token_userPasswordIsCorrect; Java_org_mozilla_jss_pkcs11_TokenProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PK11Signature_engineRawSignNative; Java_org_mozilla_jss_pkcs11_PK11Signature_engineRawVerifyNative; Java_org_mozilla_jss_pkcs11_PK11Signature_engineSignNative; Java_org_mozilla_jss_pkcs11_PK11Signature_engineUpdateNative; Java_org_mozilla_jss_pkcs11_PK11Signature_engineVerifyNative; Java_org_mozilla_jss_pkcs11_PK11Signature_initSigContext; Java_org_mozilla_jss_pkcs11_PK11Signature_initVfyContext; Java_org_mozilla_jss_pkcs11_PK11Store_deleteCert; Java_org_mozilla_jss_pkcs11_PK11Store_deletePrivateKey; Java_org_mozilla_jss_pkcs11_PK11Store_importPrivateKey; Java_org_mozilla_jss_pkcs11_PK11Store_putCertsInVector; Java_org_mozilla_jss_pkcs11_PK11Store_putKeysInVector; Java_org_mozilla_jss_pkcs11_PK11Store_putSymKeysInVector; Java_org_mozilla_jss_pkcs11_PK11Store_putSymKeysInVector; Java_org_mozilla_jss_pkcs11_SigContextProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PK11RSAPublicKey_getModulusByteArray; Java_org_mozilla_jss_pkcs11_PK11RSAPublicKey_getPublicExponentByteArray; Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getGByteArray; Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getPByteArray; Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getQByteArray; Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getYByteArray; Java_org_mozilla_jss_pkcs11_PK11SecureRandom_nextBytes; Java_org_mozilla_jss_pkcs11_PK11SecureRandom_setSeed; Java_org_mozilla_jss_ssl_SSLServerSocket_clearSessionCache; Java_org_mozilla_jss_ssl_SSLServerSocket_configServerSessionIDCache; Java_org_mozilla_jss_ssl_SSLServerSocket_setServerCertNickname; Java_org_mozilla_jss_ssl_SSLServerSocket_socketAccept; Java_org_mozilla_jss_ssl_SSLServerSocket_socketListen; Java_org_mozilla_jss_ssl_SSLSocket_forceHandshake; Java_org_mozilla_jss_ssl_SSLSocket_getKeepAlive; Java_org_mozilla_jss_ssl_SSLSocket_getLocalAddressNative; Java_org_mozilla_jss_ssl_SocketBase_getLocalAddressByteArrayNative; Java_org_mozilla_jss_ssl_SSLSocket_getPort; Java_org_mozilla_jss_ssl_SSLSocket_getReceiveBufferSize; Java_org_mozilla_jss_ssl_SSLSocket_getSendBufferSize; Java_org_mozilla_jss_ssl_SSLSocket_getSoLinger; Java_org_mozilla_jss_ssl_SSLSocket_getStatus; Java_org_mozilla_jss_ssl_SSLSocket_getTcpNoDelay; Java_org_mozilla_jss_ssl_SSLSocket_invalidateSession; Java_org_mozilla_jss_ssl_SSLSocket_redoHandshake; Java_org_mozilla_jss_ssl_SSLSocket_resetHandshakeNative; Java_org_mozilla_jss_ssl_SSLSocket_setCipherPolicyNative; Java_org_mozilla_jss_ssl_SSLSocket_setCipherPreference; Java_org_mozilla_jss_ssl_SSLSocket_setKeepAlive; Java_org_mozilla_jss_ssl_SSLSocket_setReceiveBufferSize; Java_org_mozilla_jss_ssl_SSLSocket_setSSLDefaultOption; Java_org_mozilla_jss_ssl_SSLSocket_setSendBufferSize; Java_org_mozilla_jss_ssl_SSLSocket_setSoLinger; Java_org_mozilla_jss_ssl_SSLSocket_setTcpNoDelay; Java_org_mozilla_jss_ssl_SSLSocket_shutdownNative; Java_org_mozilla_jss_ssl_SSLSocket_socketAvailable; Java_org_mozilla_jss_ssl_SSLSocket_socketConnect; Java_org_mozilla_jss_ssl_SSLSocket_socketRead; Java_org_mozilla_jss_ssl_SSLSocket_socketWrite; Java_org_mozilla_jss_ssl_SocketBase_getLocalPortNative; Java_org_mozilla_jss_ssl_SocketBase_getPeerAddressNative; Java_org_mozilla_jss_ssl_SocketBase_getPeerAddressByteArrayNative; Java_org_mozilla_jss_ssl_SocketBase_setClientCertNicknameNative; Java_org_mozilla_jss_ssl_SocketBase_requestClientAuthNoExpiryCheckNative; Java_org_mozilla_jss_ssl_SocketBase_setSSLOption; Java_org_mozilla_jss_ssl_SocketBase_socketBind; Java_org_mozilla_jss_ssl_SocketBase_socketClose; Java_org_mozilla_jss_ssl_SocketBase_socketCreate; Java_org_mozilla_jss_util_Password_readPasswordFromConsole; # # Data objects (NONE) # # # commands (NONE) # # local: *; }; JSS_3.1 { # JSS 3.1 release global: Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymPlaintext; Java_org_mozilla_jss_pkcs11_PK11Store_getEncryptedPrivateKeyInfo; local: *; }; JSS_3.1.1 { # JSS 3.1.1 release global: Java_org_mozilla_jss_ssl_SSLServerSocket_setReuseAddress; Java_org_mozilla_jss_ssl_SSLServerSocket_getReuseAddress; local: *; }; JSS_3.2 { # JSS 3.2 release global: Java_org_mozilla_jss_crypto_SecretDecoderRing_encrypt; Java_org_mozilla_jss_crypto_SecretDecoderRing_decrypt; Java_org_mozilla_jss_pkcs11_PK11PrivKey_fromPrivateKeyInfo; Java_org_mozilla_jss_pkcs11_PK11PubKey_fromRawNative; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getRawAliases; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineDeleteEntry; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getDERCert; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getCertNickname; Java_org_mozilla_jss_pkcs11_PK11PubKey_fromSPKI; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineGetKey; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineIsCertificateEntry; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineSetKeyEntryNative; Java_org_mozilla_jss_CryptoManager_initializeAllNative2; Java_org_mozilla_jss_ssl_SocketBase_getLocalAddressNative; Java_org_mozilla_jss_pkcs11_PK11PrivKey_getDSAParamsNative; Java_org_mozilla_jss_CryptoManager_verifyCertNowNative; Java_org_mozilla_jss_ssl_SSLServerSocket_setServerCert; Java_org_mozilla_jss_ssl_SocketBase_setClientCert; Java_org_mozilla_jss_CryptoManager_verifyCertTempNative; Java_org_mozilla_jss_ssl_SocketProxy_releaseNativeResources; local: *; }; JSS_3.3 { # JSS 3.3 release global: Java_org_mozilla_jss_ssl_SSLSocket_getImplementedCipherSuites; Java_org_mozilla_jss_ssl_SSLSocket_getCipherPreferenceDefault; Java_org_mozilla_jss_ssl_SSLSocket_setCipherPreferenceDefault; Java_org_mozilla_jss_ssl_SSLSocket_getCipherPreference; Java_org_mozilla_jss_CryptoManager_configureOCSPNative; Java_org_mozilla_jss_pkcs11_PK11SymKey_getLength; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getCertObject; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineGetKeyNative; Java_org_mozilla_jss_SecretDecoderRing_KeyManager_generateKeyNative; Java_org_mozilla_jss_SecretDecoderRing_KeyManager_lookupKeyNative; Java_org_mozilla_jss_SecretDecoderRing_KeyManager_deleteKeyNative; local: *; }; JSS_3.4 { # JSS 3.4 release global: Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits; local: *; }; JSS_3.5 { # JSS 3.5 release global: Java_org_mozilla_jss_SecretDecoderRing_KeyManager_generateUniqueNamedKeyNative; Java_org_mozilla_jss_SecretDecoderRing_KeyManager_lookupUniqueNamedKeyNative; local: *; }; JSS_4.1 { # JSS 4.1 release global: Java_org_mozilla_jss_ssl_SSLSocket_abortReadWrite; Java_org_mozilla_jss_ssl_SSLServerSocket_abortAccept; local: *; }; JSS_4.2 { # JSS 4.2 release global: Java_org_mozilla_jss_ssl_SocketBase_getSSLOption; Java_org_mozilla_jss_ssl_SSLSocket_getSSLDefaultOption; Java_org_mozilla_jss_pkcs11_PK11Store_deleteCertOnly; local: *; }; JSS_4.2.3 { # JSS 4.2.3 release global: Java_org_mozilla_jss_pkcs11_PK11ECPublicKey_getCurveByteArray; Java_org_mozilla_jss_pkcs11_PK11ECPublicKey_getWByteArray; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPair; local: *; }; JSS_4.2.5 { # JSS 4.2.5 release global: Java_org_mozilla_jss_ssl_SSLSocket_setSSLDefaultOptionMode; Java_org_mozilla_jss_ssl_SocketBase_setSSLOptionMode; Java_org_mozilla_jss_ssl_SSLSocket_isFipsCipherSuiteNative; local: *; }; JSS_4.3 { # JSS 4.3 release global: Java_org_mozilla_jss_pkcs11_PK11Token_needsLogin; local: *; }; JSS_4.2.6 { # JSS 4.2.6 release global: Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPairWithOpFlags; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPairWithOpFlags; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPairWithOpFlags; Java_org_mozilla_jss_CryptoManager_OCSPCacheSettingsNative; Java_org_mozilla_jss_CryptoManager_setOCSPTimeoutNative; Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative; Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2; Java_org_mozilla_jss_CryptoManager_verifyCertificateNowCUNative; Java_org_mozilla_jss_asn1_ASN1Util_getTagDescriptionByOid; Java_org_mozilla_jss_ssl_SocketBase_setSSLVersionRange; Java_org_mozilla_jss_ssl_SSLSocket_setSSLVersionRangeDefault; Java_org_mozilla_jss_pkcs11_PK11SymmetricKeyDeriver_nativeDeriveSymKey; Java_org_mozilla_jss_pkcs11_PK11SymKey_setNickNameNative; local: *; }; JSS_4.3.1 { # JSS 4.3.1 release global: Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPairWithOpFlags; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPairWithOpFlags; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPairWithOpFlags; Java_org_mozilla_jss_CryptoManager_OCSPCacheSettingsNative; Java_org_mozilla_jss_CryptoManager_setOCSPTimeoutNative; Java_org_mozilla_jss_pkcs11_PK11SymmetricKeyDeriver_nativeDeriveSymKey; Java_org_mozilla_jss_pkcs11_PK11SymKey_setNickNameNative; local: *; }; JSS_4.4.1 { # JSS 4.4.1 release global: Java_org_mozilla_jss_pkcs11_PK11Store_importEncryptedPrivateKeyInfo; local: *; }; JSS_4.5 { # JSS 4.5 release global: Java_org_mozilla_jss_pkcs11_PK11RSAPrivateKey_getModulusByteArray; Java_org_mozilla_jss_pkcs11_PK11Token_importPublicKey; Java_org_mozilla_jss_pkcs11_PK11Store_loadPrivateKeys; Java_org_mozilla_jss_pkcs11_PK11Store_loadPublicKeys; Java_org_mozilla_jss_pkcs11_PK11Store_deletePublicKey; Java_org_mozilla_jss_ssl_SSLSocket_boundSSLVersionRange; local: *; }; JSS_4.5.1 { global: Java_org_mozilla_jss_CryptoManager_getJSSMajorVersion; Java_org_mozilla_jss_CryptoManager_getJSSMinorVersion; Java_org_mozilla_jss_CryptoManager_getJSSPatchVersion; local: *; }; JSS_4.5.3 { global: Java_org_mozilla_jss_nss_PR_Open; Java_org_mozilla_jss_nss_PR_Close; Java_org_mozilla_jss_nss_PR_Write; Java_org_mozilla_jss_nss_PR_Read; Java_org_mozilla_jss_nss_PR_Send; Java_org_mozilla_jss_nss_PR_Recv; Java_org_mozilla_jss_nss_PR_NewTCPSocket; Java_org_mozilla_jss_nss_PR_NewBufferPRFD; Java_org_mozilla_jss_nss_PR_Shutdown; Java_org_mozilla_jss_nss_PR_GetError; Java_org_mozilla_jss_nss_PR_GetErrorTextNative; Java_org_mozilla_jss_nss_PR_ErrorToNameNative; Java_org_mozilla_jss_nss_PR_getPRShutdownRcv; Java_org_mozilla_jss_nss_PR_getPRShutdownSend; Java_org_mozilla_jss_nss_PR_getPRShutdownBoth; Java_org_mozilla_jss_nss_PR_getPRSuccess; Java_org_mozilla_jss_nss_PR_getPRFailure; Java_org_mozilla_jss_nss_PRErrors_getWouldBlockError; Java_org_mozilla_jss_nss_SSL_ImportFD; Java_org_mozilla_jss_nss_SSL_OptionSet; Java_org_mozilla_jss_nss_SSL_OptionGet; Java_org_mozilla_jss_nss_SSL_SetURL; Java_org_mozilla_jss_nss_SSL_CipherPrefSet; Java_org_mozilla_jss_nss_SSL_CipherPrefGet; Java_org_mozilla_jss_nss_SSL_VersionRangeSetNative; Java_org_mozilla_jss_nss_SSL_VersionRangeGet; Java_org_mozilla_jss_nss_SSL_SecurityStatus; Java_org_mozilla_jss_nss_SSL_ResetHandshake; Java_org_mozilla_jss_nss_SSL_ForceHandshake; Java_org_mozilla_jss_nss_SSL_ConfigSecureServer; Java_org_mozilla_jss_nss_SSL_ConfigServerCert; Java_org_mozilla_jss_nss_SSL_ConfigServerSessionIDCache; Java_org_mozilla_jss_nss_SSL_PeerCertificate; Java_org_mozilla_jss_nss_SSL_PeerCertificateChain; Java_org_mozilla_jss_nss_SSL_getSSLRequestCertificate; Java_org_mozilla_jss_nss_SSL_getSSLRequireCertificate; Java_org_mozilla_jss_nss_SSL_getSSLSECSuccess; Java_org_mozilla_jss_nss_SSL_getSSLSECFailure; Java_org_mozilla_jss_nss_SSL_getSSLSECWouldBlock; Java_org_mozilla_jss_nss_Buffer_Create; Java_org_mozilla_jss_nss_Buffer_Capacity; Java_org_mozilla_jss_nss_Buffer_CanRead; Java_org_mozilla_jss_nss_Buffer_ReadCapacity; Java_org_mozilla_jss_nss_Buffer_CanWrite; Java_org_mozilla_jss_nss_Buffer_WriteCapacity; Java_org_mozilla_jss_nss_Buffer_Read; Java_org_mozilla_jss_nss_Buffer_Write; Java_org_mozilla_jss_nss_Buffer_Get; Java_org_mozilla_jss_nss_Buffer_Put; Java_org_mozilla_jss_nss_Buffer_Free; local: *; }; JSS_4.6.2 { global: Java_org_mozilla_jss_pkcs11_PK11PrivKey_getPublicKey; Java_org_mozilla_jss_CryptoManager_importDERCertNative; Java_org_mozilla_jss_nss_SSL_AttachClientCertCallback; Java_org_mozilla_jss_CryptoManager_getJSSDebug; Java_org_mozilla_jss_util_GlobalRefProxy_releaseNativeResources; Java_org_mozilla_jss_nss_SSL_EnableAlertLoggingNative; local: *; }; JSS_4.6.3 { global: Java_org_mozilla_jss_pkcs11_attrs_CKAClass_acquireNativeResources; Java_org_mozilla_jss_pkcs11_attrs_CKAClass_releaseNativeResources; Java_org_mozilla_jss_pkcs11_attrs_CKAKeyType_acquireNativeResources; Java_org_mozilla_jss_pkcs11_attrs_CKAKeyType_releaseNativeResources; Java_org_mozilla_jss_pkcs11_attrs_CKAUsage_acquireNativeResources; Java_org_mozilla_jss_pkcs11_attrs_CKAUsage_releaseNativeResources; Java_org_mozilla_jss_pkcs11_attrs_CKAValueLen_acquireNativeResources; Java_org_mozilla_jss_pkcs11_attrs_CKAValueLen_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generateKBKDF; Java_org_mozilla_jss_crypto_KBKDFByteArrayParam_acquireNativeResourcesInternal; Java_org_mozilla_jss_crypto_KBKDFByteArrayParam_releaseNativeResourcesInternal; Java_org_mozilla_jss_crypto_KBKDFCounterParams_acquireNativeResourcesInternal; Java_org_mozilla_jss_crypto_KBKDFCounterParams_releaseNativeResourcesInternal; Java_org_mozilla_jss_crypto_KBKDFDerivedKey_acquireNativeResourcesInternal; Java_org_mozilla_jss_crypto_KBKDFDerivedKey_getKeyFromHandle; Java_org_mozilla_jss_crypto_KBKDFDerivedKey_releaseNativeResourcesInternal; Java_org_mozilla_jss_crypto_KBKDFDKMLengthParam_acquireNativeResources; Java_org_mozilla_jss_crypto_KBKDFDKMLengthParam_releaseNativeResources; Java_org_mozilla_jss_crypto_KBKDFFeedbackParams_acquireNativeResourcesInternal; Java_org_mozilla_jss_crypto_KBKDFFeedbackParams_releaseNativeResourcesInternal; Java_org_mozilla_jss_crypto_KBKDFIterationVariableParam_acquireNativeResources; Java_org_mozilla_jss_crypto_KBKDFIterationVariableParam_releaseNativeResources; Java_org_mozilla_jss_crypto_KBKDFOptionalCounterParam_acquireNativeResources; Java_org_mozilla_jss_crypto_KBKDFOptionalCounterParam_releaseNativeResources; Java_org_mozilla_jss_crypto_KBKDFPipelineParams_acquireNativeResourcesInternal; Java_org_mozilla_jss_crypto_KBKDFPipelineParams_releaseNativeResourcesInternal; Java_org_mozilla_jss_crypto_Policy_getRSAMinimumKeySize; Java_org_mozilla_jss_crypto_Policy_getDHMinimumKeySize; Java_org_mozilla_jss_crypto_Policy_getDSAMinimumKeySize; Java_org_mozilla_jss_nss_SSL_ConfigJSSDefaultCertAuthCallback; Java_org_mozilla_jss_ssl_SSLCipher_checkSupportedStatus; Java_org_mozilla_jss_nss_PRErrors_getSocketShutdownError; local: *; }; jss-4.6.3/org/000077500000000000000000000000001362106420000131045ustar00rootroot00000000000000jss-4.6.3/org/mozilla/000077500000000000000000000000001362106420000145535ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/000077500000000000000000000000001362106420000153525ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/CRLImportException.java000066400000000000000000000014261362106420000217120ustar00rootroot00000000000000/* 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; /** * Thrown if a CRL cannot be imported */ public class CRLImportException extends java.lang.Exception { private static final long serialVersionUID = 1L; public CRLImportException() {} public CRLImportException(String mesg) { super(mesg); } public CRLImportException(String mesg, Throwable cause) { super(mesg, cause); } public CRLImportException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/CertDatabaseException.java000066400000000000000000000015621362106420000224220ustar00rootroot00000000000000/* 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; /** * This exception is thrown if the certificate database does not exist, * or if an error occurs while opening it. */ public class CertDatabaseException extends java.lang.Exception { private static final long serialVersionUID = 1L; public CertDatabaseException() {} public CertDatabaseException(String mesg) { super(mesg); } public CertDatabaseException(String mesg, Throwable cause) { super(mesg, cause); } public CertDatabaseException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/CertificateUsage.java000066400000000000000000000122351362106420000214270ustar00rootroot00000000000000/* 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; import java.util.ArrayList; import java.util.Iterator; /** * CertificateUsage options for validation */ public final class CertificateUsage { private int usage; private int value; private String name; // certificateUsage, these must be kept in sync with nss/lib/certdb/certt.h private static final int certificateUsageCheckAllUsages = 0x0000; private static final int certificateUsageSSLClient = 0x0001; private static final int certificateUsageSSLServer = 0x0002; private static final int certificateUsageSSLServerWithStepUp = 0x0004; private static final int certificateUsageSSLCA = 0x0008; private static final int certificateUsageEmailSigner = 0x0010; private static final int certificateUsageEmailRecipient = 0x0020; private static final int certificateUsageObjectSigner = 0x0040; private static final int certificateUsageUserCertImport = 0x0080; private static final int certificateUsageVerifyCA = 0x0100; private static final int certificateUsageProtectedObjectSigner = 0x0200; private static final int certificateUsageStatusResponder = 0x0400; private static final int certificateUsageAnyCA = 0x0800; private static final int certificateUsageIPsec = 0x1000; // SECCertUsage enum values private static final int certUsageSSLClient = 0; private static final int certUsageSSLServer = 1; private static final int certUsageSSLServerWithStepUp = 2; private static final int certUsageSSLCA = 3; private static final int certUsageEmailSigner = 4; private static final int certUsageEmailRecipient = 5; private static final int certUsageObjectSigner = 6; private static final int certUsageUserCertImport = 7; private static final int certUsageVerifyCA = 8; private static final int certUsageProtectedObjectSigner = 9; private static final int certUsageStatusResponder = 10; private static final int certUsageAnyCA = 11; private static final int certUsageIPsec = 12; static private ArrayList list = new ArrayList<>(); private CertificateUsage() { } private CertificateUsage(int usage, int value, String name) { this.usage = usage; this.value = value; this.name = name; list.add(this); } public int getUsage() { return usage; } static public Iterator getCertificateUsages() { return list.iterator(); } public String toString() { return name; } public int getEnumValue() { return value; } public static final CertificateUsage CheckAllUsages = new CertificateUsage(certificateUsageCheckAllUsages, -1, "CheckAllUsages"); public static final CertificateUsage SSLClient = new CertificateUsage(certificateUsageSSLClient, certUsageSSLClient, "SSLClient"); public static final CertificateUsage SSLServer = new CertificateUsage(certificateUsageSSLServer, certUsageSSLServer, "SSLServer"); public static final CertificateUsage SSLServerWithStepUp = new CertificateUsage(certificateUsageSSLServerWithStepUp, certUsageSSLServerWithStepUp, "SSLServerWithStepUp"); public static final CertificateUsage SSLCA = new CertificateUsage(certificateUsageSSLCA, certUsageSSLCA, "SSLCA"); public static final CertificateUsage EmailSigner = new CertificateUsage(certificateUsageEmailSigner, certUsageEmailSigner, "EmailSigner"); public static final CertificateUsage EmailRecipient = new CertificateUsage(certificateUsageEmailRecipient, certUsageEmailRecipient, "EmailRecipient"); public static final CertificateUsage ObjectSigner = new CertificateUsage(certificateUsageObjectSigner, certUsageObjectSigner, "ObjectSigner"); public static final CertificateUsage UserCertImport = new CertificateUsage(certificateUsageUserCertImport, certUsageUserCertImport, "UserCertImport"); public static final CertificateUsage VerifyCA = new CertificateUsage(certificateUsageVerifyCA, certUsageVerifyCA, "VerifyCA"); public static final CertificateUsage ProtectedObjectSigner = new CertificateUsage(certificateUsageProtectedObjectSigner, certUsageProtectedObjectSigner, "ProtectedObjectSigner"); public static final CertificateUsage StatusResponder = new CertificateUsage(certificateUsageStatusResponder, certUsageStatusResponder, "StatusResponder"); public static final CertificateUsage AnyCA = new CertificateUsage(certificateUsageAnyCA, certUsageAnyCA, "AnyCA"); public static final CertificateUsage IPsec = new CertificateUsage(certificateUsageIPsec, certUsageIPsec, "IPsec"); /* The folllowing usages cannot be verified: certUsageAnyCA certUsageProtectedObjectSigner certUsageUserCertImport certUsageVerifyCA */ public static final int basicCertificateUsages = /*0x0b80;*/ certificateUsageUserCertImport | certificateUsageVerifyCA | certificateUsageProtectedObjectSigner | certificateUsageAnyCA ; } jss-4.6.3/org/mozilla/jss/CryptoManager.c000066400000000000000000000752001362106420000202750ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_CryptoManager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pk11util.h" #if defined(AIX) || defined(HPUX) #include #endif /** These externs are only here to ** keep certain compilers from optimizing the ** version info away. */ #include "util/jssver.h" extern const char __jss_base_rcsid[]; extern const char __jss_base_sccsid[]; const char * jss_rcsid() { return __jss_base_rcsid; } const char * jss_sccsid() { return __jss_base_sccsid; } /********************************************************************/ /* The VERSION Strings should be updated everytime a new release */ /* of JSS is generated. Note that this is done by changing */ /* cmake/JSSConfig.cmake. */ /********************************************************************/ /* JSS_VERSION from mozilla/security/jss/org/mozilla/jss/util/jssver.h */ static const char* VARIABLE_MAY_NOT_BE_USED DLL_JSS_VERSION = "JSS_VERSION = " JSS_VERSION; /* NSS_VERSION from mozilla/security/nss/lib/nss/nss.h */ static const char* VARIABLE_MAY_NOT_BE_USED DLL_NSS_VERSION = "NSS_VERSION = " NSS_VERSION; /* NSPR_version from mozilla/nsprpub/pr/include/prinit.h */ static const char* VARIABLE_MAY_NOT_BE_USED DLL_NSPR_VERSION = "NSPR_VERSION = " PR_VERSION; static jobject makePWCBInfo(JNIEnv *env, PK11SlotInfo *slot); static char* getPWFromCallback(PK11SlotInfo *slot, PRBool retry, void *arg); /************************************************************* * AIX and HP signal handling madness * * In order for the JVM, kernel, and NSPR to work together, we setup * a signal handler for SIGCHLD that does nothing. This is only done * on AIX and HP. *************************************************************/ #if defined(AIX) || defined(HPUX) static PRStatus handleSigChild(JNIEnv *env) { struct sigaction action; sigset_t signalset; int result; sigemptyset(&signalset); action.sa_handler = SIG_DFL; action.sa_mask = signalset; action.sa_flags = 0; result = sigaction( SIGCHLD, &action, NULL ); if( result != 0 ) { JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "Failed to set SIGCHLD handler"); return PR_FAILURE; } return PR_SUCCESS; } #endif int ConfigureOCSP( JNIEnv *env, jboolean ocspCheckingEnabled, jstring ocspResponderURL, jstring ocspResponderCertNickname ) { const char *ocspResponderURL_string = NULL; const char *ocspResponderCertNickname_string = NULL; SECStatus status; int result = SECSuccess; CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); /* if caller specified default responder, get the * strings associated with these args */ ocspResponderURL_string = JSS_RefJString(env, ocspResponderURL); ocspResponderCertNickname_string = JSS_RefJString(env, ocspResponderCertNickname); /* first disable OCSP - we'll enable it later */ CERT_DisableOCSPChecking(certdb); /* if they set the default responder, then set it up * and enable it */ if (ocspResponderURL_string) { /* if ocspResponderURL is set they must specify the ocspResponderCertNickname */ if (ocspResponderCertNickname == NULL ) { JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "if OCSP responderURL is set, the Responder Cert nickname must be set"); result = SECFailure; goto finish; } else { CERTCertificate *cert; /* if the nickname is set */ cert = CERT_FindCertByNickname(certdb, ocspResponderCertNickname_string); if (cert == NULL) { /* * look for the cert on an external token. */ cert = PK11_FindCertFromNickname(ocspResponderCertNickname_string, NULL); } if (cert == NULL) { JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "Unable to find the OCSP Responder Certificate nickname."); result = SECFailure; goto finish; } CERT_DestroyCertificate(cert); } status = CERT_SetOCSPDefaultResponder( certdb, ocspResponderURL_string, ocspResponderCertNickname_string ); if (status == SECFailure) { /* deal with error */ JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "OCSP Could not set responder"); result = SECFailure; goto finish; } CERT_EnableOCSPDefaultResponder(certdb); } else if (ocspResponderURL == NULL) { /* if no defaultresponder is set, disable it */ CERT_DisableOCSPDefaultResponder(certdb); } /* enable OCSP checking if requested */ if (ocspCheckingEnabled) { CERT_EnableOCSPChecking(certdb); } finish: JSS_DerefJString(env, ocspResponderURL, ocspResponderURL_string); JSS_DerefJString(env, ocspResponderCertNickname, ocspResponderCertNickname_string); return result; } /********************************************************************** * This is the PasswordCallback object that will be used to login * to tokens implicitly. */ static jobject globalPasswordCallback = NULL; /********************************************************************** * The Java virtual machine can be used to retrieve the JNI environment * pointer from callback functions. */ JavaVM * JSS_javaVM = NULL; JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_initializeAllNative (JNIEnv *env, jclass clazz, jstring configDir, jstring certPrefix, jstring keyPrefix, jstring secmodName, jboolean readOnly, jstring manuString, jstring libraryString, jstring tokString, jstring keyTokString, jstring slotString, jstring keySlotString, jstring fipsString, jstring fipsKeyString, jboolean ocspCheckingEnabled, jstring ocspResponderURL, jstring ocspResponderCertNickname, jboolean initializeJavaOnly, jboolean PKIXVerify, jboolean noCertDB, jboolean noModDB, jboolean forceOpen, jboolean noRootInit, jboolean optimizeSpace, jboolean PK11ThreadSafe, jboolean PK11Reload, jboolean noPK11Finalize, jboolean cooperate) { Java_org_mozilla_jss_CryptoManager_initializeAllNative2( env, clazz, configDir, certPrefix, keyPrefix, secmodName, readOnly, manuString, libraryString, tokString, keyTokString, slotString, keySlotString, fipsString, fipsKeyString, ocspCheckingEnabled, ocspResponderURL, ocspResponderCertNickname, JNI_FALSE, /*initializeJavaOnly*/ PKIXVerify, noCertDB, noModDB, forceOpen, noRootInit, optimizeSpace, PK11ThreadSafe, PK11Reload, noPK11Finalize, cooperate); } JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_initializeAllNative2 (JNIEnv *env, jclass clazz, jstring configDir, jstring certPrefix, jstring keyPrefix, jstring secmodName, jboolean readOnly, jstring manuString, jstring libraryString, jstring tokString, jstring keyTokString, jstring slotString, jstring keySlotString, jstring fipsString, jstring fipsKeyString, jboolean ocspCheckingEnabled, jstring ocspResponderURL, jstring ocspResponderCertNickname, jboolean initializeJavaOnly, jboolean PKIXVerify, jboolean noCertDB, jboolean noModDB, jboolean forceOpen, jboolean noRootInit, jboolean optimizeSpace, jboolean PK11ThreadSafe, jboolean PK11Reload, jboolean noPK11Finalize, jboolean cooperate) { SECStatus rv = SECFailure; const char *szConfigDir = NULL; const char *szCertPrefix = NULL; const char *szKeyPrefix = NULL; const char *szSecmodName = NULL; const char *manuChars = NULL; const char *libraryChars = NULL; const char *tokChars = NULL; const char *keyTokChars = NULL; const char *slotChars = NULL; const char *keySlotChars = NULL; const char *fipsChars = NULL; const char *fipsKeyChars = NULL; PRUint32 initFlags; /* This is thread-safe because initialize is synchronized */ static PRBool initialized=PR_FALSE; if( configDir == NULL || manuString == NULL || libraryString == NULL || tokString == NULL || keyTokString == NULL || slotString == NULL || keySlotString == NULL || fipsString == NULL || fipsKeyString == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } /* Make sure initialize() completes only once */ if(initialized) { JSS_throw(env, ALREADY_INITIALIZED_EXCEPTION); goto finish; } /* * Save the JavaVM pointer so we can retrieve the JNI environment * later. This only works if there is only one Java VM. */ if( (*env)->GetJavaVM(env, &JSS_javaVM) != 0 ) { JSS_trace(env, JSS_TRACE_ERROR, "Unable to to access Java virtual machine"); PR_ASSERT(PR_FALSE); goto finish; } /* * Initialize the errcode translation table. */ JSS_initErrcodeTranslationTable(); /* * The rest of the initialization (the NSS stuff) is skipped if * the initializeJavaOnly flag is set. */ if( initializeJavaOnly) { initialized = PR_TRUE; goto finish; } /* * Set the PKCS #11 strings */ manuChars = JSS_RefJString(env, manuString); libraryChars = JSS_RefJString(env, libraryString); tokChars = JSS_RefJString(env, tokString); keyTokChars = JSS_RefJString(env, keyTokString); slotChars = JSS_RefJString(env, slotString); keySlotChars = JSS_RefJString(env, keySlotString); fipsChars = JSS_RefJString(env, fipsString); fipsKeyChars = JSS_RefJString(env, fipsKeyString); if( (*env)->ExceptionOccurred(env) ) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT( strlen(manuChars) == 33 ); PR_ASSERT( strlen(libraryChars) == 33 ); PR_ASSERT( strlen(tokChars) == 33 ); PR_ASSERT( strlen(keyTokChars) == 33 ); PR_ASSERT( strlen(slotChars) == 65 ); PR_ASSERT( strlen(keySlotChars) == 65 ); PR_ASSERT( strlen(fipsChars) == 65 ); PR_ASSERT( strlen(fipsKeyChars) == 65 ); PK11_ConfigurePKCS11( manuChars, libraryChars, tokChars, keyTokChars, slotChars, keySlotChars, fipsChars, fipsKeyChars, 0, /* minimum pin length */ PR_FALSE /* password required */ ); szConfigDir = JSS_RefJString(env, configDir); if( certPrefix != NULL || keyPrefix != NULL || secmodName != NULL || noCertDB || noModDB || forceOpen || noRootInit || optimizeSpace || PK11ThreadSafe || PK11Reload || noPK11Finalize || cooperate) { /* * Set up arguments to NSS_Initialize */ szCertPrefix = JSS_RefJString(env, certPrefix); szKeyPrefix = JSS_RefJString(env, keyPrefix); szSecmodName = JSS_RefJString(env, secmodName); initFlags = 0; if( readOnly ) { initFlags |= NSS_INIT_READONLY; } if( noCertDB ) { initFlags |= NSS_INIT_NOCERTDB; } if( noModDB ) { initFlags |= NSS_INIT_NOMODDB; } if( forceOpen ) { initFlags |= NSS_INIT_FORCEOPEN; } if( noRootInit ) { initFlags |= NSS_INIT_NOROOTINIT; } if( optimizeSpace ) { initFlags |= NSS_INIT_OPTIMIZESPACE; } if( PK11ThreadSafe ) { initFlags |= NSS_INIT_PK11THREADSAFE; } if( PK11Reload ) { initFlags |= NSS_INIT_PK11RELOAD; } if( noPK11Finalize ) { initFlags |= NSS_INIT_NOPK11FINALIZE; } if( cooperate ) { initFlags |= NSS_INIT_COOPERATE; } /* * Initialize NSS. */ rv = NSS_Initialize(szConfigDir, szCertPrefix, szKeyPrefix, szSecmodName, initFlags); } else { if( readOnly ) { rv = NSS_Init(szConfigDir); } else { rv = NSS_InitReadWrite(szConfigDir); } } if( rv != SECSuccess ) { JSS_throwMsgPrErr(env, SECURITY_EXCEPTION, "Unable to initialize security library"); goto finish; } /* * Set default password callback. This is the only place this * should ever be called if you are using Ninja. */ PK11_SetPasswordFunc(getPWFromCallback); /* * Setup NSS to call the specified OCSP responder */ rv = ConfigureOCSP( env, ocspCheckingEnabled, ocspResponderURL, ocspResponderCertNickname ); if (rv != SECSuccess) { goto finish; } /* * Set up policy. We're always domestic now. Thanks to the US Government! */ if( NSS_SetDomesticPolicy() != SECSuccess ) { JSS_throwMsg(env, SECURITY_EXCEPTION, "Unable to set security policy"); goto finish; } if ( PKIXVerify ) { CERT_SetUsePKIXForValidation(PR_TRUE); } initialized = PR_TRUE; finish: JSS_DerefJString(env, configDir, szConfigDir); JSS_DerefJString(env, certPrefix, szCertPrefix); JSS_DerefJString(env, keyPrefix, szKeyPrefix); JSS_DerefJString(env, secmodName, szSecmodName); JSS_DerefJString(env, manuString, manuChars); JSS_DerefJString(env, libraryString, libraryChars); JSS_DerefJString(env, tokString, tokChars); JSS_DerefJString(env, keyTokString, keyTokChars); JSS_DerefJString(env, slotString, slotChars); JSS_DerefJString(env, keySlotString, keySlotChars); JSS_DerefJString(env, fipsString, fipsChars); JSS_DerefJString(env, fipsKeyString, fipsKeyChars); return; } /********************************************************************** * * JSS_setPasswordCallback * * Sets the global PasswordCallback object, which will be used to * login to tokens implicitly if necessary. * */ void JSS_setPasswordCallback(JNIEnv *env, jobject callback) { PR_ASSERT(env!=NULL && callback!=NULL); /* Free the previously-registered password callback */ if( globalPasswordCallback != NULL ) { (*env)->DeleteGlobalRef(env, globalPasswordCallback); globalPasswordCallback = NULL; } /* Store the new password callback */ globalPasswordCallback = (*env)->NewGlobalRef(env, callback); if(globalPasswordCallback == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); } } /********************************************************************** * * CryptoManager.setNativePasswordCallback * * Sets the global PasswordCallback object, which will be used to * login to tokens implicitly if necessary. * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_setNativePasswordCallback (JNIEnv *env, jclass clazz, jobject callback) { JSS_setPasswordCallback(env, callback); } /******************************************************************** * * g e t P W F r o m C a l l b a c k * * Extracts a password from a password callback and returns * it to PKCS #11. * * INPUTS * slot * The PK11SlotInfo* for the slot we are logging into. * retry * PR_TRUE if this is the first time we are trying to login, * PR_FALSE if we tried before and our password was wrong. * arg * This can contain a Java PasswordCallback object reference, * or NULL to use the default password callback. * RETURNS * The password as extracted from the callback, or NULL if the * callback gives up. */ static char* getPWFromCallback(PK11SlotInfo *slot, PRBool retry, void *arg) { jobject pwcbInfo; jobject pwObject; jbyteArray pwArray=NULL; char* pwchars; char* returnchars=NULL; jclass callbackClass; jclass passwordClass; jmethodID getPWMethod; jmethodID getByteCopyMethod; jmethodID clearMethod; jthrowable exception; jobject callback; JNIEnv *env; PR_ASSERT(slot!=NULL); if(slot==NULL) { return NULL; } /* Get the callback from the arg, or use the default */ PR_ASSERT(sizeof(void*) == sizeof(jobject)); callback = (jobject)arg; if(callback == NULL) { callback = globalPasswordCallback; if(callback == NULL) { /* No global password callback set, no way to get a password */ return NULL; } } /* Get the JNI environment */ if((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != 0){ PR_ASSERT(PR_FALSE); goto finish; } PR_ASSERT(env != NULL); /***************************************** * Construct the JSS_PasswordCallbackInfo *****************************************/ pwcbInfo = makePWCBInfo(env, slot); if(pwcbInfo==NULL) { goto finish; } /***************************************** * Get the callback class and methods *****************************************/ callbackClass = (*env)->GetObjectClass(env, callback); if(callbackClass == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find password " "callback class"); PR_ASSERT(PR_FALSE); } if(retry) { getPWMethod = (*env)->GetMethodID( env, callbackClass, PW_CALLBACK_GET_PW_AGAIN_NAME, PW_CALLBACK_GET_PW_AGAIN_SIG); } else { getPWMethod = (*env)->GetMethodID( env, callbackClass, PW_CALLBACK_GET_PW_FIRST_NAME, PW_CALLBACK_GET_PW_FIRST_SIG); } if(getPWMethod == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find password callback accessor method"); ASSERT_OUTOFMEM(env); goto finish; } /***************************************** * Get the password from the callback *****************************************/ pwObject = (*env)->CallObjectMethod( env, callback, getPWMethod, pwcbInfo); if( (*env)->ExceptionOccurred(env) != NULL) { goto finish; } if( pwObject == NULL ) { JSS_throw(env, GIVE_UP_EXCEPTION); goto finish; } /***************************************** * Get Password class and methods *****************************************/ passwordClass = (*env)->GetObjectClass(env, pwObject); if(passwordClass == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find Password class"); ASSERT_OUTOFMEM(env); goto finish; } getByteCopyMethod = (*env)->GetMethodID( env, passwordClass, PW_GET_BYTE_COPY_NAME, PW_GET_BYTE_COPY_SIG); clearMethod = (*env)->GetMethodID( env, passwordClass, PW_CLEAR_NAME, PW_CLEAR_SIG); if(getByteCopyMethod==NULL || clearMethod==NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find Password manipulation methods from native " "implementation"); ASSERT_OUTOFMEM(env); goto finish; } /************************************************ * Get the bytes from the password, then clear it ***********************************************/ pwArray = (*env)->CallObjectMethod( env, pwObject, getByteCopyMethod); (*env)->CallVoidMethod(env, pwObject, clearMethod); exception = (*env)->ExceptionOccurred(env); if(exception == NULL) { PR_ASSERT(pwArray != NULL); /************************************************************* * Copy the characters out of the byte array, * then erase it *************************************************************/ pwchars = (char*) (*env)->GetByteArrayElements(env, pwArray, NULL); PR_ASSERT(pwchars!=NULL); returnchars = PL_strdup(pwchars); JSS_wipeCharArray(pwchars); JSS_DerefByteArray(env, pwArray, pwchars, 0); } else { returnchars = NULL; } finish: #ifdef DEBUG if( (exception=(*env)->ExceptionOccurred(env)) != NULL) { jclass giveupClass; jmethodID printStackTrace; jclass excepClass; (*env)->ExceptionClear(env); giveupClass = (*env)->FindClass(env, GIVE_UP_EXCEPTION); PR_ASSERT(giveupClass != NULL); if( ! (*env)->IsInstanceOf(env, exception, giveupClass) ) { excepClass = (*env)->GetObjectClass(env, exception); printStackTrace = (*env)->GetMethodID(env, excepClass, "printStackTrace", "()V"); (*env)->CallVoidMethod(env, exception, printStackTrace); PR_ASSERT( PR_FALSE ); } PR_ASSERT(returnchars==NULL); } #else if( ((*env)->ExceptionOccurred(env)) != NULL) { (*env)->ExceptionClear(env); } #endif return returnchars; } /********************************************************************** * * m a k e P W C B I n f o * * Creates a Java PasswordCallbackInfo structure from a PKCS #11 token. * Returns this object, or NULL if an exception was thrown. */ static jobject makePWCBInfo(JNIEnv *env, PK11SlotInfo *slot) { jclass infoClass; jmethodID constructor; jstring name; jobject pwcbInfo=NULL; PR_ASSERT(env!=NULL && slot!=NULL); /***************************************** * Turn the token name into a Java String *****************************************/ name = (*env)->NewStringUTF(env, PK11_GetTokenName(slot)); if(name == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /***************************************** * Look up the class and constructor *****************************************/ infoClass = (*env)->FindClass(env, TOKEN_CBINFO_CLASS_NAME); if(infoClass == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Unable to find TokenCallbackInfo " "class"); ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, infoClass, TOKEN_CBINFO_CONSTRUCTOR_NAME, TOKEN_CBINFO_CONSTRUCTOR_SIG); if(constructor == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Unable to find " "TokenCallbackInfo constructor"); ASSERT_OUTOFMEM(env); goto finish; } /***************************************** * Create the CallbackInfo object *****************************************/ pwcbInfo = (*env)->NewObject(env, infoClass, constructor, name); if(pwcbInfo == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Unable to create TokenCallbackInfo"); ASSERT_OUTOFMEM(env); } finish: return pwcbInfo; } /********************************************************************** * CryptoManager.putModulesInVector * * Wraps all PKCS #11 modules in PK11Module Java objects, then puts * these into a Vector. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_putModulesInVector (JNIEnv *env, jobject this, jobject vector) { SECMODListLock *listLock=NULL; SECMODModuleList *list; SECMODModule *modp=NULL; jclass vectorClass; jmethodID addElement; jobject module; PR_ASSERT(env!=NULL && this!=NULL && vector!=NULL); /*************************************************** * Get JNI ids ***************************************************/ vectorClass = (*env)->GetObjectClass(env, vector); if(vectorClass == NULL) goto finish; addElement = (*env)->GetMethodID(env, vectorClass, VECTOR_ADD_ELEMENT_NAME, VECTOR_ADD_ELEMENT_SIG); if(addElement==NULL) goto finish; /*************************************************** * Lock the list ***************************************************/ listLock = SECMOD_GetDefaultModuleListLock(); PR_ASSERT(listLock!=NULL); SECMOD_GetReadLock(listLock); /*************************************************** * Loop over the modules, adding each one to the vector ***************************************************/ for( list = SECMOD_GetDefaultModuleList(); list != NULL; list=list->next) { PR_ASSERT(list->module != NULL); /** Make a PK11Module **/ modp = SECMOD_ReferenceModule(list->module); module = JSS_PK11_wrapPK11Module(env, &modp); PR_ASSERT(modp==NULL); if(module == NULL) { goto finish; } /** Stick the PK11Module in the Vector **/ (*env)->CallVoidMethod(env, vector, addElement, module); } finish: /*** Unlock the list ***/ if(listLock != NULL) { SECMOD_ReleaseReadLock(listLock); } /*** Free this module if it wasn't properly Java-ized ***/ if(modp!=NULL) { SECMOD_DestroyModule(modp); } return; } /********************************************************************** * CryptoManager.enableFIPS * * Enables or disables FIPS mode. * INPUTS * fips * true means turn on FIPS mode, false means turn it off. * RETURNS * true if a switch happened, false if the library was already * in the requested mode. * THROWS * java.security.GeneralSecurityException if an error occurred with * the PKCS #11 library. */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_CryptoManager_enableFIPS (JNIEnv *env, jclass clazz, jboolean fips) { char *name=NULL; jboolean switched = JNI_FALSE; SECStatus status = SECSuccess; if( ((fips==JNI_TRUE) && !PK11_IsFIPS()) || ((fips==JNI_FALSE) && PK11_IsFIPS()) ) { name = PL_strdup(SECMOD_GetInternalModule()->commonName); status = SECMOD_DeleteInternalModule(name); PR_Free(name); switched = JNI_TRUE; } if(status != SECSuccess) { JSS_throwMsgPortErr(env, GENERAL_SECURITY_EXCEPTION, "Failed to toggle FIPS mode"); } return switched; } /*********************************************************************** * CryptoManager.FIPSEnabled * * Returns true if FIPS mode is currently on, false if it ain't. */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_CryptoManager_FIPSEnabled(JNIEnv *env, jobject this) { if( PK11_IsFIPS() ) { return JNI_TRUE; } else { return JNI_FALSE; } } /*********************************************************************** * DatabaseCloser.closeDatabases * * Closes the cert and key database, rendering the security library * unusable. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_DatabaseCloser_closeDatabases (JNIEnv *env, jobject this) { NSS_Shutdown(); } /********************************************************************** * configureOCSPNative * * Allows configuration of the OCSP responder during runtime. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_configureOCSPNative( JNIEnv *env, jobject this, jboolean ocspCheckingEnabled, jstring ocspResponderURL, jstring ocspResponderCertNickname ) { SECStatus rv = SECFailure; rv = ConfigureOCSP(env,ocspCheckingEnabled, ocspResponderURL, ocspResponderCertNickname); if (rv != SECSuccess) { JSS_throwMsgPrErr(env, GENERAL_SECURITY_EXCEPTION, "Failed to configure OCSP"); } } /********************************************************************** * OCSPCacheSettingsNative * * Allows configuration of the OCSP responder cache during runtime. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_OCSPCacheSettingsNative( JNIEnv *env, jobject this, jint ocsp_cache_size, jint ocsp_min_cache_entry_duration, jint ocsp_max_cache_entry_duration) { SECStatus rv = SECFailure; rv = CERT_OCSPCacheSettings( ocsp_cache_size, ocsp_min_cache_entry_duration, ocsp_max_cache_entry_duration); if (rv != SECSuccess) { JSS_throwMsgPrErrArg(env, GENERAL_SECURITY_EXCEPTION, "Failed to set OCSP cache: error", PORT_GetError()); } } JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_setOCSPTimeoutNative( JNIEnv *env, jobject this, jint ocsp_timeout ) { SECStatus rv = SECFailure; rv = CERT_SetOCSPTimeout(ocsp_timeout); if (rv != SECSuccess) { JSS_throwMsgPrErrArg(env, GENERAL_SECURITY_EXCEPTION, "Failed to set OCSP timeout: error ", PORT_GetError()); } } JNIEXPORT int JNICALL Java_org_mozilla_jss_CryptoManager_getJSSMajorVersion( JNIEnv *env, jobject this) { return JSS_VMAJOR; } JNIEXPORT int JNICALL Java_org_mozilla_jss_CryptoManager_getJSSMinorVersion( JNIEnv * env, jobject this) { return JSS_VMINOR; } JNIEXPORT int JNICALL Java_org_mozilla_jss_CryptoManager_getJSSPatchVersion( JNIEnv *env, jobject this) { return JSS_VPATCH; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_CryptoManager_getJSSDebug(JNIEnv *env, jobject this) { #ifdef DEBUG return JNI_TRUE; #else return JNI_FALSE; #endif } jss-4.6.3/org/mozilla/jss/CryptoManager.java000066400000000000000000001514641362106420000210030ustar00rootroot00000000000000/* 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; import java.security.GeneralSecurityException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.crypto.Algorithm; import org.mozilla.jss.crypto.AlreadyInitializedException; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.InternalCertificate; import org.mozilla.jss.crypto.NoSuchItemOnTokenException; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.TokenSupplier; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.pkcs11.KeyType; import org.mozilla.jss.pkcs11.PK11Cert; import org.mozilla.jss.pkcs11.PK11Module; import org.mozilla.jss.pkcs11.PK11SecureRandom; import org.mozilla.jss.pkcs11.PK11Token; import org.mozilla.jss.provider.java.security.JSSMessageDigestSpi; import org.mozilla.jss.util.Assert; import org.mozilla.jss.util.InvalidNicknameException; import org.mozilla.jss.util.PasswordCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class is the starting poing for the crypto package. * Use it to initialize the subsystem and to lookup certs, keys, and tokens. * Initialization is done with static methods, and must be done before * an instance can be created. All other operations are done with instance * methods. * @version $Revision$ $Date$ */ public final class CryptoManager implements TokenSupplier { public static Logger logger = LoggerFactory.getLogger(CryptoManager.class); static { logger.info("CryptoManager: loading JSS library"); try { System.loadLibrary("jss4"); logger.info("CryptoManager: loaded JSS library from java.library.path"); } catch (UnsatisfiedLinkError e) { try { System.load("/usr/lib64/jss/libjss4.so"); logger.info("CryptoManager: loaded JSS library from /usr/lib64/jss/libjss4.so"); } catch (UnsatisfiedLinkError e1) { System.load("/usr/lib/jss/libjss4.so"); logger.info("CryptoManager: loaded JSS library from /usr/lib/jss/libjss4.so"); } } } /** * note: this is obsolete in NSS * CertUsage options for validation */ public final static class CertUsage { static private ArrayList list = new ArrayList<>(); private int usage; private String name; private CertUsage() { } private CertUsage(int usage, String name) { this.usage = usage; this.name = name; list.add(this); } public int getUsage() { return usage; } static public Iterator getCertUsages() { return list.iterator(); } public String toString() { return name; } // certUsage, these must be kept in sync with nss/lib/certdb/certt.h public static final CertUsage SSLClient = new CertUsage(0, "SSLClient"); public static final CertUsage SSLServer = new CertUsage(1, "SSLServer"); public static final CertUsage SSLServerWithStepUp = new CertUsage(2, "SSLServerWithStepUp"); public static final CertUsage SSLCA = new CertUsage(3, "SSLCA"); public static final CertUsage EmailSigner = new CertUsage(4, "EmailSigner"); public static final CertUsage EmailRecipient = new CertUsage(5, "EmailRecipient"); public static final CertUsage ObjectSigner = new CertUsage(6, "ObjectSigner"); public static final CertUsage UserCertImport = new CertUsage(7, "UserCertImport"); public static final CertUsage VerifyCA = new CertUsage(8, "VerifyCA"); public static final CertUsage ProtectedObjectSigner = new CertUsage(9, "ProtectedObjectSigner"); public static final CertUsage StatusResponder = new CertUsage(10, "StatusResponder"); public static final CertUsage AnyCA = new CertUsage(11, "AnyCA"); } //////////////////////////////////////////////////// // Module and Token Management //////////////////////////////////////////////////// /** * Retrieves the internal cryptographic services token. This is the * token built into NSS that performs bulk * cryptographic operations. *

In FIPS mode, the internal cryptographic services token is the * same as the internal key storage token. * * @return The internal cryptographic services token. */ public synchronized CryptoToken getInternalCryptoToken() { return internalCryptoToken; } /** * Retrieves the internal key storage token. This is the token * provided by NSS to store private keys. * The keys stored in this token are stored in an encrypted key database. *

In FIPS mode, the internal key storage token is the same as * the internal cryptographic services token. * * @return The internal key storage token. */ public synchronized CryptoToken getInternalKeyStorageToken() { return internalKeyStorageToken; } /** * Looks up the CryptoToken with the given name. Searches all * loaded cryptographic modules for the token. * * @param name The name of the token. * @return The token. * @exception org.mozilla.jss.NoSuchTokenException If no token * is found with the given name. */ public synchronized CryptoToken getTokenByName(String name) throws NoSuchTokenException { Enumeration tokens = getAllTokens(); CryptoToken token; while(tokens.hasMoreElements()) { token = tokens.nextElement(); try { if( name.equals(token.getName()) ) { return token; } } catch( TokenException e ) { throw new RuntimeException(e); } } throw new NoSuchTokenException("No such token: " + name); } /** * Retrieves all tokens that support the given algorithm. * * @param alg Algorithm. * @return Enumeration of tokens. */ public synchronized Enumeration getTokensSupportingAlgorithm(Algorithm alg) { Enumeration tokens = getAllTokens(); Vector goodTokens = new Vector<>(); CryptoToken tok; while(tokens.hasMoreElements()) { tok = tokens.nextElement(); if( tok.doesAlgorithm(alg) ) { goodTokens.addElement(tok); } } return goodTokens.elements(); } /** * Retrieves all tokens. This is an enumeration of all tokens on all * modules. * * @return All tokens accessible from JSS. Each item of the enumeration * is a CryptoToken * @see org.mozilla.jss.crypto.CryptoToken */ public synchronized Enumeration getAllTokens() { Enumeration modules = getModules(); Enumeration tokens; Vector allTokens = new Vector<>(); while(modules.hasMoreElements()) { tokens = modules.nextElement().getTokens(); while(tokens.hasMoreElements()) { allTokens.addElement( tokens.nextElement() ); } } return allTokens.elements(); } /** * Retrieves all tokens except those built into NSS. * This excludes the internal token and the internal * key storage token (which are one and the same in FIPS mode). * * @return All tokens accessible from JSS, except for the built-in * internal tokens. */ public synchronized Enumeration getExternalTokens() { Enumeration modules = getModules(); Enumeration tokens; PK11Token token; Vector allTokens = new Vector<>(); while(modules.hasMoreElements()) { tokens = modules.nextElement().getTokens(); while(tokens.hasMoreElements()) { token = (PK11Token) tokens.nextElement(); if( ! token.isInternalCryptoToken() && ! token.isInternalKeyStorageToken() ) { allTokens.addElement( token ); } } } return allTokens.elements(); } /** * Retrieves all installed cryptographic modules. * * @return An enumeration of all installed PKCS #11 modules. Each * item in the enumeration is a PK11Module. * @see org.mozilla.jss.pkcs11.PK11Module */ public synchronized Enumeration getModules() { return moduleVector.elements(); } // Need to reload modules after adding new one //public native addModule(String name, String libraryName); /** * The list of modules. This should be initialized by the constructor * and updated whenever 1) a new module is added, 2) a module is deleted, * or 3) FIPS mode is switched. */ private Vector moduleVector; /** * Re-creates the Vector of modules that is stored by CryptoManager. * This entails going into native code to enumerate all modules, * wrap each one in a PK11Module, and storing the PK11Module in the vector. */ private synchronized void reloadModules() { moduleVector = new Vector<>(); putModulesInVector(moduleVector); // Get the internal tokens Enumeration tokens = getAllTokens(); internalCryptoToken = null; internalKeyStorageToken = null; while(tokens.hasMoreElements()) { PK11Token token = (PK11Token) tokens.nextElement(); if( token.isInternalCryptoToken() ) { assert(internalCryptoToken == null); internalCryptoToken = token; } if( token.isInternalKeyStorageToken() ) { assert(internalKeyStorageToken == null); internalKeyStorageToken = token; } } assert(internalKeyStorageToken != null); assert(internalCryptoToken != null); } /** * The internal cryptographic services token. */ private CryptoToken internalCryptoToken; /** * The internal key storage token. */ private CryptoToken internalKeyStorageToken; /** * Native code to traverse all PKCS #11 modules, wrap each one in * a PK11Module, and insert each PK11Module into the given vector. */ private native void putModulesInVector(Vector vector); /////////////////////////////////////////////////////////////////////// // Constructor and Accessors /////////////////////////////////////////////////////////////////////// /** * Constructor, for internal use only. */ protected CryptoManager() { TokenSupplierManager.setTokenSupplier(this); reloadModules(); } /** * Retrieve the single instance of CryptoManager. * This cannot be called before initialization. * * @see #initialize(InitializationValues) * @exception NotInitializedException If * initialize(InitializationValues has not yet been * called. * @return CryptoManager instance. */ public synchronized static CryptoManager getInstance() throws NotInitializedException { if(instance==null) { throw new NotInitializedException(); } return instance; } /** * The singleton instance, and a static initializer to create it. */ private static CryptoManager instance=null; /////////////////////////////////////////////////////////////////////// // FIPS management /////////////////////////////////////////////////////////////////////// /** * Enables or disables FIPS-140-2 compliant mode. If this returns true, * you must reloadModules(). This should only be called once in a program, * at the beginning, because it invalidates tokens and modules. * * @param fips true to turn FIPS compliant mode on, false to turn it off. */ private static native boolean enableFIPS(boolean fips) throws GeneralSecurityException; /** * Determines whether FIPS-140-2 compliance is active. * * @return true if the security library is in FIPS-140-2 compliant mode. */ public synchronized native boolean FIPSEnabled(); /////////////////////////////////////////////////////////////////////// // Password Callback management /////////////////////////////////////////////////////////////////////// /** * This function sets the global password callback. It is * not thread-safe to change this. *

The callback may be NULL, in which case password callbacks will * fail gracefully. * * @param pwcb Password callback. */ public synchronized void setPasswordCallback(PasswordCallback pwcb) { passwordCallback = pwcb; setNativePasswordCallback( pwcb ); } private native void setNativePasswordCallback(PasswordCallback cb); /** * Returns the currently registered password callback. * * @return Password callback. */ public synchronized PasswordCallback getPasswordCallback() { return passwordCallback; } private PasswordCallback passwordCallback; //////////////////////////////////////////////////// // Initialization //////////////////////////////////////////////////// /** * Initialize the security subsystem. Opens the databases, loads all * PKCS #11 modules, initializes the internal random number generator. * The initialize methods that take arguments should be * called only once, otherwise they will throw * an exception. It is OK to call them after calling * initialize(). * * @param configDir The directory containing the security databases. * @exception org.mozilla.jss.KeyDatabaseException Unable to open * the key database, or it was currupted. * @exception org.mozilla.jss.CertDatabaseException Unable * to open the certificate database, or it was currupted. * @exception AlreadyInitializedException If the security subsystem is already initialized. * @exception GeneralSecurityException If other security error occurred. **/ public static synchronized void initialize( String configDir ) throws KeyDatabaseException, CertDatabaseException, AlreadyInitializedException, GeneralSecurityException { initialize( new InitializationValues(configDir) ); } /** * Initialize the security subsystem. Opens the databases, loads all * PKCS #11 modules, initializes the internal random number generator. * The initialize methods that take arguments should be * called only once, otherwise they will throw * an exception. It is OK to call them after calling * initialize(). * * @param values The options with which to initialize CryptoManager. * @exception org.mozilla.jss.KeyDatabaseException Unable to open * the key database, or it was corrupted. * @exception org.mozilla.jss.CertDatabaseException Unable * to open the certificate database, or it was currupted. * @exception AlreadyInitializedException If security subsystem is already initialized. * @exception GeneralSecurityException If other security error occurred. **/ public static synchronized void initialize( InitializationValues values ) throws KeyDatabaseException, CertDatabaseException, AlreadyInitializedException, GeneralSecurityException { if(instance != null) { throw new AlreadyInitializedException(); } if (values.ocspResponderURL != null) { if (values.ocspResponderCertNickname == null) { throw new GeneralSecurityException( "Must set ocspResponderCertNickname"); } } logger.info("CryptoManager: initializing NSS database at " + values.configDir); initializeAllNative2(values.configDir, values.certPrefix, values.keyPrefix, values.secmodName, values.readOnly, values.getManufacturerID(), values.getLibraryDescription(), values.getInternalTokenDescription(), values.getInternalKeyStorageTokenDescription(), values.getInternalSlotDescription(), values.getInternalKeyStorageSlotDescription(), values.getFIPSSlotDescription(), values.getFIPSKeyStorageSlotDescription(), values.ocspCheckingEnabled, values.ocspResponderURL, values.ocspResponderCertNickname, values.initializeJavaOnly, values.PKIXVerify, values.noCertDB, values.noModDB, values.forceOpen, values.noRootInit, values.optimizeSpace, values.PK11ThreadSafe, values.PK11Reload, values.noPK11Finalize, values.cooperate ); instance = new CryptoManager(); instance.setPasswordCallback(values.passwordCallback); if( values.fipsMode != InitializationValues.FIPSMode.UNCHANGED) { if( enableFIPS(values.fipsMode == InitializationValues.FIPSMode.ENABLED) ) { instance.reloadModules(); } } // Force class load before we install the provider. Otherwise we get // an infinite loop as the Security manager tries to instantiate the // digest to verify its own JAR file. JSSMessageDigestSpi mds = new JSSMessageDigestSpi.SHA1(); logger.debug("Loaded " + mds); // Force the KeyType class to load before we can install JSS as a // provider. JSS's signature provider accesses KeyType. KeyType kt = KeyType.getKeyTypeFromAlgorithm( SignatureAlgorithm.RSASignatureWithSHA1Digest); logger.debug("Loaded " + kt); if( values.installJSSProvider ) { int insert_position = 1; if (!values.installJSSProviderFirst) { insert_position = java.security.Security.getProviders().length + 1; } int position = java.security.Security.insertProviderAt(new JSSProvider(), insert_position); if (position < 0) { logger.warn("JSS provider is already installed"); } // This returns -1 if the provider was already installed, in which // case it is not installed again. Is this // an error? I don't think so, although it might be confusing // if the provider is not in the position they expected. // However, this will only happen if they are installing the // provider themselves, so presumably they know what they're // doing. } if( values.removeSunProvider ) { java.security.Security.removeProvider("SUN"); } } private static native void initializeAllNative2(String configDir, String certPrefix, String keyPrefix, String secmodName, boolean readOnly, String manufacturerID, String libraryDescription, String internalTokenDescription, String internalKeyStorageTokenDescription, String internalSlotDescription, String internalKeyStorageSlotDescription, String fipsSlotDescription, String fipsKeyStorageSlotDescription, boolean ocspCheckingEnabled, String ocspResponderURL, String ocspResponderCertNickname, boolean initializeJavaOnly, boolean PKIXVerify, boolean noCertDB, boolean noModDB, boolean forceOpen, boolean noRootInit, boolean optimizeSpace, boolean PK11ThreadSafe, boolean PK11Reload, boolean noPK11Finalize, boolean cooperate) throws KeyDatabaseException, CertDatabaseException, AlreadyInitializedException; ///////////////////////////////////////////////////////////// // Cert Lookup ///////////////////////////////////////////////////////////// /** * Retrieves all CA certificates in the trust database. This * is a fairly expensive operation in that it involves traversing * the entire certificate database. * @return An array of all CA certificates stored permanently * in the trust database. */ public native X509Certificate[] getCACerts(); /** * Retrieves all certificates in the trust database. This * is a fairly expensive operation in that it involves traversing * the entire certificate database. * @return An array of all certificates stored permanently * in the trust database. */ public native X509Certificate[] getPermCerts(); /** * Imports a chain of certificates. The leaf certificate may be a * a user certificate, that is, a certificate that belongs to the * current user and whose private key is available for use. * If the leaf certificate is a user certificate, it is stored * on the token * that contains the corresponding private key, and is assigned the * given nickname. * * @param certPackage An encoded certificate or certificate chain. * Acceptable * encodings are binary PKCS #7 SignedData objects and * DER-encoded certificates, which may or may not be wrapped * in a Base-64 encoding package surrounded by * "-----BEGIN CERTIFICATE-----" and * "-----END CERTIFICATE-----". * @param nickname The nickname for the user certificate. It must * be unique. It is ignored if there is no user certificate. * @return The leaf certificate from the chain. * @exception CertificateEncodingException If the package encoding * was not recognized. * @exception NicknameConflictException If the leaf certificate * is a user certificate, and another certificate already has the * given nickname. * @exception UserCertConflictException If the leaf certificate * is a user certificate, but it has already been imported. * @exception NoSuchItemOnTokenException If the leaf certificate is * a user certificate, but the matching private key cannot be found. * @exception TokenException If an error occurs importing a leaf * certificate into a token. */ public X509Certificate importCertPackage(byte[] certPackage, String nickname ) throws CertificateEncodingException, NicknameConflictException, UserCertConflictException, NoSuchItemOnTokenException, TokenException { return importCertPackageNative(certPackage, nickname, false, false); } /** * Imports a chain of certificates. The leaf of the chain is a CA * certificate AND a user certificate (this would only be called by * a CA installing its own certificate). * * @param certPackage An encoded certificate or certificate chain. * Acceptable * encodings are binary PKCS #7 SignedData objects and * DER-encoded certificates, which may or may not be wrapped * in a Base-64 encoding package surrounded by * "-----BEGIN CERTIFICATE-----" and * "-----END CERTIFICATE-----". * @param nickname The nickname for the user certificate. It must * be unique. * @return The leaf certificate from the chain. * @exception CertificateEncodingException If the package encoding * was not recognized. * @exception NicknameConflictException If the leaf certificate * another certificate already has the given nickname. * @exception UserCertConflictException If the leaf certificate * has already been imported. * @exception NoSuchItemOnTokenException If the the private key matching * the leaf certificate cannot be found. * @exception TokenException If an error occurs importing the leaf * certificate into a token. */ public X509Certificate importUserCACertPackage(byte[] certPackage, String nickname) throws CertificateEncodingException, NicknameConflictException, UserCertConflictException, NoSuchItemOnTokenException, TokenException { return importCertPackageNative(certPackage, nickname, false, true); } /** * Imports a chain of certificates, none of which is a user certificate. * * @param certPackage An encoded certificate or certificate chain. * Acceptable * encodings are binary PKCS #7 SignedData objects and * DER-encoded certificates, which may or may not be wrapped * in a Base-64 encoding package surrounded by * "-----BEGIN CERTIFICATE-----" and * "-----END CERTIFICATE-----". * @return The leaf certificate from the chain. * @exception CertificateEncodingException If the package encoding * was not recognized. * @exception TokenException If an error occurs importing a leaf * certificate into a token. */ public X509Certificate importCACertPackage(byte[] certPackage) throws CertificateEncodingException, TokenException { try { return importCertPackageNative(certPackage, null, true, false); } catch(NicknameConflictException e) { logger.error("importing CA certs caused nickname conflict", e); throw new RuntimeException("Importing CA certs caused nickname conflict: " + e.getMessage(), e); } catch(UserCertConflictException e) { logger.error("importing CA certs caused user cert conflict", e); throw new RuntimeException("Importing CA certs caused user cert conflict: " + e.getMessage(), e); } catch(NoSuchItemOnTokenException e) { logger.error("importing CA certs caused NoSuchItemOnTokenException", e); throw new RuntimeException("Importing CA certs caused NoSuchItemOnToken"+ "Exception: " + e.getMessage(), e); } } /** * Imports a single certificate into the permanent certificate * database. * * @param cert the certificate you want to add * @param nickname the nickname you want to refer to the certificate as * (must not be null) * @return Certificate object. * @throws TokenException If an error occurred in the token. * @throws InvalidNicknameException If the nickname is invalid. */ public InternalCertificate importCertToPerm(X509Certificate cert, String nickname) throws TokenException, InvalidNicknameException { if (nickname==null) { throw new InvalidNicknameException("Nickname must be non-null"); } else { return importCertToPermNative(cert,nickname); } } /** * Imports a single DER-encoded certificate into the permanent or temporary * certificate database. */ public X509Certificate importDERCert(byte[] cert, CertificateUsage usage, boolean permanent, String nickname) { return importDERCertNative(cert, usage.getEnumValue(), permanent, nickname); } private native X509Certificate importDERCertNative(byte[] cert, int usage, boolean permanent, String nickname); private native InternalCertificate importCertToPermNative(X509Certificate cert, String nickname) throws TokenException; /** * @param noUser true if we know that none of the certs are user certs. * In this case, no attempt will be made to find a matching private * key for the leaf certificate. */ private native X509Certificate importCertPackageNative(byte[] certPackage, String nickname, boolean noUser, boolean leafIsCA) throws CertificateEncodingException, NicknameConflictException, UserCertConflictException, NoSuchItemOnTokenException, TokenException; /*============ CRL importing stuff ********************************/ private static int TYPE_KRL = 0; private static int TYPE_CRL = 1; /** * Imports a CRL, and stores it into the cert7.db * Validate CRL then import it to the dbase. If there is already a CRL with the * same CA in the dbase, it will be replaced if derCRL is more up to date. * * @param crl the DER-encoded CRL. * @param url the URL where this CRL can be retrieved from (for future updates). * [ note that CRLs are not retrieved automatically ]. Can be null * @exception CRLImportException If the package encoding * was not recognized. * @exception TokenException If an error occurred in the token. */ public void importCRL(byte[] crl,String url) throws CRLImportException, TokenException { importCRLNative(crl,url,TYPE_CRL); } /** * Imports a CRL, and stores it into the cert7.db * * @param the DER-encoded CRL. */ private native void importCRLNative(byte[] crl, String url, int rl_type) throws CRLImportException, TokenException; /*============ Cert Exporting stuff ********************************/ /** * Exports one or more certificates into a PKCS #7 certificate container. * This is just a SignedData object whose certificates * field contains the given certificates but whose content field * is empty. * * @param certs One or more certificates that should be exported into * the PKCS #7 object. The leaf certificate should be the first * in the chain. The output of buildCertificateChain * would be appropriate here. * @exception CertificateEncodingException If the array is empty, * or an error occurred encoding the certificates. * @return A byte array containing a PKCS #7 SignedData object. * @see #buildCertificateChain */ public native byte[] exportCertsToPKCS7(X509Certificate[] certs) throws CertificateEncodingException; /** * Looks up a certificate given its nickname. * * @param nickname The nickname of the certificate to look for. * @return The certificate matching this nickname, if one is found. * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. * @exception TokenException If an error occurs in the security library. */ public org.mozilla.jss.crypto.X509Certificate findCertByNickname(String nickname) throws ObjectNotFoundException, TokenException { assert(nickname!=null); return findCertByNicknameNative(nickname); } /** * Returns all certificates with the given nickname. * * @param nickname The nickname of the certificate to look for. * @return The certificates matching this nickname. The array may be empty * if no matching certs were found. * @exception TokenException If an error occurs in the security library. */ public org.mozilla.jss.crypto.X509Certificate[] findCertsByNickname(String nickname) throws TokenException { assert(nickname!=null); return findCertsByNicknameNative(nickname); } /** * Looks up a certificate by issuer and serial number. The internal * database and all PKCS #11 modules are searched. * * @param derIssuer The DER encoding of the certificate issuer name. * The issuer name has ASN.1 type Name, which is defined in * X.501. * @param serialNumber The certificate serial number. * @return Certificate object. * @exception ObjectNotFoundException If the certificate is not found * in the internal certificate database or on any PKCS #11 token. * @exception TokenException If an error occurs in the security library. */ public org.mozilla.jss.crypto.X509Certificate findCertByIssuerAndSerialNumber(byte[] derIssuer, INTEGER serialNumber) throws ObjectNotFoundException, TokenException { try { ANY sn = (ANY) ASN1Util.decode(ANY.getTemplate(), ASN1Util.encode(serialNumber) ); return findCertByIssuerAndSerialNumberNative(derIssuer, sn.getContents() ); } catch( InvalidBERException e ) { throw new RuntimeException("Invalid BER encoding of INTEGER: " + e.getMessage(), e); } } /** * @param serialNumber The contents octets of a DER-encoding of the * certificate serial number. */ private native org.mozilla.jss.crypto.X509Certificate findCertByIssuerAndSerialNumberNative(byte[] derIssuer, byte[] serialNumber) throws ObjectNotFoundException, TokenException; protected native org.mozilla.jss.crypto.X509Certificate findCertByNicknameNative(String nickname) throws ObjectNotFoundException, TokenException; protected native org.mozilla.jss.crypto.X509Certificate[] findCertsByNicknameNative(String nickname) throws TokenException; ///////////////////////////////////////////////////////////// // build cert chains ///////////////////////////////////////////////////////////// /** * Given a certificate, constructs its certificate chain. It may * or may not chain up to a trusted root. * @param leaf The certificate that is the starting point of the chain. * @return An array of certificates, starting at the leaf and ending * with the highest certificate on the chain that was found. * @throws CertificateException If the certificate is not recognized * by the underlying provider. * @throws TokenException If an error occurred in the token. */ public org.mozilla.jss.crypto.X509Certificate[] buildCertificateChain(org.mozilla.jss.crypto.X509Certificate leaf) throws java.security.cert.CertificateException, TokenException { if( ! (leaf instanceof PK11Cert) ) { throw new CertificateException( "Certificate is not a PKCS #11 certificate"); } return buildCertificateChainNative((PK11Cert)leaf); } native org.mozilla.jss.crypto.X509Certificate[] buildCertificateChainNative(PK11Cert leaf) throws CertificateException, TokenException; ///////////////////////////////////////////////////////////// // lookup private keys ///////////////////////////////////////////////////////////// /** * Looks up the PrivateKey matching the given certificate. * * @param cert Certificate. * @return Private key. * @exception ObjectNotFoundException If no private key can be * found matching the given certificate. * @exception TokenException If an error occurs in the security library. */ public org.mozilla.jss.crypto.PrivateKey findPrivKeyByCert(org.mozilla.jss.crypto.X509Certificate cert) throws ObjectNotFoundException, TokenException { assert(cert!=null); if(! (cert instanceof org.mozilla.jss.pkcs11.PK11Cert)) { throw new ObjectNotFoundException("Non-pkcs11 cert passed to PK11Finder"); } return findPrivKeyByCertNative(cert); } protected native org.mozilla.jss.crypto.PrivateKey findPrivKeyByCertNative(org.mozilla.jss.crypto.X509Certificate cert) throws ObjectNotFoundException, TokenException; ///////////////////////////////////////////////////////////// // Provide Pseudo-Random Number Generation ///////////////////////////////////////////////////////////// /** * Retrieves a FIPS-140-2 validated random number generator. * * @return A JSS SecureRandom implemented with FIPS-validated NSS. */ public org.mozilla.jss.crypto.JSSSecureRandom createPseudoRandomNumberGenerator() { return new PK11SecureRandom(); } /** * Retrieves a FIPS-140-2 validated random number generator. * * @return A JSS SecureRandom implemented with FIPS-validated NSS. */ public org.mozilla.jss.crypto.JSSSecureRandom getSecureRNG() { return new PK11SecureRandom(); } /********************************************************************/ /* The VERSION Strings should be updated everytime a new release */ /* of JSS is generated. Note that this is done by changing */ /* cmake/JSSConfig.cmake. */ /********************************************************************/ public native static int getJSSMajorVersion(); public native static int getJSSMinorVersion(); public native static int getJSSPatchVersion(); private native static boolean getJSSDebug(); public static final String JAR_JSS_VERSION = "JSS_VERSION = JSS_" + getJSSMajorVersion() + "_" + getJSSMinorVersion() + "_" + getJSSPatchVersion(); public static final boolean JSS_DEBUG = getJSSDebug(); // Hashtable is synchronized. private Hashtable perThreadTokenTable = new Hashtable<>(); /** * Sets the default token for the current thread. This token will * be used when JSS is called through the JCA interface, which has * no means of specifying which token to use. * *

If no token is set, the InternalKeyStorageToken will be used. Setting * this thread's token to null will also cause the * InternalKeyStorageToken to be used. * * @param token The token to use for crypto operations. Specifying * null will cause the InternalKeyStorageToken to be used. */ public void setThreadToken(CryptoToken token) { if( token != null ) { perThreadTokenTable.put(Thread.currentThread(), token); } else { perThreadTokenTable.remove(Thread.currentThread()); } } /** * Returns the default token for the current thread. This token will * be used when JSS is called through the JCA interface, which has * no means of specifying which token to use. * *

If no token is set, the InternalKeyStorageToken will be used. Setting * this thread's token to null will also cause the * InternalKeyStorageToken to be used. * * @return The default token for this thread. If it has not been specified, * it will be the InternalKeyStorageToken. */ public CryptoToken getThreadToken() { CryptoToken tok = perThreadTokenTable.get(Thread.currentThread()); if( tok == null ) { tok = getInternalKeyStorageToken(); } return tok; } ///////////////////////////////////////////////////////////// // isCertValid ///////////////////////////////////////////////////////////// /** * Verify a certificate that exists in the given cert database, * check if is valid and that we trust the issuer. Verify time * against Now. * @param nickname The nickname of the certificate to verify. * @param checkSig verify the signature of the certificate * @return currCertificateUsage which contains current usage bit map as defined in CertificateUsage * * @exception InvalidNicknameException If the nickname is null * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. */ public int isCertValid(String nickname, boolean checkSig) throws ObjectNotFoundException, InvalidNicknameException { if (nickname==null) { throw new InvalidNicknameException("Nickname must be non-null"); } int currCertificateUsage = 0x0000; // initialize it to 0 currCertificateUsage = verifyCertificateNowCUNative(nickname, checkSig); return currCertificateUsage; } private native int verifyCertificateNowCUNative(String nickname, boolean checkSig) throws ObjectNotFoundException; ///////////////////////////////////////////////////////////// // isCertValid ///////////////////////////////////////////////////////////// /** * Verify a certificate that exists in the given cert database, * check if is valid and that we trust the issuer. Verify time * against Now. * @param nickname The nickname of the certificate to verify. * @param checkSig verify the signature of the certificate * @param certificateUsage see certificateUsage defined to verify Certificate; to retrieve current certificate usage, call the isCertValid() above * @return true for success; false otherwise * * @exception InvalidNicknameException If the nickname is null * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. * @deprecated Use verifyCertificate() instead */ @Deprecated public boolean isCertValid(String nickname, boolean checkSig, CertificateUsage certificateUsage) throws ObjectNotFoundException, InvalidNicknameException { if (nickname==null) { throw new InvalidNicknameException("Nickname must be non-null"); } // 0 certificate usage will get current usage // should call isCertValid() call above that returns certificate usage if ((certificateUsage == null) || (certificateUsage == CertificateUsage.CheckAllUsages)){ int currCertificateUsage = 0x0000; currCertificateUsage = verifyCertificateNowCUNative(nickname, checkSig); if (currCertificateUsage == CertificateUsage.basicCertificateUsages){ // cert is good for nothing return false; } else return true; } else { return verifyCertificateNowNative(nickname, checkSig, certificateUsage.getUsage()); } } /** * Verify a certificate that exists in the given cert database, * check if it's valid and that we trust the issuer. Verify time * against now. * @param nickname nickname of the certificate to verify. * @param checkSig verify the signature of the certificate * @param certificateUsage see certificate usage defined to verify certificate * * @exception InvalidNicknameException If the nickname is null. * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. * @exception CertificateException If certificate is invalid. */ public void verifyCertificate(String nickname, boolean checkSig, CertificateUsage certificateUsage) throws ObjectNotFoundException, InvalidNicknameException, CertificateException { int usage = certificateUsage == null ? 0 : certificateUsage.getUsage(); verifyCertificateNowNative2(nickname, checkSig, usage); } /** * Verify an X509Certificate by checking if it's valid and that we trust * the issuer. Verify time against now. * @param cert the certificate to verify * @param checkSig verify the signature of the certificate * @param certificateUsage see certificate usage defined to verify certificate * * @exception InvalidNicknameException If the nickname is null. * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. * @exception CertificateException If certificate is invalid. */ public void verifyCertificate(X509Certificate cert, boolean checkSig, CertificateUsage certificateUsage) throws ObjectNotFoundException, InvalidNicknameException, CertificateException { int usage = certificateUsage == null ? 0 : certificateUsage.getUsage(); verifyCertificateNowNative3(cert, checkSig, usage); } private native boolean verifyCertificateNowNative(String nickname, boolean checkSig, int certificateUsage) throws ObjectNotFoundException; private native void verifyCertificateNowNative2( String nickname, boolean checkSig, int certificateUsage) throws ObjectNotFoundException, InvalidNicknameException, CertificateException; private native void verifyCertificateNowNative3( X509Certificate cert, boolean checkSig, int certificateUsage) throws ObjectNotFoundException, InvalidNicknameException, CertificateException; /** * note: this method calls obsolete function in NSS * * Verify a certificate that exists in the given cert database, * check if is valid and that we trust the issuer. Verify time * against Now. * @param nickname The nickname of the certificate to verify. * @param checkSig verify the signature of the certificate * @param certUsage see exposed certUsage defines to verify Certificate * @return true for success; false otherwise * * @exception InvalidNicknameException If the nickname is null * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. */ public boolean isCertValid(String nickname, boolean checkSig, CertUsage certUsage) throws ObjectNotFoundException, InvalidNicknameException { if (nickname==null) { throw new InvalidNicknameException("Nickname must be non-null"); } return verifyCertNowNative(nickname, checkSig, certUsage.getUsage()); } /* * Obsolete in NSS */ private native boolean verifyCertNowNative(String nickname, boolean checkSig, int cUsage) throws ObjectNotFoundException; ///////////////////////////////////////////////////////////// // isCertValid ///////////////////////////////////////////////////////////// /** * Verify a certificate in memory. Check if * valid and that we trust the issuer. Verify time * against Now. * @param certPackage certificate in memory * @param checkSig verify the signature of the certificate * @param certUsage see exposed certUsage defines to verify Certificate * @return true for success; false otherwise * * @exception TokenException unable to insert temporary certificate * into database. * @exception CertificateEncodingException If the package encoding * was not recognized. */ public boolean isCertValid(byte[] certPackage, boolean checkSig, CertUsage certUsage) throws TokenException, CertificateEncodingException { return verifyCertTempNative(certPackage , checkSig, certUsage.getUsage()); } private native boolean verifyCertTempNative(byte[] certPackage, boolean checkSig, int cUsage) throws TokenException, CertificateEncodingException; /////////////////////////////////////////////////////////////////////// // OCSP management /////////////////////////////////////////////////////////////////////// /* OCSP Policy related */ public enum OCSPPolicy { NONE, NORMAL, LEAF_AND_CHAIN; } private static OCSPPolicy ocspPolicy = OCSPPolicy.NONE; /** * Gets the current ocsp Policy. * Currently we only support 2 modes OCSP_LEAF_AND_CHAIN_POLICY. * And OCSP_NORMAL_POLICY, which is current processing , by default. * If we have AIA based OCSP enabled we will check all certs in the chain. * using PKIX cert verfication calls in the various cert auth callbacks we * have. * @return - The current ocsp policy in effect. */ public static synchronized int getOCSPPolicy() { return ocspPolicy.ordinal(); } /** * Gets the current OCSP Policy. * * @see getOCSPPolicy() * * @return - The current OCSP policy in effect. */ public static synchronized OCSPPolicy getOCSPPolicyEnum() { return ocspPolicy; } /** * Sets the current ocsp Policy. * Currently we only support one mode OCSP_LEAF_AND_CHAIN_POLICY. * If we have AIA based OCSP enabled we will check all certs in the chain. * using PKIX cert verfication calls in the various cert auth callbacks we * have. * @param policy - Either cert and chain or normal default processing. * */ public static synchronized void setOCSPPolicy(OCSPPolicy policy) { ocspPolicy = policy; } /** * Enables OCSP, note when you Initialize JSS for the first time, for * backwards compatibility, the initialize will enable OCSP if you * previously set values.ocspCheckingEnabled and * values.ocspResponderURL/values.ocspResponderCertNickname * configureOCSP will allow changing of the the OCSPResponder at runtime. * @param ocspCheckingEnabled true or false to enable/disable OCSP * @param ocspResponderURL - url of the OCSP responder * @param ocspResponderCertNickname - the nickname of the OCSP * signer certificate or the CA certificate found in the cert DB * @throws GeneralSecurityException If a security error has occurred. */ public void configureOCSP( boolean ocspCheckingEnabled, String ocspResponderURL, String ocspResponderCertNickname ) throws GeneralSecurityException { /* set the ocsp policy */ if(ocspCheckingEnabled && ocspResponderURL == null && ocspResponderCertNickname == null) { setOCSPPolicy(OCSPPolicy.LEAF_AND_CHAIN); } else { setOCSPPolicy(OCSPPolicy.NORMAL); } configureOCSPNative(ocspCheckingEnabled, ocspResponderURL, ocspResponderCertNickname ); } private native void configureOCSPNative( boolean ocspCheckingEnabled, String ocspResponderURL, String ocspResponderCertNickname ) throws GeneralSecurityException; /** * change OCSP cache settings * @param ocsp_cache_size max cache entries * @param ocsp_min_cache_entry_duration minimum seconds to next fetch attempt * @param ocsp_max_cache_entry_duration maximum seconds to next fetch attempt * @throws GeneralSecurityException If a security error has occurred. */ public void OCSPCacheSettings( int ocsp_cache_size, int ocsp_min_cache_entry_duration, int ocsp_max_cache_entry_duration) throws GeneralSecurityException { OCSPCacheSettingsNative(ocsp_cache_size, ocsp_min_cache_entry_duration, ocsp_max_cache_entry_duration); } private native void OCSPCacheSettingsNative( int ocsp_cache_size, int ocsp_min_cache_entry_duration, int ocsp_max_cache_entry_duration) throws GeneralSecurityException; /** * set OCSP timeout value * @param ocsp_timeout OCSP timeout in seconds * @throws GeneralSecurityException If a security error has occurred. */ public void setOCSPTimeout( int ocsp_timeout ) throws GeneralSecurityException { setOCSPTimeoutNative( ocsp_timeout); } private native void setOCSPTimeoutNative( int ocsp_timeout ) throws GeneralSecurityException; } jss-4.6.3/org/mozilla/jss/DatabaseCloser.java000066400000000000000000000030241362106420000210700ustar00rootroot00000000000000/* 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; /** * A class for closing databases. Since closing the databases is * very dangerous and breaks the JSS model, it may only be done from * special applications. This class should be subclasses by * authorized subclasses. It cannot be instantiated itself. */ public abstract class DatabaseCloser { private static final String authorizedClosers[] = { "org.mozilla.certsetup.apps.CertSetup$DatabaseCloser", "org.mozilla.jss.CloseDBs" }; /** * Creates a new DatabaseCloser. This should only be called * from an authorized subclass. This class cannot itself be * instantiated. * * @throws Exception If the instantiation is not a valid subclass. */ public DatabaseCloser() throws Exception { Class clazz = this.getClass(); String name = clazz.getName(); boolean approved = false; for(int i=0; i < authorizedClosers.length; i++) { if( name.equals( authorizedClosers[i] ) ) { approved = true; break; } } if(!approved) { throw new Exception(); } } /** * Closes the certificate and key databases. This is extremely * dangerous. */ protected native void closeDatabases(); } jss-4.6.3/org/mozilla/jss/InitializationValues.java000066400000000000000000000432041362106420000223670ustar00rootroot00000000000000/* 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; import org.mozilla.jss.util.ConsolePasswordCallback; import org.mozilla.jss.util.PasswordCallback; /** * The various options that can be used to initialize CryptoManager. */ public final class InitializationValues { protected InitializationValues() { throw new RuntimeException("Default InitializationValues constructor"); } ///////////////////////////////////////////////////////////// // Constants ///////////////////////////////////////////////////////////// /** * Token names must be this length exactly. */ public final int TOKEN_LENGTH = 33; /** * Slot names must be this length exactly. */ public final int SLOT_LENGTH = 65; /** * ManufacturerID must be this length exactly. */ public final int MANUFACTURER_LENGTH = 33; /** * Library description must be this length exactly. */ public final int LIBRARY_LENGTH = 33; /** * This class enumerates the possible modes for FIPS compliance. */ public static final class FIPSMode { private FIPSMode() {} /** * Enable FIPS mode. */ public static final InitializationValues.FIPSMode ENABLED = new FIPSMode(); /** * Disable FIPS mode. */ public static final InitializationValues.FIPSMode DISABLED = new FIPSMode(); /** * Leave FIPS mode unchanged. All servers except Admin * Server should use this, because only Admin Server should * be altering FIPS mode. */ public static final InitializationValues.FIPSMode UNCHANGED = new FIPSMode(); } public InitializationValues(String configDir) { this.configDir = configDir; } public InitializationValues(String configDir, String certPrefix, String keyPrefix, String secmodName) { this.configDir = configDir; this.certPrefix = certPrefix; this.keyPrefix = keyPrefix; this.secmodName = secmodName; } public String configDir = null; public String certPrefix = null; public String keyPrefix = null; public String secmodName = null; /** * The password callback to be used by JSS whenever a password * is needed. May be NULL, in which the library will immediately fail * to get a password if it tries to login automatically while * performing * a cryptographic operation. It will still work if the token * has been manually logged in with CryptoToken.login. *

The default is a ConsolePasswordCallback. */ public PasswordCallback passwordCallback = new ConsolePasswordCallback(); /** * The FIPS mode of the security library. Servers should * use FIPSMode.UNCHANGED, since only * Admin Server is supposed to alter this value. *

The default is FIPSMode.UNCHANGED. */ public InitializationValues.FIPSMode fipsMode = FIPSMode.UNCHANGED; /** * To open the databases in read-only mode, set this flag to * true. The default is false, meaning * the databases are opened in read-write mode. */ public boolean readOnly = false; //////////////////////////////////////////////////////////////////// // Manufacturer ID //////////////////////////////////////////////////////////////////// /** * Returns the Manufacturer ID of the internal PKCS #11 module. *

The default is "mozilla.org ". * * @return Manufacturer ID. */ public String getManufacturerID() { return manufacturerID; } /** * Sets the Manufacturer ID of the internal PKCS #11 module. * This value must be exactly MANUFACTURER_LENGTH * characters long. * * @param s Manufacturer ID. * @exception InvalidLengthException If s.length() is not * exactly MANUFACTURER_LENGTH. */ public void setManufacturerID(String s) throws InvalidLengthException { if( s.length() != MANUFACTURER_LENGTH ) { throw new InvalidLengthException(); } manufacturerID = s; } private String manufacturerID = "mozilla.org "; //////////////////////////////////////////////////////////////////// // Library Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 module. *

The default is "Internal Crypto Services ". * * @return Library description. */ public String getLibraryDescription() { return libraryDescription; } /** * Sets the description of the internal PKCS #11 module. * This value must be exactly LIBRARY_LENGTH * characters long. * * @param s Library description. * @exception InvalidLengthException If s.length() is * not exactly LIBRARY_LENGTH. */ public void setLibraryDescription(String s) throws InvalidLengthException { if( s.length() != LIBRARY_LENGTH ) { throw new InvalidLengthException(); } libraryDescription = s; } private String libraryDescription = "Internal Crypto Services "; //////////////////////////////////////////////////////////////////// // Internal Token Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 token. *

The default is "Internal Crypto Services Token ". * * @return Description of internal PKCS #11 token. */ public String getInternalTokenDescription() { return internalTokenDescription; } /** * Sets the description of the internal PKCS #11 token. * This value must be exactly TOKEN_LENGTH characters long. * * @param s Description of internal PKCS #11 token. * @exception InvalidLengthException If s.length() is * not exactly TOKEN_LENGTH. */ public void setInternalTokenDescription(String s) throws InvalidLengthException { if(s.length() != TOKEN_LENGTH) { throw new InvalidLengthException(); } internalTokenDescription = s; } private String internalTokenDescription = "NSS Generic Crypto Services "; //////////////////////////////////////////////////////////////////// // Internal Key Storage Token Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 key storage token. *

The default is "Internal Key Storage Token ". * * @return Description of internal PKCS #11 key storage token. */ public String getInternalKeyStorageTokenDescription() { return internalKeyStorageTokenDescription; } /** * Sets the description of the internal PKCS #11 key storage token. * This value must be exactly TOKEN_LENGTH characters long. * * @param s Description of internal PKCS #11 key storage token. * @exception InvalidLengthException If s.length() is * not exactly TOKEN_LENGTH. */ public void setInternalKeyStorageTokenDescription(String s) throws InvalidLengthException { if(s.length() != TOKEN_LENGTH) { throw new InvalidLengthException(); } internalKeyStorageTokenDescription = s; } private String internalKeyStorageTokenDescription = "Internal Key Storage Token "; //////////////////////////////////////////////////////////////////// // Internal Slot Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 slot. *

The default is "NSS Internal Cryptographic Services ". * * @return Description of internal PKCS #11 slot. */ public String getInternalSlotDescription() { return internalSlotDescription; } /** * Sets the description of the internal PKCS #11 slot. * This value must be exactly SLOT_LENGTH characters * long. * * @param s Description of internal PKCS #11 slot. * @exception InvalidLengthException If s.length() is * not exactly SLOT_LENGTH. */ public void setInternalSlotDescription(String s) throws InvalidLengthException { if(s.length() != SLOT_LENGTH) { throw new InvalidLengthException(); } internalSlotDescription = s; } private String internalSlotDescription = "NSS Internal Cryptographic Services "; //////////////////////////////////////////////////////////////////// // Internal Key Storage Slot Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 key storage slot. *

The default is "NSS Internal Private Key and Certificate Storage ". * * @return Description of internal PKCS #11 key storage slot. */ public String getInternalKeyStorageSlotDescription() { return internalKeyStorageSlotDescription; } /** * Sets the description of the internal PKCS #11 key storage slot. * This value must be exactly SLOT_LENGTH characters * long. * * @param s Description of internal PKCS #11 key storage slot. * @exception InvalidLengthException If s.length() is * not exactly SLOT_LENGTH. */ public void setInternalKeyStorageSlotDescription(String s) throws InvalidLengthException { if(s.length() != SLOT_LENGTH) { throw new InvalidLengthException(); } internalKeyStorageSlotDescription = s; } private String internalKeyStorageSlotDescription = "NSS User Private Key and Certificate Services "; //////////////////////////////////////////////////////////////////// // FIPS Slot Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 FIPS slot. *

The default is * "NSS FIPS 140-2 User Private Key Services". * * @return Description of internal PKCS #11 FIPS slot. */ public String getFIPSSlotDescription() { return FIPSSlotDescription; } /** * Sets the description of the internal PKCS #11 FIPS slot. * This value must be exactly SLOT_LENGTH characters * long. * * @param s Description of internal PKCS #11 FIPS slot. * @exception InvalidLengthException If s.length() is * not exactly SLOT_LENGTH. */ public void setFIPSSlotDescription(String s) throws InvalidLengthException { if(s.length() != SLOT_LENGTH) { throw new InvalidLengthException(); } FIPSSlotDescription = s; } private String FIPSSlotDescription = "NSS FIPS 140-2 User Private Key Services "; //////////////////////////////////////////////////////////////////// // FIPS Key Storage Slot Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 FIPS * Key Storage slot. *

The default is * "NSS FIPS 140-2 User Private Key Services". * * @return Description of internal PKCS #11 FIPS key storage slot. */ public String getFIPSKeyStorageSlotDescription() { return FIPSKeyStorageSlotDescription; } /** * Sets the description of the internal PKCS #11 FIPS Key Storage slot. * This value must be exactly SLOT_LENGTH characters * long. * * @param s Description of internal PKCS #11 FIPS key storage slot. * @exception InvalidLengthException If s.length() is * not exactly SLOT_LENGTH. */ public void setFIPSKeyStorageSlotDescription(String s) throws InvalidLengthException { if(s.length() != SLOT_LENGTH) { throw new InvalidLengthException(); } FIPSKeyStorageSlotDescription = s; } private String FIPSKeyStorageSlotDescription = "NSS FIPS 140-2 User Private Key Services "; /** * To have NSS check the OCSP responder for when verifying * certificates, set this flags to true. It is false by * default. */ public boolean ocspCheckingEnabled = false; /** * Specify the location and cert of the responder. * If OCSP checking is enabled *and* this variable is * set to some URL, all OCSP checking will be done via * this URL. * * If this variable is null, the OCSP responder URL will * be obtained from the AIA extension in the certificate * being queried. * * If this is set, you must also set ocspResponderCertNickname * */ public String ocspResponderURL = null; /** * The nickname of the cert to trust (expected) to * sign the OCSP responses. * Only checked when the OCSPResponder value is set. */ public String ocspResponderCertNickname = null; /** * Install the JSS crypto provider. Default is true. */ public boolean installJSSProvider = true; /** * Remove the Sun crypto provider. Default is false. */ public boolean removeSunProvider = false; /** * Whether or not to initialize the JSS provider first. Default is true. */ public boolean installJSSProviderFirst = true; /** * If true, none of the underlying NSS components will * be initialized. Only the Java portions of JSS will be * initialized. This should only be used if NSS has been initialized * elsewhere. * *

Specifically, the following components will not be * configured by CryptoManager.initialize if this flag is set: *

    *
  • The NSS databases. *
  • OCSP checking. *
  • The NSS password callback. *
  • The internal PKCS #11 software token's identifier labels: * slot, token, module, and manufacturer. *
  • The minimum PIN length for the software token. *
  • The frequency with which the user must login to the software * token. *
  • The cipher strength policy (export/domestic). *
* *

The default is false. */ public boolean initializeJavaOnly = false; /** * Enable PKIX verify rather than the old cert library, * to verify certificates. Default is false. */ public boolean PKIXVerify = false; /** * Don't open the cert DB and key DB's, just * initialize the volatile certdb. Default is false. */ public boolean noCertDB = false; /** * Don't open the security module DB, * just initialize the PKCS #11 module. * Default is false. */ public boolean noModDB = false; /** * Continue to force initializations even if the * databases cannot be opened. * Default is false. */ public boolean forceOpen = false; /** * Don't try to look for the root certs module * automatically. * Default is false. */ public boolean noRootInit = false; /** * Use smaller tables and caches. * Default is false. */ public boolean optimizeSpace = false; /** * only load PKCS#11 modules that are * thread-safe, ie. that support locking - either OS * locking or NSS-provided locks . If a PKCS#11 * module isn't thread-safe, don't serialize its * calls; just don't load it instead. This is necessary * if another piece of code is using the same PKCS#11 * modules that NSS is accessing without going through * NSS, for example the Java SunPKCS11 provider. * Default is false. */ public boolean PK11ThreadSafe = false; /** * Init PK11Reload to ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED * error when loading PKCS#11 modules. This is necessary * if another piece of code is using the same PKCS#11 * modules that NSS is accessing without going through * NSS, for example Java SunPKCS11 provider. * default is false. */ public boolean PK11Reload = false; /** * never call C_Finalize on any * PKCS#11 module. This may be necessary in order to * ensure continuous operation and proper shutdown * sequence if another piece of code is using the same * PKCS#11 modules that NSS is accessing without going * through NSS, for example Java SunPKCS11 provider. * The following limitation applies when this is set : * SECMOD_WaitForAnyTokenEvent will not use * C_WaitForSlotEvent, in order to prevent the need for * C_Finalize. This call will be emulated instead. * Default is false. */ public boolean noPK11Finalize = false; /** * Sets 4 recommended options for applications that * use both NSS and the Java SunPKCS11 provider. * Default is false. */ public boolean cooperate = false; } jss-4.6.3/org/mozilla/jss/InvalidLengthException.java000066400000000000000000000005341362106420000226260ustar00rootroot00000000000000/* 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; public final class InvalidLengthException extends Exception { private static final long serialVersionUID = 1L; } jss-4.6.3/org/mozilla/jss/JSSProvider.java000066400000000000000000000440441362106420000203750ustar00rootroot00000000000000/* 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; public final class JSSProvider extends java.security.Provider { private static final long serialVersionUID = 1L; /********************************************************************/ /* The VERSION Strings should be updated everytime a new release */ /* of JSS is generated. Note that this is done by changing */ /* cmake/JSSConfig.cmake. */ /********************************************************************/ private static int JSS_MAJOR_VERSION = CryptoManager.getJSSMajorVersion(); private static int JSS_MINOR_VERSION = CryptoManager.getJSSMinorVersion(); private static int JSS_PATCH_VERSION = CryptoManager.getJSSPatchVersion(); private static double JSS_VERSION = JSS_MAJOR_VERSION + (JSS_MINOR_VERSION * 100 + JSS_PATCH_VERSION)/10000.0; public JSSProvider() { super("Mozilla-JSS", JSS_VERSION, "Provides Signature, Message Digesting, and RNG"); ///////////////////////////////////////////////////////////// // Signature ///////////////////////////////////////////////////////////// put("Signature.SHA1withDSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$DSA"); put("Alg.Alias.Signature.DSA", "SHA1withDSA"); put("Alg.Alias.Signature.DSS", "SHA1withDSA"); put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA"); put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA"); put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA"); put("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA"); put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA"); put("Signature.MD5/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$MD5RSA"); put("Alg.Alias.Signature.MD5withRSA", "MD5/RSA"); put("Signature.MD2/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$MD2RSA"); put("Signature.SHA-1/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA1RSA"); put("Alg.Alias.Signature.SHA1/RSA", "SHA-1/RSA"); put("Alg.Alias.Signature.SHA1withRSA", "SHA-1/RSA"); put("Signature.SHA-256/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA256RSA"); put("Alg.Alias.Signature.SHA256/RSA", "SHA-256/RSA"); put("Alg.Alias.Signature.SHA256withRSA", "SHA-256/RSA"); put("Signature.SHA-384/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA384RSA"); put("Alg.Alias.Signature.SHA384/RSA", "SHA-384/RSA"); put("Alg.Alias.Signature.SHA384withRSA", "SHA-384/RSA"); put("Signature.SHA-512/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA512RSA"); put("Alg.Alias.Signature.SHA512/RSA", "SHA-512/RSA"); put("Alg.Alias.Signature.SHA512withRSA", "SHA-512/RSA"); // ECC put("Signature.SHA1withEC", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA1EC"); put("Alg.Alias.Signature.EC", "SHA1withEC"); put("Alg.Alias.Signature.ECC", "SHA1withEC"); put("Alg.Alias.Signature.ECDSA", "SHA1withEC"); put("Alg.Alias.Signature.SHA/EC", "SHA1withEC"); put("Alg.Alias.Signature.SHA1/EC", "SHA1withEC"); put("Alg.Alias.Signature.SHA-1/EC", "SHA1withEC"); put("Alg.Alias.Signature.SHA/ECDSA", "SHA1withEC"); put("Alg.Alias.Signature.SHA1/ECDSA", "SHA1withEC"); put("Alg.Alias.Signature.SHA1withECDSA", "SHA1withEC"); //JCE Standard Name put("Signature.SHA256withEC", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA256EC"); put("Alg.Alias.Signature.SHA256/EC", "SHA256withEC"); put("Alg.Alias.Signature.SHA-256/EC", "SHA256withEC"); put("Alg.Alias.Signature.SHA256withECDSA", "SHA256withEC"); //JCE Standard Name put("Signature.SHA384withEC", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA384EC"); put("Alg.Alias.Signature.SHA384/EC", "SHA384withEC"); put("Alg.Alias.Signature.SHA-384/EC", "SHA384withEC"); put("Alg.Alias.Signature.SHA384withECDSA", "SHA384withEC"); //JCE Standard Name put("Signature.SHA512withEC", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA512EC"); put("Alg.Alias.Signature.SHA512/EC", "SHA512withEC"); put("Alg.Alias.Signature.SHA-512/EC", "SHA512withEC"); put("Alg.Alias.Signature.SHA512withECDSA", "SHA512withEC"); //JCE Standard Name ///////////////////////////////////////////////////////////// // Message Digesting ///////////////////////////////////////////////////////////// put("MessageDigest.SHA-1", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA1"); put("MessageDigest.MD2", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$MD2"); put("MessageDigest.MD5", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$MD5"); put("MessageDigest.SHA-256", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA256"); put("MessageDigest.SHA-384", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA384"); put("MessageDigest.SHA-512", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA512"); put("Alg.Alias.MessageDigest.SHA1", "SHA-1"); put("Alg.Alias.MessageDigest.SHA", "SHA-1"); put("Alg.Alias.MessageDigest.SHA256", "SHA-256"); put("Alg.Alias.MessageDigest.SHA384", "SHA-384"); put("Alg.Alias.MessageDigest.SHA512", "SHA-512"); ///////////////////////////////////////////////////////////// // SecureRandom ///////////////////////////////////////////////////////////// put("SecureRandom.pkcs11prng", "org.mozilla.jss.provider.java.security.JSSSecureRandomSpi"); ///////////////////////////////////////////////////////////// // KeyPairGenerator ///////////////////////////////////////////////////////////// put("KeyPairGenerator.RSA", "org.mozilla.jss.provider.java.security.JSSKeyPairGeneratorSpi$RSA"); put("KeyPairGenerator.DSA", "org.mozilla.jss.provider.java.security.JSSKeyPairGeneratorSpi$DSA"); put("KeyPairGenerator.EC", "org.mozilla.jss.provider.java.security.JSSKeyPairGeneratorSpi$EC"); ///////////////////////////////////////////////////////////// // KeyFactory ///////////////////////////////////////////////////////////// put("KeyFactory.RSA", "org.mozilla.jss.provider.java.security.KeyFactorySpi1_2"); put("KeyFactory.DSA", "org.mozilla.jss.provider.java.security.KeyFactorySpi1_2"); put("KeyFactory.EC", "org.mozilla.jss.provider.java.security.KeyFactorySpi1_2"); ///////////////////////////////////////////////////////////// // KeyStore ///////////////////////////////////////////////////////////// put("KeyStore.PKCS11", "org.mozilla.jss.provider.java.security.JSSKeyStoreSpi"); ///////////////////////////////////////////////////////////// // AlgorithmParameters ///////////////////////////////////////////////////////////// put("AlgorithmParameters.IvAlgorithmParameters", "org.mozilla.jss.provider.java.security.IvAlgorithmParameters"); put("AlgorithmParameters.RC2AlgorithmParameters", "org.mozilla.jss.provider.java.security.RC2AlgorithmParameters"); ///////////////////////////////////////////////////////////// // Cipher ///////////////////////////////////////////////////////////// put("Cipher.DES", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$DES"); put("Cipher.DESede", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$DESede"); put("Alg.Alias.Cipher.DES3", "DESede"); put("Cipher.AES", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$AES"); put("Cipher.RC4", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$RC4"); put("Cipher.RSA", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$RSA"); put("Cipher.RC2", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$RC2"); ///////////////////////////////////////////////////////////// // KeyGenerator ///////////////////////////////////////////////////////////// String kg_spi = "org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi"; put("KeyGenerator.DES", kg_spi + "$DES"); put("KeyGenerator.DESede", kg_spi + "$DESede"); put("Alg.Alias.KeyGenerator.DES3", "DESede"); put("KeyGenerator.AES", kg_spi + "$AES"); put("KeyGenerator.RC4", kg_spi + "$RC4"); put("KeyGenerator.RC2", kg_spi + "$RC2"); put("KeyGenerator.HmacSHA1", kg_spi + "$HmacSHA1"); put("KeyGenerator.PBAHmacSHA1", kg_spi + "$PBAHmacSHA1"); put("KeyGenerator.HmacSHA256", kg_spi + "$HmacSHA256"); put("KeyGenerator.HmacSHA384", kg_spi + "$HmacSHA384"); put("KeyGenerator.HmacSHA512", kg_spi + "$HmacSHA512"); // KBKDF: Counter put("KeyGenerator.KbkdfCounter", kg_spi + "$KbkdfCounter"); put("Alg.Alias.KeyGenerator.KBKDF-Counter", "KbkdfCounter"); put("Alg.Alias.KeyGenerator.SP800-108-KDF-Counter", "KbkdfCounter"); put("Alg.Alias.KeyGenerator.SP800-108-Counter", "KbkdfCounter"); put("Alg.Alias.KeyGenerator.CounterKbkdf", "KbkdfCounter"); // KBKDF: Counter (data) put("KeyGenerator.KbkdfCounterData", kg_spi + "$KbkdfCounterData"); put("Alg.Alias.KeyGenerator.KBKDF-Counter-Data", "KbkdfCounterData"); put("Alg.Alias.KeyGenerator.SP800-108-KDF-Counter-Data", "KbkdfCounterData"); put("Alg.Alias.KeyGenerator.SP800-108-Counter-Data", "KbkdfCounterData"); put("Alg.Alias.KeyGenerator.CounterKbkdf-Data", "KbkdfCounterData"); // KBKDF: Feedback put("KeyGenerator.KbkdfFeedback", kg_spi + "$KbkdfFeedback"); put("Alg.Alias.KeyGenerator.KBKDF-Feedback", "KbkdfFeedback"); put("Alg.Alias.KeyGenerator.SP800-108-KDF-Feedback", "KbkdfFeedback"); put("Alg.Alias.KeyGenerator.SP800-108-Feedback", "KbkdfFeedback"); put("Alg.Alias.KeyGenerator.FeedbackKbkdf", "KbkdfFeedback"); // KBKDF: Feedback (data) put("KeyGenerator.KbkdfFeedbackData", kg_spi + "$KbkdfFeedbackData"); put("Alg.Alias.KeyGenerator.KBKDF-Feedback-Data", "KbkdfFeedbackData"); put("Alg.Alias.KeyGenerator.SP800-108-KDF-Feedback-Data", "KbkdfFeedbackData"); put("Alg.Alias.KeyGenerator.SP800-108-Feedback-Data", "KbkdfFeedbackData"); put("Alg.Alias.KeyGenerator.FeedbackKbkdf-Data", "KbkdfFeedbackData"); // KBKDF: Double Pipeline -- sometimes Pipeline KBKDF put("KeyGenerator.KbkdfDoublePipeline", kg_spi + "$KbkdfDoublePipeline"); put("Alg.Alias.KeyGenerator.KBKDF-DoublePipeline", "KbkdfDoublePipeline"); put("Alg.Alias.KeyGenerator.SP800-108-KDF-DoublePipeline", "KbkdfDoublePipeline"); put("Alg.Alias.KeyGenerator.SP800-108-DoublePipeline", "KbkdfDoublePipeline"); put("Alg.Alias.KeyGenerator.DoublePipelineKbkdf", "KbkdfDoublePipeline"); put("Alg.Alias.KeyGenerator.KbkdfPipeline", "KbkdfDoublePipeline"); put("Alg.Alias.KeyGenerator.KBKDF-Pipeline", "KbkdfDoublePipeline"); put("Alg.Alias.KeyGenerator.SP800-108-KDF-Pipeline", "KbkdfDoublePipeline"); put("Alg.Alias.KeyGenerator.SP800-108-Pipeline", "KbkdfDoublePipeline"); put("Alg.Alias.KeyGenerator.PipelineKbkdf", "KbkdfDoublePipeline"); // KBKDF: Double Pipeline (data) -- sometimes Pipeline KBKDF (data) put("KeyGenerator.KbkdfDoublePipelineData", kg_spi + "$KbkdfDoublePipelineData"); put("Alg.Alias.KeyGenerator.KBKDF-DoublePipeline-Data", "KbkdfDoublePipelineData"); put("Alg.Alias.KeyGenerator.SP800-108-KDF-DoublePipeline-Data", "KbkdfDoublePipelineData"); put("Alg.Alias.KeyGenerator.SP800-108-DoublePipeline-Data", "KbkdfDoublePipelineData"); put("Alg.Alias.KeyGenerator.DoublePipelineKbkdf-Data", "KbkdfDoublePipelineData"); put("Alg.Alias.KeyGenerator.KbkdfPipelineData", "KbkdfDoublePipelineData"); put("Alg.Alias.KeyGenerator.KBKDF-Pipeline-Data", "KbkdfDoublePipelineData"); put("Alg.Alias.KeyGenerator.SP800-108-KDF-Pipeline-Data", "KbkdfDoublePipelineData"); put("Alg.Alias.KeyGenerator.SP800-108-Pipeline-Data", "KbkdfDoublePipelineData"); put("Alg.Alias.KeyGenerator.PipelineKbkdf-Data", "KbkdfDoublePipelineData"); ///////////////////////////////////////////////////////////// // SecretKeyFactory ///////////////////////////////////////////////////////////// put("SecretKeyFactory.GenericSecret", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$GenericSecret"); put("Alg.Alias.SecretKeyFactory.GENERIC_SECRET", "GenericSecret"); put("SecretKeyFactory.DES", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$DES"); put("SecretKeyFactory.DESede", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$DESede"); put("Alg.Alias.SecretKeyFactory.DES3", "DESede"); put("SecretKeyFactory.AES", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$AES"); put("SecretKeyFactory.RC4", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$RC4"); put("SecretKeyFactory.RC2", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$RC2"); put("SecretKeyFactory.HmacSHA1", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$HmacSHA1"); put("SecretKeyFactory.PBAHmacSHA1", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBAHmacSHA1"); put("SecretKeyFactory.HmacSHA256", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$HmacSHA256"); put("SecretKeyFactory.HmacSHA384", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$HmacSHA384"); put("SecretKeyFactory.HmacSHA512", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$HmacSHA512"); put("SecretKeyFactory.PBEWithMD5AndDES", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_MD5_DES_CBC"); put("SecretKeyFactory.PBEWithSHA1AndDES", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_SHA1_DES_CBC"); put("SecretKeyFactory.PBEWithSHA1AndDESede", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_SHA1_DES3_CBC"); put("Alg.Alias.SecretKeyFactory.PBEWithSHA1AndDES3", "PBEWithSHA1AndDESede"); put("SecretKeyFactory.PBEWithSHA1And128RC4", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_SHA1_RC4_128"); ///////////////////////////////////////////////////////////// // MAC ///////////////////////////////////////////////////////////// put("Mac.HmacSHA1", "org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA1"); put("Alg.Alias.Mac.Hmac-SHA1", "HmacSHA1"); put("Mac.HmacSHA256", "org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA256"); put("Alg.Alias.Mac.Hmac-SHA256", "HmacSHA256"); put("Mac.HmacSHA384", "org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA384"); put("Alg.Alias.Mac.Hmac-SHA384", "HmacSHA384"); put("Mac.HmacSHA512", "org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA512"); put("Mac.CmacAES", "org.mozilla.jss.provider.javax.crypto.JSSMacSpi$CmacAES"); put("Alg.Alias.Mac.Hmac-SHA512", "HmacSHA512"); put("Alg.Alias.Mac.SHA-1-HMAC", "HmacSHA1"); put("Alg.Alias.Mac.SHA-256-HMAC", "HmacSHA256"); put("Alg.Alias.Mac.SHA-384-HMAC", "HmacSHA384"); put("Alg.Alias.Mac.SHA-512-HMAC", "HmacSHA512"); put("Alg.Alias.Mac.AES-128-CMAC", "CmacAES"); put("Alg.Alias.Mac.AES-192-CMAC", "CmacAES"); put("Alg.Alias.Mac.AES-256-CMAC", "CmacAES"); put("Alg.Alias.Mac.CmacAES128", "CmacAES"); put("Alg.Alias.Mac.CmacAES192", "CmacAES"); put("Alg.Alias.Mac.CmacAES256", "CmacAES"); put("Alg.Alias.Mac.AES_CMAC", "CmacAES"); put("Alg.Alias.Mac.CMAC_AES", "CmacAES"); ///////////////////////////////////////////////////////////// // KeyManagerFactory ///////////////////////////////////////////////////////////// put("KeyManagerFactory.NssX509", "org.mozilla.jss.provider.javax.crypto.JSSKeyManagerFactory"); put("Alg.Alias.KeyManagerFactory.SunX509", "NssX509"); put("Alg.Alias.KeyManagerFactory.PKIX", "SunX509"); ///////////////////////////////////////////////////////////// // TrustManagerFactory ///////////////////////////////////////////////////////////// put("TrustManagerFactory.NssX509", "org.mozilla.jss.provider.javax.crypto.JSSTrustManagerFactory"); put("Alg.Alias.TrustManagerFactory.SunX509", "NssX509"); put("Alg.Alias.TrustManagerFactory.PKIX", "NssX509"); put("Alg.Alias.TrustManagerFactory.X509", "NssX509"); put("Alg.Alias.TrustManagerFactory.X.509", "NssX509"); } public String toString() { String mozillaProviderVersion = JSS_MAJOR_VERSION + "." + JSS_MINOR_VERSION; if ( JSS_PATCH_VERSION != 0 ) { mozillaProviderVersion = mozillaProviderVersion + "." + JSS_PATCH_VERSION; } return "Mozilla-JSS version " + mozillaProviderVersion; } } jss-4.6.3/org/mozilla/jss/KeyDatabaseException.java000066400000000000000000000015461362106420000222570ustar00rootroot00000000000000/* 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; /** * This exception is thrown if the key database does not exist, or if * an error occurs while opening it. */ public class KeyDatabaseException extends java.lang.Exception { private static final long serialVersionUID = 1L; public KeyDatabaseException() {} public KeyDatabaseException(String mesg) { super(mesg); } public KeyDatabaseException(String mesg, Throwable cause) { super(mesg, cause); } public KeyDatabaseException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/NicknameConflictException.java000066400000000000000000000005371362106420000233100ustar00rootroot00000000000000/* 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; public final class NicknameConflictException extends Exception { private static final long serialVersionUID = 1L; } jss-4.6.3/org/mozilla/jss/NoSuchTokenException.java000066400000000000000000000014401362106420000222730ustar00rootroot00000000000000/* 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; /** * Thrown if a token cannot be found. */ public class NoSuchTokenException extends java.lang.Exception { private static final long serialVersionUID = 1L; public NoSuchTokenException() {} public NoSuchTokenException(String mesg) { super(mesg); } public NoSuchTokenException(String mesg, Throwable cause) { super(mesg, cause); } public NoSuchTokenException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/NotInitializedException.java000066400000000000000000000005351362106420000230250ustar00rootroot00000000000000/* 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; public final class NotInitializedException extends Exception { private static final long serialVersionUID = 1L; } jss-4.6.3/org/mozilla/jss/PK11Finder.c000066400000000000000000001676271362106420000173450ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_CryptoManager.h" #include #include #include #include #include #include #include #include #include #include #include #include "pk11util.h" #include "ssl/jssl.h" #include /* * This is a semi-private NSS function, exposed only for JSS. */ SECStatus CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage); /* * This is a private function, used only by JSS in this file. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2(JNIEnv *env, jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage); /* * This is a private function, used only by JSS in this file. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative3(JNIEnv *env, jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage); /***************************************************************** * * CryptoManager. f i n d C e r t B y N i c k n a m e N a t i v e * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_CryptoManager_findCertByNicknameNative (JNIEnv *env, jobject this, jstring nickname) { const char *nick = NULL; jobject certObject=NULL; CERTCertificate *cert=NULL; PK11SlotInfo *slot=NULL; PR_ASSERT(env!=NULL && this!=NULL && nickname!=NULL); nick = JSS_RefJString(env, nickname); PR_ASSERT(nick!=NULL); cert = JSS_PK11_findCertAndSlotFromNickname(nick, NULL, &slot); if(cert == NULL) { char *message = PR_smprintf("Certificate not found: %s", nick); JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, message); PR_smprintf_free(message); goto finish; } certObject = JSS_PK11_wrapCertAndSlot(env, &cert, &slot); finish: JSS_DerefJString(env, nickname, nick); if(cert != NULL) { CERT_DestroyCertificate(cert); } if(slot != NULL) { PK11_FreeSlot(slot); } return certObject; } /***************************************************************** * * CryptoManager. f i n d C e r t s B y N i c k n a m e N a t i v e * */ JNIEXPORT jobjectArray JNICALL Java_org_mozilla_jss_CryptoManager_findCertsByNicknameNative (JNIEnv *env, jobject this, jstring nickname) { CERTCertList *list =NULL; PK11SlotInfo *slot =NULL; jobjectArray certArray=NULL; CERTCertListNode *node; const char *nickChars=NULL; jclass certClass; int count; int i; /* convert the nickname string */ nickChars = JSS_RefJString(env, nickname); if( nickChars == NULL ) { goto finish; } /* get the list of certs with the given nickname */ list = JSS_PK11_findCertsAndSlotFromNickname( (char*)nickChars, NULL /*wincx*/, &slot); if( list == NULL ) { count = 0; } else { /* Since this structure changed in NSS_2_7_RTM (the reference */ /* to "count" was removed from the "list" structure) we must */ /* now count up the number of nodes manually! */ for( node = CERT_LIST_HEAD(list), count=0; ! CERT_LIST_END(node, list); node = CERT_LIST_NEXT(node), count++ ); } PR_ASSERT(count >= 0); /* create the cert array */ certClass = (*env)->FindClass(env, X509_CERT_CLASS); if( certClass == NULL ) { goto finish; } certArray = (*env)->NewObjectArray(env, count, certClass, NULL); if( certArray == NULL ) { /* exception was thrown */ goto finish; } if( list == NULL ) { goto finish; } /* traverse the list, placing each cert into the array */ for( node = CERT_LIST_HEAD(list), i=0; ! CERT_LIST_END(node, list); node = CERT_LIST_NEXT(node), i++ ) { CERTCertificate *cert; PK11SlotInfo *slotCopy; jobject certObj; /* Create a Java certificate object from the current CERTCertificate */ cert = CERT_DupCertificate(node->cert); slotCopy = PK11_ReferenceSlot(slot); certObj = JSS_PK11_wrapCertAndSlot(env, &cert, &slotCopy); if( certObj == NULL ) { goto finish; } /* put the Java certificate into the next element in the array */ (*env)->SetObjectArrayElement(env, certArray, i, certObj); if( (*env)->ExceptionOccurred(env) ) { goto finish; } } /* sanity check */ PR_ASSERT( i == count ); finish: if(list) { CERT_DestroyCertList(list); } if(slot) { PK11_FreeSlot(slot); } JSS_DerefJString(env, nickname, nickChars); return certArray; } /***************************************************************** * * CryptoManager.findCertByIssuerAndSerialNumberNative * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_CryptoManager_findCertByIssuerAndSerialNumberNative (JNIEnv *env, jobject this, jbyteArray issuerBA, jbyteArray serialNumBA) { jobject certObject=NULL; CERTCertificate *cert=NULL; SECItem *issuer=NULL, *serialNum=NULL; CERTIssuerAndSN issuerAndSN; PK11SlotInfo *slot=NULL; PR_ASSERT(env!=NULL && this!=NULL); /* validate args */ if( issuerBA == NULL || serialNumBA == NULL ) { JSS_throwMsg(env, ILLEGAL_ARGUMENT_EXCEPTION, "NULL parameter passed to CryptoManager.findCertByIssuer" "AndSerialNumberNative"); goto finish; } /* convert byte arrays to SECItems */ issuer = JSS_ByteArrayToSECItem(env, issuerBA); if( issuer == NULL ) { goto finish; } serialNum = JSS_ByteArrayToSECItem(env, serialNumBA); if( serialNum == NULL ) { goto finish; } issuerAndSN.derIssuer = *issuer; issuerAndSN.serialNumber = *serialNum; /* lookup with PKCS #11 first, then use cert database */ cert = PK11_FindCertByIssuerAndSN(&slot, &issuerAndSN, NULL /*wincx*/); if( cert == NULL ) { JSS_nativeThrow(env, OBJECT_NOT_FOUND_EXCEPTION); goto finish; } certObject = JSS_PK11_wrapCertAndSlot(env, &cert, &slot); finish: if(slot) { PK11_FreeSlot(slot); } if(cert != NULL) { CERT_DestroyCertificate(cert); } if(issuer) { SECITEM_FreeItem(issuer, PR_TRUE /*freeit*/); } if(serialNum) { SECITEM_FreeItem(serialNum, PR_TRUE /*freeit*/); } return certObject; } /***************************************************************** * * CryptoManager. f i n d P r i v K e y B y C e r t N a t i v e * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_CryptoManager_findPrivKeyByCertNative (JNIEnv *env, jobject this, jobject Cert) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread=NULL; CERTCertificate *cert; PK11SlotInfo *slot; SECKEYPrivateKey *privKey=NULL; jobject Key = NULL; pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT( pThread != NULL); PR_ASSERT( env!=NULL && this!=NULL && Cert!=NULL); if( JSS_PK11_getCertPtr(env, Cert, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } if(cert==NULL) { PR_ASSERT(PR_FALSE); JSS_throw(env, OBJECT_NOT_FOUND_EXCEPTION); goto finish; } if( JSS_PK11_getCertSlotPtr(env, Cert, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } if(slot==NULL) { PR_ASSERT(PR_FALSE); JSS_throw(env, OBJECT_NOT_FOUND_EXCEPTION); goto finish; } privKey = PK11_FindPrivateKeyFromCert(slot, cert, NULL); if(privKey == NULL) { JSS_throw(env, OBJECT_NOT_FOUND_EXCEPTION); goto finish; } Key = JSS_PK11_wrapPrivKey(env, &privKey); finish: if(privKey != NULL) { SECKEY_DestroyPrivateKey(privKey); } PR_DetachThread(); return Key; } /*********************************************************************** * Node in linked list of certificates */ typedef struct JSScertNode { struct JSScertNode *next; CERTCertificate *cert; } JSScertNode; /*********************************************************************** * * c e r t _ c h a i n _ f r o m _ c e r t * * Builds a certificate chain from a certificate. Returns a Java array * of PK11Certs. * * INPUTS: * env * The JNI environment. Must not be NULL. * handle * The certificate database in which to search for the certificate * chain. This should usually be the default cert db. Must not * be NULL. * leaf * A CERTCertificate that is the leaf of the cert chain. Must not * be NULL. * RETURNS: * NULL if an exception was thrown, or * A Java array of PK11Cert objects which constitute the chain of * certificates. The chains starts with the one passed in and * continues until either a self-signed root is found or the next * certificate in the chain cannot be found. At least one cert will * be in the chain: the leaf certificate passed in. */ static jobjectArray cert_chain_from_cert(JNIEnv *env, CERTCertDBHandle *handle, CERTCertificate *leaf) { CERTCertificate *c; int i, len = 0; JSScertNode *head=NULL, *tail, *node; jobjectArray certArray = NULL; jclass certClass; PR_ASSERT(env!=NULL && handle!=NULL && leaf!=NULL); head = tail = (JSScertNode*) PR_CALLOC( sizeof(JSScertNode) ); if (head == NULL) goto no_memory; /* put primary cert first in the linked list */ head->cert = c = CERT_DupCertificate(leaf); head->next = NULL; PR_ASSERT(c != NULL); /* CERT_DupCertificate really can't return NULL */ len++; /* * add certs until we come to a self-signed one */ while(SECITEM_CompareItem(&c->derIssuer, &c->derSubject) != SECEqual) { c = CERT_FindCertByName(handle, &tail->cert->derIssuer); if (c == NULL) break; tail->next = (JSScertNode*) PR_CALLOC( sizeof(JSScertNode) ); tail = tail->next; if (tail == NULL) goto no_memory; tail->cert = c; len++; } /* * Turn the cert chain into a Java array of certificates */ certClass = (*env)->FindClass(env, CERT_CLASS_NAME); if(certClass==NULL) { ASSERT_OUTOFMEM(env); goto finish; } certArray = (*env)->NewObjectArray(env, len, certClass, (jobject)NULL); if(certArray==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* convert linked list to array, freeing the linked list as we go */ for( i=0; head != NULL; ++i ) { jobject certObj; node = head; PR_ASSERT(i < len); PR_ASSERT(node->cert != NULL); /* Convert C cert to Java cert */ certObj = JSS_PK11_wrapCert(env, &node->cert); PR_ASSERT( node->cert == NULL ); if(certObj == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL ); goto finish; } /* Insert Java cert into array */ (*env)->SetObjectArrayElement(env, certArray, i, certObj); if( (*env)->ExceptionOccurred(env) ) { goto finish; } /* Free this list element */ head = head->next; PR_Free(node); } goto finish; no_memory: JSS_throw(env, OUT_OF_MEMORY_ERROR); finish: /* Free the linked list of certs if it hasn't been deleted already */ while(head != NULL) { node = head; head = head->next; if (node->cert != NULL) { CERT_DestroyCertificate(node->cert); } PR_Free(node); } return certArray; } /***************************************************************** * * CryptoManager. b u i l d C e r t i f i c a t e C h a i n N a t i v e * * INPUTS: * env * The JNI environment. Must not be NULL. * this * The PK11Finder object. Must not be NULL. * leafCert * A PK11Cert object from which a cert chain will be built. * Must not be NULL. * RETURNS: * NULL if an exception occurred, or * An array of PK11Certs, the cert chain, with the leaf at the bottom. * There will always be at least one element in the array (the leaf). */ JNIEXPORT jobjectArray JNICALL Java_org_mozilla_jss_CryptoManager_buildCertificateChainNative (JNIEnv *env, jobject this, jobject leafCert) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread=NULL; CERTCertificate *leaf; jobjectArray chainArray=NULL; CERTCertDBHandle *certdb; pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); PR_ASSERT(env!=NULL && this!=NULL && leafCert!=NULL); if( JSS_PK11_getCertPtr(env, leafCert, &leaf) != PR_SUCCESS) { JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Could not extract pointer from PK11Cert"); goto finish; } PR_ASSERT(leaf!=NULL); certdb = CERT_GetDefaultCertDB(); if(certdb == NULL) { PR_ASSERT(PR_FALSE); JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "No default certificate database has been registered"); goto finish; } /* Get the cert chain */ chainArray = cert_chain_from_cert(env, certdb, leaf); if(chainArray == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } finish: PR_DetachThread(); return chainArray; } /*********************************************************************** * DERCertCollection */ typedef struct { SECItem *derCerts; int numCerts; } DERCertCollection; /*********************************************************************** * c o l l e c t _ c e r t s * * Copies certs into a new array. * * 'arg' is a pointer to a DERCertCollection structure, which will be filled in. * 'certs' is an array of pointers to SECItems. */ static SECStatus collect_der_certs(void *arg, SECItem **certs, int numcerts) { int itemsCopied=0; SECItem *certCopies; /* array of SECItem */ SECStatus rv; PR_ASSERT(arg!=NULL); certCopies = PR_MALLOC( sizeof(SECItem) * numcerts); ((DERCertCollection*)arg)->derCerts = certCopies; ((DERCertCollection*)arg)->numCerts = numcerts; if(certCopies == NULL) { return SECFailure; } for(itemsCopied=0; itemsCopied < numcerts; itemsCopied++) { rv=SECITEM_CopyItem(NULL, &certCopies[itemsCopied], certs[itemsCopied]); if( rv == SECFailure ) { goto finish; } } PR_ASSERT(itemsCopied == numcerts); return SECSuccess; finish: for(; itemsCopied >= 0; itemsCopied--) { SECITEM_FreeItem( &certCopies[itemsCopied], PR_FALSE /*freeit*/); } PR_Free( certCopies ); ((DERCertCollection*)arg)->derCerts = NULL; ((DERCertCollection*)arg)->numCerts = 0; return SECFailure; } /*********************************************************************** * CryptoManager.importCertToPerm * - add the certificate to the permanent database * * throws TOKEN_EXCEPTION */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_CryptoManager_importCertToPermNative (JNIEnv *env, jobject this, jobject cert, jstring nickString) { SECStatus rv; CERTCertificate *oldCert; jobject result=NULL; char *nickname=NULL; CERTCertificate **certArray = NULL; SECItem *derCertArray[1]; PK11SlotInfo *slot; /* first, get the NSS cert pointer from the 'cert' object */ if ( JSS_PK11_getCertPtr(env, cert, &oldCert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(oldCert != NULL); /* dereference, discarding const qualifier */ nickname = (char *)JSS_RefJString(env, nickString); /* Then, add to permanent database */ derCertArray[0] = &oldCert->derCert; rv = CERT_ImportCerts(CERT_GetDefaultCertDB(), -1 /* usage */, 1, derCertArray, &certArray, PR_TRUE /*keepCerts*/, PR_FALSE /*caOnly*/, nickname); if( rv != SECSuccess || certArray == NULL || certArray[0] == NULL) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Unable to insert certificate" " into permanent database"); goto finish; } slot = PK11_GetInternalKeySlot(); /* the permanent database token */ result = JSS_PK11_wrapCertAndSlot(env, &certArray[0], &slot); finish: /* this checks for NULL */ CERT_DestroyCertArray(certArray, 1); JSS_DerefJString(env, nickString, nickname); return result; } static unsigned char* data_start(unsigned char *buf, int length, unsigned int *data_length, PRBool includeTag) { unsigned char tag; int used_length= 0; tag = buf[used_length++]; /* blow out when we come to the end */ if (tag == 0) { return NULL; } *data_length = buf[used_length++]; if (*data_length&0x80) { int len_count = *data_length & 0x7f; *data_length = 0; while (len_count-- > 0 && used_length < length) { *data_length = (*data_length << 8) | buf[used_length++]; } } if (*data_length > (unsigned)(length-used_length) ) { *data_length = length-used_length; return NULL; } if (includeTag) *data_length += used_length; return (buf + (includeTag ? 0 : used_length)); } static PRStatus getCertFields(SECItem *derCert, SECItem *issuer, SECItem *serial, SECItem *subject) { unsigned char *buf; unsigned int buf_length; unsigned char *date; unsigned int datelen; unsigned char *cert = derCert->data; unsigned int cert_length = derCert->len; /* get past the signature wrap */ buf = data_start(cert,cert_length,&buf_length,PR_FALSE); if (buf == NULL) return PR_FAILURE; /* get into the raw cert data */ buf = data_start(buf,buf_length,&buf_length,PR_FALSE); if (buf == NULL) return PR_FAILURE; /* skip past any optional version number */ if ((buf[0] & 0xa0) == 0xa0) { date = data_start(buf,buf_length,&datelen,PR_FALSE); if (date == NULL) return PR_FAILURE; buf_length -= (date-buf) + datelen; buf = date + datelen; } /* serial number */ serial->data = data_start(buf,buf_length,&serial->len,PR_FALSE); if (serial->data == NULL) return PR_FAILURE; buf_length -= (serial->data-buf) + serial->len; buf = serial->data + serial->len; /* skip the OID */ date = data_start(buf,buf_length,&datelen,PR_FALSE); if (date == NULL) return PR_FAILURE; buf_length -= (date-buf) + datelen; buf = date + datelen; /* issuer */ issuer->data = data_start(buf,buf_length,&issuer->len,PR_TRUE); if (issuer->data == NULL) return PR_FAILURE; buf_length -= (issuer->data-buf) + issuer->len; buf = issuer->data + issuer->len; /* skip the date */ date = data_start(buf,buf_length,&datelen,PR_FALSE); if (date == NULL) return PR_FAILURE; buf_length -= (date-buf) + datelen; buf = date + datelen; /*subject */ subject->data=data_start(buf,buf_length,&subject->len,PR_TRUE); if (subject->data == NULL) return PR_FAILURE; buf_length -= (subject->data-buf) + subject->len; buf = subject->data +subject->len; /*subject */ return PR_SUCCESS; } /** * Returns * -1 if operation error. * 0 if no leaf found. * 1 if leaf is found */ static int find_child_cert( CERTCertDBHandle *certdb, SECItem *derCerts, int numCerts, int *linked, int cur_link, int *leaf_link ) { int i; int status = 0; SECItem parentIssuer, parentSerial, parentSubject; PRStatus decodeStatus; decodeStatus = getCertFields(&derCerts[cur_link], &parentIssuer, &parentSerial, &parentSubject); if( decodeStatus != PR_SUCCESS ) { status = -1; goto finish; } for (i=0; iExceptionOccurred(env)); goto finish; } /*************************************************** * Decode package with NSS function ***************************************************/ status = CERT_DecodeCertPackage((char*) packageBytes, (int) packageLen, collect_der_certs, (void*) &collection); if( status != SECSuccess || collection.numCerts < 1 ) { if( (*env)->ExceptionOccurred(env) == NULL) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "Security library failed to decode certificate package"); } goto finish; } derCerts = collection.derCerts; numCerts = collection.numCerts; /*************************************************** * convert nickname to char*, discarding const ***************************************************/ nickChars = (char *)JSS_RefJString(env, nickString); /*************************************************** * user cert can be anywhere in the cert chain. loop and find it. * The point is to find the user cert with keys on the db, then * treat the other certs in the chain as CA certs to import. * The real order of the cert chain shouldn't matter, and shouldn't * be assumed, and the real location of this user cert in the chain, * if present, shouldn't be assumed either. ***************************************************/ if (numCerts > 1) { for (certi=0; certi= 1 ) { if (certi == 0) { status = CERT_ImportCAChainTrusted(derCerts+userCertFound, numCerts-userCertFound, certUsageUserCertImport); if(status != SECSuccess) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "CERT_ImportCAChainTrusted returned an error"); goto finish; } } else if (certi == numCerts) { status = CERT_ImportCAChainTrusted(derCerts, numCerts-userCertFound, certUsageUserCertImport); if(status != SECSuccess) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "CERT_ImportCAChainTrusted returned an error"); goto finish; } } else { status = CERT_ImportCAChainTrusted(derCerts, certi, certUsageUserCertImport); if(status != SECSuccess) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "CERT_ImportCAChainTrusted returned an error"); goto finish; } status = CERT_ImportCAChainTrusted(derCerts+certi+1, numCerts-certi-1, certUsageUserCertImport); if(status != SECSuccess) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "CERT_ImportCAChainTrusted returned an error"); goto finish; } } } /*************************************************** * Now lookup the leaf cert and make it into a Java object. ***************************************************/ if(slot) { PK11_FreeSlot(slot); } leafCert = PK11_FindCertByIssuerAndSN(&slot, &issuerAndSN, NULL); if( leafCert == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find certificate that was just imported"); goto finish; } leafObject = JSS_PK11_wrapCertAndSlot(env, &leafCert, &slot); finish: if(slot!=NULL) { PK11_FreeSlot(slot); } if(derCerts != NULL) { for(i=0; i < numCerts; i++) { SECITEM_FreeItem(&derCerts[i], PR_FALSE /*freeit*/); } PR_Free(derCerts); } /* don't copy back */ JSS_DerefByteArray(env, packageArray, packageBytes, JNI_ABORT); if(leafCert != NULL) { CERT_DestroyCertificate(leafCert); } JSS_DerefJString(env, nickString, nickChars); return leafObject; } /********************************************************************** * PKCS #7 Encoding data structures */ typedef struct BufferNodeStr { char *data; unsigned long len; struct BufferNodeStr *next; } BufferNode; typedef struct { BufferNode *head; BufferNode *tail; unsigned long totalLen; } EncoderCallbackInfo; /********************************************************************** * c r e a t e E n c o d e r C a l l b a c k I n f o * * Constructor for EncoderCallbackInfo structure. * Returns NULL if it runs out of memory, otherwise a new EncoderCallbackInfo. */ static EncoderCallbackInfo* createEncoderCallbackInfo() { EncoderCallbackInfo *info; info = PR_Malloc( sizeof(EncoderCallbackInfo) ); if( info == NULL ) { return NULL; } info->head = info->tail = NULL; info->totalLen = 0; return info; } /*********************************************************************** * d e s t r o y E n c o d e r C a l l b a c k I n f o * * Destructor for EncoderCallbackInfo structure. */ static void destroyEncoderCallbackInfo(EncoderCallbackInfo *info) { BufferNode *node; PR_ASSERT(info != NULL); while(info->head != NULL) { node = info->head; info->head = info->head->next; if(node->data) { PR_Free(node->data); } PR_Free(node); } PR_Free(info); } /*********************************************************************** * e n c o d e r O u t p u t C a l l b a c k * * Called by the PKCS #7 encoder whenever output is available. * Appends the output to a linked list. */ static void encoderOutputCallback( void *arg, const char *buf, unsigned long len) { BufferNode *node; EncoderCallbackInfo *info; /*************************************************** * validate arguments ***************************************************/ PR_ASSERT(arg!=NULL); info = (EncoderCallbackInfo*) arg; if(len == 0) { return; } PR_ASSERT(buf != NULL); /*************************************************** * Create a new node to store this information ***************************************************/ node = PR_NEW( BufferNode ); if( node == NULL ) { PR_ASSERT(PR_FALSE); goto finish; } node->len = len; node->data = PR_Malloc( len ); if( node->data == NULL ) { PR_ASSERT(PR_FALSE); goto finish; } memcpy( node->data, buf, len ); node->next = NULL; /*************************************************** * Stick the new node onto the end of the list ***************************************************/ if( info->head == NULL ) { PR_ASSERT(info->tail == NULL); info->head = info->tail = node; } else { PR_ASSERT(info->tail != NULL); info->tail->next = node; info->tail = node; } node = NULL; info->totalLen += len; finish: if(node != NULL) { if( node->data != NULL) { PR_Free(node->data); } PR_Free(node); } return; } /*********************************************************************** * CryptoManager.exportCertsToPKCS7 */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_CryptoManager_exportCertsToPKCS7 (JNIEnv *env, jobject this, jobjectArray certArray) { int i, certcount; SEC_PKCS7ContentInfo *cinfo=NULL; CERTCertificate *cert; jclass certClass; jbyteArray pkcs7ByteArray=NULL; jbyte *pkcs7Bytes=NULL; EncoderCallbackInfo *info=NULL; SECStatus status; /************************************************** * Validate arguments **************************************************/ PR_ASSERT(env!=NULL && this!=NULL); if(certArray == NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } certcount = (*env)->GetArrayLength(env, certArray); if(certcount < 1) { JSS_throwMsg(env, CERTIFICATE_ENCODING_EXCEPTION, "At least one certificate must be passed to exportCertsToPKCS7"); goto finish; } /* * JNI ID lookup */ certClass = (*env)->FindClass(env, CERT_CLASS_NAME); if(certClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /*************************************************** * Add each cert to the PKCS #7 context. Create the context * for the first cert. ***************************************************/ for(i=0; i < certcount; i++) { jobject certObject; certObject = (*env)->GetObjectArrayElement(env, certArray, i); if( (*env)->ExceptionOccurred(env) != NULL) { goto finish; } PR_ASSERT( certObject != NULL ); /* * Make sure this is a PK11Cert */ if( ! (*env)->IsInstanceOf(env, certObject, certClass) ) { JSS_throwMsg(env, CERTIFICATE_ENCODING_EXCEPTION, "Certificate was not a PK11 Certificate"); goto finish; } /* * Convert it to a CERTCertificate */ if( JSS_PK11_getCertPtr(env, certObject, &cert) != PR_SUCCESS) { JSS_trace(env, JSS_TRACE_ERROR, "Unable to convert Java certificate to CERTCertificate"); goto finish; } PR_ASSERT(cert != NULL); if( i == 0 ) { /* * First certificate: create a new PKCS #7 cert-only context */ PR_ASSERT(cinfo == NULL); cinfo = SEC_PKCS7CreateCertsOnly(cert, PR_FALSE, /* don't include chain */ NULL /* cert db */ ); if(cinfo == NULL) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "Failed to create PKCS #7 encoding context"); goto finish; } } else { /* * All remaining certificates: add cert to context */ PR_ASSERT(cinfo != NULL); if( SEC_PKCS7AddCertificate(cinfo, cert) != SECSuccess ) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "Failed to add certificate to PKCS #7 encoding context"); goto finish; } } } PR_ASSERT( i == certcount ); PR_ASSERT( cinfo != NULL ); /************************************************** * Encode the PKCS #7 context into its DER encoding **************************************************/ info = createEncoderCallbackInfo(); if(info == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } status = SEC_PKCS7Encode(cinfo, encoderOutputCallback, (void*)info, NULL /* bulk key */, NULL /* password function */, NULL /* password function arg */ ); if( status != SECSuccess ) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "Failed to encode PKCS #7 context"); } /* Make sure we got at least some data from the encoder */ PR_ASSERT(info->totalLen > 0); PR_ASSERT(info->head != NULL); /************************************************** * Create a new byte array to hold the encoded PKCS #7 **************************************************/ pkcs7ByteArray = (*env)->NewByteArray(env, info->totalLen); if(pkcs7ByteArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } pkcs7Bytes = (*env)->GetByteArrayElements(env, pkcs7ByteArray, NULL); if(pkcs7Bytes == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /************************************************** * Copy the PKCS #7 encoding into the byte array **************************************************/ { BufferNode *node; unsigned long processed=0; for(node=info->head; node!=NULL; node = node->next) { PR_ASSERT(processed < info->totalLen); PR_ASSERT(node->data != NULL); PR_ASSERT(node->len > 0); memcpy(pkcs7Bytes+processed, node->data, node->len); processed += node->len; } PR_ASSERT( processed == info->totalLen ); } finish: /************************************************** * Free allocated resources **************************************************/ if( cinfo != NULL) { SEC_PKCS7DestroyContentInfo(cinfo); } JSS_DerefByteArray(env, pkcs7ByteArray, pkcs7Bytes, 0); if( info != NULL ) { destroyEncoderCallbackInfo(info); } /************************************************** * Return the PKCS #7 information in a byte array, or NULL if an * exception occurred **************************************************/ PR_ASSERT( (*env)->ExceptionOccurred(env)!=NULL || pkcs7ByteArray!=NULL ); return pkcs7ByteArray; } /*************************************************************************** * getCerts * * Gathers all certificates of the given type into a Java array. */ static jobjectArray getCerts(JNIEnv *env, PK11CertListType type) { jobjectArray certArray = NULL; jclass certClass; jobject certObject; CERTCertList *certList = NULL; CERTCertListNode *node; int numCerts, i; certList = PK11_ListCerts(type, NULL); if( certList == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Unable to list certificates"); goto finish; } /* first count the damn certs */ numCerts = 0; for( node = CERT_LIST_HEAD(certList); ! CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node) ) { ++numCerts; } /************************************************** * Create array of Java certificates **************************************************/ certClass = (*env)->FindClass(env, X509_CERT_CLASS); if(certClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } certArray = (*env)->NewObjectArray( env, numCerts, certClass, NULL ); if( certArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT( (*env)->ExceptionOccurred(env) == NULL ); /************************************************** * Put all the certs in the array **************************************************/ i = 0; for( node = CERT_LIST_HEAD(certList); ! CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node) ) { PR_ASSERT( i < numCerts ); certObject = JSS_PK11_wrapCert(env, &(node->cert)); if( certObject == NULL ) { goto finish; } (*env)->SetObjectArrayElement(env, certArray, i, certObject); if( (*env)->ExceptionOccurred(env) ) { goto finish; } ++i; } PR_ASSERT( i == numCerts ); finish: if( certList != NULL ) { CERT_DestroyCertList(certList); } return certArray; } /*********************************************************************** * CryptoManager.getCACerts */ JNIEXPORT jobjectArray JNICALL Java_org_mozilla_jss_CryptoManager_getCACerts (JNIEnv *env, jobject this) { return getCerts(env, PK11CertListCA); } /*********************************************************************** * CryptoManager.getPermCerts */ JNIEXPORT jobjectArray JNICALL Java_org_mozilla_jss_CryptoManager_getPermCerts (JNIEnv *env, jobject this) { return getCerts(env, PK11CertListUnique); } /* Imports a CRL, and stores it into the cert7.db * * @param the DER-encoded CRL. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_importCRLNative (JNIEnv *env, jobject this, jbyteArray der_crl, jstring url_jstr, jint rl_type) { CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); CERTSignedCrl *crl = NULL; SECItem *packageItem = NULL; int status = SECFailure; char *url = NULL; const char *errmsg = NULL; /*************************************************** * Validate arguments ***************************************************/ PR_ASSERT( env!=NULL && this!=NULL ); if(der_crl == NULL) { PR_ASSERT(PR_FALSE); /* XXX need new exception here */ JSS_throwMsg(env, CERTIFICATE_ENCODING_EXCEPTION, "CRL package is NULL"); goto finish; } PR_ASSERT(certdb != NULL); /* convert CRL byte[] into secitem */ packageItem = JSS_ByteArrayToSECItem(env, der_crl); if ( packageItem == NULL ) { goto finish; } url = (char *)JSS_RefJString(env, url_jstr); if (url_jstr != NULL && url == NULL) { goto finish; } crl = CERT_ImportCRL( certdb, packageItem, url, rl_type, NULL); if( crl == NULL ) { status = PR_GetError(); errmsg = NULL; switch (status) { case SEC_ERROR_OLD_CRL: case SEC_ERROR_OLD_KRL: /* not an error - leave as NULL */ errmsg = NULL; goto finish; case SEC_ERROR_CRL_EXPIRED: errmsg = "CRL Expired"; break; case SEC_ERROR_KRL_EXPIRED: errmsg = "KRL Expired"; break; case SEC_ERROR_CRL_NOT_YET_VALID: errmsg = "CRL Not yet valid"; break; case SEC_ERROR_KRL_NOT_YET_VALID: errmsg = "KRL Not yet valid"; break; case SEC_ERROR_CRL_INVALID: errmsg = "Invalid encoding of CRL"; break; case SEC_ERROR_KRL_INVALID: errmsg = "Invalid encoding of KRL"; break; case SEC_ERROR_BAD_DATABASE: errmsg = "Database error"; break; default: /* printf("NSS ERROR = %d\n",status); */ errmsg = "Failed to import Revocation List"; } if (errmsg) { JSS_throwMsgPrErr(env, CRL_IMPORT_EXCEPTION, errmsg); } } finish: if (packageItem) { SECITEM_FreeItem(packageItem, PR_TRUE /*freeit*/); } JSS_DerefJString(env, url_jstr, url); if (crl) { SEC_DestroyCrl(crl); } } /*********************************************************************** * 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; const char *nickname = NULL; nickname = JSS_RefJString(env, nickString); if( nickname == NULL ) { goto finish; } int ocspPolicy = JSSL_getOCSPPolicy(); certificateUsage = required_certificateUsage; cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname); if (cert == NULL) { char *message = PR_smprintf("Certificate not found: %s", nickname); JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, message); PR_smprintf_free(message); goto finish; } else { /* 0 for certificateUsage in call to CERT_VerifyCertificateNow will * retrieve the current valid usage into currUsage */ if( ocspPolicy == OCSP_LEAF_AND_CHAIN_POLICY) { rv = JSSL_verifyCertPKIX( cert, certificateUsage, NULL /* pin arg */, ocspPolicy, NULL, currUsage); /* we need to do this just to get the cert usages, the pkix version doesn't seem to honor the method to get the usages as of yet. Let the PKIX call only determine the final fate. */ if(rv == SECSuccess) { CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert, checkSig, certificateUsage, NULL, currUsage ); } } else { 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: JSS_DerefJString(env, nickString, nickname); if(cert != NULL) { CERT_DestroyCertificate(cert); } return rv; } /*********************************************************************** * CryptoManager.verifyCertificateNowNative * * Returns JNI_TRUE if success, JNI_FALSE otherwise */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative(JNIEnv *env, jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage) { SECStatus rv = SECFailure; SECCertificateUsage certificateUsage; SECCertificateUsage currUsage; /* unexposed for now */ CERTCertificate *cert=NULL; const char *nickname = NULL; nickname = JSS_RefJString(env, nickString); if( nickname == NULL ) { goto finish; } int ocspPolicy = JSSL_getOCSPPolicy(); certificateUsage = required_certificateUsage; cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname); if (cert == NULL) { char *message = PR_smprintf("Certificate not found: %s", nickname); JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, message); PR_smprintf_free(message); goto finish; } else { /* 0 for certificateUsage in call to CERT_VerifyCertificateNow to * just get the current usage (which we are not passing back for now * but will bypass the certificate usage check */ if( ocspPolicy == OCSP_LEAF_AND_CHAIN_POLICY) { rv= JSSL_verifyCertPKIX( cert, certificateUsage, NULL /* pin arg */, ocspPolicy, NULL, &currUsage); /* we need to do this just to get the cert usages, the pkix version doesn't seem to honor the method to get the usages as of yet. Let the PKIX call only determine the final fate. */ if(rv == SECSuccess) { CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert, checkSig, certificateUsage, NULL, &currUsage ); } } else { rv = CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert, checkSig, certificateUsage, NULL, &currUsage ); } } finish: JSS_DerefJString(env, nickString, nickname); if(cert != NULL) { CERT_DestroyCertificate(cert); } if( rv == SECSuccess) { return JNI_TRUE; } else { return JNI_FALSE; } } /*********************************************************************** * 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; } void JSS_VerifyCertificate(JNIEnv *env, CERTCertificate *cert, jboolean checkSig, jint usage) { jint certificateUsage; SECCertificateUsage currUsage = 0x0000; /* unexposed for now */ SECStatus rv = SECFailure; int ocspPolicy = JSSL_getOCSPPolicy(); certificateUsage = usage; /* 0 for certificateUsage in call to CERT_VerifyCertificateNow will * retrieve the current valid usage into currUsage */ if( ocspPolicy == OCSP_LEAF_AND_CHAIN_POLICY) { rv = JSSL_verifyCertPKIX( cert, certificateUsage, NULL /* pin arg */, ocspPolicy, NULL, &currUsage); /* we need to do this just to get the cert usages, the pkix version doesn't seem to honor the method to get the usages as of yet. Let the PKIX call only determine the final fate. */ if(rv == SECSuccess) { CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert, checkSig, certificateUsage, NULL, &currUsage ); } } else { rv = CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert, checkSig, certificateUsage, NULL, &currUsage); } if (rv != SECSuccess) { JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Invalid certificate"); return; } if ((certificateUsage == 0x0000) && (currUsage == ( certUsageUserCertImport | certUsageVerifyCA | certUsageProtectedObjectSigner | certUsageAnyCA ))) { /* The certificate is good for nothing. * The following usages cannot be verified: * certUsageAnyCA * certUsageProtectedObjectSigner * certUsageUserCertImport * certUsageVerifyCA * (0x0b80) */ JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Unusable certificate"); return; } } /*********************************************************************** * CryptoManager.verifyCertificateNowNative2 * * Verify a certificate that exists in the given cert database, * check if it's valid and that we trust the issuer. Verify time * against now. * @param nickname nickname of the certificate to verify. * @param checkSig verify the signature of the certificate * @param certificateUsage see certificate usage defined to verify certificate * * @exception InvalidNicknameException If the nickname is null. * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. * @exception CertificateException If certificate is invalid. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2(JNIEnv *env, jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage) { CERTCertificate *cert = NULL; const char *nickname = NULL; if (nickString == NULL) { JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname"); goto finish; } nickname = JSS_RefJString(env, nickString); if (nickname == NULL) { JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname"); goto finish; } cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname); if (cert == NULL) { char *msgBuf; msgBuf = PR_smprintf("Certificate not found: %s", nickname); JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, msgBuf); PR_Free(msgBuf); goto finish; } JSS_VerifyCertificate(env, cert, checkSig, required_certificateUsage); finish: JSS_DerefJString(env, nickString, nickname); CERT_DestroyCertificate(cert); } JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative3(JNIEnv *env, jobject self, jobject Cert, jboolean checkSig, jint required_certificateUsage) { CERTCertificate *cert = NULL; if (JSS_PK11_getCertPtr(env, Cert, &cert) != PR_SUCCESS) { PR_ASSERT((*env)->ExceptionOccurred(env) != NULL); return; } JSS_VerifyCertificate(env, cert, checkSig, required_certificateUsage); } /*********************************************************************** * CryptoManager.verifyCertNowNative * note: this calls obsolete NSS function * Returns JNI_TRUE if success, JNI_FALSE otherwise */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertNowNative(JNIEnv *env, jobject self, jstring nickString, jboolean checkSig, jint cUsage) { SECStatus rv = SECFailure; SECCertUsage certUsage; CERTCertificate *cert=NULL; const char *nickname = NULL; nickname = JSS_RefJString(env, nickString); if( nickname == NULL ) { goto finish; } int ocspPolicy = JSSL_getOCSPPolicy(); certUsage = cUsage; cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname); if (cert == NULL) { char *message = PR_smprintf("Certificate not found: %s", nickname); JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, message); PR_smprintf_free(message); goto finish; } else { if( ocspPolicy == OCSP_LEAF_AND_CHAIN_POLICY) { rv = JSSL_verifyCertPKIX( cert, certUsage, NULL /* pin arg */, ocspPolicy, NULL, NULL); } else { rv = CERT_VerifyCertNow(CERT_GetDefaultCertDB(), cert, checkSig, certUsage, NULL ); } } finish: JSS_DerefJString(env, nickString, nickname); if(cert != NULL) { CERT_DestroyCertificate(cert); } if( rv == SECSuccess) { return JNI_TRUE; } else { return JNI_FALSE; } } /*********************************************************************** * CryptoManager.verifyCertNative * * Returns JNI_TRUE if success, JNI_FALSE otherwise */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertTempNative(JNIEnv *env, jobject self, jbyteArray packageArray,jboolean checkSig, jint cUsage) { SECStatus rv = SECFailure; SECCertUsage certUsage; SECItem *derCerts[2] = { NULL, NULL }; CERTCertificate **certArray = NULL; CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); /*************************************************** * Validate arguments ***************************************************/ if (packageArray == NULL) { JSS_throwMsg(env, CERTIFICATE_ENCODING_EXCEPTION, "Certificate package is NULL"); goto finish; } PR_ASSERT(certdb != NULL); derCerts[0] = JSS_ByteArrayToSECItem(env, packageArray); derCerts[1] = NULL; int ocspPolicy = JSSL_getOCSPPolicy(); rv = CERT_ImportCerts(certdb, cUsage, 1, derCerts, &certArray, PR_FALSE /*temp Certs*/, PR_FALSE /*caOnly*/, NULL); if ( rv != SECSuccess || certArray == NULL || certArray[0] == NULL) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Unable to insert certificate" " into temporary database"); goto finish; } certUsage = cUsage; if( ocspPolicy == OCSP_LEAF_AND_CHAIN_POLICY) { rv = JSSL_verifyCertPKIX( certArray[0], certUsage, NULL /* pin arg */, ocspPolicy, NULL, NULL); } else { rv = CERT_VerifyCertNow(certdb, certArray[0], checkSig, certUsage, NULL ); } finish: /* this checks for NULL */ CERT_DestroyCertArray(certArray, 1); if (derCerts[0]) { SECITEM_FreeItem(derCerts[0], PR_TRUE /*freeit*/); } if ( rv == SECSuccess) { return JNI_TRUE; } else { return JNI_FALSE; } } /*********************************************************************** * CryptoManager.importDERCertNative */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_CryptoManager_importDERCertNative(JNIEnv *env, jobject self, jbyteArray cert, int usage, jboolean permanent, jstring nickname) { char *nickname_raw = NULL; jsize derCertLen; SECItem *derCert = calloc(1, sizeof(SECItem)); CERTCertificate **retCert = NULL; PR_ASSERT(env != NULL &&& self != NULL); if (cert == NULL) { return NULL; } if (nickname != NULL) { nickname_raw = (char *)JSS_RefJString(env, nickname); } derCert->type = siDERCertBuffer; if (!JSS_RefByteArray(env, cert, (signed char **)&derCert->data, &derCertLen)) { return NULL; } PR_ASSERT(derCertLen > 0); derCert->len = (unsigned int)derCertLen; /* At the time of writing, caOnly is an unused parameter. */ if (CERT_ImportCerts(CERT_GetDefaultCertDB(), usage, 1, &derCert, &retCert, permanent, PR_FALSE, nickname_raw) != SECSuccess) { JSS_DerefByteArray(env, cert, derCert->data, JNI_ABORT); JSS_DerefJString(env, nickname, nickname_raw); JSS_throwMsgPortErr(env, INVALID_PARAMETER_EXCEPTION, "Unable to import certificate"); return NULL; } JSS_DerefByteArray(env, cert, derCert->data, JNI_ABORT); JSS_DerefJString(env, nickname, nickname_raw); return JSS_PK11_wrapCert(env, retCert); } jss-4.6.3/org/mozilla/jss/SecretDecoderRing/000077500000000000000000000000001362106420000207055ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/SecretDecoderRing/Decryptor.java000066400000000000000000000066211362106420000235300ustar00rootroot00000000000000/* 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.SecretDecoderRing; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.TokenException; /** * Decrypts data with the SecretDecoderRing. */ public class Decryptor { private CryptoToken token; private KeyManager keyManager; /** * Creates a Decryptor for use with the given CryptoToken. */ public Decryptor(CryptoToken token) { this.token = token; this.keyManager = new KeyManager(token); } /** * Decrypts the given ciphertext. It must have been created previously * with the SecretDecoderRing, either the JSS version or the NSS version. * The key used for decryption must exist on the token that was passed * into the constructor. The token will be searched for a key whose keyID * matches the keyID in the encoded SecretDecoderRing result. * * @param ciphertext A DER-encoded Encoding object, created from a previous * call to Encryptor.encrypt(), or with the NSS SecretDecoderRing. * @return The decrypted plaintext. * @throws InvalidKeyException If no key can be found with the matching * keyID. */ public byte[] decrypt(byte[] ciphertext) throws NotInitializedException, GeneralSecurityException, TokenException { CryptoManager cm = CryptoManager.getInstance(); CryptoToken savedToken = cm.getThreadToken(); try { cm.setThreadToken(token); // // decode ASN1 // Encoding encoding = (Encoding) ASN1Util.decode(Encoding.getTemplate(), ciphertext); // // lookup the algorithm // EncryptionAlgorithm alg = EncryptionAlgorithm.fromOID( encoding.getEncryptionOID() ); // // Lookup the key // SecretKey key = keyManager.lookupKey(alg, encoding.getKeyID()); if( key == null ) { throw new InvalidKeyException("No matching key found"); } // // do the decryption // IvParameterSpec ivSpec = new IvParameterSpec(encoding.getIv()); Cipher cipher = Cipher.getInstance(alg.toString(), Encryptor.PROVIDER); cipher.init(Cipher.DECRYPT_MODE, key, ivSpec); byte[] paddedPtext = cipher.doFinal(encoding.getCiphertext()); return org.mozilla.jss.crypto.Cipher.unPad(paddedPtext, alg.getBlockSize() ); } catch(InvalidBERException ibe) { throw new GeneralSecurityException(ibe.toString()); } catch(IllegalStateException ise) { throw new GeneralSecurityException(ise.toString()); } finally { cm.setThreadToken(savedToken); } } } jss-4.6.3/org/mozilla/jss/SecretDecoderRing/Encoding.java000066400000000000000000000070331362106420000233010ustar00rootroot00000000000000/* 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.SecretDecoderRing; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.io.*; /** * An ASN.1 class for encoding the SecretDecoderRing result. * This class is used internally by the SecretDecoderRing. * You need not use this class directly in order to use the SecretDecoderRing. */ public class Encoding implements ASN1Value { private SEQUENCE seq = new SEQUENCE(); private byte[] iv; private OBJECT_IDENTIFIER encOID; private byte[] ctext; private byte[] keyID; public Encoding(byte[] keyID, byte[] iv, OBJECT_IDENTIFIER encOID, byte[] ctext) { this.keyID = keyID; this.iv = iv; this.encOID = encOID; this.ctext = ctext; AlgorithmIdentifier algID = new AlgorithmIdentifier( encOID, new OCTET_STRING(iv) ); seq.addElement(new OCTET_STRING(keyID)); seq.addElement(algID); seq.addElement(new OCTET_STRING(ctext)); } public byte[] getKeyID() { return keyID; } public byte[] getIv() { return iv; } public OBJECT_IDENTIFIER getEncryptionOID() { return encOID; } public byte[] getCiphertext() { return ctext; } 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 { seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * An ASN.1 class for decoding the SecretDecoderRing result. * This class is used internally by the SecretDecoderRing. * You need not use this class directly in order to use the * SecretDecoderRing. */ public static class Template extends SEQUENCE.Template { private SEQUENCE.Template template; public Template() { template = new SEQUENCE.Template(); template.addElement(OCTET_STRING.getTemplate() ); template.addElement(AlgorithmIdentifier.getTemplate() ); template.addElement(OCTET_STRING.getTemplate() ); } 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 implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) template.decode(implicitTag, istream); OCTET_STRING keyID = (OCTET_STRING) seq.elementAt(0); AlgorithmIdentifier algID = (AlgorithmIdentifier) seq.elementAt(1); OCTET_STRING ivOS = (OCTET_STRING) ((ANY)algID.getParameters()).decodeWith( OCTET_STRING.getTemplate()); OCTET_STRING ctextOS = (OCTET_STRING)seq.elementAt(2); return new Encoding(keyID.toByteArray(), ivOS.toByteArray(), algID.getOID(), ctextOS.toByteArray()); } } } jss-4.6.3/org/mozilla/jss/SecretDecoderRing/Encryptor.java000066400000000000000000000076111362106420000235420ustar00rootroot00000000000000/* 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.SecretDecoderRing; import java.security.*; import javax.crypto.*; import javax.crypto.spec.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.TokenException; /** * Encrypts data with the SecretDecoderRing. */ public class Encryptor { private CryptoToken token; private byte[] keyID; private SecretKey key; private EncryptionAlgorithm alg; private KeyManager keyManager; /** * The default encryption algorithm, currently DES3_CBC. */ public static final EncryptionAlgorithm DEFAULT_ENCRYPTION_ALG = EncryptionAlgorithm.DES3_CBC; static final String PROVIDER = "Mozilla-JSS"; static final String RNG_ALG = "pkcs11prng"; /** * Creates an Encryptor on the given CryptoToken, using the key with * the given keyID and algorithm * @param token The CryptoToken to use for encryption. The key must * reside on this token. * @param keyID The keyID of the key to use for encryption. This key * must have been generated on this token with KeyManager. * @param alg The EncryptionAlgorithm this key will be used for. * @throws InvalidKeyException If no key exists on this token with this * keyID. */ public Encryptor(CryptoToken token, byte[] keyID, EncryptionAlgorithm alg) throws TokenException, InvalidKeyException { this.token = token; this.keyID = keyID; this.alg = alg; this.keyManager = new KeyManager(token); // make sure this key exists on the token key = keyManager.lookupKey(alg, keyID); if( key == null ) { throw new InvalidKeyException("Key not found"); } // make sure key matches algorithm // !!! not sure how to do this } /** * Encrypts a byte array. * @param plaintext The plaintext bytes to be encrypted. * @return The ciphertext. This is actually a DER-encoded Encoding * object. It contains the keyID, AlgorithmIdentifier, and the encrypted * plaintext. It is compatible with the SDRResult created by NSS's * SecretDecoderRing. */ public byte[] encrypt(byte[] plaintext) throws NotInitializedException, GeneralSecurityException, InvalidBERException { CryptoManager cm = CryptoManager.getInstance(); CryptoToken savedToken = cm.getThreadToken(); try { cm.setThreadToken(token); // // generate an IV // byte[] iv = new byte[alg.getIVLength()]; SecureRandom rng = SecureRandom.getInstance(RNG_ALG, PROVIDER); rng.nextBytes(iv); IvParameterSpec ivSpec = new IvParameterSpec(iv); // // do the encryption // Cipher cipher = Cipher.getInstance(alg.toString(),PROVIDER); cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); byte[] paddedPtext = org.mozilla.jss.crypto.Cipher.pad( plaintext, alg.getBlockSize() ); byte[] rawCtext = cipher.doFinal(paddedPtext); // // package the encrypted content and IV // Encoding encoding = new Encoding(keyID, iv, alg.toOID(), rawCtext); return ASN1Util.encode(encoding); } catch(IllegalStateException ise ) { throw new GeneralSecurityException(ise.toString()); } finally { cm.setThreadToken(savedToken); } } } jss-4.6.3/org/mozilla/jss/SecretDecoderRing/KeyManager.c000066400000000000000000000237151362106420000231040ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_SecretDecoderRing_KeyManager.h" #include #include #include #include #include #include #include JNIEXPORT void JNICALL Java_org_mozilla_jss_SecretDecoderRing_KeyManager_generateKeyNative (JNIEnv *env, jobject this, jobject tokenObj, jobject algObj, jbyteArray keyIDba, jint keySize) { PK11SlotInfo *slot = NULL; CK_MECHANISM_TYPE mech; PK11SymKey *symk = NULL; SECItem *keyID = NULL; /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) { goto finish; } if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/) != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to login to token"); goto finish; } /* get the key ID */ keyID = JSS_ByteArrayToSECItem(env, keyIDba); if( keyID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* get the algorithm */ mech = JSS_getPK11MechFromAlg(env, algObj); if( mech == CKM_INVALID_MECHANISM) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find PKCS #11 " "mechanism for key generation algorithm"); goto finish; } /* generate the key */ symk = PK11_TokenKeyGen(slot, mech, NULL /*param*/, keySize, keyID, PR_TRUE /* isToken */, NULL /*wincx*/); if( symk == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to generate token symmetric key"); goto finish; } finish: if( symk != NULL ) { PK11_FreeSymKey(symk); } if( keyID != NULL ) { SECITEM_FreeItem(keyID, PR_TRUE /*freeit*/); } return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_SecretDecoderRing_KeyManager_generateUniqueNamedKeyNative (JNIEnv *env, jobject this, jobject tokenObj, jobject algObj, jbyteArray keyIDba, jint keySize, jstring nickname) { PK11SlotInfo *slot = NULL; CK_MECHANISM_TYPE mech; PK11SymKey *symk = NULL; SECItem *keyID = NULL; const char *keyname = NULL; SECStatus status; /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) { goto finish; } if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/) != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to login to token"); goto finish; } /* get the key ID */ keyID = JSS_ByteArrayToSECItem(env, keyIDba); if( keyID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* get the algorithm */ mech = JSS_getPK11MechFromAlg(env, algObj); if( mech == CKM_INVALID_MECHANISM) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find PKCS #11 " "mechanism for key generation algorithm"); goto finish; } /* generate the key */ symk = PK11_TokenKeyGen(slot, mech, NULL /*param*/, keySize, keyID, PR_TRUE /* isToken */, NULL /*wincx*/); if( symk == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to generate token symmetric key"); goto finish; } /* convert the Java String into a native "C" string */ keyname = JSS_RefJString(env, nickname); /* name the key */ status = PK11_SetSymKeyNickname( symk, keyname ); if( status != SECSuccess ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to name token symmetric key"); } finish: if( symk != NULL ) { PK11_FreeSymKey(symk); } if( keyID != NULL ) { SECITEM_FreeItem(keyID, PR_TRUE /*freeit*/); } /* free the native "C" string */ JSS_DerefJString(env, nickname, keyname); return; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_SecretDecoderRing_KeyManager_lookupKeyNative (JNIEnv *env, jobject this, jobject tokenObj, jobject algObj, jbyteArray keyIDba) { PK11SlotInfo *slot = NULL; PK11SymKey *symk = NULL; SECItem *keyID = NULL; jobject symkObj = NULL; CK_MECHANISM_TYPE mech; /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) { goto finish; } if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/) != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to login to token"); goto finish; } /* get the key ID */ keyID = JSS_ByteArrayToSECItem(env, keyIDba); if( keyID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* get the algorithm */ mech = JSS_getPK11MechFromAlg(env, algObj); if( mech == CKM_INVALID_MECHANISM) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find PKCS #11 " "mechanism for key generation algorithm"); goto finish; } symk = PK11_FindFixedKey(slot, mech, keyID, NULL /*wincx*/); if( symk != NULL ) { symkObj = JSS_PK11_wrapSymKey(env, &symk); } finish: if( symk != NULL ) { PK11_FreeSymKey(symk); } if( keyID != NULL ) { SECITEM_FreeItem(keyID, PR_TRUE /*freeit*/); } return symkObj; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_SecretDecoderRing_KeyManager_lookupUniqueNamedKeyNative (JNIEnv *env, jobject this, jobject tokenObj, jobject algObj, jstring nickname) { PK11SlotInfo *slot = NULL; CK_MECHANISM_TYPE mech; const char *keyname = NULL; char *name = NULL; int count = 0; int keys_found = 0; PK11SymKey *symKey = NULL; PK11SymKey *nextSymKey = NULL; jobject symKeyObj = NULL; /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) { goto finish; } if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/) != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to login to token"); goto finish; } /* get the algorithm -- although this is not currently used */ mech = JSS_getPK11MechFromAlg(env, algObj); if( mech == CKM_INVALID_MECHANISM) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find PKCS #11 " "mechanism for key generation algorithm"); goto finish; } /* convert the Java String into a native "C" string */ keyname = JSS_RefJString(env, nickname); /* initialize the symmetric key list. */ symKey = PK11_ListFixedKeysInSlot( /* slot */ slot, /* nickname */ NULL, /* wincx */ NULL ); /* iterate through the symmetric key list. */ while( symKey != NULL ) { name = PK11_GetSymKeyNickname( /* symmetric key */ symKey ); if( name != NULL ) { if( keyname != NULL ) { if( PL_strcmp( keyname, name ) == 0 ) { keys_found++; } } PORT_Free(name); } nextSymKey = PK11_GetNextSymKey( /* symmetric key */ symKey ); PK11_FreeSymKey( /* symmetric key */ symKey ); symKey = nextSymKey; count++; } /* case 1: the token is empty */ if( count == 0 ) { /* the specified token is empty */ goto finish; } /* case 2: the specified key is not on this token */ if( ( keyname != NULL ) && ( keys_found == 0 ) ) { /* the key called "keyname" could not be found */ goto finish; } /* case 3: the specified key exists more than once on this token */ if( keys_found != 1 ) { /* more than one key called "keyname" was found on this token */ JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Duplicate named keys exist on this token"); goto finish; } /* Re-initialize the symmetric key list. */ symKey = PK11_ListFixedKeysInSlot( /* slot */ slot, /* nickname */ NULL, /* wincx */ NULL ); /* Reiterate through the symmetric key list once more, */ /* this time returning an actual reference to the key. */ while( symKey != NULL ) { name = PK11_GetSymKeyNickname( /* symmetric key */ symKey ); if( name != NULL ) { if( keyname != NULL ) { if( PL_strcmp( keyname, name ) == 0 ) { symKeyObj = JSS_PK11_wrapSymKey(env, &symKey); PORT_Free(name); goto finish; } } PORT_Free(name); } nextSymKey = PK11_GetNextSymKey( /* symmetric key */ symKey ); PK11_FreeSymKey( /* symmetric key */ symKey ); symKey = nextSymKey; } finish: if( symKey != NULL ) { PK11_FreeSymKey(symKey); } /* free the native "C" string */ JSS_DerefJString(env, nickname, keyname); return symKeyObj; } JNIEXPORT void JNICALL Java_org_mozilla_jss_SecretDecoderRing_KeyManager_deleteKeyNative (JNIEnv *env, jobject this, jobject tokenObj, jobject key) { PK11SlotInfo *slot = NULL; PK11SymKey *symk = NULL; /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) { goto finish; } if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/) != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to login to token"); goto finish; } /* get the key pointer */ if( JSS_PK11_getSymKeyPtr(env, key, &symk) != PR_SUCCESS) { goto finish; } if( PK11_DeleteTokenSymKey(symk) != SECSuccess ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to delete token symmetric key"); goto finish; } finish: /* don't free symk or slot, they are owned by their Java objects */ return; } jss-4.6.3/org/mozilla/jss/SecretDecoderRing/KeyManager.java000066400000000000000000000252011362106420000235730ustar00rootroot00000000000000/* 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.SecretDecoderRing; import java.security.*; import javax.crypto.*; import org.mozilla.jss.crypto.*; /** * Creates, finds, and deletes keys for SecretDecoderRing. */ public class KeyManager { private static final int KEYID_LEN = 16; private static final String RNG_ALG = "pkcs11prng"; private static final String RNG_PROVIDER = "Mozilla-JSS"; /** * The default key generation algorithm, currently DES3. */ public static final KeyGenAlgorithm DEFAULT_KEYGEN_ALG = KeyGenAlgorithm.DES3; /** * The default key size (in bytes). This is only relevant for algorithms * with variable-length keys, such as AES. */ public static final int DEFAULT_KEYSIZE = 0; private CryptoToken token; /** * Creates a new KeyManager using the given CryptoToken. * @param token The token on which this KeyManager operates. */ public KeyManager(CryptoToken token) { if( token == null ) { throw new NullPointerException("token is null"); } this.token = token; } /** * Generates an SDR key with the default algorithm and key size. * The default algorithm is stored in the constant DEFAULT_KEYGEN_ALG. * The default key size is stored in the constant DEFAULT_KEYSIZE. * @return The keyID of the generated key. A random keyID will be chosen * that is not currently used on the token. The keyID must be stored * by the application in order to use this key for encryption in the * future. */ public byte[] generateKey() throws TokenException { return generateKey(DEFAULT_KEYGEN_ALG, DEFAULT_KEYSIZE); } /** * Generates an SDR key with the given algorithm and key size. * @param keySize Length of key in bytes. This is only relevant for * algorithms that take more than one key size. Otherwise it can just * be set to 0. * @return The keyID of the generated key. A random keyID will be chosen * that is not currently used on the token. The keyID must be stored * by the application in order to use this key for encryption in the * future. */ public byte[] generateKey(KeyGenAlgorithm alg, int keySize) throws TokenException { if( alg == null ) { throw new NullPointerException("alg is null"); } byte[] keyID = generateUnusedKeyID(); generateKeyNative(token, alg, keyID, keySize); return keyID; } /** * @param keySize Key length in bytes. */ private native void generateKeyNative(CryptoToken token, KeyGenAlgorithm alg, byte[] keyID, int keySize); /** * Generates an SDR key with the default algorithm and key size. * and names it with the specified nickname. * The default algorithm is stored in the constant DEFAULT_KEYGEN_ALG. * The default key size is stored in the constant DEFAULT_KEYSIZE. * @param nickname the name of the symmetric key. Duplicate keynames * will be checked for, and are not allowed. * @return The keyID of the generated key. A random keyID will be chosen * that is not currently used on the token. The keyID must be stored * by the application in order to use this key for encryption in the * future. */ public byte[] generateUniqueNamedKey(String nickname) throws TokenException { return generateUniqueNamedKey(DEFAULT_KEYGEN_ALG, DEFAULT_KEYSIZE, nickname); } /** * Generates an SDR key with the given algorithm, key size, and nickname. * @param alg The algorithm that this key will be used for. * This is necessary because it will be stored along with the * key for later use by the security library. * @param keySize Length of key in bytes. This is only relevant for * algorithms that take more than one key size. Otherwise it can just * be set to 0. * @param nickname the name of the symmetric key. Duplicate keynames * will be checked for, and are not allowed. * @return The keyID of the generated key. A random keyID will be chosen * that is not currently used on the token. The keyID must be stored * by the application in order to use this key for encryption in the * future. */ public byte[] generateUniqueNamedKey(KeyGenAlgorithm alg, int keySize, String nickname) throws TokenException { // always strip all preceding/trailing whitespace // from passed-in String parameters if( nickname != null ) { nickname = nickname.trim(); } if( alg == null ) { throw new NullPointerException("alg is null"); } // disallow duplicates (i. e. - symmetric keys with the same name) if( uniqueNamedKeyExists(nickname) ) { throw new NullPointerException("duplicate symmetric key"); } byte[] keyID = generateUnusedKeyID(); generateUniqueNamedKeyNative(token, alg, keyID, keySize, nickname); return keyID; } /** * @param keySize Key length in bytes. * @param nickname the name of the symmetric key. Duplicate keynames * will be checked for, and are not allowed. */ private native void generateUniqueNamedKeyNative(CryptoToken token, KeyGenAlgorithm alg, byte[] keyID, int keySize, String nickname); /** * Generates a key ID that is currently unused on this token. * The caller is responsible for synchronization issues that may arise * if keys are generated by different threads. */ private byte[] generateUnusedKeyID() throws TokenException { try { SecureRandom rng = SecureRandom.getInstance(RNG_ALG, RNG_PROVIDER); byte[] keyID = new byte[KEYID_LEN]; do { rng.nextBytes(keyID); } while( keyExists(keyID) ); return keyID; } catch(NoSuchAlgorithmException nsae) { throw new RuntimeException("No such algorithm: " + RNG_ALG); } catch(NoSuchProviderException nspe) { throw new RuntimeException("No such provider: " + RNG_PROVIDER); } } private boolean keyExists(byte[] keyid) throws TokenException { return (lookupKey(Encryptor.DEFAULT_ENCRYPTION_ALG, keyid) != null); } /** * Looks up the key on this token with the given algorithm and key ID. * @param alg The algorithm that this key will be used for. * This is necessary because it will be stored along with the * key for later use by the security library. It should match * the actual algorithm of the key you are looking for. If you * pass in a different algorithm and try to use the key that is returned, * the results are undefined. * @return The key, or null if the key is not found. */ public SecretKey lookupKey(EncryptionAlgorithm alg, byte[] keyid) throws TokenException { if( alg == null || keyid == null ) { throw new NullPointerException(); } SymmetricKey k = lookupKeyNative(token, alg, keyid); if( k == null ) { return null; } else { return new SecretKeyFacade(k); } } private native SymmetricKey lookupKeyNative(CryptoToken token, EncryptionAlgorithm alg, byte[] keyid) throws TokenException; public boolean uniqueNamedKeyExists(String nickname) throws TokenException { return (lookupUniqueNamedKey(Encryptor.DEFAULT_ENCRYPTION_ALG, nickname) != null); } /** * Looks up the key on this token with the given algorithm and nickname. * @param alg The algorithm that this key will be used for. * This is necessary because it will be stored along with the * key for later use by the security library. It should match * the actual algorithm of the key you are looking for. If you * pass in a different algorithm and try to use the key that is returned, * the results are undefined. * @param nickname the name of the symmetric key. Duplicate keynames * will be checked for, and are not allowed. * @return The key, or null if the key is not found. */ public SecretKey lookupUniqueNamedKey(EncryptionAlgorithm alg, String nickname) throws TokenException { // always strip all preceding/trailing whitespace // from passed-in String parameters if( nickname != null ) { nickname = nickname.trim(); } if( alg == null || nickname == null || nickname.equals("") ) { throw new NullPointerException(); } SymmetricKey k = lookupUniqueNamedKeyNative(token, alg, nickname); if( k == null ) { return null; } else { return new SecretKeyFacade(k); } } private native SymmetricKey lookupUniqueNamedKeyNative(CryptoToken token, EncryptionAlgorithm alg, String nickname) throws TokenException; /** * Deletes the key with the given keyID from this token. * @throws InvalidKeyException If the key does not exist on this token. */ public void deleteKey(byte[] keyID) throws TokenException, InvalidKeyException { deleteKey(lookupKey(Encryptor.DEFAULT_ENCRYPTION_ALG, keyID)); } /** * If it exists, delete the key with the specified nickname from this * token. */ public void deleteUniqueNamedKey(String nickname) throws TokenException, InvalidKeyException { // only delete this symmetric key if it exists if( uniqueNamedKeyExists(nickname) ) { deleteKey(lookupUniqueNamedKey(Encryptor.DEFAULT_ENCRYPTION_ALG, nickname)); } } /** * Deletes this key from this token. * @throws InvalidKeyException If the key does not reside on this token, * or is not a JSS key. */ public void deleteKey(SecretKey key) throws TokenException, InvalidKeyException { if( key == null ) { throw new NullPointerException(); } if( ! (key instanceof SecretKeyFacade) ) { throw new InvalidKeyException("Key must be a JSS key"); } deleteKeyNative(token, ((SecretKeyFacade)key).key); } private native void deleteKeyNative(CryptoToken token, SymmetricKey key) throws TokenException; } jss-4.6.3/org/mozilla/jss/SecretDecoderRing/package.html000066400000000000000000000010511362106420000231630ustar00rootroot00000000000000 A facility for encrypting and decrypting small amounts of data with a symmetric key. This is most commonly used for encrypting password files to implement single sign-on.

KeyManager is used to create, lookup, and delete the symmetric keys used for SecretDecoderRing. Encryptor is used to encrypt data. Decryptor is used to decrypt data that was previously encrypted with Encryptor. Encoding and Encoding.Template are used internally, but they were made public because they may occasionally be useful to applications. jss-4.6.3/org/mozilla/jss/UserCertConflictException.java000066400000000000000000000005371362106420000233170ustar00rootroot00000000000000/* 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; public final class UserCertConflictException extends Exception { private static final long serialVersionUID = 1L; } jss-4.6.3/org/mozilla/jss/asn1/000077500000000000000000000000001362106420000162145ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/asn1/ANY.java000066400000000000000000000216661362106420000175210ustar00rootroot00000000000000/* 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.asn1; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.util.Assert; /** * Represents an ASN.1 ANY value. An ANY is just an arbitrary * ASN.1 value. It can be thought of as the simplest implementation of the * ASN1Value interface. Although they can be created * from scratch (from raw BER), instances of ANY are usually * found after decoding * with a template that has an ANY field. * *

An ANY supports extracting the BER encoding, or decoding * with a different template. */ public class ANY implements ASN1Value { // The complete encoding of header + contents private byte[] encoded; private Tag tag; /** * Creates an ANY value, which is just a generic ASN.1 value. * This method is provided for efficiency if the tag is already known, * so that we don't have to parse the encoding for it. * @param tag The tag of this value. It must be the same as the actual tag * contained in the encoding. * @param encoded The complete BER encoding of this value, including * tag, form, length, and contents. */ public ANY(Tag tag, byte[] encoded) { this.encoded = encoded; this.tag = tag; } /** * Creates an ANY value, which is just a generic ASN.1 value. * @param encoded The complete BER encoding of this value, including * tag, form, length, and contents. * @throws InvalidBERException If there is an invalid BER encoding. */ public ANY(byte[] encoded) throws InvalidBERException { try { this.encoded = encoded; ByteArrayInputStream bis = new ByteArrayInputStream(encoded); ASN1Header head = new ASN1Header(bis); this.tag = head.getTag(); } catch(IOException e) { throw new org.mozilla.jss.util.AssertionException( "IOException while creating ANY: "+e); } } /** * Returns the tag of this value. */ public Tag getTag() { return tag; } /** * Returns the complete encoding of header and contents, as passed into * the constructor or read from a BER input stream. * * @return Encoded header and contents. */ public byte[] getEncoded() { return encoded; } /** * Returns the ASN.1 header from the encoding. * * @return ASN.1 header. * @throws InvalidBERException If there is an invalid BER encoding. * @throws IOException If other error occurred. */ public ASN1Header getHeader() throws InvalidBERException, IOException { if( header == null ) { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); header = new ASN1Header(bis); } return header; } private ASN1Header header=null; /** * Strips out the header and returns just the contents octets of the * encoding. */ private byte[] contents=null; public byte[] getContents() throws InvalidBERException { try { if( contents==null ) { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); header = new ASN1Header(bis); contents = new byte[ bis.available() ]; if( (contents.length != header.getContentLength()) && ( header.getContentLength() != -1 ) ) { throw new InvalidBERException("Length of contents was not the "+ "same as the header predicted"); } ASN1Util.readFully(contents, bis); } return contents; } catch( IOException e ) { throw new RuntimeException("Unable to read byte array: " + e.getMessage(), e); } } public void encode(OutputStream ostream) throws IOException { ostream.write(encoded); } /** * Decodes this ANY using the given template. This is useful if you * originally decoded something as an ANY because you didn't know * what it was, but now you know what it is supposed to be. * * @param template The template to use to decode this ANY. * @return The output of the given template when it is fed the * encoding of this ANY. * @throws InvalidBERException If there is an invalid BER encoding. */ public ASN1Value decodeWith(ASN1Template template) throws InvalidBERException { try { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); return template.decode(bis); } catch( IOException e ) { throw new RuntimeException("Unable to read byte array: " + e.getMessage(), e); } } /** * Decodes this ANY using the given template. This is useful if you * originally decoded something as an ANY because you didn't know * what it was, but now you know what it is supposed to be. * * @param implicitTag The implicit tag for the encoding. * @param template The template to use to decode this ANY. * @return The output of the given template when it is fed the * encoding of this ANY. * @throws InvalidBERException If there is an invalid BER encoding. * @throws IOException If other error occurred. */ public ASN1Value decodeWith(Tag implicitTag, ASN1Template template) throws IOException, InvalidBERException { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); return template.decode(implicitTag, bis); } /** * @param implicitTag This parameter is ignored, because * ANY values cannot have implicit tags. * @throws IOException If an error occurred. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { if( ! implicitTag.equals(tag) ) { throw new RuntimeException("No implicit tags allowed for ANY"); } ostream.write(encoded); } /** * Extracts the contents from the ANY and encodes them with * the provided tag. * * @param alternateTag Alternate tag. * @param ostream Output stream. * @throws InvalidBERException If there is an invalid BER encoding. * @throws IOException If other error occurred. */ public void encodeWithAlternateTag(Tag alternateTag, OutputStream ostream) throws IOException, InvalidBERException { byte[] contents = getContents(); ASN1Header oldHead = getHeader(); assert( contents.length == oldHead.getContentLength() ); ASN1Header newHead = new ASN1Header( alternateTag, oldHead.getForm(), contents.length); newHead.encode(ostream); ostream.write(contents); } /** * Returns a singleton instance of a decoding template. * * @return Decoding template. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A class for decoding ANY values from BER. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return true; // wheeeeee...it's ANY! } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = ASN1Header.lookAhead(istream); if( head.getContentLength() == -1 ) { // indefinite length encoding ByteArrayOutputStream recording = new ByteArrayOutputStream(); // eat the header off the input stream head = new ASN1Header(istream); // write the header to the recording stream recording.write( head.encode() ); // write all objects from the input stream to the recording // stream, until we hit an END-OF-CONTENTS tag ANY any; ANY.Template anyt = new ANY.Template(); int count=0; do { any = (ANY) anyt.decode(istream); recording.write( any.getEncoded() ); } while( ! any.getTag().equals(Tag.EOC) ); return new ANY( head.getTag(), recording.toByteArray() ); } else { // definite length encoding byte[] data = new byte[ (int) head.getTotalLength() ]; ASN1Util.readFully(data, istream); return new ANY(head.getTag(), data); } } catch( InvalidBERException e ) { throw new InvalidBERException(e, "ANY"); } } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { throw new InvalidBERException("Implicit tag on ANY"); } } // End of Template } jss-4.6.3/org/mozilla/jss/asn1/ASN1Header.java000066400000000000000000000304531362106420000206770ustar00rootroot00000000000000/* 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.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.util.Vector; import org.mozilla.jss.util.Assert; /** * The portion of a BER encoding that precedes the contents octets. Consists * of the tag, form, and length octets. */ public class ASN1Header { // This is set by the the decoding constructor, and by the encode() // method. If it is set by the decoding constructor, it is supposed // to represent what was actually read from the input stream, so it // must not be overwritten later by the output of encode(), which could // be a different encoding (DER vs. BER, for example). private byte[] cachedEncoding = null; /** * Returns the length of the header plus the length of the contents; * the total length of the DER encoding of an ASN1 value. Returns * -1 if indefinite length encoding was used. * @return Total length. */ public long getTotalLength() { if( contentLength == -1 ) { return -1; } else { return encode().length + contentLength; } } private Tag tag; public Tag getTag() { return tag; } // -1 means indefinite length encoding private long contentLength; /** * Returns -1 for indefinite length encoding. * @return Content length. */ public long getContentLength() { return contentLength; } // PRIMITIVE or CONSTRUCTED public static final Form PRIMITIVE = Form.PRIMITIVE; public static final Form CONSTRUCTED = Form.CONSTRUCTED; private Form form; /** * Returns the Form, PRIMITIVE or CONSTRUCTED. * @return The form. */ public Form getForm() { return form; } // This is the maximum size of ASN1 Header we support. // 32 bytes is pretty huge, I've never seen anything bigger than 7. private static final int MAX_LOOK_AHEAD = 32; /** * Returns information about the next item in the stream, but does not * consume any octets. * @param derStream DER stream. * @return ASN.1 header. * @throws InvalidBERException If there is an invalid BER encoding. * @exception IOException If the input stream does not support look ahead. */ public static ASN1Header lookAhead(InputStream derStream) throws IOException, InvalidBERException { if( ! derStream.markSupported() ) { throw new IOException("Mark not supported on this input stream"); } derStream.mark(MAX_LOOK_AHEAD); ASN1Header info = new ASN1Header(derStream); derStream.reset(); return info; } /** * Gets info about the next item in the DER stream, consuming the * identifier and length octets. * @param istream Input stream. * @throws InvalidBERException If there is an invalid BER encoding. * @throws IOException If other error occurred. */ public ASN1Header(InputStream istream) throws InvalidBERException, IOException { // default BAOS size is 32 bytes, which is plenty ByteArrayOutputStream encoding = new ByteArrayOutputStream(); int inInt = istream.read(); if( inInt == -1 ) { throw new InvalidBERException("End-of-file reached while "+ "decoding ASN.1 header"); } encoding.write(inInt); byte byte1 = (byte) inInt; Tag.Class tagClass; // // Get Tag Class // tagClass = Tag.Class.fromInt( (byte1 & 0xff) >>> 6 ); // // Get form // if( (byte1 & 0x20) == 0x20 ) { form = CONSTRUCTED; } else { form = PRIMITIVE; } // // Get Tag Number // long tagNum; if( (byte1 & 0x1f) == 0x1f ) { // long form // // read all octets into a Vector of Bytes // byte next; Vector bV = new Vector<>(); // last byte has MSB == 0. do { inInt = istream.read(); if( inInt == -1 ) { throw new InvalidBERException("End-of-file reached while" +" decoding ASN.1 header"); } encoding.write(inInt); next = (byte) inInt; bV.addElement( Byte.valueOf(next) ); } while( (next & 0x80) == 0x80 ); assert( bV.size() > 0 ); // // Copy Vector of 7-bit bytes into array of 8-bit bytes. // byte[] bA = new byte[ ( (bV.size()*7) + 7 ) / 8 ]; int v; // vector index int a; // array index // clear the target array for( a = 0; a < bA.length; a++ ) { bA[a] = 0; } int shift = 0; // the amount the Vector is shifted from the array // copy bits from the Vector to the array, going from the // end (LSB) to the beginning (MSB). a = bA.length - 1; for( v=bV.size()-1 ; v >= 0; v--) { assert( v >= 0 ); assert( v < bV.size() ); assert( a >= 0 ); assert( a < bA.length ); // MSB is not part of the number byte b = (byte) ( bV.elementAt(v).byteValue() & 0x7f ); bA[a] |= b << shift; if( shift > 1 ) { // The byte from the Vector falls across a byte boundary // in the array. We've already got the less-significant // bits, now copy the more-significant bits into // the next element of the array. assert( a > 0 ); --a; bA[a] |= b >>> (8-shift); } shift = (shift+7)%8; // update shift } // Create a new unsigned BigInteger from the byte array tagNum = (new BigInteger( 1, bA )).longValue(); } else { // short form tagNum = byte1 & 0x1f; } tag = new Tag(tagClass, tagNum); // // Get Length // inInt = istream.read(); if(inInt == -1) { throw new InvalidBERException("End-of-file reached while "+ "decoding ASN.1 header"); } encoding.write(inInt); byte lenByte = (byte) inInt; if( (lenByte & 0x80) == 0 ) { // short form contentLength = lenByte; } else { // long form if( (lenByte & 0x7f) == 0 ) { // indefinite contentLength = -1; } else { // definite byte[] lenBytes = new byte[ lenByte & 0x7f ]; ASN1Util.readFully(lenBytes, istream); encoding.write( lenBytes ); contentLength = (new BigInteger( 1, lenBytes )).longValue(); } } // save our encoding so we don't have to recompute it later cachedEncoding = encoding.toByteArray(); } /** * This constructor is to be called when we are constructing an ASN1Value * rather than decoding it. * @param tag Tag. * @param form Form. * @param contentLength Must be ≥0. Although indefinite length * decoding is supported, indefinite length encoding * is not. */ public ASN1Header( Tag tag, Form form, long contentLength) { this.tag = tag; this.form = form; assert(contentLength >= 0); this.contentLength = contentLength; } public void encode( OutputStream ostream ) throws IOException { ostream.write( encode() ); } public byte[] encode() { // It's important that we not recompute the encoding if it was // set by ASN1Header(InputStream), since in that case it represents // the encoding that was actually read from the InputStream. if( cachedEncoding != null ) { return cachedEncoding; } ByteArrayOutputStream cache = new ByteArrayOutputStream(); // // Identifier octet(s) // byte idOctet = 0; idOctet |= tag.getTagClass().toInt() << 6; if( form == CONSTRUCTED ) { idOctet |= 0x20; } if( tag.getNum() <= 30 ) { // short form idOctet |= (tag.getNum() & 0x1f ); cache.write( idOctet ); } else { // long form idOctet |= 0x1f; BigInteger tagNum = BigInteger.valueOf(tag.getNum()); cache.write( idOctet ); int bitlength = tagNum.bitLength(); int reps = (bitlength+6)/7; for( reps = reps-1; reps > 0 ; reps--) { long shifted = tag.getNum() >>> ( 7*reps ); cache.write( (((byte)shifted) & 0x7f) | 0x80 ); } cache.write( ((byte)tag.getNum()) & 0x7f ); } // // Length Octets // if( contentLength == -1 ) { // indefinite form cache.write( (byte) 0x80 ); } else if( contentLength <= 127 ) { // short form cache.write( (byte) contentLength ); } else { // long form byte[] val = unsignedBigIntToByteArray( BigInteger.valueOf(contentLength) ); cache.write( ((byte)val.length) | 0x80 ); cache.write( val, 0, val.length ); } cachedEncoding = cache.toByteArray(); return cachedEncoding; } /** * Converts an unsigned BigInteger to a minimal-length byte array. * This is necessary because BigInteger.toByteArray() attaches an extra * sign bit, which could cause the size of the byte representation to * be bumped up by an extra byte. * @param bi Input BigInteger. * @return Byte array. */ public static byte[] unsignedBigIntToByteArray(BigInteger bi) { // make sure it is not negative assert( bi.compareTo(BigInteger.valueOf(0)) != -1 ); // find minimal number of bytes to hold this value int bitlen = bi.bitLength(); // minimal number of bits, without sign int bytelen; if( bitlen == 0 ) { // special case, since bitLength() returns 0 bytelen = 1; } else { bytelen = (bitlen + 7) / 8; } byte[] withSign = bi.toByteArray(); if( bytelen == withSign.length ) { return withSign; } else { // trim off extra byte at the beginning assert( bytelen == withSign.length - 1 ); assert( withSign[0] == 0 ); byte[] without = new byte[bytelen]; System.arraycopy(withSign,1, without, 0, bytelen); return without; } } /** * Verifies that this header has the given tag and form. * @param expectedTag Expected tag. * @param expectedForm Expected form. * @exception InvalidBERException If the header's tag or form * differ from those passed in. */ public void validate(Tag expectedTag, Form expectedForm) throws InvalidBERException { validate(expectedTag); if( getForm() != expectedForm ) { throw new InvalidBERException("Incorrect form: expected ["+ expectedForm+"], found ["+getForm()); } } /** * Verifies that this head has the given tag. * @param expectedTag Expected tag. * @exception InvalidBERException If the header's tag differs from that * passed in. */ public void validate(Tag expectedTag) throws InvalidBERException { if( ! getTag().equals( expectedTag ) ) { throw new InvalidBERException("Incorrect tag: expected ["+ expectedTag+"], found ["+getTag()+"]"); } } /** * @return true if this is a BER end-of-contents marker. */ public boolean isEOC() { return( tag.equals(Tag.EOC) ); } } jss-4.6.3/org/mozilla/jss/asn1/ASN1Template.java000066400000000000000000000037271362106420000212660ustar00rootroot00000000000000/* 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.asn1; import java.io.IOException; import java.io.InputStream; /** * An interface for decoding ASN1Values from their BER encodings. * * @see ASN1Value */ public interface ASN1Template { /** * Determines whether the given tag will satisfy this template. * * @param tag Tag. * @return True if the given tag will satisfy this template. */ public boolean tagMatch(Tag tag); /** * Decodes an ASN1Value from the InputStream without an implicit tag. * @param istream Must support marking (markSupported() == true). * For example, ByteArrayInputStream and BufferedInputStream * support marking, but FileInputStream does not. If your source * does not support marking, you can wrap it in a * BufferedInputStream. * @return ASN.1 value. * @throws InvalidBERException If there is an invalid BER encoding. * @throws IOException If other error occurred. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException; /** * Decodes an ASN1Value from the InputStream with the given implicit * tag. * @param implicitTag Implicit tag. * @param istream Must support marking (markSupported() == true). * For example, ByteArrayInputStream and BufferedInputStream * support marking, but FileInputStream does not. If your source * does not support marking, you can wrap it in a * BufferedInputStream. * @return ASN.1 value. * @throws InvalidBERException If there is an invalid BER encoding. * @throws IOException If other error occurred. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException; } jss-4.6.3/org/mozilla/jss/asn1/ASN1Util.c000066400000000000000000000071251362106420000177250ustar00rootroot00000000000000/* ***** 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 ***** */ #include "_jni/org_mozilla_jss_asn1_ASN1Util.h" #include #include #include #include #include #include #include #include #include /*********************************************************************** * * Java_org_mozilla_jss_asn1_ASN1Util_getTagDescriptionByOid * retrieves OID description by NSS's OID Tag identifier * the OID byte array is expected to be without the OID Tag (6) and size * (together 2 bytes) */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_asn1_ASN1Util_getTagDescriptionByOid(JNIEnv *env, jobject this, jbyteArray oidBA) { SECItem *oid = NULL; SECOidTag oidTag = SEC_OID_UNKNOWN; const char *oidDesc = NULL; jstring description = (jstring)""; if (oidBA == NULL) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "JSS getTagDescriptionByOid: oidBA null"); goto finish; } else { /************************************************** * Setup the parameters *************************************************/ oid = JSS_ByteArrayToSECItem(env, oidBA); if (oid == NULL) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "JSS getTagDescriptionByOid: JSS_ByteArrayToSECItem failed"); goto finish; } /* * SECOID_FindOIDTag() returns SEC_OID_UNKNOWN if no match */ oidTag = SECOID_FindOIDTag(oid); if (oidTag == SEC_OID_UNKNOWN) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "JSS getTagDescriptionByOid: OID UNKNOWN"); goto finish; } oidDesc = SECOID_FindOIDTagDescription(oidTag); if (oidDesc == NULL) { oidDesc = ""; } description = (*env)->NewStringUTF(env, oidDesc); } finish: return description; } jss-4.6.3/org/mozilla/jss/asn1/ASN1Util.java000066400000000000000000000120631362106420000204210ustar00rootroot00000000000000/* 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.asn1; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; public class ASN1Util { public static byte[] encode(ASN1Value val) { return encode(val.getTag(), val); } public static byte[] encode(Tag implicitTag, ASN1Value val) { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); val.encode(implicitTag, bos); return bos.toByteArray(); } catch( IOException e ) { throw new RuntimeException("Unable to encode byte array: " + e.getMessage(), e); } } public static ASN1Value decode(ASN1Template template, byte[] encoded) throws InvalidBERException { try { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); return template.decode(bis); } catch( IOException e ) { throw (InvalidBERException) new InvalidBERException("Unable to decode byte array: " + e.getMessage()).initCause(e); } } public static ASN1Value decode(Tag implicitTag, ASN1Template template, byte[] encoded) throws InvalidBERException { try { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); return template.decode(implicitTag, bis); } catch( IOException e ) { throw (InvalidBERException) new InvalidBERException("Unable to decode byte array: " + e.getMessage()).initCause(e); } } /** * Fills a byte array with bytes from an input stream. This method * keeps reading until the array is filled, an IOException occurs, or EOF * is reached. The byte array will be completely filled unless an * exception is thrown. * * @param bytes A byte array which will be filled up. * @param istream The input stream from which to read the bytes. * @exception IOException If an IOException occurs reading from the * stream, or EOF is reached before the byte array is filled. */ public static void readFully(byte[] bytes, InputStream istream) throws IOException { int numRead=0; while(numRead < bytes.length) { int nr = istream.read(bytes, numRead, bytes.length-numRead); if( nr == -1 ) { throw new EOFException(); } numRead += nr; } } /** * returns the ECC curve byte array given the X509 public key byte array * * @param X509PubKeyBytes byte array of an X509PubKey * @param withHeader tells if the return byes should inclulde the tag and size header or not * @return ECC curve byte array. */ public static byte[] getECCurveBytesByX509PublicKeyBytes(byte[] X509PubKeyBytes, boolean withHeader) throws IllegalArgumentException, ArrayIndexOutOfBoundsException, NullPointerException { if ((X509PubKeyBytes == null) || (X509PubKeyBytes.length == 0)) { throw new IllegalArgumentException("X509PubKeyBytes null"); } /* EC public key OID complete with tag and size */ byte[] EC_PubOIDBytes_full = ASN1Util.encode(OBJECT_IDENTIFIER.EC_PUBKEY_OID); /* EC public key OID without tag and size */ byte[] EC_PubOIDBytes = Arrays.copyOfRange(EC_PubOIDBytes_full, 2, EC_PubOIDBytes_full.length); int curveBeginIndex = 0; for (int idx = 0; idx<= X509PubKeyBytes.length; idx++) { byte[] tmp = Arrays.copyOfRange(X509PubKeyBytes, idx, idx+EC_PubOIDBytes.length); if (Arrays.equals(tmp, EC_PubOIDBytes)) { curveBeginIndex = idx+ EC_PubOIDBytes.length; break; } } int curveByteArraySize = X509PubKeyBytes[curveBeginIndex+ 1]; if (withHeader) { /* actual curve with tag and size */ byte curve[] = Arrays.copyOfRange(X509PubKeyBytes, curveBeginIndex, curveBeginIndex + curveByteArraySize + 2); return curve; } else { /* actual curve without tag and size */ byte curve[] = Arrays.copyOfRange(X509PubKeyBytes, curveBeginIndex + 2, curveBeginIndex + 2 + curveByteArraySize); return curve; } } /** * getOIDdescription() returns a text description of the OID * from OID byte array * the OID byte array is expected to be without the OID Tag (6) and size * (together 2 bytes) * @param oidBA OID byte array. * @return OID description. */ public static String getOIDdescription(byte[] oidBA) { return getTagDescriptionByOid(oidBA); } /** * get OID description JNI method */ private native static String getTagDescriptionByOid(byte[] oidBA); } jss-4.6.3/org/mozilla/jss/asn1/ASN1Value.java000066400000000000000000000022571362106420000205640ustar00rootroot00000000000000/* 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.asn1; import java.io.IOException; import java.io.OutputStream; /** * A value that can be decoded from BER and encoded to DER. * * @see ASN1Template */ public interface ASN1Value { /** * Returns the base tag for this type, not counting any tags * that may be imposed on it by its context. * * @return Base tag. */ public Tag getTag(); /** * Write this value's DER encoding to an output stream using * its own base tag. * * @param ostream Output stream. * @throws IOException If an error occurred. */ public void encode(OutputStream ostream) throws IOException; /** * Write this value's DER encoding to an output stream using * an implicit tag. * * @param implicitTag Implicit tag. * @param ostream Output stream. * @throws IOException If an error occurred. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException; } jss-4.6.3/org/mozilla/jss/asn1/BIT_STRING.java000066400000000000000000000232121362106420000205630ustar00rootroot00000000000000/* 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.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.BitSet; import org.mozilla.jss.util.Assert; /** * An ASN.1 BIT STRING, which is an ordered sequence of bits. * The bits are stored the same way they are encoded in BER: as an array * of bytes with 0-7 unused bits at the end. */ public class BIT_STRING implements ASN1Value { private byte[] bits; private int padCount; private boolean removeTrailingZeroes = false; /** * @param bits The bits packed into an array of bytes, with padding * at the end. The array may be empty (but not null), in which case * padCount must be zero. The array is referenced, * not cloned. * @param padCount The number of padding bits at the end of the array. * Must be in the range [0,7]. * @exception NumberFormatException If padCount is not in * the range [0,7], or bits is * empty and padCount is non-zero. */ public BIT_STRING(byte[] bits, int padCount) throws NumberFormatException { if(padCount < 0 || padCount > 7) { throw new NumberFormatException(); } if(bits.length == 0 && padCount != 0) { throw new NumberFormatException(); } this.bits = bits; this.padCount = padCount; } /** * Constructs a BIT_STRING from a BitSet. * @param bs A BitSet. * @param numBits The number of bits to copy from the BitSet. * This is necessary because the size of a BitSet is always padded * up to a multiple of 64, but not all of these bits may * be significant. * @exception NumberFormatException If numBits is larger * than bs.size() or less than zero. */ public BIT_STRING(BitSet bs, int numBits) throws NumberFormatException { if( numBits < 0 || numBits > bs.size() ) { throw new NumberFormatException(); } // allocate enough bytes to hold all the bits bits = new byte[(numBits+7) / 8]; padCount = (bits.length * 8) - numBits; assert( padCount >= 0 && padCount <= 7); for(int i=0; i < numBits; i++) { if( bs.get(i) ) { bits[i/8] |= 0x80 >>> (i%8); } } } /** * Determines whether the DER-encoding of this bitstring will have * its trailing zeroes removed. Generally, DER requires that trailing * zeroes be removed when the bitstring is used to hold flags, but * not when it is used to hold binary data (such as a public key). * The default is false. * @return True if trailing zeroes are to be removed. */ public boolean getRemoveTrailingZeroes() { return this.removeTrailingZeroes; } /** * Determines whether the DER-encoding of this bitstring will have * its trailing zeroes removed. Generally, DER requires that trailing * zeroes be removed when the bitstring is used to hold flags, but * not when it is used to hold binary data (such as a public key). * The default is false. If this bit string is used to hold * flags, you should set this to true. * @param removeTrailingZeroes True if trailing zeroes are to be removed. */ public void setRemoveTrailingZeroes(boolean removeTrailingZeroes) { this.removeTrailingZeroes = removeTrailingZeroes; } /** * Returns the bits packed into an array of bytes, with padding * at the end. The array may be empty (but not null), in which case * padCount must be zero. The array is referenced, * not cloned. * @return BIT STRING as byte array. */ public byte[] getBits() { return bits; } /** * Copies this BIT STRING into a Java BitSet. Note that BitSet.size() * will not accurately reflect the number of bits in the BIT STRING, * because the size of a BitSet is always rounded up to the next multiple * of 64. The extra bits will be set to 0. * @return BIT STRING as BitSet. */ public BitSet toBitSet() { BitSet bs = new BitSet(); int numBits = (bits.length * 8) - padCount; for( int i=0; i < numBits; i++) { if( (bits[i/8] & (0x80 >>> (i%8))) != 0 ) { bs.set(i); } else { bs.clear(i); } } return bs; } /** * Copies this BIT STRING into a boolean array. Each element of the array * represents one bit with true for 1 and false * for 0. * @return BIT STRING as boolean array. */ public boolean[] toBooleanArray() { boolean[] array = new boolean[(bits.length*8) - padCount]; // all elements are set to false by default for(int i=0; i < array.length; i++) { if( (bits[i/8] & (0x80 >>> (i%8))) != 0 ) { array[i] = true; } } return array; } /** * Returns the number of padding bits at the end of the array. * Must be in the range [0,7]. * @return Number of padding. */ public int getPadCount() { return padCount; } public static final Tag TAG = new Tag(Tag.UNIVERSAL, 3); public static final Form FORM = Form.PRIMITIVE; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { // force all unused bits to be zero, in support of DER standard. if( bits.length > 0 ) { bits[bits.length-1] &= (0xff << padCount); } int padBits; int numBytes; if( removeTrailingZeroes ) { // first pare off empty bytes numBytes = bits.length; for( ; numBytes > 0; --numBytes) { if( bits[numBytes-1] != 0 ) { break; } } // Now compute the number of unused bits. This includes any // trailing zeroes, whether they are significant or not. if( numBytes == 0 ) { padBits = 0; } else { for( padBits=0; padBits < 8; ++padBits ) { if( (bits[numBytes-1] & (1 << padBits)) != 0 ) { break; } } assert(padBits >=0 && padBits <= 7); } } else { // Don't remove trailing zeroes. Just write the bits out as-is. padBits = padCount; numBytes = bits.length; } ASN1Header head = new ASN1Header(implicitTag, FORM, numBytes+1); head.encode(ostream); ostream.write(padBits); ostream.write(bits, 0, numBytes); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A class for decoding a BIT_STRING from its BER encoding. */ 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 implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header( istream ); head.validate( implicitTag ); if( head.getContentLength() == -1 ) { // indefinite length encoding ByteArrayOutputStream bos = new ByteArrayOutputStream(); int padCount=0; ASN1Header ahead; do { ahead = ASN1Header.lookAhead(istream); if( ! ahead.isEOC() ) { if(padCount != 0 ) { throw new InvalidBERException("Element of constructed "+ "BIT STRING has nonzero unused bits, but is not\n"+ "the last element of the construction."); } BIT_STRING.Template bst = new BIT_STRING.Template(); BIT_STRING bs = (BIT_STRING) bst.decode(istream); bos.write( bs.getBits() ); padCount = bs.getPadCount(); } } while( ! ahead.isEOC() ); // consume the EOC ahead = new ASN1Header(istream); return new BIT_STRING( bos.toByteArray(), padCount ); } // First octet is the number of unused bits in last octet int padCount = istream.read(); if( padCount == -1 ) { throw new InvalidBERException.EOF(); } else if( padCount < 0 || padCount > 7 ) { throw new InvalidBERException("Unused bits not in range [0,7]"); } // get the rest of the octets byte[] bits = new byte[ (int) head.getContentLength() - 1]; ASN1Util.readFully(bits, istream); return new BIT_STRING(bits, padCount); } catch(InvalidBERException e) { throw new InvalidBERException(e, "BIT STRING"); } } } // end of Template } jss-4.6.3/org/mozilla/jss/asn1/BMPString.java000066400000000000000000000067031362106420000206720ustar00rootroot00000000000000/* 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.asn1; import java.io.CharConversionException; import java.io.UnsupportedEncodingException; /** * The ASN.1 type BMPString. BMPStrings use the Unicode character set. * They are encoded and decoded in big-endian format using two octets. */ public class BMPString extends CharacterString implements ASN1Value { /** * Creates a new BMPString from an array of Java characters. * @param chars Input characters. * @throws CharConversionException If an error occurred. */ public BMPString(char[] chars) throws CharConversionException { super(chars); } /** * Creates a new BMPString from a Java String. * @param s Input string. * @throws CharConversionException If an error occurred. */ public BMPString(String s) throws CharConversionException { super(s); } /** * Returns the conversion object for converting between an encoded byte * array an an array of Java characters. * @return Character converter. */ CharConverter getCharConverter() { return converterInstance; } private static final BMPConverter converterInstance = new BMPConverter(); static final Tag TAG = new Tag( Tag.UNIVERSAL, 30 ); static final Form FORM = Form.PRIMITIVE; public Tag getTag() { return TAG; } /** * Returns a singleton instance of BMPString.Template. This is more * efficient than creating a new BMPString.Template. * @return BMSString template. */ public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); // nested class public static class Template extends CharacterString.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected CharConverter getCharConverter() { return new BMPConverter(); } protected CharacterString generateInstance(char[] chars) throws CharConversionException { return new BMPString(chars); } protected String typeName() { return "BMPString"; } } private static class BMPConverter implements CharConverter { public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { try { String s = new String(bytes, offset, len, "UnicodeBig"); return s.toCharArray(); } catch( UnsupportedEncodingException e ) { String err = "Unable to find UnicodeBig encoding mechanism"; throw (CharConversionException) new CharConversionException(err).initCause(e); } } public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { try { // We don't want the byte-order mark String s = new String(chars, offset, len); return s.getBytes("UnicodeBigUnmarked"); } catch( UnsupportedEncodingException e ) { String err = "Unable to find UnicodeBigUnmarked encoding mechanism"; throw (CharConversionException) new CharConversionException(err).initCause(e); } } } // end of char converter } jss-4.6.3/org/mozilla/jss/asn1/BOOLEAN.java000066400000000000000000000055171362106420000201460ustar00rootroot00000000000000/* 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.asn1; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * An ASN.1 BOOLEAN value. */ public class BOOLEAN implements ASN1Value { public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 1); public static final Form FORM = Form.PRIMITIVE; public Tag getTag() { return TAG; } private ASN1Header getHeader(Tag implicitTag) { return new ASN1Header(implicitTag, FORM, 1 ); } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { getHeader(implicitTag).encode(ostream); if( val ) { ostream.write( 0xff ); } else { ostream.write( 0x00 ); } } private boolean val; /** * Creates a BOOLEAN with the given value. * @param val Boolean value. */ public BOOLEAN(boolean val) { this.val = val; } /** * @return The boolean value of this BOOLEAN. */ public boolean toBoolean() { return val; } /** * Returns "true" or "false". */ public String toString() { if(val) { return "true"; } else { return "false"; } } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Class for decoding BOOLEAN values from their BER * encodings. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return( tag.equals( BOOLEAN.TAG ) ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag tag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); head.validate(tag, FORM); int b = istream.read(); if( b == -1 ) { throw new InvalidBERException("End-of-file reached while "+ "decoding BOOLEAN"); } if( b == 0x00 ) { return new BOOLEAN(false); } else { return new BOOLEAN(true); } } catch(InvalidBERException e) { throw new InvalidBERException(e, "BOOLEAN"); } } } } jss-4.6.3/org/mozilla/jss/asn1/CHOICE.java000066400000000000000000000174221362106420000200170ustar00rootroot00000000000000/* 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.asn1; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Vector; import org.mozilla.jss.util.Assert; /** * Objects of this class are generated by CHOICE.Template.decode(). It is * not necessary to use them to encode a CHOICE. Since the encoding of a * CHOICE is simply the encoding of the chosen element, it is easier * to just write out the chosen element. */ public class CHOICE implements ASN1Value { private Tag tag; private ASN1Value val; /** * Create a CHOICE whose chosen element has an implicit tag. * @param implicitTag Implicit tag. * @param val The value. */ public CHOICE(Tag implicitTag, ASN1Value val) { tag = implicitTag; this.val = val; } /** * Create a CHOICE whose chosen element has no implicit tag. * @param val The value. */ public CHOICE(ASN1Value val) { this.tag = val.getTag(); this.val = val; } /** * Returns the tag that the chosen element is encoded with, which is * either the underlying tag of the element or an implicit tag. */ public Tag getTag() { return tag; } /** * @return The chosen value. */ public ASN1Value getValue() { return val; } public static CHOICE.Template getTemplate() { return new CHOICE.Template(); } /** * Encodes this CHOICE. This merely consists of encoding the chosen * element with an implicit tag, if one was given in the constructor, * or with its own underlying tag. */ public void encode( OutputStream ostream ) throws IOException { val.encode( tag, ostream ); } /** * Encodes this CHOICE. This merely consists of encoding the chosen * element with an implicit tag, if one was given in the constructor, * or with its own underlying tag. * * @param implicitTag This value is ignored. The tag of a CHOICE * is merely the tag of the chosen element of the CHOICE. A * CHOICE cannot itself have an implicit tag. */ public void encode( Tag implicitTag, OutputStream ostream ) throws IOException { assert(implicitTag.equals(tag)); val.encode( tag, ostream ); } /** * A Template for decoding ASN.1 CHOICEs */ public static class Template implements ASN1Template { // The the various possibilities in this CHOICE private Vector templates = new Vector<>(); /** * Creates an empty CHOICE template */ public Template() { } /** * Adds a new sub-template to this CHOICE template with no implicit tag. * @param template Sub-template. */ public void addElement( ASN1Template template ) { templates.addElement( new Element( template ) ); } /** * Adds a new sub-template to this CHOICE template with an implicit tag. * @param implicitTag Implicit tag. * @param template Sub-template. */ public void addElement( Tag implicitTag, ASN1Template template) { templates.addElement( new Element( implicitTag, template) ); } /** * @return The number of elements in this CHOICE template. */ public int size() { return templates.size(); } /** * @param index Element index. * @return The element at the specified index. */ public ASN1Template elementAt(int index) { return templates.elementAt(index).getTemplate(); } /** * Retrieves the implicit tag of the element at the specified index. * Returns null if there is no implicit tag for this element. * @param index Element index. * @return The implicit tag. */ public Tag implicitTagAt(int index) { return templates.elementAt(index).getImplicitTag(); } /** * Empties this CHOICE template. */ public void removeAllElements() { templates.removeAllElements(); } /** * Removes the element at the specified index. * @param index Element index. */ public void removeElementAt(int index) { templates.removeElementAt(index); } /** * Determines whether the given tag will satisfy this template. * @param t The tag. * @return True if the tag satisfies any sub-template. */ public boolean tagMatch(Tag t) { int size = size(); for(int i = 0; i < size; i++) { Tag impl = implicitTagAt(i); if( impl != null ) { // There is an implicit tag, if we match it we have a match if( impl.equals(t) ) { return true; } } else { // no implicit tag, look at the sub-template itself ASN1Template templ = elementAt(i); if( templ.tagMatch(t) ) { return true; } } } // none of the elements matched return false; } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { ASN1Header head = ASN1Header.lookAhead(istream); Tag tag = head.getTag(); // Loop over all the elements of the CHOICE template until we // find one with a matching tag. int size = size(); for(int i=0; i < size; i++) { if( implicitTagAt(i) != null ) { if( implicitTagAt(i).equals(tag) ) { // match by implicit tag! ASN1Value val = elementAt(i).decode( implicitTagAt(i), istream ); //return elementAt(i).decode( implicitTagAt(i), istream ); return new CHOICE( implicitTagAt(i), val ); } } else { if( elementAt(i).tagMatch(tag) ) { // match by base tag ! //return elementAt(i).decode(istream); return new CHOICE( elementAt(i).decode(istream) ); } } } // we didn't find any match throw new InvalidBERException("Unable to decode CHOICE"); } // Implicit tags are illegal for CHOICE (and ANY) /** * Decodes a CHOICE. * @param implicitTag This parameter is ignored. A choice * cannot have an implicit tag. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { return decode(istream); } /** * An element in a CHOICE template, consisting of a nested template * and, optionally, an implicit tag for that template. */ private static class Element { private ASN1Template template; private Tag implicitTag=null; /** * Creates a CHOICE template element with no implicit tag. */ public Element(ASN1Template template) { this.template = template; } /** * Creates a CHOICE template element with an implicit tag. */ public Element(Tag implicitTag, ASN1Template template) { this.template = template; this.implicitTag = implicitTag; } /** * Returns the template of this CHOICE template element. */ public ASN1Template getTemplate() { return template; } /** * Returns the implicit tag for this CHOICE template element, * if there is one. If not, returns null. */ public Tag getImplicitTag() { return implicitTag; } } } } jss-4.6.3/org/mozilla/jss/asn1/CharConverter.java000066400000000000000000000007701362106420000216300ustar00rootroot00000000000000/* 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.asn1; import java.io.CharConversionException; interface CharConverter { public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException; public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException; } jss-4.6.3/org/mozilla/jss/asn1/CharacterString.java000066400000000000000000000112551362106420000221460ustar00rootroot00000000000000/* 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.asn1; import java.io.ByteArrayOutputStream; import java.io.CharConversionException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * An abstract base class for all character string types in ASN.1. */ public abstract class CharacterString implements ASN1Value { abstract CharConverter getCharConverter(); public abstract Tag getTag(); static final Form FORM = Form.PRIMITIVE; private char[] chars; /** * Converts this ASN.1 character string to a Java String. * @return ASN.1 character string as String. */ public String toString() { return new String(chars); } /** * Converts this ASN.1 character string to an array of Java characters. * @return ASN.1 character string as character array. */ public char[] toCharArray() { return chars; } protected CharacterString(char[] chars) throws CharConversionException { this.chars = chars; cachedContents = computeContents(); } protected CharacterString(String s) throws CharConversionException { this.chars = s.toCharArray(); cachedContents = computeContents(); } private byte[] cachedContents; private byte[] getEncodedContents() { return cachedContents; } private byte[] computeContents() throws CharConversionException { CharConverter converter = getCharConverter(); byte[] contents = converter.charToByte(chars, 0, chars.length); return contents; } public void encode(OutputStream ostream) throws IOException { encode( getTag(), ostream ); } public void encode( Tag implicitTag, OutputStream ostream ) throws IOException { byte[] contents = getEncodedContents(); ASN1Header head = new ASN1Header( implicitTag, FORM, contents.length); head.encode(ostream); ostream.write( contents ); } public abstract static class Template implements ASN1Template { /** * Must be overridden to return the tag for the subclass. * @return Tag. */ protected abstract Tag getTag(); public abstract boolean tagMatch(Tag tag); /** * Must be overridden to return the correct character converter * for the subclass. * @return Character converter. */ protected abstract CharConverter getCharConverter(); /** * Must be overridden to create an instance of the subclass given * a char array. * @param chars Input characters. * @return Character string. * @throws CharConversionException If an error occurred. */ protected abstract CharacterString generateInstance(char[] chars) throws CharConversionException; /** * Must be overridden to provide the name of the subclass, for including * into error messages. * @return Name of the subclass. */ protected abstract String typeName(); public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); head.validate(implicitTag); byte[] raw; // raw bytes, not translated to chars yet if( head.getContentLength() == -1 ) { // indefinite length encoding ASN1Header ahead; ByteArrayOutputStream bos = new ByteArrayOutputStream(); do { ahead = ASN1Header.lookAhead( istream ); if( ! ahead.isEOC() ) { OCTET_STRING.Template ot = new OCTET_STRING.Template(); OCTET_STRING os = (OCTET_STRING) ot.decode(istream); bos.write( os.toByteArray() ); } } while( ! ahead.isEOC() ); // consume EOC ahead = new ASN1Header(istream); raw = bos.toByteArray(); } else { // definite length raw = new byte[ (int) head.getContentLength() ]; ASN1Util.readFully(raw, istream); } char[] chars = getCharConverter().byteToChar(raw, 0, raw.length); return generateInstance(chars); } catch( CharConversionException e ) { throw new InvalidBERException(e.getMessage()); } catch( InvalidBERException e ) { throw new InvalidBERException(e, typeName()); } } } } jss-4.6.3/org/mozilla/jss/asn1/CountingStream.java000066400000000000000000000052001362106420000220160ustar00rootroot00000000000000/* 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.asn1; import java.io.IOException; import java.io.InputStream; /** * This class keeps track of the number of bytes that have been read from * a stream. It will be incremented by the number of bytes read or skipped. * If the stream is marked and then reset, the number of bytes read will * be reset as well. */ class CountingStream extends InputStream { private int count=0; private int markpos; private InputStream source; private static final boolean DEBUG = false; public CountingStream(InputStream source) { this.source = source; } public int available() throws IOException { return source.available(); } public void mark(int readlimit) { source.mark(readlimit); markpos = count; if(DEBUG) { System.out.println("Marked at position "+markpos); } } public boolean markSupported() { return source.markSupported(); } public int read() throws IOException { int n = source.read(); if( n != -1 ) { count++; if(DEBUG) { System.out.println("read() 1 byte, count="+count); } } return n; } public int read(byte[] buffer) throws IOException { int n = source.read(buffer); if( n != -1 ) { count += n; } if(DEBUG) { System.out.println("read([]) "+n+" bytes, count="+count); } return n; } public int read(byte[] buffer, int offset, int count) throws IOException { int n = source.read(buffer, offset, count); if( n != -1 ) { this.count += n; } if(DEBUG) { System.out.println("read(...) "+n+" bytes, count="+this.count); } return n; } public void reset() throws IOException { source.reset(); if(DEBUG) { System.out.println("reset from "+count+" to "+markpos); } count = markpos; } public long skip(long count) throws IOException { this.count += count; if(DEBUG) { System.out.println("skipped "+count+", now at "+this.count); } return source.skip(count); } public int getNumRead() { return count; } public void resetNumRead() { count = 0; markpos = 0; if(DEBUG) { System.out.println("resetting count to 0"); } } } jss-4.6.3/org/mozilla/jss/asn1/ENUMERATED.java000066400000000000000000000044511362106420000205140ustar00rootroot00000000000000/* 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.asn1; import java.io.IOException; import java.io.InputStream; /** * Represents an ASN.1 ENUMERATED value. This has the same * interface as INTEGER */ public class ENUMERATED extends INTEGER implements ASN1Value { private static final long serialVersionUID = 1L; public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 10); public Tag getTag() { return TAG; } /** * Creates a new ENUMERATED value from a long int. * @param val Input value. */ public ENUMERATED( long val ) { super( val ); } ENUMERATED( byte[] valBytes ) { super( valBytes ); } /** * @return The value as a long int. */ public long getValue() { return longValue(); } private static final ENUMERATED.Template templateInstance = new ENUMERATED.Template(); public static ASN1Template getTemplate() { return templateInstance; } /** * A template for decoding ENUMERATED values from their BER encodings. * The template reads the value as an INTEGER. It does not check that it * is a valid value for the ENUMERATED type. */ public static class Template extends INTEGER.Template implements ASN1Template { Tag getTag() { return ENUMERATED.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals(ENUMERATED.TAG) ); } public ASN1Value decode(Tag tag, InputStream derStream) throws InvalidBERException, IOException { try { ASN1Header wrapper = new ASN1Header(derStream); wrapper.validate(tag, FORM); // Is length < 1 ? if( wrapper.getContentLength() < 1 ) { throw new InvalidBERException("Invalid 0 length for ENUMERATED"); } byte[] valBytes = new byte[ (int) wrapper.getContentLength() ]; ASN1Util.readFully(valBytes, derStream); return new ENUMERATED( valBytes ); } catch(InvalidBERException e) { throw new InvalidBERException(e, "ENUMERATED"); } } } // end of Template } jss-4.6.3/org/mozilla/jss/asn1/EXPLICIT.java000066400000000000000000000075031362106420000203050ustar00rootroot00000000000000/* 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.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.util.Assert; /** * An explicit tag. */ public class EXPLICIT implements ASN1Value { public static final Form FORM = Form.CONSTRUCTED; private ASN1Value content; private Tag tag; /** * Creates an EXPLICIT tag wrapping some other ASN1Value. For example, * for the following ASN.1 snippet: *

     * MyType [3] EXPLICIT INTEGER
     * 
* assuming a sample value of 5 for the INTEGER, a MyType could be * created with: *
     *  EXPLICIT myValue = new EXPLICIT( new Tag(3), new INTEGER(5) );
     * 
* @param tag Tag. * @param content Content. */ public EXPLICIT( Tag tag, ASN1Value content ) { assert(tag!=null && content!=null); this.content = content; this.tag = tag; } /** * @return the ASN1Value that is wrapped by this EXPLICIT tag. */ public ASN1Value getContent() { return content; } /** * Returns the Tag of this EXPLICIT 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 { ByteArrayOutputStream bos = new ByteArrayOutputStream(); content.encode(bos); byte[] contentBytes = bos.toByteArray(); ASN1Header head = new ASN1Header(implicitTag, FORM, contentBytes.length ); head.encode(ostream); ostream.write(contentBytes); } public static Template getTemplate( Tag tag, ASN1Template content) { return new Template(tag, content); } /** * A template for decoding an object wrapped in an EXPLICIT tag. */ public static class Template implements ASN1Template { private ASN1Template content; private Tag tag; /** * Creates a template for unwrapping an object wrapped in an explicit tag. * For example, to decode: *
     * MyValue ::= [3] EXPLICIT INTEGER
     * 
* use: *
     * EXPLICIT.Template myTemplate = new EXPLICIT.Template( new Tag(3),
     *      new INTEGER.Template() );
     * 
* * @param tag The tag value of the EXPLICIT tag. * @param content The template for decoding the object that is wrapped * in the explicit tag. */ public Template(Tag tag, ASN1Template content) { this.content = content; this.tag = tag; } public boolean tagMatch(Tag tag) { return( this.tag.equals(tag) ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(tag, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); head.validate( implicitTag, Form.CONSTRUCTED ); ASN1Value val = content.decode(istream); EXPLICIT e = new EXPLICIT(tag, val); // if indefinite content length, consume the end-of-content marker if( head.getContentLength() == -1 ) { head = new ASN1Header(istream); if( ! head.isEOC() ) { throw new InvalidBERException("No end-of-contents marker"); } } return e; } catch(InvalidBERException e) { throw new InvalidBERException(e, "EXPLICIT"); } } } // end of Template } jss-4.6.3/org/mozilla/jss/asn1/FieldNotPresentException.java000066400000000000000000000015511362106420000240050ustar00rootroot00000000000000/* 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.asn1; /** * An exception thrown when an optional field is not present. */ public class FieldNotPresentException extends java.lang.Exception { private static final long serialVersionUID = 1L; public FieldNotPresentException() { super(); } public FieldNotPresentException(String mesg) { super(mesg); } public FieldNotPresentException(String mesg, Throwable cause) { super(mesg, cause); } public FieldNotPresentException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/asn1/Form.java000066400000000000000000000012601362106420000177610ustar00rootroot00000000000000/* 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.asn1; /** * An enumerated type representing the forms of an ASN.1 value. * The possibilities are PRIMITIVE and CONSTRUCTED. */ public class Form { private String name; private Form() { } private Form(String name) { this.name = name; } public static final Form PRIMITIVE = new Form("PRIMITIVE"); public static final Form CONSTRUCTED = new Form("CONSTRUCTED"); public String toString() { return name; } } jss-4.6.3/org/mozilla/jss/asn1/GeneralizedTime.java000066400000000000000000000027231362106420000221330ustar00rootroot00000000000000/* 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.asn1; import java.util.Date; /** * The ASN.1 type GeneralizedTime */ public class GeneralizedTime extends TimeBase implements ASN1Value { public static final Tag TAG = new Tag(Tag.UNIVERSAL, 24); public Tag getTag() { return TAG; } /** * Creates a GeneralizedTime from a Date. * @param date Input date. */ public GeneralizedTime(Date date) { super(date); } protected boolean isUTC() { return false; } private static final GeneralizedTime.Template templateInstance = new GeneralizedTime.Template(); public static GeneralizedTime.Template getTemplate() { return templateInstance; } /** * A class for decoding GeneralizedTimes. */ public static class Template extends TimeBase.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected boolean isUTC() { return false; } protected TimeBase generateInstance(Date date) { return new GeneralizedTime(date); } } } jss-4.6.3/org/mozilla/jss/asn1/IA5String.java000066400000000000000000000050071362106420000206260ustar00rootroot00000000000000/* 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.asn1; import java.io.CharConversionException; public class IA5String extends CharacterString implements ASN1Value { public IA5String(char[] chars) throws CharConversionException { super(chars); } public IA5String(String s) throws CharConversionException { super(s); } CharConverter getCharConverter() { return new IA5Converter(); } public static final Tag TAG = new Tag( Tag.Class.UNIVERSAL, 22 ); public Tag getTag() { return TAG; } public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); // nested class public static class Template extends CharacterString.Template implements ASN1Template { public Tag getTag() { return IA5String.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals( IA5String.TAG )); } protected CharConverter getCharConverter() { return new IA5Converter(); } protected CharacterString generateInstance(char[] chars) throws CharConversionException { return new IA5String(chars); } protected String typeName() { return "IA5String"; } } // nested class private static class IA5Converter implements CharConverter { public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { char[] chars = new char[len]; int c; // char index int b; // byte index for(b = offset, c=0; c < len; b++, c++) { if( (bytes[b] & 0x80) != 0 ) { throw new CharConversionException("Invalid character: "+ bytes[b]); } chars[c] = (char) (bytes[b] & 0x7f); } return chars; } public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { byte[] bytes = new byte[len]; int c; // char index int b; // byte index for(c = offset, b = 0; b < len; c++, b++) { if( (chars[c] & 0x7f) != chars[c] ) { throw new CharConversionException("Invalid character: "+ chars[c]); } bytes[b] = (byte) (chars[c] & 0x7f); } return bytes; } } } jss-4.6.3/org/mozilla/jss/asn1/INTEGER.java000066400000000000000000000143051362106420000201570ustar00rootroot00000000000000/* 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.asn1; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.util.Random; /** * The ASN.1 type INTEGER. This class extends BigInteger. */ public class INTEGER extends BigInteger implements ASN1Value { private static final long serialVersionUID = 1L; private byte[] encodedContents = null; private byte[] getEncodedContents() { if( encodedContents == null ) { encodedContents = toByteArray(); } return encodedContents; } private ASN1Header getHeader(Tag t) { return new ASN1Header( t, FORM, getContentLength() ); } public INTEGER(String s) throws NumberFormatException { super(s); } public INTEGER(String s, int r) throws NumberFormatException { super(s, r); } public INTEGER(byte[] bval) throws NumberFormatException { super(bval); } public INTEGER(int sign, byte[] mag) throws NumberFormatException { super(sign, mag); } public INTEGER(int numBits, Random rnd) throws NumberFormatException { super(numBits, rnd); } public INTEGER(int bitLength, int certainty, Random rnd) { super(bitLength, certainty, rnd); } public INTEGER(long val) { super( BigInteger.valueOf(val).toByteArray() ); } public INTEGER(BigInteger bi) { super( bi.toByteArray() ); } public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 2); public Tag getTag() { return TAG; } public static final Form FORM = Form.PRIMITIVE; public void encode(OutputStream outStream) throws IOException { encode(getTag(), outStream); } public void encode(Tag implicitTag, OutputStream outStream) throws IOException { // write header getHeader(implicitTag).encode( outStream ); // write contents outStream.write( getEncodedContents() ); } public long getContentLength() { return getEncodedContents().length; } public byte[] encode() throws IOException { ByteArrayOutputStream b = new ByteArrayOutputStream(); encode(b); return b.toByteArray(); } private static final INTEGER.Template templateInstance = new INTEGER.Template(); public static ASN1Template getTemplate() { return templateInstance; } /** * Tests the DER encoding and decoding of the INTEGER class. * @param args Arguments. */ public static void main(String args[]) { try { int[] Is = new int[11]; int[][] Bs = new int[11][]; int i = 0; Is[i] = 0; Bs[i++] = new int[]{ 0x02, 0x01, 0x00 }; Is[i] = 1; Bs[i++] = new int[]{ 0x02, 0x01, 0x01 }; Is[i] = -1; Bs[i++] = new int[]{ 0x02, 0x01, 0xff }; Is[i] = 127; Bs[i++] = new int[]{ 0x02, 0x01, 0x7f }; Is[i] = 128; Bs[i++] = new int[]{ 0x02, 0x02, 0x00, 0x80 }; Is[i] = 255; Bs[i++] = new int[]{ 0x02, 0x02, 0x00, 0xff }; Is[i] = 256; Bs[i++] = new int[]{ 0x02, 0x02, 0x01, 0x00 }; Is[i] = -128; Bs[i++] = new int[]{ 0x02, 0x01, 0x80 }; Is[i] = -129; Bs[i++] = new int[]{ 0x02, 0x02, 0xff, 0x7f }; Is[i] = 43568; Bs[i++] = new int[]{ 0x02, 0x03, 0x00, 0xaa, 0x30 }; Is[i] = -43568; Bs[i++] = new int[]{ 0x02, 0x03, 0xff, 0x55, 0xd0 }; for( i = 0; i < Is.length; i++) { INTEGER I = new INTEGER( Is[i] ); byte[] compare = I.encode(); if( ! arraysEqual(compare, Bs[i]) ) { System.err.println("Encoding FAILED: "+Is[i]); System.exit(-1); } ByteArrayInputStream bis = new ByteArrayInputStream(compare); Template template = new Template(); INTEGER create = (INTEGER) template.decode(bis); if( create.intValue() != Is[i] ) { System.err.println("Decoding FAILED: "+Is[i]); System.exit(-1); } } System.out.println("PASS"); } catch( Exception e ) { e.printStackTrace(); } } private static boolean arraysEqual(byte[] bytes, int[] ints) { if(bytes == null || ints == null) { return false; } if(bytes.length != ints.length) { return false; } for( int i=0; i < bytes.length; i++) { if( bytes[i] != (byte)ints[i] ) { return false; } } return true; } /////////////////////////////////////////////////////////////////////// // INTEGER.Template // This is a nested class. // public static class Template implements ASN1Template { Tag getTag() { return INTEGER.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals(INTEGER.TAG)); } public ASN1Value decode(InputStream derStream) throws InvalidBERException, IOException { return decode( getTag(), derStream ); } public ASN1Value decode(Tag tag, InputStream derStream) throws InvalidBERException, IOException { try { ASN1Header wrapper = new ASN1Header(derStream); wrapper.validate(tag, FORM); // Is length < 1 ? if( wrapper.getContentLength() < 1 ) { throw new InvalidBERException("Invalid 0 length for INTEGER"); } byte[] valBytes = new byte[ (int) wrapper.getContentLength() ]; ASN1Util.readFully(valBytes, derStream); return new INTEGER( valBytes ); } catch(InvalidBERException e) { throw new InvalidBERException(e, "INTEGER"); } } } // end of class Template } jss-4.6.3/org/mozilla/jss/asn1/InvalidBERException.java000066400000000000000000000043151362106420000226600ustar00rootroot00000000000000/* 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.asn1; import java.util.Vector; /** * An exception thrown when BER decoding fails. */ public class InvalidBERException extends java.lang.Exception { private static final long serialVersionUID = 1L; private InvalidBERException child=null; private Vector mesgList = new Vector<>(); public InvalidBERException(String mesg) { super(mesg); } public void append(String mesg) { mesgList.addElement(mesg); } public InvalidBERException(InvalidBERException e, String mesg) { super(mesg); child = e; } /** * Prints out the exception class and error message, including * all the nested exceptions. */ private void appendMessages(StringBuffer sb) { int numMessages = mesgList.size(); for( int i=numMessages-1; i >= 0; --i ) { sb.append(mesgList.elementAt(i)); sb.append(" >> "); } sb.append(getMessage()); } public String toString() { StringBuffer sb = new StringBuffer(); sb.append( this.getClass().getName() ); sb.append(": "); appendMessages(sb); return sb.toString(); } public String toStringNested() { StringBuffer sb = new StringBuffer(); appendMessages(sb); if( child != null ) { sb.append(" >> "); sb.append( child.toStringNested() ); } return sb.toString(); } public static class EOF extends InvalidBERException { private static final long serialVersionUID = 1L; public EOF() { super("Unexpected end-of-file encountered"); } } public static class InvalidChar extends InvalidBERException { private static final long serialVersionUID = 1L; public InvalidChar(byte b, int offset) { super("Invalid character ("+b+") encountered at offset "+offset); } public InvalidChar(char c, int offset) { super("Invalid character ("+c+") encountered at offset"+offset); } } } jss-4.6.3/org/mozilla/jss/asn1/NULL.java000066400000000000000000000037651362106420000176440ustar00rootroot00000000000000/* 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.asn1; import java.io.OutputStream; import java.io.InputStream; import java.io.IOException; public class NULL implements ASN1Value { public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 5); public Tag getTag() { return TAG; } public static final Form FORM = Form.PRIMITIVE; public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { ASN1Header head = new ASN1Header(implicitTag, FORM, 0); head.encode(ostream); } private static final NULL instance = new NULL(); public static NULL getInstance() { return instance; } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public static class Template implements ASN1Template { public Tag getTag() { return NULL.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals(NULL.TAG) ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); head.validate(implicitTag, FORM); if( head.getContentLength() != 0 ) { throw new InvalidBERException("Invalid length ("+ head.getContentLength()+") for NULL; only 0 is permitted"); } return new NULL(); } catch(InvalidBERException e) { throw new InvalidBERException(e, "NULL"); } } } // end of Template } jss-4.6.3/org/mozilla/jss/asn1/OBJECT_IDENTIFIER.java000066400000000000000000000435421362106420000215370ustar00rootroot00000000000000/* 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.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.StringTokenizer; import java.util.Vector; import org.mozilla.jss.util.Assert; public class OBJECT_IDENTIFIER implements ASN1Value { /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Standard object identifiers /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * The OID space for EC */ public static final OBJECT_IDENTIFIER EC_PUBKEY_OID = new OBJECT_IDENTIFIER( new long[]{1, 2, 840, 10045, 2, 1} ); /** * The OID space for RSA Data Security, Inc. */ public static final OBJECT_IDENTIFIER RSADSI = new OBJECT_IDENTIFIER( new long[]{1, 2, 840, 113549} ); /** * The OID space for RSA's PKCS (public key cryptography standards). */ public static final OBJECT_IDENTIFIER PKCS = RSADSI.subBranch(1); /** * The OID space for RSA's PKCS #1. */ public static final OBJECT_IDENTIFIER PKCS1 = PKCS.subBranch(1); /** * The OID space for RSA's PKCS #2, which has since been folded into * PKCS #1. */ public static final OBJECT_IDENTIFIER PKCS2 = PKCS.subBranch(2); /** * The OID space for RSA's message digest algorithms. */ public static final OBJECT_IDENTIFIER RSA_DIGEST = RSADSI.subBranch(2); /** * The OID space for RSA's password-based encryption standard. */ public static final OBJECT_IDENTIFIER PKCS5 = PKCS.subBranch(5); /** * The OID space for RSA's Selected Attribute Types standard, PKCS #9. */ public static final OBJECT_IDENTIFIER PKCS9 = PKCS.subBranch(9); /** * The OID space for RSA's personal information exchange syntax standard. */ public static final OBJECT_IDENTIFIER PKCS12 = PKCS.subBranch(12); /** * The OID space for RSA's ciphers. */ public static final OBJECT_IDENTIFIER RSA_CIPHER = RSADSI.subBranch(3); /** * The OID space for FIPS standardized algorithms. */ public static final OBJECT_IDENTIFIER ALGORITHM = new OBJECT_IDENTIFIER( new long[] { 1, 3, 14, 3, 2 } ); /** * The OID space for FIPS-180-2 SHA256/SHA384/SHA512 standardized algorithms. */ public static final OBJECT_IDENTIFIER HASH_ALGORITHM = new OBJECT_IDENTIFIER( new long[] {2, 16, 840, 1, 101, 3, 4, 2 } ); /** * The OID space for PKIX. */ public static final OBJECT_IDENTIFIER PKIX = new OBJECT_IDENTIFIER( new long[] { 1, 3, 6, 1, 5, 5, 7 } ); public static final OBJECT_IDENTIFIER id_cmc = PKIX.subBranch( 7 ); /** * CMC control attributes */ public static final OBJECT_IDENTIFIER id_cmc_cMCStatusInfo = id_cmc.subBranch(1); public static final OBJECT_IDENTIFIER id_cmc_identification = id_cmc.subBranch(2); public static final OBJECT_IDENTIFIER id_cmc_identityProof = id_cmc.subBranch(3); public static final OBJECT_IDENTIFIER id_cmc_dataReturn = id_cmc.subBranch(4); public static final OBJECT_IDENTIFIER id_cmc_transactionId = id_cmc.subBranch(5); public static final OBJECT_IDENTIFIER id_cmc_senderNonce = id_cmc.subBranch(6); public static final OBJECT_IDENTIFIER id_cmc_recipientNonce = id_cmc.subBranch(7); public static final OBJECT_IDENTIFIER id_cmc_addExtensions = id_cmc.subBranch(8); public static final OBJECT_IDENTIFIER id_cmc_encryptedPOP = id_cmc.subBranch(9); public static final OBJECT_IDENTIFIER id_cmc_decryptedPOP = id_cmc.subBranch(10); public static final OBJECT_IDENTIFIER id_cmc_lraPOPWitness = id_cmc.subBranch(11); public static final OBJECT_IDENTIFIER id_cmc_getCert = id_cmc.subBranch(15); public static final OBJECT_IDENTIFIER id_cmc_getCRL = id_cmc.subBranch(16); public static final OBJECT_IDENTIFIER id_cmc_revokeRequest = id_cmc.subBranch(17); public static final OBJECT_IDENTIFIER id_cmc_regInfo = id_cmc.subBranch(18); public static final OBJECT_IDENTIFIER id_cmc_responseInfo = id_cmc.subBranch(19); public static final OBJECT_IDENTIFIER id_cmc_QueryPending = id_cmc.subBranch(21); public static final OBJECT_IDENTIFIER id_cmc_idPOPLinkRandom = id_cmc.subBranch(22); public static final OBJECT_IDENTIFIER 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 ); public static final OBJECT_IDENTIFIER id_cct_PKIData = id_cct.subBranch( 2 ); public static final OBJECT_IDENTIFIER id_cct_PKIResponse = id_cct.subBranch( 3 ); public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 6); public Tag getTag() { return TAG; } public static final Form FORM = Form.PRIMITIVE; private long[] numbers; /** * Creates an OBJECT_IDENTIFIER from an array of longs, which constitute * the numbers that make up the OBJECT IDENTIFIER. * @param numbers Numbers. */ public OBJECT_IDENTIFIER( long[] numbers ) { checkLongArray(numbers); this.numbers = numbers; } /** * Checks the given array of numbers to see if it is a valid OID. * This is not an exhaustive test, it just looks for obvious problems. * It will throw an assertion if a problem is found. With DEBUG turned * off, it just checks for null. */ private static void checkLongArray(long[] numbers) { assert(numbers != null); if(numbers == null) { throw new NullPointerException(); } assert(numbers.length >= 2); assert( numbers[0]==0 || numbers[0]==1 || numbers[0]==2 ); } /** * Creates an OBJECT_IDENTIFIER from a String version. The proper format * for the OID string is dotted numbers, for example: * "3.2.456.53.23.64". * * Because the toString() method here provides a different format, we also * allow that format, for example: * "{3 2 456 53 23 64}". * * @param dottedOID OID string. * @exception NumberFormatException If the given string cannot be * parsed into an OID. */ public OBJECT_IDENTIFIER( String dottedOID ) throws NumberFormatException { if( dottedOID == null || dottedOID.length()==0 ) { throw new NumberFormatException("OID string is zero-length"); } if (dottedOID.startsWith("{")) { // input string is of the format provided by OBJECT_IDENTIFIER,toString() // convert this first to dotted OID // remove the leading and trailing brackets dottedOID = dottedOID.substring(1, dottedOID.length()-1); // convert spaces to dots dottedOID = dottedOID.replaceAll(" ", "."); } StringTokenizer stok = new StringTokenizer(dottedOID, "."); numbers = new long[ stok.countTokens() ]; int i = 0; while(stok.hasMoreElements()) { numbers[i++] = Long.parseLong( stok.nextToken() ); } assert( i == numbers.length ); checkLongArray(numbers); } public long[] getNumbers() { return numbers; } public int hashCode() { int code = 1; for(int i = 0; i < numbers.length; i++) { code = (int) (code + numbers[i])*10; } return code; } /** * Creates a new OBJECT_IDENTIFIER that is a sub-branch of this one. * For example, if OBJECT_IDENTIFIER oid has the value * { 1 3 5 6 }, * then calling oid.subBranch(4) would return a new * OBJECT_IDENTIFIER with the value { 1 3 5 6 4 }. * @param num Number. * @return New sub-branch. */ public OBJECT_IDENTIFIER subBranch(long num) { long[] nums = new long[ numbers.length + 1]; System.arraycopy(numbers, 0, nums, 0, numbers.length); nums[numbers.length] = num; return new OBJECT_IDENTIFIER(nums); } /** * Creates a new OBJECT_IDENTIFIER that is a sub-branch of this one. * For example, if OBJECT_IDENTIFIER oid has the value * { 1 3 5 6 }, * then calling oid.subBranch(new long[]{ 4, 3}) * would return a new * OBJECT_IDENTIFIER with the value { 1 3 5 6 4 3}. * @param newNums New numbers. * @return New sub-branch. */ public OBJECT_IDENTIFIER subBranch(long[] newNums) { long[] nums = new long[ numbers.length + newNums.length]; System.arraycopy(numbers, 0, nums, 0, numbers.length); System.arraycopy(newNums, 0, nums, numbers.length, newNums.length); return new OBJECT_IDENTIFIER(nums); } public boolean equals(Object obj) { if(obj == null || ! (obj instanceof OBJECT_IDENTIFIER)) { return false; } long[] nums = ((OBJECT_IDENTIFIER)obj).numbers; if( nums.length != numbers.length ) { return false; } for(int i = 0; i < nums.length; i++) { if( nums[i] != numbers[i] ) { return false; } } return true; } public String toString() { String ret = "{" + String.valueOf(numbers[0]); for(int i=1; i < numbers.length; i++) { ret = ret + " " + numbers[i]; } ret += "}"; return ret; } public String toDottedString() { String ret = String.valueOf(numbers[0]); for(int i=1; i < numbers.length; i++) { ret = ret + "." + numbers[i]; } return ret; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } private byte[] encodedContents = null; /** * Gets the encoding of the contents, or a cached copy. * Since the content encoding is the same regardless of the Tag, * this only needs to be computed once. */ private byte[] getEncodedContents() { if( encodedContents == null ) { encodedContents = computeEncodedContents(); } return encodedContents; } // We cache our encoding for a given tag. 99% of the time, only // one tag will be used for an instance, so we will get a cache hit. // In the remaining 1%, we'll have to recompute the encoding. byte[] cachedEncoding=null; Tag tagForCache=null; /** * Returns the encoding for the given tag. If the encoding for * this tag was previously computed (and no encoding for a different * tag has since been computed), this method returns a cached copy. * Otherwise, the encoding will be recomputed. */ private byte[] getEncoding(Tag tag) { if( ! tag.equals(tagForCache) ) { // recompute for new tag ByteArrayOutputStream out = new ByteArrayOutputStream(); ASN1Header head = getHeader(tag); try { head.encode(out); } catch( IOException e ) { throw new RuntimeException("Unable to encode ASN.1 header: " + e.getMessage(), e); } out.write( getEncodedContents(), 0, getEncodedContents().length ); tagForCache = tag; cachedEncoding = out.toByteArray(); } return cachedEncoding; } /** * Compute the ASN1 header for this tag. */ private ASN1Header getHeader(Tag implicitTag) { return new ASN1Header( implicitTag, FORM, getEncodedContents().length ); } /** * Actually computes the encoding of this object identifier. */ private byte[] computeEncodedContents() { ByteArrayOutputStream out = new ByteArrayOutputStream(); // handle first number assert(numbers.length >= 2); long n = numbers[0]; assert( n == 0 || n == 1 || n == 2 ); long outb = ( numbers[0] * 40 ) + numbers[1]; assert( ((byte)outb) == outb ); out.write( (byte)outb ); // handle consecutive numbers for( int i = 2; i < numbers.length; i++ ) { n = numbers[i]; assert( n >= 0 ); // array of output bytes, in reverse order. 10 bytes, at 7 bits // per byte, is 70 bits, which is more than enough to handle // the maximum value of a long, which takes up 63 bits. byte[] rev = new byte[10]; int idx=0; // index into reversed bytes // Create reversed byte list do { rev[idx++] = (byte) (n % 128); n = n / 128; } while( n > 0 ); idx--; // backup to point to last element // now print them in reverse order while( idx > 0 ) { // all but last byte have MSB==1 out.write( rev[idx--] | 0x80 ); } assert(idx == 0); // last byte has MSB==0 out.write( rev[0] ); } return out.toByteArray(); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { ostream.write( getEncoding(implicitTag) ); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /////////////////////////////////////////////////////////////////////// // OBJECT_IDENTIFIER.Template // public static class Template implements ASN1Template { public Tag getTag() { return OBJECT_IDENTIFIER.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals(OBJECT_IDENTIFIER.TAG) ); } public Form getForm() { return OBJECT_IDENTIFIER.FORM; } public boolean formMatch(Form form) { return( form == OBJECT_IDENTIFIER.FORM ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); long remainingContent = head.getContentLength(); // Check the information gleaned from the header if( ! head.getTag().equals( implicitTag ) ) { throw new InvalidBERException("Incorrect tag for "+ "OBJECT IDENTIFIER: "+ head.getTag() ); } if( head.getForm() != getForm() ) { throw new InvalidBERException("Incorrect form for OBJECT "+ "IDENTIFIER"); } if( remainingContent < 1 ) { throw new InvalidBERException("Invalid 0 length for OBJECT"+ " IDENTIFIER"); } Vector numberV = new Vector<>(); // handle first byte, which contains first two numbers byte b = readByte(istream); remainingContent--; long num = b % 40; numberV.addElement( Long.valueOf(b % 40) ); // second number numberV.insertElementAt( Long.valueOf(b / 40), 0); // first number // handle the rest of the numbers while( remainingContent > 0 ) { num = 0; // keep reading until MSB == 0 int bitcount=0; do { if( (bitcount+=7) > 63 ) { // we're about to overflow our long throw new InvalidBERException("OBJECT IDENTIFIER "+ "element too long; max is 63 bits"); } b = readByte(istream); remainingContent--; num <<= 7; num |= (b & 0x7f); } while( (b & 0x80) != 0 ); numberV.addElement( Long.valueOf(num) ); } // convert Vector to array long numbers[] = new long[ numberV.size() ]; for(int i = 0; i < numbers.length; i++) { numbers[i] = numberV.elementAt(i).longValue(); } // create OBJECT_IDENTIFIER from array return new OBJECT_IDENTIFIER(numbers); } catch(InvalidBERException e) { throw new InvalidBERException(e, "OBJECT IDENTIFIER"); } } /** * Reads in a byte from the stream, throws an InvalidBERException * if EOF is reached. */ private static byte readByte(InputStream istream) throws InvalidBERException, IOException { int n = istream.read(); if( n == -1 ) { throw new InvalidBERException("End-of-file reached while "+ "decoding OBJECT IDENTIFIER"); } assert( (n & 0xff) == n ); return (byte) n; } } // end of OBJECT_IDENTIFIER.Template } jss-4.6.3/org/mozilla/jss/asn1/OCTET_STRING.java000066400000000000000000000060501362106420000210240ustar00rootroot00000000000000/* 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.asn1; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class OCTET_STRING implements ASN1Value { public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 4); public Tag getTag() { return TAG; } public static final Form FORM = Form.PRIMITIVE; byte[] data; public OCTET_STRING( byte[] data ) { this.data = data; } public byte[] toByteArray() { return data; } public void encode(OutputStream ostream) throws IOException { // use getTag() so we can be subclassed encode(getTag(), ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { ASN1Header head = new ASN1Header(implicitTag, FORM, data.length); head.encode(ostream); ostream.write(data); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public static class Template implements ASN1Template { public Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return( TAG.equals(tag) ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } // this can be overridden by subclasses protected ASN1Value generateInstance(byte[] bytes) { return new OCTET_STRING( bytes ); } // this can be overridden by subclasses protected String getName() { return "OCTET_STRING"; } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); head.validate(implicitTag); byte[] data; if( head.getContentLength() == -1 ) { // indefinite length encoding ASN1Header ahead; ByteArrayOutputStream bos = new ByteArrayOutputStream(); do { ahead = ASN1Header.lookAhead( istream ); if( ! ahead.isEOC() ) { OCTET_STRING.Template ot = new OCTET_STRING.Template(); OCTET_STRING os = (OCTET_STRING) ot.decode(istream); bos.write( os.toByteArray() ); } } while( ! ahead.isEOC() ); // consume EOC ahead = new ASN1Header(istream); data = bos.toByteArray(); } else { data = new byte[ (int) head.getContentLength() ]; ASN1Util.readFully(data, istream); } return generateInstance(data); } catch( InvalidBERException e ) { throw new InvalidBERException(e, getName()); } } } // end of Template } jss-4.6.3/org/mozilla/jss/asn1/PrintableString.java000066400000000000000000000070661362106420000221770ustar00rootroot00000000000000/* 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.asn1; import java.io.CharConversionException; public class PrintableString extends CharacterString implements ASN1Value { public PrintableString(char[] chars) throws CharConversionException { super(chars); } public PrintableString(String s) throws CharConversionException { super(s); } CharConverter getCharConverter() { return new PrintableConverter(); } public static final Tag TAG = new Tag( Tag.UNIVERSAL, 19 ); public static final Form FORM = Form.PRIMITIVE; public Tag getTag() { return TAG; } /** * Returns a singleton instance of the decoding template for this class. * @return The template. */ public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); // nested class public static class Template extends CharacterString.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected CharConverter getCharConverter() { return new PrintableConverter(); } protected CharacterString generateInstance(char[] chars) throws CharConversionException { return new PrintableString(chars); } protected String typeName() { return "PrintableString"; } } private static class PrintableConverter implements CharConverter { private static boolean[] isPrintable = new boolean[128]; static { char b; for(b='A'; b <= 'Z'; b++) { isPrintable[b] = true; } for(b='a'; b <= 'z'; b++) { isPrintable[b] = true; } for(b='0'; b <= '9'; b++) { isPrintable[b] = true; } isPrintable[' '] = true; isPrintable['\''] = true; isPrintable['('] = true; isPrintable[')'] = true; isPrintable['+'] = true; isPrintable[','] = true; isPrintable['-'] = true; isPrintable['.'] = true; isPrintable['/'] = true; isPrintable[':'] = true; isPrintable['='] = true; isPrintable['?'] = true; } public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { char[] chars = new char[len]; int c; // char index int b; // byte index for(c=0, b=offset; c < len; b++, c++) { if( (bytes[b] & 0x80) != 0 || !isPrintable[bytes[b]] ) { /* fix for bug 359010 - don't throw, just skip * throw new CharConversionException(bytes[b]+ " is not "+ * "a valid character for a PrintableString"); */ } else { chars[c] = (char) bytes[b]; } } return chars; } public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { byte[] bytes = new byte[len]; int c; // char index int b; // byte index for(c=0, b=0; b < len; b++, c++) { if( (chars[c] & 0xff80) != 0 || !isPrintable[chars[c]] ) { throw new CharConversionException(chars[c]+ " is not "+ "a valid character for a PrintableString"); } bytes[b] = (byte) (chars[c] & 0x7f); } return bytes; } } // end of char converter } jss-4.6.3/org/mozilla/jss/asn1/SEQUENCE.java000066400000000000000000000637751362106420000203110ustar00rootroot00000000000000/* 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.asn1; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Vector; import org.mozilla.jss.util.Assert; /** * An ASN.1 SEQUENCE. This class is an ordered collection of ASN.1 values. * It has an interface similar to a Java Vector. * Null entries may be added; they will be skipped when encoded. */ public class SEQUENCE extends SET implements ASN1Value { public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 16); public Tag getTag() { return TAG; } public static Template getTemplate() { return new Template(); } /** * Writes the DER encoding to the given output stream, * using the given implicit tag. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { BERencode(implicitTag, ostream); } // SET.Element and SEQUENCE.Element are identical types. We could // have just reused SET.Element, but that would have been a bit // confusing for users. private static class Element extends SET.Element { public Element( ASN1Value val ) { super(val); } public Element( Tag implicitTag, ASN1Value val) { super(implicitTag, val); } } /** * A class for constructing a SEQUENCE from its BER encoding. * It is an ordered collection of sub-templates. Each sub-template can be * marked optional, or a default value can be given. */ public static class Template implements ASN1Template { private Vector elements = new Vector<>(); private void addElement(Element el) { elements.addElement( el ); } private void insertElementAt(Element e, int index) { elements.insertElementAt(e, index); } /** * Adds a sub-template to the end of this SEQUENCE template. For example, * if the ASN.1 included: *
     * MySequence ::= SEQUENCE {
     *      item        SubType,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addElement( new SubType.Template() );
     * 
* @param t Sub-template. */ public void addElement( ASN1Template t ) { addElement( new Element(null, t, false) ); } /** * Inserts the template at the given index. * @param t Sub-template. * @param index Index. */ public void insertElementAt( ASN1Template t, int index ) { insertElementAt( new Element(null, t, false), index ); } /** * Adds a sub-template to the end of this SEQUENCE template, with the * given implicit tag. For example, if the ASN.1 were: *
     * MySequence ::= SEQUENCE {
     *      item        [0] IMPLICIT  SubType,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addElement( new Tag(0), new SubType.Template());
     * 
* @param implicitTag Implicit tag. * @param t Sub-template. */ public void addElement( Tag implicitTag, ASN1Template t ) { addElement( new Element(implicitTag, t, false) ); } /** * Inserts the template with the given implicit tag at the given index. * @param implicit Implicit tag. * @param t Sub-Template. * @param index Index. */ public void insertElementAt( Tag implicit, ASN1Template t, int index ) { insertElementAt( new Element(implicit, t, false), index ); } /** * Adds an optional sub-template. For example, if the ASN.1 were: *
     * MySequence ::= SEQUENCE {
     *      item        SubType OPTIONAL,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addOptionalElement( new SubType.Template() );
     * 
* @param t Optional sub-template. */ public void addOptionalElement( ASN1Template t ) { addElement( new Element(null, t, true) ); } /** * Inserts the optional template at the given index. * @param t Optional sub-template. * @param index Index. */ public void insertOptionalElementAt( ASN1Template t, int index ) { insertElementAt( new Element(null, t, true), index ); } /** * Adds an optional sub-template with an implicit tag. For example, * if the ASN.1 were: *
     * MySequence ::= SEQUENCE {
     *      item        [0] IMPLICIT SubType OPTIONAL,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addOptionalElement( new SubType.Template() );
     * 
* @param implicitTag Implicit tag. * @param t Optional sub-template. */ public void addOptionalElement( Tag implicitTag, ASN1Template t ) { addElement( new Element(implicitTag, t, true) ); } /** * Inserts the optional template with the given default * value at the given index. * @param implicit Implicit tag. * @param t Optional sub-template. * @param index Index. */ public void insertOptionalElementAt( Tag implicit, ASN1Template t, int index ) { insertElementAt( new Element(implicit, t, true), index ); } /** * Adds a sub-template with a default value. For example, * if the ASN.1 were: *
     * MySequence ::= SEQUENCE {
     *      version     INTEGER DEFAULT 1,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addElement( new INTEGER.Template(), new INTEGER(1) );
     * 
* @param t Sub-template. * @param def The default value for this field, which will be used if * no value is supplied by the encoded structure. It must be of * the same type as what the template would produce. */ public void addElement( ASN1Template t, ASN1Value def ) { addElement( new Element(null, t, def) ); } /** * Inserts the template with the given default * value at the given index. * @param t Sub-template. * @param def Default value. * @param index Index. */ public void insertElementAt( ASN1Template t, ASN1Value def, int index ) { insertElementAt( new Element(null, t, def), index ); } /** * Adds a sub-template with a default value and an implicit tag. * For example, if the ASN.1 were: *
     * MySequence ::= SEQUENCE {
     *      version     [0] IMPLICIT INTEGER DEFAULT 1,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addElement( new Tag(0), new INTEGER.Template(),
     *      new INTEGER(1) );
     * 
* @param implicitTag Implicit tag. * @param t Sub-template. * @param def The default value for this field, which will be used if * no value is supplied by the encoded structure. It must be of * the same type as what the template would produce. */ public void addElement( Tag implicitTag, ASN1Template t, ASN1Value def) { addElement( new Element(implicitTag, t, def) ); } /** * Inserts the template with the given implicit tag and given default * value at the given index. * @param implicit Implicit tag. * @param t Sub-template. * @param def Default value. * @param index Index. */ public void insertElementAt( Tag implicit, ASN1Template t, ASN1Value def, int index ) { insertElementAt( new Element(implicit, t, def), index ); } /** * Returns the implicit tag of the item stored at the given index. * May be NULL if no implicit tag was specified. * @param index Index. * @return Tag. */ public Tag implicitTagAt( int index ) { return elements.elementAt(index).getImplicitTag(); } /** * Returns the sub-template stored at the given index. * @param index Index. * @return Sub-template. */ public ASN1Template templateAt( int index ) { return elements.elementAt(index).getTemplate(); } /** * Returns whether the sub-template at the given index is optional. * @param index Index. * @return True if the sub-template is optional. */ public boolean isOptionalAt( int index ) { return elements.elementAt(index).isOptional(); } /** * Returns the default value for the sub-template at the given index. * May return NULL if no default value was specified. * @param index Index. * @return Default value. */ public ASN1Value defaultAt( int index ) { return elements.elementAt(index).getDefault(); } /** * @return The number of elements in this SEQUENCE template. */ public int size() { return elements.size(); } /** * Removes all sub-templates from this SEQUENCE template. */ public void removeAllElements() { elements.removeAllElements(); } /** * Removes the sub-template at the given index. * @param index Index. */ public void removeElementAt(int index) { elements.removeElementAt(index); } Tag getTag() { return SEQUENCE.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals(SEQUENCE.TAG) ); } /** * Decodes a SEQUENCE from its BER encoding. * @param istream Input stream. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } /** * Decodes a SEQUENCE from its BER encoding, where the SEQUENCE itself has * an implicit tag. * @param tag Tag. * @param istream Input stream. */ public ASN1Value decode(Tag tag, InputStream istream) throws IOException, InvalidBERException { int index = 0; try { ASN1Header header = new ASN1Header(istream); header.validate( tag, Form.CONSTRUCTED ); // will be -1 for indefinite encoding long remainingContent = header.getContentLength(); boolean repeatableElement=false; SEQUENCE seq = new SEQUENCE(); ASN1Header lookAhead=null; // go through the whole template for( index = 0; index < size(); index++ ) { // find out about the next item if( remainingContent == 0 ) { lookAhead = null; } else { // remainingContent > 0 or remainingContent == -1, which means // indefinite encoding. lookAhead = ASN1Header.lookAhead(istream); } // skip over items that don't match. Hopefully they are // optional or have a default. Otherwise, it's an error. Element e = elements.elementAt(index); if( (lookAhead == null) || lookAhead.isEOC() || ! e.tagMatch( lookAhead.getTag() ) ) { if( e.isRepeatable() ) { repeatableElement = true; } else if( e.isOptional() ) { // put an empty entry into the SEQUENCE SEQUENCE.Element se = new SEQUENCE.Element(null, null ); seq.addElement( null ); } else if( e.getDefault() != null ) { // use the default seq.addElement( e.getDefault() ); } else { String tagDesc; if( lookAhead == null ) { tagDesc = "(null)"; } else { tagDesc = lookAhead.getTag().toString(); } throw new InvalidBERException("Missing item #" + index + ": found " + tagDesc ); } continue; } // Decode this element ASN1Template t = e.getTemplate(); ASN1Value val; try (CountingStream countstream = new CountingStream(istream)) { if (e.getImplicitTag() == null) { val = t.decode(countstream); } else { val = t.decode(e.getImplicitTag(), countstream); } // Decrement remaining count long len = countstream.getNumRead(); if (remainingContent != -1) { if (remainingContent < len) { // this item went past the end of the SEQUENCE throw new InvalidBERException("Item went "+ (len-remainingContent) + " bytes past the end of" + " the SEQUENCE"); } remainingContent -= len; } } // Store this element in the SEQUENCE if( e.producesOutput() ) { if( e.getImplicitTag() == null ) { // no implicit tag seq.addElement( val ); } else { // there is an implicit tag seq.addElement( e.getImplicitTag(), val ); } } // If this element is repeatable, don't go on to the next element if( e.isRepeatable() ) { repeatableElement = true; index--; } } if( remainingContent > 0 ) { throw new InvalidBERException("SEQUENCE is " + remainingContent + " bytes longer than expected"); } assert( remainingContent == 0 || remainingContent == -1 ); // If this was indefinite-length encoding, consume the end-of-contents if( remainingContent == -1 ) { lookAhead = new ASN1Header(istream); if( ! lookAhead.isEOC() ) { throw new InvalidBERException("No end-of-contents marker"); } } // Make sure we stayed in sync if( ! repeatableElement ) { assert(index == seq.size()); } return seq; } catch(InvalidBERException e) { e.append("SEQUENCE(item #" +index + ")"); throw e; } } /** * An element of a SEQUENCE template. For each sub-template, contains the * template, its optionality, its implicit tag, and its default value. */ static class Element { /** * Creates a new element, which may or may not be optional. * @param implicitTag Implicit tag. * @param type Type. * @param optional Optional. */ public Element(Tag implicitTag, ASN1Template type, boolean optional) { this(implicitTag, type, optional, true); } /** * Creates a new element, which may or may not be optional. * @param implicitTag Implicit tag. * @param type Type. * @param optional Optional. * @param doesProduceOutput True if produces output. */ public Element(Tag implicitTag, ASN1Template type, boolean optional, boolean doesProduceOutput) { this.type = type; defaultVal = null; this.optional = optional; this.implicitTag = implicitTag; this.doesProduceOutput = doesProduceOutput; } /** * Creates a new element with a default value. * @param implicitTag Implicit tag. * @param type Type. * @param defaultVal Default value. */ public Element(Tag implicitTag, ASN1Template type, ASN1Value defaultVal) { this.type = type; this.defaultVal = defaultVal; optional = false; this.implicitTag = implicitTag; } private boolean doesProduceOutput = true; boolean producesOutput() { return doesProduceOutput; } // repeatability is provided to allow for SEQUENCE OF SIZE // constructs. It is package private. private boolean repeatable; void makeRepeatable() { repeatable = true; } boolean isRepeatable() { return repeatable; } private boolean optional; public boolean isOptional() { return optional; } private Tag implicitTag=null; public Tag getImplicitTag() { return implicitTag; } public boolean tagMatch(Tag tag) { if( implicitTag != null ) { return( implicitTag.equals(tag) ); } else { return type.tagMatch(tag); } } private ASN1Template type; public ASN1Template getTemplate() { return type; } private ASN1Value defaultVal=null; public ASN1Value getDefault() { return defaultVal; } } } // End of SEQUENCE.Template /** * A Template for decoding SEQUENCE OF values. The main difference between * a SEQUENCE.Template and a SEQUENCE.OF_Template is that a regular template * specifies the exact ordering, number, and type of elements of the sequence, * while * an OF_Template has an indefinite number of elements, all the same type. * For example, given: *
 * MyType ::= SEQUENCE OF Extension
 * 
* a MyType could be decoded with: *
 *  SEQUENCE.OF_Template myTypeTemplate = new SEQUENCE.OF_Template( new
 *      Extension.Template) );
 *  SEQUENCE seq = (SEQUENCE) myTypeTemplate.decode(someInputStream);
 * 
* The number of Extensions actually decoded could be found * with seq.size(). */ public static class OF_Template implements ASN1Template { private OF_Template() { } Template template; // a normal SEQUENCE template public OF_Template(ASN1Template type) { template = new Template(); Template.Element el = new Template.Element(null, type, true); //optional el.makeRepeatable(); template.addElement( el ); } public static OF_Template makeOutputlessOFTemplate(ASN1Template type) { OF_Template t = new OF_Template(); t.template = new Template(); Template.Element el = new Template.Element(null, type, true, false); el.makeRepeatable(); t.template.addElement(el); return t; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } /** * Decodes a SEQUENCE OF from an input stream. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return template.decode(istream); } /** * Decodes a SEQUENCE OF with an implicit tag from an input stream. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { return template.decode(implicitTag, istream); } } public static void main(String args[]) { try { if(args.length > 0) { // input Template type = new Template(); type.addOptionalElement( new Tag(15), new INTEGER.Template() ); type.addElement( new Tag(16), new INTEGER.Template(), new INTEGER(42) ); type.addElement( new INTEGER.Template() ); type.addElement( new BOOLEAN.Template() ); type.addElement( new INTEGER.Template() ); type.addOptionalElement( new Tag(12), new INTEGER.Template() ); type.addElement( new BOOLEAN.Template() ); type.addElement( new Tag(13), new INTEGER.Template(), new INTEGER(53) ); type.addElement( new INTEGER.Template() ); type.addElement( new INTEGER.Template() ); type.addOptionalElement( new Tag(14), new INTEGER.Template() ); type.addElement( new OBJECT_IDENTIFIER.Template() ); type.addElement( new NULL.Template() ); type.addElement( new EXPLICIT.Template( new Tag(27), new INTEGER.Template())); type.addElement( new ENUMERATED.Template() ); type.addElement( new OCTET_STRING.Template() ); type.addElement( new IA5String.Template() ); CHOICE.Template choice = new CHOICE.Template(); choice.addElement( new Tag(23), new INTEGER.Template() ); choice.addElement( new BOOLEAN.Template() ); type.addElement( choice ); type.addElement( new BIT_STRING.Template() ); type.addElement( new ANY.Template() ); type.addElement( new PrintableString.Template() ); type.addElement( new OF_Template( new INTEGER.Template() ) ); type.addElement( new OF_Template( new INTEGER.Template() ) ); byte[] stuff; try (FileInputStream fin = new FileInputStream(args[0])) { System.out.println("Available: " + fin.available()); stuff = new byte[fin.available()]; ASN1Util.readFully(stuff, fin); } SEQUENCE s=null; for( int i = 0; i < 1; i++) { s = (SEQUENCE) type.decode( new ByteArrayInputStream(stuff) ); } for(int i=0; i < s.size(); i ++ ) { ASN1Value v = s.elementAt(i); if(v instanceof ENUMERATED) { ENUMERATED en = (ENUMERATED) v; System.out.println("ENUMERATED: "+en); } else if( v instanceof INTEGER ) { INTEGER in = (INTEGER) v; System.out.println("INTEGER: "+in); } else if(v instanceof BOOLEAN ) { BOOLEAN bo = (BOOLEAN) v; System.out.println("BOOLEAN: "+bo); } else if(v instanceof OBJECT_IDENTIFIER) { OBJECT_IDENTIFIER oid = (OBJECT_IDENTIFIER) v; System.out.println("OID: "+oid); } else if(v instanceof NULL) { NULL n = (NULL) v; System.out.println("NULL"); } else if(v instanceof EXPLICIT) { EXPLICIT ex = (EXPLICIT) v; INTEGER in = (INTEGER) ex.getContent(); System.out.println("EXPLICIT ["+ex.getTag()+"]: "+ "INTEGER: "+in); } else if(v instanceof OCTET_STRING) { OCTET_STRING os = (OCTET_STRING) v; byte[] bytes = os.toByteArray(); System.out.print("OCTET_STRING: "); for(int j = 0; j < bytes.length; j++) { System.out.print(bytes[j]+" "); } System.out.println(""); } else if( v instanceof CharacterString ) { CharacterString cs = (CharacterString) v; System.out.println("String: "+cs); } else if( v instanceof BIT_STRING ) { BIT_STRING bs = (BIT_STRING) v; System.out.print("BIT_STRING: padCount="+ bs.getPadCount()+" : "); byte[] bits = bs.getBits(); for(int j = 0; j < bits.length; j++) { System.out.print(bits[j]+" "); } System.out.println(""); } else if( v instanceof ANY ) { ANY any = (ANY) v; Tag tag = any.getTag(); System.out.println("Got ANY, tag is "+tag); ByteArrayInputStream bos = new ByteArrayInputStream( any.getEncoded() ); INTEGER in = (INTEGER) new INTEGER.Template().decode(bos); System.out.println(" INTEGER: "+in); } else if(v instanceof SEQUENCE ) { SEQUENCE seq = (SEQUENCE)v; System.out.println("SEQUENCE: "); for(int j=0; j < seq.size(); j++ ) { INTEGER in = (INTEGER) seq.elementAt(j); System.out.println(" INTEGER: "+in); } } else { System.out.println("Unknown value"); } } } else { // output SEQUENCE seq = new SEQUENCE(); seq.addElement( new INTEGER(5) ); seq.addElement( new BOOLEAN(true) ); seq.addElement( new INTEGER(-322) ); seq.addElement( new BOOLEAN(false) ); seq.addElement( new INTEGER(0) ); seq.addElement( new INTEGER("2934293834242") ); seq.addElement( new OBJECT_IDENTIFIER( new long[] { 1, 2, 127, 563, 1231982 } ) ); seq.addElement( new NULL() ); seq.addElement( new EXPLICIT( new Tag(27), new INTEGER(39) )); seq.addElement( new ENUMERATED(983) ); seq.addElement( new OCTET_STRING( new byte[] { (byte)0x0, (byte)0xff, (byte)0xcc} ) ); seq.addElement( new IA5String("foobar") ); seq.addElement( new Tag(23), new INTEGER(234) ); //seq.addElement( new BOOLEAN(false) ); byte[] bits = new byte[]{ (byte)0x80, (byte)0xff, (byte)0x0f }; seq.addElement( new BIT_STRING( bits, 3 ) ); seq.addElement( new INTEGER(82734) ); seq.addElement( new PrintableString("I'm printable??") ); SEQUENCE nested = new SEQUENCE(); nested.addElement( new INTEGER( 5 ) ); nested.addElement( new INTEGER( 6 ) ); seq.addElement( nested ); nested = new SEQUENCE(); seq.addElement( nested ); seq.encode(System.out); System.out.flush(); } } catch( Exception e) { e.printStackTrace(); } } } jss-4.6.3/org/mozilla/jss/asn1/SET.java000066400000000000000000000702471362106420000175240ustar00rootroot00000000000000/* 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.asn1; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Vector; import org.mozilla.jss.util.Assert; /** * An ASN.1 SET, which is an unordered collection of ASN.1 values. * It has an interface like a Java Vector, but the ordering is arbitrary. * Null entries may be added; they will be skipped when encoding. */ public class SET implements ASN1Value { public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 17); public Tag getTag() { return TAG; } protected static final Form FORM = Form.CONSTRUCTED; // The elements of the set protected Vector elements = new Vector<>(); private void addElement( Element e ) { elements.addElement(e); } private void insertElementAt( Element e, int index ) { elements.insertElementAt(e, index); } /** * Adds an element to this SET. * @param v Element. */ public void addElement( ASN1Value v ) { addElement( new Element(v) ); } /** * Adds an element to this SET with the given implicit tag. For example, * if the ASN.1 were: *
     *  MyType ::= SET {
     *      item        [0] IMPLICIT INTEGER,
     *      ... }
     * 
* then the "item" element could be added (with a sample value of 45) * to the SET with: *
     * myTypeInstance.addElement( new Tag(0), new INTEGER(45) );
     * 
* @param implicitTag Implicit tag. * @param v Element. */ public void addElement( Tag implicitTag, ASN1Value v ) { addElement( new Element(implicitTag, v) ); } /** * Inserts an element at the given index. * @param v Element. * @param index Index. */ public void insertElementAt( ASN1Value v, int index ) { insertElementAt( new Element(v), index ); } /** * Inserts an element with the given implicit tag at the given index. * @param implicitTag Implicit tag. * @param v Element. * @param index Index. */ public void insertElementAt( Tag implicitTag, ASN1Value v, int index ) { insertElementAt( new Element(implicitTag, v), index ); } /** * Returns the element at the given index in the SET. * @param index Index. * @return Element. */ public ASN1Value elementAt( int index ) { return elements.elementAt(index).getValue(); } /** * Returns the tag of the element at the given index. If the element * has an implicit tag, that is returned. Otherwise, the tag of the * underlying type is returned. * @param index Index. * @return Tag. */ public Tag tagAt( int index ) { Tag implicit = elements.elementAt(index).getImplicitTag(); if( implicit != null ) { return implicit; } else { return elementAt(index).getTag(); } } /** * Returns the element with the given Tag, or null if no element exists * with the given tag. * @param tag Tag. * @return Element. */ public ASN1Value elementWithTag( Tag tag ) { // hmmm...linear search for now, should use hashtable later int size = elements.size(); for( int i=0; i < size; i++ ) { Element e = elements.elementAt(i); if( e.getTag().equals(tag) ) { return e.getValue(); } } return null; } /** * @return The number of elements in this SET. */ public int size() { return elements.size(); } /** * Removes all elements from this SET. */ public void removeAllElements() { elements.removeAllElements(); } /** * Removes the element from the specified index. * @param index Index. */ public void removeElementAt(int index) { elements.removeElementAt(index); } /** * Writes the DER encoding to the given output stream. * @param ostream Output stream. */ public void encode(OutputStream ostream) throws IOException { encode(getTag(), ostream); } /** * Writes the DER encoding to the given output stream, * using the given implicit tag. To satisfy DER encoding rules, * the elements will be re-ordered either by tag or lexicographically. * @param implicitTag Implicit tag. * @param ostream Output stream. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { // what ordering method? boolean lexOrdering; if( elements.size() < 2 ) { // doesn't matter, only one element lexOrdering = true; } else if( tagAt(0).equals(tagAt(1)) ) { // tags are the same, lexicographic ordering lexOrdering = true; } else { // tags are different, order by tag lexOrdering = false; } // compute and order contents int numElements = elements.size(); int totalBytes = 0; Vector encodings = new Vector<>(numElements); Vector tags = new Vector<>(numElements); int i; for(i = 0; i < numElements; i++ ) { // if an entry is null, just skip it if( elementAt(i) != null ) { byte[] enc = ASN1Util.encode(tagAt(i), elementAt(i)); totalBytes += enc.length; if( lexOrdering ) { insertInOrder(encodings, enc); } else { insertInOrder(encodings, enc, tags, (int) tagAt(i).getNum()); } } } // write header ASN1Header header = new ASN1Header( implicitTag, FORM, totalBytes ); header.encode(ostream); // write contents in order for(i=0; i < numElements; i++ ) { ostream.write( encodings.elementAt(i) ); } } /** * Encodes this SET without re-ordering it. This may violate * DER, but it is within BER. * @param implicitTag Implicit tag. * @param ostream Output stream. * @throws IOException If an error occurred. */ public void BERencode(Tag implicitTag, OutputStream ostream) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); // compute contents int size = elements.size(); for(int i = 0; i < size; i++ ) { ASN1Value el = elementAt(i); if(el!=null) { el.encode(tagAt(i), bos); } } byte[] bytes = bos.toByteArray(); // write header ASN1Header header = new ASN1Header( implicitTag, FORM, bytes.length ); header.encode(ostream); // write contents ostream.write(bytes); } // performs ascending lexicographic ordering // linear search, but number of items is usually going to be small. private static void insertInOrder(Vector encs, byte[] enc) { int size = encs.size(); // find the lowest item that we are less than or equal to int i; for(i=0; i < size; i++) { if( compare(enc, encs.elementAt(i)) < 1 ) { break; } } // insert ourself before this item encs.insertElementAt(enc, i); } // performs ascending ordering by tag // linear search, but number of items is usually going to be small. private static void insertInOrder(Vector encs, byte[] enc, Vector tags, int tag) { int size = encs.size(); // find the lowest item that we are less than or equal to int i; for(i = 0; i < size; i++) { if( tag <= tags.elementAt(i).intValue() ) { break; } } // insert ourself before this item encs.insertElementAt(enc, i); tags.insertElementAt(Integer.valueOf(i), i ); } // compares two byte arrays // returns 1 if left > right, -1 if left < right, 0 if left == right private static int compare(byte[] left, byte[] right) { int min = (left.length < right.length) ? left.length : right.length; for(int i=0; i < min; i++) { if( (left[i]&0xff) < (right[i]&0xff) ) { return -1; } else if( (left[i]&0xff) > (right[i]&0xff) ) { return 1; } } // equal up to the minimal endpoint if( left.length > min ) { assert(right.length==min); return 1; } if( right.length > min ) { assert(left.length==min); return -1; } return 0; } /** * An element of a SET */ static class Element { /** * Makes a new SET element from the given value. */ public Element( ASN1Value val ) { this.val = val; } /** * Makes a new SET element from the given value with the given * implicit tag. */ public Element( Tag implicitTag, ASN1Value val ) { this.val = val; this.implicitTag = implicitTag; } private ASN1Value val; /** * Returns the value of this SET element. */ public ASN1Value getValue() { return val; } /** * Returns the tag that actually shows up in the encoding. * If there is an implicit tag, it will be used. Otherwise, * it will be the base tag for the value. */ public Tag getTag() { if(implicitTag!=null) { return implicitTag; } else { return val.getTag(); } } private Tag implicitTag=null; /** * Returns the implicit tag for this value, if there is one. * If not, returns null. */ public Tag getImplicitTag() { return implicitTag; } } /** * SET.Template * This class is used for decoding DER-encoded SETs. */ public static class Template implements ASN1Template { private Vector elements = new Vector<>(); private void addElement( Element e ) { elements.addElement(e); } private void insertElementAt( Element e, int index ) { elements.insertElementAt(e, index); } /** * Adds a sub-template to the end of this SET template. For example, * if the ASN.1 included: *
     * MySet ::= SET {
     *      item        SubType,
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addElement( new SubType.Template() );
     * 
* @param t Sub-template. */ public void addElement( ASN1Template t ) { addElement( new Element(TAG, t, false) ); } /** * Inserts the template at the given index. * @param t Sub-template. * @param index Index. */ public void insertElementAt( ASN1Template t, int index ) { insertElementAt( new Element(TAG, t, false), index ); } /** * Adds a sub-template with the given implicit tag to the end of this * SET template. For example, if the ASN.1 included: *
     * MySet ::= SET {
     *      item        [0] IMPLICIT SubType,
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addElement( new Tag(0), new SubType.Template() );
     * 
* @param implicit Implicit tag. * @param t Sub-template. */ public void addElement( Tag implicit, ASN1Template t ) { addElement( new Element(implicit, t, false) ); } /** * Inserts the template with the given implicit tag at the given index. * @param implicit Implicit tag. * @param t Sub-template. * @param index Index. */ public void insertElementAt( Tag implicit, ASN1Template t, int index ) { insertElementAt( new Element(implicit, t, false), index ); } /** * Adds an optional sub-template to the end * of this SET template. For example, if the ASN.1 included: *
     * MySet ::= SET {
     *      item        SubType OPTIONAL,
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addOptionalElement( new SubType.Template() );
     * 
* @param t Optional sub-template. */ public void addOptionalElement( ASN1Template t ) { addElement( new Element(TAG, t, true) ); } /** * Inserts the optional template at the given index. * @param t Optional sub-template. * @param index Index. */ public void insertOptionalElementAt( ASN1Template t, int index ) { insertElementAt( new Element(null, t, true), index ); } /** * Adds an optional sub-template with the given implicit tag to the end * of this SET template. For example, if the ASN.1 included: *
     * MySet ::= SET {
     *      item        [0] IMPLICIT SubType OPTIONAL,
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addOptionalElement( new Tag(0), new SubType.Template() );
     * 
* @param implicit Implicit tag. * @param t Optional sub-template. */ public void addOptionalElement( Tag implicit, ASN1Template t ) { addElement( new Element(implicit, t, true) ); } /** * Inserts the optional template with the given default * value at the given index. * @param implicit Implicit tag. * @param t Optional sub-template. * @param index Index. */ public void insertOptionalElementAt( Tag implicit, ASN1Template t, int index ) { insertElementAt( new Element(implicit, t, true), index ); } /** * Adds a sub-template with the given default value to the end * of this SET template. For example, if the ASN.1 included: *
     * MySet ::= SET {
     *      item        INTEGER DEFAULT (5),
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addElement( new SubType.Template(), new INTEGER(5) );
     * 
* @param t Sub-template. * @param def Default value. */ public void addElement( ASN1Template t, ASN1Value def ) { addElement( new Element(TAG, t, def) ); } /** * Inserts the template with the given default * value at the given index. * @param t Sub-template. * @param def Default value. * @param index Index. */ public void insertElementAt( ASN1Template t, ASN1Value def, int index ) { insertElementAt( new Element(null, t, def), index ); } /** * Adds a sub-template with the given default value and implicit tag to * the end of this SET template. For example, if the ASN.1 included: *
     * MySet ::= SET {
     *      item        [0] IMPLICIT INTEGER DEFAULT (5),
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addElement( new Tag(0), new SubType.Template(), new INTEGER(5) );
     * 
* @param implicit Implicit tag. * @param t Sub-template. * @param def Default value. */ public void addElement( Tag implicit, ASN1Template t, ASN1Value def ) { addElement( new Element(implicit, t, def) ); } /** * Inserts the template with the given implicit tag and given default * value at the given index. * @param implicit Implicit tag. * @param t Sub-template. * @param def Default value. * @param index Index. */ public void insertElementAt( Tag implicit, ASN1Template t, ASN1Value def, int index ) { insertElementAt( new Element(implicit, t, def), index ); } /** * Returns the implicit tag of the item stored at the given index. * May be NULL if no implicit tag was specified. * @param index Index. * @return Implicit tag. */ public Tag implicitTagAt(int index) { return elements.elementAt(index).getImplicitTag(); } /** * Returns the sub-template stored at the given index. * @param index Index. * @return Sub-template. */ public ASN1Template templateAt(int index) { return elements.elementAt(index).getTemplate(); } /** * Returns true if the sub-template at the given index * is optional. * @param index Index. * @return True if sub-template is optional. */ public boolean isOptionalAt(int index) { return elements.elementAt(index).isOptional(); } private boolean isRepeatableAt(int index) { return elements.elementAt(index).isRepeatable(); } /** * Returns the default value for the sub-template at the given index. * May return NULL if no default value was specified. * @param index Index. * @return Default value. */ public ASN1Value defaultAt(int index) { return elements.elementAt(index).getDefault(); } /** * @return The number of elements in the SET. */ public int size() { return elements.size(); } public void removeAllElements() { elements.removeAllElements(); } public void removeElementAt(int index) { elements.removeElementAt(index); } private Tag getTag() { return SET.TAG; } /** * Determines whether the given tag satisfies this template. * @param tag Tag. * @return True if tag satisfies this template. */ public boolean tagMatch(Tag tag) { return( tag.equals(SET.TAG) ); } /** * Decodes the input stream into a SET value. * @param istream Input stream. * @return Decoded SET value. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } /** * Decodes the input stream into a SET value with the given implicit * tag. * @param tag Implicit tag. * @param istream Input stream. * @return Decoded SET value. */ public ASN1Value decode(Tag tag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header header = new ASN1Header(istream); header.validate( tag, Form.CONSTRUCTED ); // remainingContent will be -1 for indefinite length encoding long remainingContent = header.getContentLength(); SET set = new SET(); ASN1Header lookAhead; boolean[] found = new boolean[ elements.size() ]; // while content remains, try to decode it while( remainingContent > 0 || remainingContent == -1) { // find out about the next item lookAhead = ASN1Header.lookAhead(istream); // if we found the end-of-content marker, we're done if( lookAhead.isEOC() ) { if( remainingContent != -1 ) { throw new InvalidBERException("Unexpected end-of-content"+ "marker"); } lookAhead = new ASN1Header(istream); break; } // Find the element with the matching tag int index = findElementByTag( lookAhead.getTag() ); if( index == -1 ) { // element not found throw new InvalidBERException("Unexpected Tag in SET: "+ lookAhead.getTag() ); } Element e = elements.elementAt(index); if( found[index] && ! e.isRepeatable() ) { // element already found, and it's not repeatable throw new InvalidBERException("Duplicate Tag in SET: "+ lookAhead.getTag() ); } // mark this element as found found[index] = true; // Decode this element ASN1Template t = e.getTemplate(); ASN1Value val; try (CountingStream countstream = new CountingStream(istream)) { if (e.getImplicitTag() == null) { val = t.decode(countstream); } else { val = t.decode(e.getImplicitTag(), countstream); } // Decrement remaining count long len = countstream.getNumRead(); if (remainingContent != -1) { if (remainingContent < len) { // this item went past the end of the SET throw new InvalidBERException("Item went "+ (len-remainingContent) + " bytes past the end of" + " the SET"); } remainingContent -= len; } } // Store this element in the SET SET.Element se; if( e.getImplicitTag() == null ) { // no implicit tag se = new SET.Element(val); } else { // there is an implicit tag se = new SET.Element( e.getImplicitTag(), val ); } set.addElement(se); } // We check for this after we read in each item, so this shouldn't // happen assert( remainingContent == 0 || remainingContent == -1); // Deal with elements that weren't present. int size = elements.size(); for(int i = 0; i < size; i++) { if( !found[i] ) { if( isOptionalAt(i) || isRepeatableAt(i) ) { // no problem } else if( defaultAt(i) != null ) { set.addElement( new SET.Element(defaultAt(i)) ); } else { throw new InvalidBERException("Field not found in SET"); } } } return set; } catch(InvalidBERException e) { throw new InvalidBERException(e, "SET"); } } /** * Returns the index in the vector of the type with this tag and class, * or -1 if not found. * lame linear search - but we're dealing with small numbers of elements, * so it's probably not worth it to use a hashtable * @param tag Tag. */ private int findElementByTag(Tag tag) { int size = elements.size(); for( int i = 0; i < size ; i++ ) { Element e = elements.elementAt(i); if( e.tagMatch( tag ) ) { // match! return i; } } // no match return -1; } /** * An element of a SET template. */ public static class Element { public Element(Tag implicitTag, ASN1Template type, boolean optional) { this.type = type; defaultVal = null; this.optional = optional; this.implicitTag = implicitTag; } public Element(Tag implicitTag, ASN1Template type, ASN1Value defaultVal) { this.type = type; this.defaultVal = defaultVal; optional = false; this.implicitTag = implicitTag; } // Repeatability is used for SET OF. It is package private. private boolean repeatable; void makeRepeatable() { repeatable = true; } boolean isRepeatable() { return repeatable; } private boolean optional; public boolean isOptional() { return optional; } private Tag implicitTag=null; public Tag getImplicitTag() { return implicitTag; } /** * Determines whether the given tag satisfies this SET element. * @param tag Tag. * @return True if tag satisfies SET. */ public boolean tagMatch(Tag tag) { if( implicitTag != null ) { return( implicitTag.equals(tag) ); } else { return type.tagMatch(tag); } } private ASN1Template type; /** * @return The template for this element. */ public ASN1Template getTemplate() { return type; } private ASN1Value defaultVal=null; /** * Returns the default value for this element, if one exists. * Otherwise, returns null. * @return Default value. */ public ASN1Value getDefault() { return defaultVal; } } } // End of SET.Template /** * A Template for decoding SET OF values. * Use this if you have a SIZE qualifier on your SET OF. * The SET will consume as many instances of type as it can, rather than * stopping after the first one. This is equivalent to SIZE (0..MAX). * If you need something more restrictive, you can look at what gets parsed * and decide whether it's OK or not yourself. */ public static class OF_Template implements ASN1Template { private Template template; // a normal SET template /** * Creates an OF_Template with the given type. For example: *
     * MySet ::= SET OF INTEGER;
     * 
* A MySet template would be constructed with: *
     * SET.OF_Template mySetTemplate = new SET.OF_Template( new
     *                                          INTEGER.Template() );
     * 
* @param type Type. */ public OF_Template(ASN1Template type) { template = new Template(); Template.Element el = new Template.Element( null, type, false ); el.makeRepeatable(); template.addElement( el ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } /** * Decodes a SET OF from its BER encoding. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return template.decode(istream); } /** * Decodes a SET OF with an implicit tag from its BER * encoding. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { return template.decode(implicitTag, istream); } } // Test driver for SET public static void main(String args[]) { try { if(args.length > 0) { Template t = new SET.Template(); t.addElement(new Tag(0), new INTEGER.Template() ); t.addElement( new Tag(3), new INTEGER.Template() ); t.addOptionalElement( new Tag(4), new INTEGER.Template() ); t.addElement( new Tag(5), new INTEGER.Template(), new INTEGER(67) ); t.addElement( new Tag(29), new BOOLEAN.Template() ); t.addElement( new Tag(30), new BOOLEAN.Template(), new BOOLEAN(false) ); t.addElement( new Tag(1), new INTEGER.Template() ); t.addElement( new Tag(2), new INTEGER.Template() ); SET st; FileInputStream fin = new FileInputStream(args[0]); try (BufferedInputStream is = new BufferedInputStream(fin)) { st = (SET) t.decode(is); } for(int i=0; i < st.size(); i++) { ASN1Value v = st.elementAt(i); if( v instanceof INTEGER ) { INTEGER in = (INTEGER) st.elementAt(i); System.out.println("INTEGER: "+in); } else if( v instanceof BOOLEAN ) { BOOLEAN bo = (BOOLEAN) st.elementAt(i); System.out.println("BOOLEAN: "+bo); } else { System.out.println("Unknown value"); } } } else { SET s = new SET(); s.addElement( new Tag(0), new INTEGER(255) ); s.addElement( new Tag(29), new BOOLEAN(true) ); s.addElement( new Tag(1), new INTEGER(-322) ); s.addElement( new Tag(2), new INTEGER(0) ); s.addElement( new Tag(3), new INTEGER("623423948273") ); s.encode(System.out); } } catch( Exception e ) { e.printStackTrace(); } } } jss-4.6.3/org/mozilla/jss/asn1/Tag.java000066400000000000000000000117101362106420000175720ustar00rootroot00000000000000/* 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.asn1; /** * Represents an ASN.1 Tag. A tag consists of a class and a number. */ public class Tag { private long num; /** * @return The tag number. */ public long getNum() { return num; } private Class tClass; /** * @return The tag class. */ public Class getTagClass() { return tClass; } /** * A tag class. */ public static final Class UNIVERSAL = Class.UNIVERSAL; /** * A tag class. */ public static final Class APPLICATION = Class.APPLICATION; /** * A tag class. */ public static final Class CONTEXT_SPECIFIC = Class.CONTEXT_SPECIFIC; /** * A tag class. */ public static final Class PRIVATE = Class.PRIVATE; /** * The end-of-contents marker for indefinite length encoding. * It is encoded the same as an ASN.1 header whose tag is [UNIVERSAL 0]. */ public static final Tag END_OF_CONTENTS = new Tag( UNIVERSAL, 0 ); /** * An alias for END_OF_CONTENTS. */ public static final Tag EOC = END_OF_CONTENTS; /** * Creates a tag with the given class and number. * @param clazz The class of the tag. * @param num The tag number. */ public Tag(Class clazz, long num) { tClass = clazz; this.num = num; } /** * Creates a CONTEXT-SPECIFIC tag with the given tag number. * @param num The tag number. */ public Tag(long num) { this(Class.CONTEXT_SPECIFIC, num); } /////////////////////////////////////////////////////////////////////// // Tag Instances // // Since grabbing a context-specific tag is a very common operation, // let's make singletons of the most frequently used tags. /////////////////////////////////////////////////////////////////////// private static final int numTagInstances = 10; private static Tag tagInstances[] = new Tag[numTagInstances]; static { for(int i=0; i < numTagInstances; i++) { tagInstances[i] = new Tag(i); } } /** * Returns an instance of a context-specific tag with the given number. * The returned instance may be singleton. It is usually more efficient to * call this method than create your own context-specific tag. * @param num Number. * @return Tag. */ public static Tag get(long num) { if( num >= 0 && num < numTagInstances ) { return tagInstances[(int)num]; } else { return new Tag(num); } } public int hashCode() { return (tClass.toInt() * 131) + (int)num; } /** * Compares two tags for equality. Tags are equal if they have * the same class and tag number. * @param obj Tag. * @return True if equal. */ public boolean equals(Object obj) { if(obj == null) { return false; } if(! (obj instanceof Tag) ) { return false; } Tag t = (Tag) obj; if( num == t.num && tClass == t.tClass ) { return true; } else { return false; } } /** * Returns a String representation of the tag. For example, a tag * whose class was UNIVERSAL and whose number was 16 would return * "UNIVERSAL 16". */ public String toString() { return tClass+" "+num; } /** * An enumeration of the ASN.1 tag classes. */ public static class Class { private Class() { } private Class(int enc, String name) { encoding = enc; this.name = name; } private int encoding; private String name; public static final Class UNIVERSAL = new Class(0, "UNIVERSAL"); public static final Class APPLICATION = new Class(1, "APPLICATION"); public static final Class CONTEXT_SPECIFIC = new Class(2, "CONTEXT-SPECIFIC"); public static final Class PRIVATE = new Class(3, "PRIVATE"); public int toInt() { return encoding; } public String toString() { return name; } /** * @param i Tag encoding. * @return Tag class. * @exception InvalidBERException If the given int does not correspond * to any tag class. */ public static Class fromInt(int i) throws InvalidBERException { if( i == 0 ) { return UNIVERSAL; } else if(i == 1) { return APPLICATION; } else if(i == 2) { return CONTEXT_SPECIFIC; } else if(i == 3) { return PRIVATE; } else { throw new InvalidBERException("Invalid tag class: " + i); } } } } jss-4.6.3/org/mozilla/jss/asn1/TeletexString.java000066400000000000000000000051101362106420000216550ustar00rootroot00000000000000/* 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.asn1; import java.io.CharConversionException; /** * The ASN.1 type TeletexString. */ public class TeletexString extends CharacterString implements ASN1Value { public static final Tag TAG = new Tag(Tag.UNIVERSAL, 20); public Tag getTag() { return TAG; } public TeletexString(char[] chars) throws CharConversionException { super(chars); } public TeletexString(String s) throws CharConversionException { super(s); } CharConverter getCharConverter() { return new TeletexConverter(); } /** * Returns a singleton instance of the decoding template for this class. * @return Template. */ public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); // nested class public static class Template extends CharacterString.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected CharConverter getCharConverter() { return new TeletexConverter(); } protected CharacterString generateInstance(char[] bytes) throws CharConversionException { return new TeletexString( bytes ); } protected String typeName() { return "TeletexString"; } } // end of Template private static class TeletexConverter implements CharConverter { public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { char[] chars = new char[len]; int b; int c; for(b=offset, c=0; c < len; b++, c++) { chars[c] = (char) (bytes[b] & 0xff); } return chars; } public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { byte[] bytes = new byte[len]; int b; int c; for(b=0, c=offset; b < len; b++, c++) { if( (chars[c]&0xff00) != 0 ) { throw new CharConversionException("Invalid character for"+ " TeletexString"); } bytes[b] = (byte) (chars[c] & 0xff); } return bytes; } } } jss-4.6.3/org/mozilla/jss/asn1/TimeBase.java000066400000000000000000000226361362106420000205610ustar00rootroot00000000000000/* 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.asn1; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import org.mozilla.jss.util.Assert; public abstract class TimeBase implements ASN1Value { public static final Form FORM = Form.PRIMITIVE; abstract public Tag getTag(); private Date date; public Date toDate() { return date; } abstract protected boolean isUTC(); public TimeBase(Date date) { this.date = date; } public void encode(OutputStream ostream) throws IOException { encode(getTag(), ostream); } /** * Write the DER-encoding of this TimeBase. */ public void encode(Tag implicit, OutputStream ostream) throws IOException { if( isUTC() ) { // length will always be 13 (new ASN1Header(implicit, FORM, 13)).encode(ostream); } else { // length will always be 15 (new ASN1Header(implicit, FORM, 15)).encode(ostream); } int i=0, val; // DER-encoding mandates GMT time zone Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("GMT") ); cal.setTime( date ); if( isUTC() ) { val = cal.get(Calendar.YEAR); ostream.write( ((val % 100) / 10) + '0' ); ostream.write( (val % 10) + '0' ); } else { val = cal.get(Calendar.YEAR); ostream.write( ((val % 10000) / 1000) + '0' ); ostream.write( ((val % 1000) / 100) + '0' ); ostream.write( ((val % 100) / 10) + '0' ); ostream.write( (val % 10) + '0' ); } val = cal.get(Calendar.MONTH) + 1; assert( val >= 1 && val <= 12 ); ostream.write( (val / 10) + '0' ); ostream.write( (val % 10) + '0' ); val = cal.get(Calendar.DAY_OF_MONTH); assert( val >=1 && val <= 31 ); ostream.write( (val / 10) + '0' ); ostream.write( (val % 10) + '0' ); val = cal.get(Calendar.HOUR_OF_DAY); assert( val >= 0 && val <= 23 ); ostream.write( (val / 10) + '0' ); ostream.write( (val % 10) + '0' ); val = cal.get(Calendar.MINUTE); assert( val >=0 && val <= 59 ); ostream.write( (val / 10) + '0' ); ostream.write( (val % 10) + '0' ); val = cal.get(Calendar.SECOND); assert( val >= 0 && val <= 59 ); ostream.write( (val / 10) + '0' ); ostream.write( (val % 10) + '0' ); ostream.write('Z'); } public abstract static class Template { protected abstract boolean isUTC(); protected abstract Tag getTag(); protected abstract TimeBase generateInstance(Date date); public boolean tagMatch(Tag tag) { return getTag().equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { PrintableString.Template pst = new PrintableString.Template(); PrintableString ps = (PrintableString) pst.decode(implicitTag, istream); char[] chars = ps.toCharArray(); int i=0; int year, month, day, hour, minute, second, hourOff, minOff; ////////////////////////////////////////// // Get year // if( isUTC() ) { checkBounds(i, 2, chars.length); year = (chars[i] - '0') * 10; year += chars[i+1] - '0'; // Y2K HACK!!!!! But this is what the spec says to do. // The range is 1970 to 2069 if( year < 70 ) { year += 2000; } else { year += 1900; } i += 2; } else { checkBounds(i, 4, chars.length); year = (chars[i] - '0') * 1000; year += (chars[i+1] - '0') * 100; year += (chars[i+2] - '0') * 10; year += (chars[i+3] - '0'); checkRange(year, 0, 9999, "year"); i += 4; } ////////////////////////////////////////// // get month // month = 0; checkBounds(i, 2, chars.length); month = (chars[i] - '0') * 10; month += chars[i+1] - '0'; checkRange(month, 1, 12, "month"); month--; // Java months start at 0 i += 2; ////////////////////////////////////////// // get day // checkBounds(i, 2, chars.length); day = (chars[i] - '0') * 10; day += chars[i+1] - '0'; checkRange(day, 1, 31, "day"); i += 2; ////////////////////////////////////////// // get hour // checkBounds(i, 2, chars.length); hour = (chars[i] - '0') * 10; hour += chars[i+1] - '0'; checkRange(hour, 0, 23, "hour"); i += 2; ////////////////////////////////////////// // get minute // checkBounds(i, 2, chars.length); minute = (chars[i] - '0') * 10; minute += chars[i+1] - '0'; checkRange(minute, 0, 59, "minute"); i += 2; ////////////////////////////////////////// // get second, if it's there // if( i < chars.length && chars[i] >= '0' && chars[i] <= '9' ) { checkBounds(i, 2, chars.length); second = (chars[i] - '0') * 10; second += chars[i+1] - '0'; checkRange(second, 0, 59, "second"); i += 2; } else { second = 0; } ////////////////////////////////////////// // Skip milliseconds for GeneralizedTime. There are no // milliseconds in UTCTime. // if( ! isUTC() ) { while( i < chars.length && chars[i] != '+' && chars[i] != '-' && chars[i] != 'Z' ) { i++; } } ////////////////////////////////////////// // get time zone // TimeZone tz; if( i < chars.length ) { checkBounds(i, 1, chars.length); if( chars[i] == '+' || chars[i] == '-') { checkBounds(i+1, 4, chars.length); hourOff = (chars[i+1] - '0') * 10; hourOff += chars[i+2] - '0'; minOff = (chars[i+3] - '0') * 10; minOff += chars[i+4] - '0'; checkRange(hourOff, 0, 23, "hour offset"); checkRange(minOff, 0, 59, "minute offset"); if( chars[i] == '-' ) { hourOff = -hourOff; minOff = -minOff; } i += 5; tz = (TimeZone) TimeZone.getTimeZone("GMT").clone(); tz.setRawOffset( ((hourOff*60)+minOff)*60*1000 ); } else if( chars[i] == 'Z' ) { i += 1; hourOff = minOff = 0; tz = (TimeZone) TimeZone.getTimeZone("GMT").clone(); } else { throw new InvalidBERException("Invalid character "+ chars[i]); } } else { if( isUTC() ) { // Only UTC requires timezone throw new InvalidBERException("no timezone specified for"+ " UTCTime"); } // No timezone specified, use local time. // This is generally a bad idea, because who knows what the // local timezone is? But the spec allows it. tz = TimeZone.getDefault(); } // make sure we ate all the characters, there were no stragglers // at the end if( i != chars.length ) { throw new InvalidBERException("Extra characters at end"); } // Create a calendar object from the date and time zone. Calendar cal = Calendar.getInstance( tz ); cal.set(year, month, day, hour, minute, second); return generateInstance(cal.getTime()); } private static void checkRange(int val, int low, int high, String field) throws InvalidBERException { if( val < low || val > high ) { throw new InvalidBERException("Invalid "+field); } } private static void checkBounds(int index, int increment, int bound) throws InvalidBERException { if(index+increment > bound) { throw new InvalidBERException("Too few characters in " + "TimeBase"); } } } } jss-4.6.3/org/mozilla/jss/asn1/UTCTime.java000066400000000000000000000023051362106420000203310ustar00rootroot00000000000000/* 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.asn1; import java.util.Date; public class UTCTime extends TimeBase implements ASN1Value { public static final Tag TAG = new Tag(Tag.UNIVERSAL, 23); public Tag getTag() { return TAG; } public UTCTime(Date date) { super(date); } protected boolean isUTC() { return true; } private static final UTCTime.Template templateInstance = new UTCTime.Template(); public static UTCTime.Template getTemplate() { return templateInstance; } public static class Template extends TimeBase.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected boolean isUTC() { return true; } protected TimeBase generateInstance(Date date) { return new UTCTime(date); } } } jss-4.6.3/org/mozilla/jss/asn1/UTF8String.java000066400000000000000000000052201362106420000207730ustar00rootroot00000000000000/* 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.asn1; import java.io.CharConversionException; import java.io.UnsupportedEncodingException; public class UTF8String extends CharacterString implements ASN1Value { public UTF8String(char[] chars) throws CharConversionException { super(chars); } public UTF8String(String s) throws CharConversionException { super(s); } CharConverter getCharConverter() { return new UTF8Converter(); } public static final Tag TAG = new Tag( Tag.UNIVERSAL, 12 ); public static final Form FORM = Form.PRIMITIVE; public Tag getTag() { return TAG; } private static final Template templateInstance = new Template(); /** * Returns a singleton instance of UTF8String.Template. This is more * efficient than creating a new UTF8String.Template. * @return Template. */ public static Template getTemplate() { return templateInstance; } // nested class public static class Template extends CharacterString.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected CharConverter getCharConverter() { return new UTF8Converter(); } protected CharacterString generateInstance(char[] chars) throws CharConversionException { return new UTF8String(chars); } protected String typeName() { return "UTF8String"; } } private static class UTF8Converter implements CharConverter { public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { try { String s = new String(bytes, offset, len, "UTF8"); return s.toCharArray(); } catch( UnsupportedEncodingException e ) { String err = "Unable to find UTF8 encoding mechanism"; throw (CharConversionException) new CharConversionException(err).initCause(e); } } public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { try { String s = new String(chars, offset, len); return s.getBytes("UTF8"); } catch( UnsupportedEncodingException e ) { String err = "Unable to find UTF8 encoding mechanism"; throw (CharConversionException) new CharConversionException(err).initCause(e); } } } // end of char converter } jss-4.6.3/org/mozilla/jss/asn1/UniversalString.java000066400000000000000000000152371362106420000222260ustar00rootroot00000000000000/* 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.asn1; import java.io.ByteArrayOutputStream; import java.io.CharArrayWriter; import java.io.CharConversionException; /** * A UCS4 string. */ public class UniversalString extends CharacterString implements ASN1Value { public static final Tag TAG = new Tag(Tag.UNIVERSAL, 28); public Tag getTag() { return TAG; } public UniversalString(char[] chars) throws CharConversionException { super(chars); } public UniversalString(String s) throws CharConversionException { super(s); } CharConverter getCharConverter() { return new UniversalConverter(); } /** * Returns a singleton instance of the decoding template for this class. * @return Template. */ public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); // nested class public static class Template extends CharacterString.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected CharConverter getCharConverter() { return new UniversalConverter(); } protected CharacterString generateInstance(char[] chars) throws CharConversionException { return new UniversalString( chars ); } protected String typeName() { return "UniversalString"; } } // end of Template /** * A class for converting between Unicode and UCS4. */ private static class UniversalConverter implements CharConverter { // This is the maximum a UCS4 character can be if it has // straight Unicode inside it. public static final int MAX_UNICODE = 0x0000ffff; // This is the maximum a UCS4 character can be if it is UTF-16 // encoded. UTF-16 encoding allows UCS4 chars to be stored across // two Unicode chars. public static final int MAX_UTF16 = 0x0010ffff; // This Unicode character is used to represent an unknown character // in some other encoding. We use it for UCS4 characters that // are not a part of normal Unicode and also cannot be encoded // across two Unicode chars with UTF-16. public static final char REPLACEMENT_CHAR = 0xfffd; // This is the base for UCS4 characters that can be mapped with UTF16. public static final int UTF16_BASE = 0x00100000; // In UTF16 encoding, each Unicode character has 10 bits of // information. public static final int HALF_SHIFT = 10; // The lowest 10 bits public static final int HALF_MASK = 0x3ff; public static final int UTF16_HIGH_START = 0xd800; public static final int UTF16_HIGH_END = 0xdcff; public static final int UTF16_LOW_START = 0xdc00; public static final int UTF16_LOW_END = 0xdfff; /** * Turns big-endian UCS4 characters into Unicode Java characters */ public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { // Each UCS4 character is 4 bytes. Most UCS4 characters will // map to one Unicode character. The exception is UTF-16 // characters, which map to two Unicode characters. CharArrayWriter out = new CharArrayWriter( len / 4 ); int end = offset + len; while( offset < end ) { // eat 4 bytes and make a UCS4 char if( end - offset < 4 ) { throw new CharConversionException("input exhausted"); } int ucs4 = (bytes[offset++] & 0xff) << 24; ucs4 += (bytes[offset++] & 0xff) << 16; ucs4 += (bytes[offset++] & 0xff) << 8; ucs4 += bytes[offset++] & 0xff; // convert UCS4 to Unicode if( ucs4 <= MAX_UNICODE ) { // Unicode is a subset of UCS4, and this char is // in the common subset. Just chop off the unused top // two bytes. out.write( ucs4 & 0xffff ); } else if( ucs4 <= MAX_UTF16 ) { // This UCS4 char is not in Unicode, but can be encoded // into two Unicode chars using UTF16. ucs4 -= UTF16_BASE; out.write( (ucs4 >>> HALF_SHIFT) + UTF16_HIGH_START ); out.write( (ucs4 & HALF_MASK) + UTF16_LOW_START ); } else { // This character is not in Unicode or UTF16. We can't // provide a suitable translation, so use the Unicode // replacement char. out.write( REPLACEMENT_CHAR ); } } return out.toCharArray(); } // Convert Unicode chars to UCS4 chars public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { ByteArrayOutputStream out = new ByteArrayOutputStream(len * 4); int end = offset + len; while( offset < end ) { char c = chars[offset++]; int ucs4; if( c >= UTF16_HIGH_START && c <= UTF16_HIGH_END ) { // This is the beginning of a UTF16 char if( offset == end ) { throw new CharConversionException("input exhausted"); } char low = chars[offset++]; // make sure the next char is the low half of a UTF16 char if( low < UTF16_LOW_START || low > UTF16_LOW_END ) { throw new CharConversionException("UTF16 high "+ "character not followed by a UTF16 low character"); } ucs4 = UTF16_BASE; ucs4 += (c - UTF16_HIGH_START) << HALF_SHIFT; ucs4 += low - UTF16_LOW_START; } else { // this is a normal Unicode char ucs4 = (c & 0x0000ffff); } out.write( (ucs4 & 0xff000000) >>> 24 ); out.write( (ucs4 & 0x00ff0000) >>> 16 ); out.write( (ucs4 & 0x0000ff00) >>> 8 ); out.write( (ucs4 & 0x000000ff) ); } return out.toByteArray(); } } } jss-4.6.3/org/mozilla/jss/asn1/package.html000066400000000000000000000004441362106420000204770ustar00rootroot00000000000000 ASN.1 structures, BER decoding, and DER encoding. jss-4.6.3/org/mozilla/jss/crypto/000077500000000000000000000000001362106420000166725ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/crypto/Algorithm.c000066400000000000000000000240341362106420000207670ustar00rootroot00000000000000/* 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/. */ #include #include #include #include #include #include #include #include #include #include "Algorithm.h" static PRStatus getAlgInfo(JNIEnv *env, jobject alg, JSS_AlgInfo *info); /* Helpers to handle differences in NSS versions. */ #ifndef CKM_AES_CMAC #define CKM_AES_CMAC CKM_INVALID_MECHANISM #endif #ifndef CKM_SP800_108_COUNTER_KDF /* All added at the same time. */ #define CKM_SP800_108_COUNTER_KDF CKM_INVALID_MECHANISM #define CKM_SP800_108_FEEDBACK_KDF CKM_INVALID_MECHANISM #define CKM_SP800_108_DOUBLE_PIPELINE_KDF CKM_INVALID_MECHANISM #define CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA CKM_INVALID_MECHANISM #define CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA CKM_INVALID_MECHANISM #define CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA CKM_INVALID_MECHANISM #endif /*********************************************************************** ** ** Algorithm indices. This must be kept in sync with the algorithm ** tags in the Algorithm class. ** We only store CKMs as a last resort if there is no corresponding ** SEC_OID. **/ JSS_AlgInfo JSS_AlgTable[NUM_ALGS] = { /* 0 */ {SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 1 */ {SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 2 */ {SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 3 */ {SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST, SEC_OID_TAG}, /* 4 */ {SEC_OID_PKCS1_RSA_ENCRYPTION, SEC_OID_TAG}, /* 5 */ {CKM_RSA_PKCS_KEY_PAIR_GEN, PK11_MECH}, /* 6 */ {CKM_DSA_KEY_PAIR_GEN, PK11_MECH}, /* 7 */ {SEC_OID_ANSIX9_DSA_SIGNATURE, SEC_OID_TAG}, /* 8 */ {SEC_OID_RC4, SEC_OID_TAG}, /* 9 */ {SEC_OID_DES_ECB, SEC_OID_TAG}, /* 10 */ {SEC_OID_DES_CBC, SEC_OID_TAG}, /* 11 */ {CKM_DES_CBC_PAD, PK11_MECH}, /* 12 */ {CKM_DES3_ECB, PK11_MECH}, /* 13 */ {SEC_OID_DES_EDE3_CBC, SEC_OID_TAG}, /* 14 */ {CKM_DES3_CBC_PAD, PK11_MECH}, /* 15 */ {CKM_DES_KEY_GEN, PK11_MECH}, /* 16 */ {CKM_DES3_KEY_GEN, PK11_MECH}, /* 17 */ {CKM_RC4_KEY_GEN, PK11_MECH}, /* 18 */ {SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC, SEC_OID_TAG}, /* 19 */ {SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC, SEC_OID_TAG}, /* 20 */ {SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC, SEC_OID_TAG}, /* 21 */ {SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4, SEC_OID_TAG}, /* 22 */ {SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4, SEC_OID_TAG}, /* 23 */ {SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC, SEC_OID_TAG}, /* 24 */ {SEC_OID_MD2, SEC_OID_TAG}, /* 25 */ {SEC_OID_MD5, SEC_OID_TAG}, /* 26 */ {SEC_OID_SHA1, SEC_OID_TAG}, /* 27 */ {CKM_SHA_1_HMAC, PK11_MECH}, /* 28 */ {SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC, SEC_OID_TAG}, /* 29 */ {SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC, SEC_OID_TAG}, /* 30 */ {SEC_OID_RC2_CBC, SEC_OID_TAG}, /* 31 */ {CKM_PBA_SHA1_WITH_SHA1_HMAC, PK11_MECH}, /* 32 */ {CKM_AES_KEY_GEN, PK11_MECH}, /* 33 */ {CKM_AES_ECB, PK11_MECH}, /* 34 */ {CKM_AES_CBC, PK11_MECH}, /* 35 */ {CKM_AES_CBC_PAD, PK11_MECH}, /* 36 */ {CKM_RC2_CBC_PAD, PK11_MECH}, /* 37 */ {CKM_RC2_KEY_GEN, PK11_MECH}, /* 38 */ {SEC_OID_SHA256, SEC_OID_TAG}, /* 39 */ {SEC_OID_SHA384, SEC_OID_TAG}, /* 40 */ {SEC_OID_SHA512, SEC_OID_TAG}, /* 41 */ {SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 42 */ {SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 43 */ {SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 44 */ {SEC_OID_ANSIX962_EC_PUBLIC_KEY, SEC_OID_TAG}, /* 45 */ {SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE, SEC_OID_TAG}, /* 46 */ {CKM_EC_KEY_PAIR_GEN, PK11_MECH}, /* 47 */ {SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, SEC_OID_TAG}, /* 48 */ {SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE, SEC_OID_TAG}, /* 49 */ {SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE, SEC_OID_TAG}, /* 50 */ {SEC_OID_HMAC_SHA256, SEC_OID_TAG}, /* 51 */ {SEC_OID_HMAC_SHA384, SEC_OID_TAG}, /* 52 */ {SEC_OID_HMAC_SHA512, SEC_OID_TAG}, /* 53 */ {SEC_OID_PKCS5_PBKDF2, SEC_OID_TAG}, /* 54 */ {SEC_OID_PKCS5_PBES2, SEC_OID_TAG}, /* 55 */ {SEC_OID_PKCS5_PBMAC1, SEC_OID_TAG}, /* 56 */ {SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST, SEC_OID_TAG}, /* 57 */ {CKM_NSS_AES_KEY_WRAP, PK11_MECH}, /* 58 */ {CKM_NSS_AES_KEY_WRAP_PAD, PK11_MECH}, /* 59 */ {SEC_OID_AES_128_ECB, SEC_OID_TAG}, /* 60 */ {SEC_OID_AES_128_CBC, SEC_OID_TAG}, /* 61 */ {SEC_OID_AES_192_ECB, SEC_OID_TAG}, /* 62 */ {SEC_OID_AES_192_CBC, SEC_OID_TAG}, /* 63 */ {SEC_OID_AES_256_ECB, SEC_OID_TAG}, /* 64 */ {SEC_OID_AES_256_CBC, SEC_OID_TAG}, /* the CKM_AES_KEY_WRAP_* have different defs than CKM_NSS_AES_KEY_WRAP_* */ /* 65 */ {CKM_AES_KEY_WRAP, PK11_MECH}, /* 66 */ {CKM_AES_KEY_WRAP_PAD, PK11_MECH}, /* 67 */ {CKM_SHA256_HMAC, PK11_MECH}, /* 68 */ {CKM_SHA384_HMAC, PK11_MECH}, /* 69 */ {CKM_SHA512_HMAC, PK11_MECH}, /* CKM_AES_CMAC is new to NSS; some implementations might not yet have it. */ /* 70 */ {CKM_AES_CMAC, PK11_MECH}, /* CKM_GENERIC_SECRET_KEY_GEN stub for additional keys. */ /* 71 */ {CKM_GENERIC_SECRET_KEY_GEN, PK11_MECH}, /* CKM_SP800_108_* and CKM_NSS_SP800_108_*_DERIVE_DATA are new to NSS; some * implementations might not yet have it. */ /* 72 */ {CKM_SP800_108_COUNTER_KDF, PK11_MECH}, /* 73 */ {CKM_SP800_108_FEEDBACK_KDF, PK11_MECH}, /* 74 */ {CKM_SP800_108_DOUBLE_PIPELINE_KDF, PK11_MECH}, /* 75 */ {CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA, PK11_MECH}, /* 76 */ {CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA, PK11_MECH}, /* 77 */ {CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA, PK11_MECH}, /* REMEMBER TO UPDATE NUM_ALGS!!! (in Algorithm.h) */ }; /*********************************************************************** * * J S S _ g e t P K 1 1 M e c h F r o m A l g * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * RETURNS * CK_MECHANISM_TYPE corresponding to this algorithm, or * CKM_INVALID_MECHANISM if none exists. */ CK_MECHANISM_TYPE JSS_getPK11MechFromAlg(JNIEnv *env, jobject alg) { JSS_AlgInfo info; if( getAlgInfo(env, alg, &info) != PR_SUCCESS) { return CKM_INVALID_MECHANISM; } if( info.type == PK11_MECH ) { return (CK_MECHANISM_TYPE) info.val; } else { PR_ASSERT( info.type == SEC_OID_TAG ); return PK11_AlgtagToMechanism( (SECOidTag) info.val); } } /*********************************************************************** * * J S S _ g e t O i d T a g F r o m A l g * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * RETURNS * SECOidTag corresponding to this algorithm, or SEC_OID_UNKNOWN * if none was found. */ SECOidTag JSS_getOidTagFromAlg(JNIEnv *env, jobject alg) { JSS_AlgInfo info; if( getAlgInfo(env, alg, &info) != PR_SUCCESS) { return SEC_OID_UNKNOWN; } if( info.type == SEC_OID_TAG ) { return (SECOidTag) info.val; } else { PR_ASSERT( info.type == PK11_MECH ); /* We only store things as PK11 mechanisms as a last resort if * there is no corresponding sec oid tag. */ return SEC_OID_UNKNOWN; } } /*********************************************************************** * * J S S _ g e t A l g I n d e x * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * RETURNS * The index obtained from the algorithm, or -1 if an exception was * thrown. */ static jint getAlgIndex(JNIEnv *env, jobject alg) { jclass algClass; jint index=-1; jfieldID indexField; PR_ASSERT(env!=NULL && alg!=NULL); algClass = (*env)->GetObjectClass(env, alg); #ifdef DEBUG /* Make sure this really is an Algorithm. */ { jclass realClass = ((*env)->FindClass(env, ALGORITHM_CLASS_NAME)); PR_ASSERT( (*env)->IsInstanceOf(env, alg, realClass) ); } #endif indexField = (*env)->GetFieldID( env, algClass, OID_INDEX_FIELD_NAME, OID_INDEX_FIELD_SIG); if(indexField==NULL) { ASSERT_OUTOFMEM(env); goto finish; } index = (*env)->GetIntField(env, alg, indexField); PR_ASSERT( (index >= 0) && (index < NUM_ALGS) ); finish: return index; } /*********************************************************************** * * J S S _ g e t E n u m F r o m A l g * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * OUTPUTS * info * Pointer to a JSS_AlgInfo which will get the information about * this algorithm, if it is found. Must not be NULL. * RETURNS * PR_SUCCESS if the enum was found, otherwise PR_FAILURE. */ static PRStatus getAlgInfo(JNIEnv *env, jobject alg, JSS_AlgInfo *info) { jint index; PRStatus status = PR_FAILURE; PR_ASSERT(env!=NULL && alg!=NULL && info!=NULL); index = getAlgIndex(env, alg); if( index == -1 ) { goto finish; } *info = JSS_AlgTable[index]; status = PR_SUCCESS; finish: return status; } /*********************************************************************** * * EncryptionAlgorithm.getIVLength * */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_crypto_EncryptionAlgorithm_getIVLength (JNIEnv *env, jobject this) { CK_MECHANISM_TYPE mech; mech = JSS_getPK11MechFromAlg(env, this); if( mech == CKM_INVALID_MECHANISM ) { PR_ASSERT(PR_FALSE); return 0; } else { return PK11_GetIVLength(mech); } } /* * This must be synchronized with SymmetricKey.Usage */ CK_ULONG JSS_symkeyUsage[] = { CKA_ENCRYPT, /* 0 */ CKA_DECRYPT, /* 1 */ CKA_WRAP, /* 2 */ CKA_UNWRAP, /* 3 */ CKA_SIGN, /* 4 */ CKA_VERIFY, /* 5 */ 0UL }; jss-4.6.3/org/mozilla/jss/crypto/Algorithm.h000066400000000000000000000035321362106420000207740ustar00rootroot00000000000000/* 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/. */ /* These headers must be included before this header: #include #include #include #include */ #ifndef JSS_ALGORITHM_H #define JSS_ALGORITHM_H PR_BEGIN_EXTERN_C typedef enum JSS_AlgType { PK11_MECH, /* CK_MECHANISM_TYPE */ SEC_OID_TAG /* SECOidTag */ } JSS_AlgType; typedef struct JSS_AlgInfoStr { unsigned long val; /* either a CK_MECHANISM_TYPE or a SECOidTag */ JSS_AlgType type; } JSS_AlgInfo; #define NUM_ALGS 78 extern JSS_AlgInfo JSS_AlgTable[]; extern CK_ULONG JSS_symkeyUsage[]; /*********************************************************************** * * J S S _ g e t O i d T a g F r o m A l g * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * RETURNS * SECOidTag corresponding to this algorithm, or SEC_OID_UNKNOWN * if none was found. */ SECOidTag JSS_getOidTagFromAlg(JNIEnv *env, jobject alg); /*********************************************************************** * * J S S _ g e t P K 1 1 M e c h F r o m A l g * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * RETURNS * CK_MECHANISM_TYPE corresponding to this algorithm, or * CKM_INVALID_MECHANISM if none was found. */ CK_MECHANISM_TYPE JSS_getPK11MechFromAlg(JNIEnv *env, jobject alg); // The following are put here because NSS has not defined these yet #ifndef CKM_AES_KEY_WRAP #define CKM_AES_KEY_WRAP 0x2109 #endif #ifndef CKM_AES_KEY_WRAP_PAD #define CKM_AES_KEY_WRAP_PAD 0x210a #endif #ifndef CKM_AES_KEY_WRAP_KWP #define CKM_AES_KEY_WRAP_KWP 0x210b #endif PR_END_EXTERN_C #endif jss-4.6.3/org/mozilla/jss/crypto/Algorithm.java000066400000000000000000000235571362106420000214770ustar00rootroot00000000000000/* 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.crypto; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; /** * Represents a cryptographic algorithm. * @see EncryptionAlgorithm * @see SignatureAlgorithm */ public class Algorithm { /** * @param oidIndex Index of the oid that this algorithm represents. * @param name A String representation of the Algorithm. */ protected Algorithm(int oidIndex, String name) { this.oidIndex = oidIndex; this.name = name; } /** * @param oidIndex Index of the oid that this algorithm represents. * @param name A String representation of the Algorithm. * @param oid The object identifier for this Algorithm. */ protected Algorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid) { this(oidIndex, name); this.oid = oid; } protected Algorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid, Class paramClass) { this(oidIndex, name, oid); if( paramClass == null ) { this.parameterClasses = new Class[0]; } else { this.parameterClasses = new Class[1]; this.parameterClasses[0] = paramClass; } } protected Algorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid, Class []paramClasses) { this(oidIndex, name, oid); if( paramClasses != null ) { this.parameterClasses = paramClasses; } } /** * Returns a String representation of the algorithm. */ public String toString() { return name; } /** * @return The object identifier for this algorithm. * @exception NoSuchAlgorithmException If no OID is registered for this * algorithm. */ public OBJECT_IDENTIFIER toOID() throws NoSuchAlgorithmException { if( oid == null ) { throw new NoSuchAlgorithmException(); } else { return oid; } } /** * The type of parameter that this algorithm expects. Returns * null if this algorithm does not take any parameters. * If the algorithm can accept more than one type of parameter, * this method returns only one of them. It is better to call * getParameterClasses(). * @return Parameter type. * @deprecated Call getParameterClasses() instead. */ @Deprecated public Class getParameterClass() { if( parameterClasses.length == 0) { return null; } else { return parameterClasses[0]; } } /** * The types of parameter that this algorithm expects. Returns * null if this algorithm does not take any parameters. * @return Parameter types. */ public Class[] getParameterClasses() { return parameterClasses.clone(); } /** * Validates if the given Object can be used as a parameter * for this algorithm. *

If null is passed in, this method will return true * if this algorithm takes no parameters, and false * if this algorithm does take parameters. * @param o Object. * @return Returns true if the given Object can be used as a parameter. */ public boolean isValidParameterObject(Object o) { if( o == null ) { return (parameterClasses.length == 0); } if( parameterClasses.length == 0 ){ return false; } Class c = o.getClass(); for( int i = 0; i < parameterClasses.length; ++i) { if( c.equals( parameterClasses[i] ) ) { return true; } } return false; } public PKCS11Algorithm getEnum() { return PKCS11Algorithm.valueOfIndex(this.oidIndex); } /** * Index into the SECOidTag array in Algorithm.c. */ protected int oidIndex; String name; protected OBJECT_IDENTIFIER oid; private Class[] parameterClasses=new Class[0]; ////////////////////////////////////////////////////////////// // Algorithm OIDs ////////////////////////////////////////////////////////////// static final OBJECT_IDENTIFIER ANSI_X9_ALGORITHM = new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10040, 4 } ); static final OBJECT_IDENTIFIER ANSI_X962_OID = new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10045 } ); // Algorithm indices. These must be kept in sync with the // algorithm array in Algorithm.c. Any PKCS11 Algorithms must be added // to the org.mozilla.jss.crypto.PKCS11Algorithm enum. protected static final int SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION=0; protected static final int SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION=1; protected static final int SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION=2; protected static final int SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST=3; protected static final int SEC_OID_PKCS1_RSA_ENCRYPTION=4; protected static final int CKM_RSA_PKCS_KEY_PAIR_GEN=5; protected static final int CKM_DSA_KEY_PAIR_GEN=6; protected static final int SEC_OID_ANSIX9_DSA_SIGNATURE=7; protected static final int SEC_OID_RC4=8; protected static final int SEC_OID_DES_ECB=9; protected static final int SEC_OID_DES_CBC=10; protected static final int CKM_DES_CBC_PAD=11; protected static final int CKM_DES3_ECB=12; protected static final int SEC_OID_DES_EDE3_CBC=13; protected static final int CKM_DES3_CBC_PAD=14; protected static final int CKM_DES_KEY_GEN=15; protected static final int CKM_DES3_KEY_GEN=16; protected static final int CKM_RC4_KEY_GEN=17; protected static final int SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC=18; protected static final int SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC=19; protected static final int SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC=20; protected static final int SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4=21; protected static final int SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4=22; protected static final int SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC=23; protected static final int SEC_OID_MD2=24; protected static final int SEC_OID_MD5=25; protected static final int SEC_OID_SHA1=26; protected static final int CKM_SHA_1_HMAC=27; protected static final int SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC=28; protected static final int SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC=29; protected static final int SEC_OID_RC2_CBC=30; protected static final int CKM_PBA_SHA1_WITH_SHA1_HMAC=31; // AES protected static final int CKM_AES_KEY_GEN=32; protected static final int CKM_AES_ECB=33; protected static final int CKM_AES_CBC=34; protected static final int CKM_AES_CBC_PAD=35; protected static final int CKM_RC2_CBC_PAD=36; protected static final int CKM_RC2_KEY_GEN=37; //FIPS 180-2 protected static final int SEC_OID_SHA256=38; protected static final int SEC_OID_SHA384=39; protected static final int SEC_OID_SHA512=40; protected static final int SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION=41; protected static final int SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION=42; protected static final int SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION=43; protected static final int SEC_OID_ANSIX962_EC_PUBLIC_KEY=44; protected static final int SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE=45; protected static final int CKM_EC_KEY_PAIR_GEN=46; protected static final int SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE=47; protected static final int SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE=48; protected static final int SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE=49; protected static final int SEC_OID_HMAC_SHA256=50; protected static final int SEC_OID_HMAC_SHA384=51; protected static final int SEC_OID_HMAC_SHA512=52; //PKCS5 V2 protected static final int SEC_OID_PKCS5_PBKDF2=53; protected static final int SEC_OID_PKCS5_PBES2=54; protected static final int SEC_OID_PKCS5_PBMAC1=55; protected static final int SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST=56; // NSS AES KeyWrap protected static final int CKM_NSS_AES_KEY_WRAP=57; protected static final int CKM_NSS_AES_KEY_WRAP_PAD=58; // AES Encryption Algorithms protected static final int SEC_OID_AES_128_ECB = 59; protected static final int SEC_OID_AES_128_CBC = 60; protected static final int SEC_OID_AES_192_ECB = 61; protected static final int SEC_OID_AES_192_CBC = 62; protected static final int SEC_OID_AES_256_ECB = 63; protected static final int SEC_OID_AES_256_CBC = 64; // PKCS#11 AES KeyWrap // These underlying defs are currently different from the NSS AES KeyWrap protected static final int CKM_AES_KEY_WRAP=65; protected static final int CKM_AES_KEY_WRAP_PAD=66; // PKCS#11 SHA2 HMAC protected static final int CKM_SHA256_HMAC=67; protected static final int CKM_SHA384_HMAC=68; protected static final int CKM_SHA512_HMAC=69; // PKCS#11 AES-CMAC protected static final int CKM_AES_CMAC=70; // Generic Secret protected static final int CKM_GENERIC_SECRET_KEY_GEN=71; // PKCS#11 NIST SP800-108 KBKDFs (including NSS variants) protected static final int CKM_SP800_108_COUNTER_KDF=72; protected static final int CKM_SP800_108_FEEDBACK_KDF=73; protected static final int CKM_SP800_108_DOUBLE_PIPELINE_KDF=74; protected static final int CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA=75; protected static final int CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA=76; protected static final int CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA=77; } jss-4.6.3/org/mozilla/jss/crypto/AlreadyInitializedException.java000066400000000000000000000016311362106420000251640ustar00rootroot00000000000000/* 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.crypto; /** * This exception is thrown if an initialization operation * is attempted on something that is already initialized. */ public class AlreadyInitializedException extends java.lang.Exception { private static final long serialVersionUID = 1L; public AlreadyInitializedException() {} public AlreadyInitializedException(String mesg) { super(mesg); } public AlreadyInitializedException(String mesg, Throwable cause) { super(mesg, cause); } public AlreadyInitializedException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/crypto/BadPaddingException.java000066400000000000000000000010761362106420000233750ustar00rootroot00000000000000/* 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.crypto; /** * @deprecated Use javax.crypto.BadPaddingException. */ @Deprecated public class BadPaddingException extends javax.crypto.BadPaddingException { private static final long serialVersionUID = 1L; public BadPaddingException() { super(); } public BadPaddingException(String mesg) { super(mesg); } } jss-4.6.3/org/mozilla/jss/crypto/CMACAlgorithm.java000066400000000000000000000046711362106420000221170ustar00rootroot00000000000000/* 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.crypto; import java.security.NoSuchAlgorithmException; import java.util.Hashtable; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; /** * Algorithms for performing CMACs. These can be used to create * MessageDigests. */ public class CMACAlgorithm extends DigestAlgorithm { protected CMACAlgorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid, int outputSize) { super(oidIndex, name, oid, outputSize); if (oid != null && oidMap.get(oid) == null) { oidMap.put(oid, this); } } /////////////////////////////////////////////////////////////////////// // OID mapping /////////////////////////////////////////////////////////////////////// private static Hashtable oidMap = new Hashtable<>(); /** * Looks up the CMAC algorithm with the given OID. * * @param oid OID. * @return CMAC algorithm. * @exception NoSuchAlgorithmException If no registered CMAC algorithm * has the given OID. */ public static CMACAlgorithm fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { CMACAlgorithm alg = oidMap.get(oid); if (alg == null) { throw new NoSuchAlgorithmException("No such algorithm for OID: " + oid); } return alg; } /** * CMAC AES-X. This is a Message Authentication Code that uses a * symmetric key together with the AES cipher to create a form of * signature. * * Note that we pass null for the OID here: neither NIST nor any other * standards body has defined an OID for use with CMAC. Since we use * a PKCS#11 backend and NSS doesn't otherwise define CMAC based on a * SEC OID, we don't strictly need one. * * We've left the fromOID code (and oid parameter in the constructor) as * other projects use them for HMACAlgorith. At such time as an OID is * defined, it can be added here. */ public static final CMACAlgorithm AES = new CMACAlgorithm(CKM_AES_CMAC, "AES-CMAC", null, 16); public static final CMACAlgorithm AES128 = AES; public static final CMACAlgorithm AES192 = AES; public static final CMACAlgorithm AES256 = AES; } jss-4.6.3/org/mozilla/jss/crypto/Cipher.java000066400000000000000000000170161362106420000207540ustar00rootroot00000000000000/* 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.crypto; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import org.mozilla.jss.util.Assert; /** * A context for performing symmetric encryption and decryption. * First, the context must be initialized. Then, it can be updated * with input through zero or more calls to update. Finally, * doFinal is called to finalize the operation. Note that * it is not necessary to call update if all of the data is * available at once. In this case, all of the input can be processed with one * call to doFinal. */ public abstract class Cipher { // Note: Cipher can't extend javax.crypto.Cipher because it is part of the // provider mechanism. In particular, it isn't an abstract class, many of // the methods are marked final, and it expects to instantiate a CipherSpi // class instead of be directly created like things which override our // Cipher class expect (e.g., PK11Cipher). This is why JSSCipherSpi exists. /** * Initializes a encryption context with a symmetric key. */ public abstract void initEncrypt(SymmetricKey key) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException; /** * Initializes a decryption context with a symmetric key. */ public abstract void initDecrypt(SymmetricKey key) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException; /** * Initializes an encryption context with a symmetric key and * algorithm parameters. */ public abstract void initEncrypt(SymmetricKey key, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException; /** * Initializes a decryption context with a symmetric key and * algorithm parameters. */ public abstract void initDecrypt(SymmetricKey key, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException; /** * Updates the encryption context with additional input. * @param bytes Bytes of plaintext (if encrypting) or ciphertext (if * decrypting). * @return Bytes of ciphertext (if encrypting) or plaintext (if decrypting). */ public abstract byte[] update(byte[] bytes) throws IllegalStateException, TokenException; /** * Updates the encryption context with additional plaintext. * @param bytes Bytes of plaintext (if encrypting) or ciphertext (if * decrypting). * @param offset The index in bytes at which to begin reading. * @param length The number of bytes from bytes to read. * @return Bytes of ciphertext (if encrypting) or plaintext (if decrypting). */ public abstract byte[] update(byte[] bytes, int offset, int length) throws IllegalStateException, TokenException; /** * Completes an cipher operation. This can be called directly after * the context is initialized, or update may be called * any number of times before calling final. * @param bytes Bytes of plaintext (if encrypting) or ciphertext (if * decrypting). * @return The last of the output. */ public abstract byte[] doFinal(byte[] bytes) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException; /** * Completes an cipher operation. * @param bytes Bytes of plaintext (if encrypting) or ciphertext (if * decrypting). * @param offset The index in bytes at which to begin reading. * @param length The number of bytes from bytes to read. * @return The last of the output. */ public abstract byte[] doFinal(byte[] bytes, int offset, int length) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException; /** * Completes an cipher operation. * @return The last of the output. */ public abstract byte[] doFinal() throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException; /** * Pads a byte array so that its length is a multiple of the given * blocksize. The method of padding is the one defined in the RSA * PKCS standards. If M is the length of the data and * B is the block size, the padding string consists of * B - (M mod B) octets, each having the value * B - (M mod B). * @param toBePadded The byte array to pad. * @param blockSize The block size of the encryption algorithm. Must be greater * than zero. * @see #unPad */ public static byte[] pad(byte[] toBePadded, int blockSize) { assert(blockSize > 0); // the padOctet is also the number of pad octets byte padOctet = (byte) (blockSize - (toBePadded.length % blockSize)); byte[] padded = new byte[toBePadded.length + padOctet]; System.arraycopy(toBePadded, 0, padded, 0, toBePadded.length); for(int i = toBePadded.length; i < padded.length; i++) { padded[i] = padOctet; } return padded; } /** * Un-pads a byte array that is padded with PKCS padding. * * @param blockSize The block size of the encryption algorithm. This * is only used for error checking: if the pad size is not * between 1 and blockSize, a BadPaddingException is thrown. * * @see #pad */ public static byte[] unPad(byte[] padded, int blockSize) throws BadPaddingException { if(padded.length == 0) { return new byte[0]; } if( padded.length < blockSize ) { throw new BadPaddingException("Length of padded array is less than"+ " one block"); } byte padOctet = padded[padded.length-1]; if(padOctet > blockSize) { throw new BadPaddingException("Padding octet ("+padOctet+") is "+ "larger than block size ("+blockSize+")"); } if(padOctet < 1) { throw new BadPaddingException("Padding octet is less than 1"); } byte[] unpadded = new byte[padded.length - padOctet]; System.arraycopy(padded, 0, unpadded, 0, unpadded.length); return unpadded; } /** * Un-pads a byte array that is padded with PKCS padding. Since * this version does not take block size as a parameter, it cannot * error check. * @see #pad */ public static byte[] unPad(byte[] padded) throws BadPaddingException { if(padded.length == 0) { return new byte[0]; } byte padOctet = padded[padded.length-1]; if(padOctet < 1) { throw new BadPaddingException("Padding octet is less than 1"); } else if(padOctet >= padded.length) { throw new BadPaddingException("Padding is larger than entire"+ " array"); } byte[] unpadded = new byte[padded.length - padOctet]; System.arraycopy(padded, 0, unpadded, 0, unpadded.length); return unpadded; } } jss-4.6.3/org/mozilla/jss/crypto/CryptoStore.java000066400000000000000000000157201362106420000220370ustar00rootroot00000000000000/* 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.crypto; import java.security.PublicKey; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.util.Password; /** * This is an interface for a permanent repository of cryptographic objects, * such as keys, certs, and passwords. */ public interface CryptoStore { //////////////////////////////////////////////////////////// // Private Keys //////////////////////////////////////////////////////////// /** * Imports a raw private key into this token (permanently). * * @param key The private key. * @exception TokenException If the key cannot be imported to this token. * @exception KeyAlreadyImportedException If the key already exists on this token. */ public PrivateKey importPrivateKey( byte[] key, PrivateKey.Type type ) throws TokenException, KeyAlreadyImportedException; /** * Imports a raw private key into this token. * * @param key The private key. * @param temporary Whether the key should be temporary. * @exception TokenException If the key cannot be imported to this token. * @exception KeyAlreadyImportedException If the key already exists on this token. */ public PrivateKey importPrivateKey( byte[] key, PrivateKey.Type type, boolean temporary) throws TokenException, KeyAlreadyImportedException; /** * Returns all private keys stored on this token. * * @return An array of all private keys stored on this token. * @exception TokenException If an error occurs on the token while * gathering the keys. */ public PrivateKey[] getPrivateKeys() throws TokenException; /** * Returns all public keys stored on this token. * * @return An array of all public keys stored on this token. * @exception TokenException If an error occurs on the token while * gathering the keys. */ public PublicKey[] getPublicKeys() throws TokenException; /** * Returns the public key corresponding to the private key. * * @param privateKey * @return The corresponding public key. * @throws ObjectNotFoundException If the corresponding public key is not found. * @throws TokenException If an error occurs on the token. */ public PublicKey findPublicKey(PrivateKey privateKey) throws ObjectNotFoundException, TokenException; /** * Returns all symmetric keys stored on this token. * * @return An array of all symmetric keys stored on this token. * @exception TokenException If an error occurs on the token while * gathering the keys. */ public SymmetricKey[] getSymmetricKeys() throws TokenException; /** * Permanently deletes a private key from the token. * * @param privateKey A private key to be permanently deleted. * @exception NoSuchItemOnTokenException If the given private key does * not reside on this token. * @exception TokenException If an error occurs on the token while * deleting the key. */ public void deletePrivateKey(PrivateKey privateKey) throws NoSuchItemOnTokenException, TokenException; /** * Permanently deletes a public key from the token. * * @param publicKey A public key to be permanently deleted. * @exception NoSuchItemOnTokenException If the given public key does * not reside on this token. * @exception TokenException If an error occurs on the token while * deleting the key. */ public void deletePublicKey(PublicKey publicKey) throws NoSuchItemOnTokenException, TokenException; /** * Get an encrypted private key for the given cert. * * @param cert Certificate of key to be exported * @param pbeAlg The PBEAlgorithm to use * @param pw The password to encrypt with * @param iteration Iteration count; default of 2000 if le 0 */ public byte[] getEncryptedPrivateKeyInfo(X509Certificate cert, PBEAlgorithm pbeAlg, Password pw, int iteration) throws NotInitializedException, ObjectNotFoundException, TokenException; /** * Get an encrypted private key, with optional password * conversion. * * @param conv Password converter. If null, pw.getByteCopy() * will be used to get password bytes. * @param pw The password * @param alg The encryption algorithm * @param n Iteration count; default of 2000 if le 0 * @param k The private key */ public byte[] getEncryptedPrivateKeyInfo( KeyGenerator.CharToByteConverter conv, Password pw, Algorithm alg, int n, PrivateKey k); /** * @param conv Password converter. If null, pw.getByteCopy() * will be used to get password bytes. * @param pw The password * @param nickname Nickname to use for private key * @param pubKey Public key corresponding to private key */ public void importEncryptedPrivateKeyInfo( KeyGenerator.CharToByteConverter conv, Password pw, String nickname, PublicKey pubKey, byte[] epkiBytes); //////////////////////////////////////////////////////////// // Certs //////////////////////////////////////////////////////////// /** * Returns all user certificates stored on this token. A user certificate * is one that has a matching private key. * * @return An array of all user certificates present on this token. * @exception TokenException If an error occurs on the token while * gathering the certificates. */ public X509Certificate[] getCertificates() throws TokenException; /** * Deletes a certificate and the corresponding keys. * * @param cert A certificate to be deleted from this token. The cert * must actually reside on this token. * @exception NoSuchItemOnTokenException If the given cert does not * reside on this token. * @exception TokenException If an error occurred on the token while * deleting the certificate. */ public void deleteCert(X509Certificate cert) throws NoSuchItemOnTokenException, TokenException; /** * Deletes a certificate without deleting the corresponding keys. * * @param cert A certificate to be deleted from this token. The cert * must actually reside on this token. * @exception NoSuchItemOnTokenException If the given cert does not * reside on this token. * @exception TokenException If an error occurred on the token while * deleting the certificate. */ public void deleteCertOnly(X509Certificate cert) throws NoSuchItemOnTokenException, TokenException; } jss-4.6.3/org/mozilla/jss/crypto/CryptoToken.java000066400000000000000000000256531362106420000220310ustar00rootroot00000000000000/* 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.crypto; import org.mozilla.jss.util.*; import java.security.*; /** * A CryptoToken performs cryptographic operations and stores * cryptographic items, such as keys and certs. It corresponds to a * Cryptographic Service Provider (CSP) in CDSA, and to a PKCS #11 token. *

Instances of CryptoToken are obtained from CryptoManager. * @see org.mozilla.jss.CryptoManager */ public interface CryptoToken { // // SERVICES // /** * Creates a Signature object, which can perform signing and signature * verification. Signing and verification cryptographic operations will * take place on this token. The signing key must be located on this * token. * * @param algorithm The algorithm used for the signing/verification. * @exception java.security.NoSuchAlgorithmException If the given * algorithm is not supported by this provider. */ public abstract org.mozilla.jss.crypto.Signature getSignatureContext(SignatureAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, TokenException; /** * Creates a Digest object. Digesting cryptographic operations will * take place on this token. * * @param algorithm The algorithm used for digesting. * @exception java.security.NoSuchAlgorithmException If this provider * does not support the given algorithm. */ public abstract JSSMessageDigest getDigestContext(DigestAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, DigestException; // !!! MAC ??? /** * Creates a Cipher object, which can be used for encryption and * decryption. Cryptographic operations will take place on this token. * The keys used in the operations must be located on this token. * * @param algorithm The algorithm used for encryption/decryption. * @exception java.security.NoSuchAlgorithmException If this provider * does not support the given algorithm. */ public abstract Cipher getCipherContext(EncryptionAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, TokenException; public abstract SymmetricKeyDeriver getSymmetricKeyDeriver() throws TokenException; public abstract KeyWrapper getKeyWrapper(KeyWrapAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, TokenException; /** * Returns a Random Number Generator implemented on this token. * * @exception org.mozilla.jss.crypto.ServiceNotProvidedException If this token * does not perform random number generation */ /* public abstract SecureRandom getRandomGenerator() throws NotImplementedException, TokenException; */ // !!! Derive Keys ??? /** * Creates a KeyGenerator object, which can be used to generate * symmetric encryption keys. Any keys generated with this KeyGenerator * will be generated on this token. * * @param algorithm The algorithm that the keys will be used with. * @exception java.security.NoSuchAlgorithmException If this token does not * support the given algorithm. */ public abstract KeyGenerator getKeyGenerator(KeyGenAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, TokenException; /** * Clones a SymmetricKey from a different token onto this token. * * @exception SymmetricKey.NotExtractableException If the key material * cannot be extracted from the current token. * @exception InvalidKeyException If the owning token cannot process * the key to be cloned. */ public SymmetricKey cloneKey(SymmetricKey key) throws SymmetricKey.NotExtractableException, InvalidKeyException, TokenException; /** * Creates a KeyPairGenerator object, which can be used to generate * key pairs. Any keypairs generated with this generator will be generated * on this token. * * @param algorithm The algorithm that the keys will be used with (RSA, * DSA, EC, etc.) * @exception java.security.NoSuchAlgorithmException If this token does * not support the given algorithm. */ public abstract KeyPairGenerator getKeyPairGenerator(KeyPairAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, TokenException; /** * Generates a b64 encoded PKCS10 blob used for making cert * request. Begin/End brackets included. * @param subject subject dn of the certificate * @param keysize size of the key * @param keyType "rsa" or "dsa" * @param P The DSA prime parameter * @param Q The DSA sub-prime parameter * @param G The DSA base parameter * @return base64 encoded pkcs10 certificate request with * Begin/end brackets */ public abstract String generateCertRequest(String subject, int keysize, String keyType, byte[] P, byte[] Q, byte[] G) throws TokenException, InvalidParameterException, PQGParamGenException; /** * Determines whether this token supports the given algorithm. * * @param alg A JSS algorithm. Note that for Signature, a token may * fail to support a specific SignatureAlgorithm (such as * RSASignatureWithMD5Digest) even though it does support the * generic algorithm (RSASignature). In this case, the signature * operation will be performed on that token, but the digest * operation will be performed on the internal token. * @return true if the token supports the algorithm. */ public boolean doesAlgorithm(Algorithm alg); /** * Login to the token. If a token is logged in, it will not trigger * password callbacks. * * @param pwcb The password callback for this token. * @exception IncorrectPasswordException If the supplied password is * incorrect. * @see #setLoginMode * @see org.mozilla.jss.CryptoManager#setPasswordCallback */ public abstract void login(PasswordCallback pwcb) throws IncorrectPasswordException, TokenException; /** * Logout of the token. * */ public abstract void logout() throws TokenException; /** * Login once, never need to re-enter the password until you log out. */ public static final int ONE_TIME=0; /** * Need to re-login after a period of time. * @see org.mozilla.jss.crypto.CryptoToken#setLoginTimeoutMinutes */ public static final int TIMEOUT=1; /** * Need to provide a password before each crypto operation. */ public static final int EVERY_TIME=2; /** * Returns the login mode of this token: ONE_TIME, TIMEOUT, or * EVERY_TIME. The default is ONE_TIME. * @see #getLoginTimeoutMinutes * @exception TokenException If an error occurs on the token. */ public abstract int getLoginMode() throws TokenException; /** * Sets the login mode of this token. * * @param mode ONE_TIME, TIMEOUT, or EVERY_TIME * @exception TokenException If this mode is not supported by this token, * or an error occurs on the token. * @see #login * @see #setLoginTimeoutMinutes */ public abstract void setLoginMode(int mode) throws TokenException; /** * Returns the login timeout period. The timeout is only used if the * login mode is TIMEOUT. * * @see #getLoginMode * @exception TokenException If an error occurs on the token. */ public abstract int getLoginTimeoutMinutes() throws TokenException; /** * Sets the timeout period for logging in. This will only be used * if the login mode is TIMEOUT. * * @exception TokenException If timeouts are not supported by this * token, or an error occurs on the token. * @see #setLoginMode */ public abstract void setLoginTimeoutMinutes(int timeoutMinutes) throws TokenException; /** * Find out if the token is currently logged in. * * @see #login * @see #logout */ public boolean isLoggedIn() throws TokenException; /** * returns true if this token needs to be logged into before * it can be used. * * @see #login * @see #logout */ public boolean needsLogin() throws TokenException; /** * Initialize the password of this token. * * @param securityOfficerPW A callback to obtain the password of the * SecurityOfficer. Pass in a NullPasswordCallback if there is * no security officer password. Must not be null. * @param userPW A callback to obtain the new password for this token. * Must not be null. * @exception IncorrectPasswordException If the supplied security officer * password is incorrect. * @exception AlreadyInitializedException If the token only allows one * password initialization, and it has already occurred. * @exception TokenException If an error occurs on the token. */ public abstract void initPassword(PasswordCallback securityOfficerPW, PasswordCallback userPW) throws IncorrectPasswordException, AlreadyInitializedException, TokenException; /** * Determine whether the password has been initialized yet. Some tokens * (such as the Netscape Internal Key Token) don't allow initializing * the PIN more than once. * * @exception TokenException If an error occurs on the token. */ public abstract boolean passwordIsInitialized() throws TokenException; /** * Change the password of this token. * * @exception IncorrectPasswordException If the supplied old password is * incorrect. * @param oldpw A callback (which could be just a Password) to retrieve * the current password. * @param newpw A callback (which could be just a Password) to retrieve * the new password. */ public abstract void changePassword(PasswordCallback oldpw, PasswordCallback newpw) throws IncorrectPasswordException, TokenException; /** * Obtain the nickname, or label, of this token. * * @exception TokenException If an error occurs on the token. */ public abstract String getName() throws TokenException; /** * Get the CryptoStore interface to this token's objects. */ public abstract CryptoStore getCryptoStore(); /** * Deep comparison operation. Use this, rather than ==, to determine * whether two CryptoTokens are the same. */ public boolean equals(Object object); /** * Determines whether this token is currently present. * This could return false if the token is a smart card that was * removed from its slot. */ public boolean isPresent(); public void importPublicKey( PublicKey pubKey, boolean permanent) throws TokenException; } jss-4.6.3/org/mozilla/jss/crypto/DigestAlgorithm.java000066400000000000000000000055611362106420000226320ustar00rootroot00000000000000/* 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.crypto; import java.security.NoSuchAlgorithmException; import java.util.Hashtable; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; public class DigestAlgorithm extends Algorithm { // The size in bytes of the output of this hash. private int outputSize; protected DigestAlgorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid, int outputSize) { super(oidIndex, name, oid); this.outputSize = outputSize; // only store the first algorithm for a given oid. More than one // alg might share the same oid, such as from child classes. if( oid != null && oidMap.get(oid)==null ) { oidMap.put(oid, this); } } /////////////////////////////////////////////////////////////////////// // OID mapping /////////////////////////////////////////////////////////////////////// private static Hashtable oidMap = new Hashtable<>(); public static DigestAlgorithm fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { DigestAlgorithm alg = oidMap.get(oid); if( alg == null ) { throw new NoSuchAlgorithmException(); } else { return alg; } } /** * @return The output size in bytes for this algorithm. */ public int getOutputSize() { return outputSize; } /** * The MD2 digest algorithm, from RSA. */ public static final DigestAlgorithm MD2 = new DigestAlgorithm (SEC_OID_MD2, "MD2", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(2), 16 ); /** * The MD5 digest algorithm, from RSA. */ public static final DigestAlgorithm MD5 = new DigestAlgorithm (SEC_OID_MD5, "MD5", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(5), 16 ); /** * The SHA-1 digest algorithm, from Uncle Sam. */ public static final DigestAlgorithm SHA1 = new DigestAlgorithm (SEC_OID_SHA1, "SHA-1", OBJECT_IDENTIFIER.ALGORITHM.subBranch(26), 20); /* * The SHA-256 digest Algorithm from FIPS 180-2 */ public static final DigestAlgorithm SHA256 = new DigestAlgorithm (SEC_OID_SHA256, "SHA-256", OBJECT_IDENTIFIER.HASH_ALGORITHM.subBranch(1), 32); /* * The SHA-384 digest Algorithm from FIPS 180-2 */ public static final DigestAlgorithm SHA384 = new DigestAlgorithm (SEC_OID_SHA384, "SHA-384", OBJECT_IDENTIFIER.HASH_ALGORITHM.subBranch(2), 48); /* * The SHA-512 digest Algorithm from FIPS 180-2 */ public static final DigestAlgorithm SHA512 = new DigestAlgorithm (SEC_OID_SHA512, "SHA-512", OBJECT_IDENTIFIER.HASH_ALGORITHM.subBranch(3), 64); } jss-4.6.3/org/mozilla/jss/crypto/EncryptionAlgorithm.java000066400000000000000000000327771362106420000235560ustar00rootroot00000000000000/* 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.crypto; import java.security.NoSuchAlgorithmException; import java.util.Hashtable; import java.util.Vector; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; /** * An algorithm for performing symmetric encryption. */ public class EncryptionAlgorithm extends Algorithm { public static class Mode { private String name; private static Hashtable nameHash = new Hashtable<>(); private Mode() { } private Mode(String name) { this.name = name; nameHash.put(name.toLowerCase(), this); } public static Mode fromString(String name) throws NoSuchAlgorithmException { Mode m = nameHash.get(name.toLowerCase()); if( m == null ) { throw new NoSuchAlgorithmException( "Unrecognized mode \"" + name + "\""); } return m; } public String toString() { return name; } public static final Mode NONE = new Mode("NONE"); public static final Mode ECB = new Mode("ECB"); public static final Mode CBC = new Mode("CBC"); } public static class Alg { private String name; private static Hashtable nameHash = new Hashtable<>(); private Alg() { } private Alg(String name) { this.name = name; nameHash.put(name.toLowerCase(), this); } private static Alg fromString(String name) throws NoSuchAlgorithmException { Alg a = nameHash.get(name.toLowerCase()); if( a == null ) { throw new NoSuchAlgorithmException("Unrecognized algorithm \"" + name + "\""); } return a; } public String toString() { return name; } public static final Alg RC4 = new Alg("RC4"); public static final Alg DES = new Alg("DES"); public static final Alg DESede = new Alg("DESede"); public static final Alg AES = new Alg("AES"); public static final Alg RC2 = new Alg("RC2"); } public static class Padding { private String name; private static Hashtable nameHash = new Hashtable<>(); private Padding() { } private Padding(String name) { this.name = name; nameHash.put(name.toLowerCase(), this); } public String toString() { return name; } public static Padding fromString(String name) throws NoSuchAlgorithmException { Padding p = nameHash.get(name.toLowerCase()); if( p == null ) { throw new NoSuchAlgorithmException("Unrecognized Padding " + "type \"" + name + "\""); } return p; } public static final Padding NONE = new Padding("NoPadding"); public static final Padding PKCS5 = new Padding("PKCS5Padding"); } private static String makeName(Alg alg, Mode mode, Padding padding) { StringBuffer buf = new StringBuffer(); buf.append(alg.toString()); buf.append('/'); buf.append(mode.toString()); buf.append('/'); buf.append(padding.toString()); return buf.toString(); } protected EncryptionAlgorithm(int oidTag, Alg alg, Mode mode, Padding padding, Class paramClass, int blockSize, OBJECT_IDENTIFIER oid, int keyStrength) { super(oidTag, makeName(alg, mode, padding), oid, paramClass); this.alg = alg; this.mode = mode; this.padding = padding; this.blockSize = blockSize; if(oid!=null) { oidMap.put(oid, this); } if( name != null ) { nameMap.put(name.toLowerCase(), this); } this.keyStrength = keyStrength; algList.addElement(this); } protected EncryptionAlgorithm(int oidTag, Alg alg, Mode mode, Padding padding, Class []paramClasses, int blockSize, OBJECT_IDENTIFIER oid, int keyStrength) { super(oidTag, makeName(alg, mode, padding), oid, paramClasses); this.alg = alg; this.mode = mode; this.padding = padding; this.blockSize = blockSize; if(oid!=null) { oidMap.put(oid, this); } if( name != null ) { nameMap.put(name.toLowerCase(), this); } this.keyStrength = keyStrength; algList.addElement(this); } private int blockSize; private Alg alg; private Mode mode; private Padding padding; private int keyStrength; /** * @return The base algorithm, without the parameters. For example, * the base algorithm of "AES/CBC/NoPadding" is "AES". */ public Alg getAlg() { return alg; } /** * @return The mode of this algorithm. */ public Mode getMode() { return mode; } /** * @return The padding type of this algorithm. */ public Padding getPadding() { return padding; } /** * @return The key strength of this algorithm in bits. Algorithms that * use continuously variable key sizes (such as RC4) will return 0 to * indicate they can use any key size. */ public int getKeyStrength() { return keyStrength; } /////////////////////////////////////////////////////////////////////// // mapping /////////////////////////////////////////////////////////////////////// private static Hashtable oidMap = new Hashtable<>(); private static Hashtable nameMap = new Hashtable<>(); private static Vector algList = new Vector<>(); public static EncryptionAlgorithm fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { Object alg = oidMap.get(oid); if( alg == null ) { throw new NoSuchAlgorithmException("OID: " + oid.toString()); } else { return (EncryptionAlgorithm) alg; } } // Note: after we remove this deprecated method, we can remove // nameMap. /** * @param name Algorithm name. * @return Encryption algorithm. * @throws NoSuchAlgorithmException If the algorithm is not found. * @deprecated This method is deprecated because algorithm strings * don't contain key length, which is necessary to distinguish between * AES algorithms. */ @Deprecated public static EncryptionAlgorithm fromString(String name) throws NoSuchAlgorithmException { Object alg = nameMap.get(name.toLowerCase()); if( alg == null ) { throw new NoSuchAlgorithmException(); } else { return (EncryptionAlgorithm) alg; } } public static EncryptionAlgorithm lookup(String algName, String modeName, String paddingName, int keyStrength) throws NoSuchAlgorithmException { int len = algList.size(); Alg alg = Alg.fromString(algName); Mode mode = Mode.fromString(modeName); Padding padding = Padding.fromString(paddingName); if (paddingName == null || paddingName.equals("")) padding = Padding.NONE; int i; for(i = 0; i < len; ++i ) { EncryptionAlgorithm cur = algList.elementAt(i); if( cur.alg == alg && cur.mode == mode && cur.padding == padding ) { if( cur.keyStrength == 0 || cur.keyStrength == keyStrength ) { break; } } } if( i == len ) { throw new NoSuchAlgorithmException(algName + "/" + modeName + "/" + paddingName + " with key strength " + keyStrength + " not found"); } return algList.elementAt(i); } /** * @return The blocksize of the algorithm in bytes. Stream algorithms (such as * RC4) have a blocksize of 1. */ public int getBlockSize() { return blockSize; } /** * @return true if this algorithm performs padding. */ public boolean isPadded() { return ! Padding.NONE.equals(padding); } /** * @return The type of padding for this algorithm. */ public Padding getPaddingType() { return padding; } private static Class[] IVParameterSpecClasses = null; static { IVParameterSpecClasses = new Class[2]; IVParameterSpecClasses[0] = IVParameterSpec.class; IVParameterSpecClasses[1] = IvParameterSpec.class; } /** * Returns the number of bytes that this algorithm expects in * its initialization vector. * * @return The size in bytes of the IV for this algorithm. A size of * 0 means this algorithm does not take an IV. */ public native int getIVLength(); public static final EncryptionAlgorithm RC4 = new EncryptionAlgorithm(SEC_OID_RC4, Alg.RC4, Mode.NONE, Padding.NONE, (Class)null, 1, OBJECT_IDENTIFIER.RSA_CIPHER.subBranch(4), 0); public static final EncryptionAlgorithm DES_ECB = new EncryptionAlgorithm(SEC_OID_DES_ECB, Alg.DES, Mode.ECB, Padding.NONE, (Class)null, 8, OBJECT_IDENTIFIER.ALGORITHM.subBranch(6), 56); public static final EncryptionAlgorithm DES_CBC = new EncryptionAlgorithm(SEC_OID_DES_CBC, Alg.DES, Mode.CBC, Padding.NONE, IVParameterSpecClasses, 8, OBJECT_IDENTIFIER.ALGORITHM.subBranch(7), 56); public static final EncryptionAlgorithm DES_CBC_PAD = new EncryptionAlgorithm(CKM_DES_CBC_PAD, Alg.DES, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 8, null, 56); // no oid public static final EncryptionAlgorithm DES3_ECB = new EncryptionAlgorithm(CKM_DES3_ECB, Alg.DESede, Mode.ECB, Padding.NONE, (Class)null, 8, null, 168); // no oid public static final EncryptionAlgorithm DES3_CBC = new EncryptionAlgorithm(SEC_OID_DES_EDE3_CBC, Alg.DESede, Mode.CBC, Padding.NONE, IVParameterSpecClasses, 8, OBJECT_IDENTIFIER.RSA_CIPHER.subBranch(7), 168); public static final EncryptionAlgorithm DES3_CBC_PAD = new EncryptionAlgorithm(CKM_DES3_CBC_PAD, Alg.DESede, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 8, null, 168); //no oid public static final EncryptionAlgorithm RC2_CBC = new EncryptionAlgorithm(SEC_OID_RC2_CBC, Alg.RC2, Mode.CBC, Padding.NONE, RC2ParameterSpec.class, 8, null, 0); // no oid, see comment below // Which algorithm should be associated with this OID, RC2_CBC or // RC2_CBC_PAD? NSS says RC2_CBC, but PKCS #5 v2.0 says RC2_CBC_PAD. // See NSS bug 202925. public static final EncryptionAlgorithm RC2_CBC_PAD = new EncryptionAlgorithm(CKM_RC2_CBC_PAD, Alg.RC2, Mode.CBC, Padding.PKCS5, RC2ParameterSpec.class, 8, OBJECT_IDENTIFIER.RSA_CIPHER.subBranch(2), 0); public static final OBJECT_IDENTIFIER AES_ROOT_OID = new OBJECT_IDENTIFIER( new long[] { 2, 16, 840, 1, 101, 3, 4, 1 } ); public static final EncryptionAlgorithm AES_128_ECB = new EncryptionAlgorithm(SEC_OID_AES_128_ECB, Alg.AES, Mode.ECB, Padding.NONE, (Class)null, 16, AES_ROOT_OID.subBranch(1), 128); public static final EncryptionAlgorithm AES_128_CBC = new EncryptionAlgorithm(SEC_OID_AES_128_CBC, Alg.AES, Mode.CBC, Padding.NONE, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(2), 128); public static final EncryptionAlgorithm AES_128_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_128_CBC, Alg.AES, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(2), 128); public static final EncryptionAlgorithm AES_192_ECB = new EncryptionAlgorithm(SEC_OID_AES_192_ECB, Alg.AES, Mode.ECB, Padding.NONE, (Class)null, 16, AES_ROOT_OID.subBranch(21), 192); public static final EncryptionAlgorithm AES_192_CBC = new EncryptionAlgorithm(SEC_OID_AES_192_CBC, Alg.AES, Mode.CBC, Padding.NONE, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(22), 192); public static final EncryptionAlgorithm AES_192_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_192_CBC, Alg.AES, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(22), 192); public static final EncryptionAlgorithm AES_256_ECB = new EncryptionAlgorithm(SEC_OID_AES_256_ECB, Alg.AES, Mode.ECB, Padding.NONE, (Class)null, 16, AES_ROOT_OID.subBranch(41), 256); public static final EncryptionAlgorithm AES_256_CBC = new EncryptionAlgorithm(SEC_OID_AES_256_CBC, Alg.AES, Mode.CBC, Padding.NONE, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(42), 256); public static final EncryptionAlgorithm AES_CBC_PAD = new EncryptionAlgorithm(CKM_AES_CBC_PAD, Alg.AES, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 16, null, 256); // no oid public static final EncryptionAlgorithm AES_256_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_256_CBC, Alg.AES, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(42), 256); } jss-4.6.3/org/mozilla/jss/crypto/HMACAlgorithm.java000066400000000000000000000045611362106420000221220ustar00rootroot00000000000000/* 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.crypto; import java.security.NoSuchAlgorithmException; import java.util.Hashtable; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; /** * Algorithms for performing HMACs. These can be used to create * MessageDigests. */ public class HMACAlgorithm extends DigestAlgorithm { protected HMACAlgorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid, int outputSize) { super(oidIndex, name, oid, outputSize); if( oid!=null && oidMap.get(oid)==null) { oidMap.put(oid, this); } } /////////////////////////////////////////////////////////////////////// // OID mapping /////////////////////////////////////////////////////////////////////// private static Hashtable oidMap = new Hashtable<>(); /** * Looks up the HMAC algorithm with the given OID. * * @param oid OID. * @return HMAC algorithm. * @exception NoSuchAlgorithmException If no registered HMAC algorithm * has the given OID. */ public static HMACAlgorithm fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { Object alg = oidMap.get(oid); if( alg == null ) { throw new NoSuchAlgorithmException(); } else { return (HMACAlgorithm) alg; } } /** * SHA-X HMAC. This is a Message Authentication Code that uses a * symmetric key together with SHA-X digesting to create a form of * signature. */ public static final HMACAlgorithm SHA1 = new HMACAlgorithm (CKM_SHA_1_HMAC, "SHA-1-HMAC", OBJECT_IDENTIFIER.ALGORITHM.subBranch(26), 20); public static final HMACAlgorithm SHA256 = new HMACAlgorithm (CKM_SHA256_HMAC, "SHA-256-HMAC", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(9), 32); public static final HMACAlgorithm SHA384 = new HMACAlgorithm (CKM_SHA384_HMAC, "SHA-384-HMAC", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(10), 48); public static final HMACAlgorithm SHA512 = new HMACAlgorithm (CKM_SHA512_HMAC, "SHA-512-HMAC", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(11), 64); } jss-4.6.3/org/mozilla/jss/crypto/IVParameterSpec.java000066400000000000000000000012451362106420000225310ustar00rootroot00000000000000/* 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.crypto; import java.security.spec.AlgorithmParameterSpec; /** * An algorithm parameter that consists of an initialization vector (IV). */ public class IVParameterSpec implements AlgorithmParameterSpec { private byte[] iv; public IVParameterSpec(byte[] iv) { this.iv = iv; } /** * @return Reference to an internal copy of the initialization vector. */ public byte[] getIV() { return iv; } } jss-4.6.3/org/mozilla/jss/crypto/IllegalBlockSizeException.java000066400000000000000000000005401362106420000245720ustar00rootroot00000000000000/* 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.crypto; public class IllegalBlockSizeException extends Exception { private static final long serialVersionUID = 1L; } jss-4.6.3/org/mozilla/jss/crypto/InternalCertificate.java000066400000000000000000000047241362106420000234630ustar00rootroot00000000000000/* 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.crypto; /** * Certificates residing in the internal database. Their trust flags * can be viewed and modified. Other types of certificates do not * have trust flags. */ public interface InternalCertificate extends X509Certificate { //////////////////////////////////////////////////// // Trust manipulation //////////////////////////////////////////////////// public static final int VALID_PEER = (1<<0); public static final int TRUSTED_PEER = (1<<1); // CERTDB_TRUSTED public static final int VALID_CA = (1<<3); public static final int TRUSTED_CA = (1<<4); public static final int USER = (1<<6); public static final int TRUSTED_CLIENT_CA = (1<<7); /** * Set the SSL trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract void setSSLTrust(int trust); /** * Set the email (S/MIME) trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract void setEmailTrust(int trust); /** * Set the object signing trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract void setObjectSigningTrust(int trust); /** * Get the SSL trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract int getSSLTrust(); /** * Get the email (S/MIME) trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract int getEmailTrust(); /** * Get the object signing trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract int getObjectSigningTrust(); } jss-4.6.3/org/mozilla/jss/crypto/InvalidDERException.java000066400000000000000000000014431362106420000233370ustar00rootroot00000000000000/* 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.crypto; /** * This exception is thrown when we encounter a bogus DER blob. */ public class InvalidDERException extends Exception { private static final long serialVersionUID = 1L; public InvalidDERException() { super(); } public InvalidDERException(String mesg) { super(mesg); } public InvalidDERException(String mesg, Throwable cause) { super(mesg, cause); } public InvalidDERException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/crypto/InvalidKeyFormatException.java000066400000000000000000000014661362106420000246330ustar00rootroot00000000000000/* 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.crypto; /** * An exception of this type is thrown if an encoded private key * cannot be decoded. */ public class InvalidKeyFormatException extends java.security.spec.InvalidKeySpecException { private static final long serialVersionUID = 1L; public InvalidKeyFormatException() { super(); } public InvalidKeyFormatException(String mesg) { super(mesg); } public InvalidKeyFormatException(String mesg, Throwable cause) { super(mesg, cause); } public InvalidKeyFormatException(Throwable cause) { super(cause); } } jss-4.6.3/org/mozilla/jss/crypto/JSSMessageDigest.java000066400000000000000000000075101362106420000226440ustar00rootroot00000000000000/* 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.crypto; import java.security.DigestException; import java.security.InvalidKeyException; /** * A class for performing message digesting (hashing) and MAC operations. */ public abstract class JSSMessageDigest { /** * Initializes an HMAC digest with the given symmetric key. This also * has the effect of resetting the digest. * * @param key Symmetric key. * @exception DigestException If this algorithm is not an HMAC algorithm. * @exception InvalidKeyException If the given key is not valid. */ public abstract void initHMAC(SymmetricKey key) throws DigestException, InvalidKeyException; /** * Updates the digest with a single byte of input. * @param input Input byte. * @throws DigestException If an error occurred. */ public void update(byte input) throws DigestException { byte[] in = { input }; update(in, 0, 1); } /** * Updates the digest with a portion of an array. * * @param input An array from which to update the digest. * @param offset The index in the array at which to start digesting. * @param len The number of bytes to digest. * @exception DigestException If an error occurs while digesting. */ public abstract void update(byte[] input, int offset, int len) throws DigestException; /** * Updates the digest with an array. * * @param input An array to feed to the digest. * @exception DigestException If an error occurs while digesting. */ public void update(byte[] input) throws DigestException { update(input, 0, input.length); } /** * Completes digestion. * * @return The, ahem, output of the digest operation. * @exception DigestException If an error occurs while digesting. */ public byte[] digest() throws DigestException { byte[] output = new byte[getOutputSize()]; digest(output, 0, output.length); return output; } /** * Completes digesting, storing the result into the provided array. * * @param buf The buffer in which to place the digest output. * @param offset The offset in the buffer at which to store the output. * @param len The amount of space available in the buffer for the * digest output. * @return The number of bytes actually stored into buf. * @exception DigestException If the provided space is too small for * the digest, or an error occurs with the digest. */ public abstract int digest(byte[] buf, int offset, int len) throws DigestException; /** * Provides final data to the digest, then completes it and returns the * output. * * @param input The digest's last meal. * @return The completed digest. * @exception DigestException If an error occurs while digesting. */ public byte[] digest(byte[] input) throws DigestException { update(input); return digest(); } /** * Resets this digest for further use. This clears all input and * output streams. If this is an HMAC digest, the HMAC key is not * cleared. * @throws DigestException If an error occurred. */ public abstract void reset() throws DigestException; /** * @return The algorithm that this digest uses. */ public abstract DigestAlgorithm getAlgorithm(); /** * Returns the length of the digest created by this digest's * digest algorithm. * * @return The size in bytes of the output of this digest. */ public int getOutputSize() { return getAlgorithm().getOutputSize(); } } jss-4.6.3/org/mozilla/jss/crypto/JSSSecureRandom.java000066400000000000000000000014121362106420000225020ustar00rootroot00000000000000/* 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.crypto; /** * An interface for secure random numbers. */ public interface JSSSecureRandom { /** * Seed the RNG with the given seed bytes. * @param seed Seed. */ public void setSeed(byte[] seed); /** * Seed the RNG with the eight bytes contained in seed. * @param seed Seed. */ public void setSeed(long seed); /** * Retrieves random bytes and stores them in the given array. * @param bytes Array to store random bytes. */ public void nextBytes(byte bytes[]); } jss-4.6.3/org/mozilla/jss/crypto/KBKDF.c000066400000000000000000000733031362106420000176650ustar00rootroot00000000000000#include #include #include #include #include #include "_jni/org_mozilla_jss_crypto_KBKDFByteArrayParam.h" #include "_jni/org_mozilla_jss_crypto_KBKDFCounterParams.h" #include "_jni/org_mozilla_jss_crypto_KBKDFDerivedKey.h" #include "_jni/org_mozilla_jss_crypto_KBKDFDKMLengthParam.h" #include "_jni/org_mozilla_jss_crypto_KBKDFFeedbackParams.h" #include "_jni/org_mozilla_jss_crypto_KBKDFIterationVariableParam.h" #include "_jni/org_mozilla_jss_crypto_KBKDFOptionalCounterParam.h" #include "_jni/org_mozilla_jss_crypto_KBKDFPipelineParams.h" #include "jssutil.h" #include "java_ids.h" #include "jss_exceptions.h" #include "pk11util.h" #include "CKAttribute.h" #include "NativeEnclosure.h" #include "StaticVoidPointer.h" #ifndef CKM_SP800_108_COUNTER_KDF #define __NOT_IMPLEMENTED__(name) JNIEXPORT void JNICALL \ name(JNIEnv *env, jobject this) \ { \ JSS_throwMsg(env, UNSUPPORTED_OPERATION_EXCEPTION, \ "KBKDF Operations aren't supported by the version of NSS that JSS was compiled against."); \ } __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFByteArrayParam_acquireNativeResourcesInternal); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFByteArrayParam_releaseNativeResourcesInternal); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFCounterParams_acquireNativeResourcesInternal); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFCounterParams_releaseNativeResourcesInternal); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFDerivedKey_acquireNativeResourcesInternal); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFDerivedKey_releaseNativeResourcesInternal); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFDKMLengthParam_acquireNativeResources); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFDKMLengthParam_releaseNativeResources); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFFeedbackParams_acquireNativeResourcesInternal); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFFeedbackParams_releaseNativeResourcesInternal); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFIterationVariableParam_acquireNativeResources); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFIterationVariableParam_releaseNativeResources); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFOptionalCounterParam_acquireNativeResources); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFOptionalCounterParam_releaseNativeResources); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFPipelineParams_acquireNativeResourcesInternal); __NOT_IMPLEMENTED__(Java_org_mozilla_jss_crypto_KBKDFPipelineParams_releaseNativeResourcesInternal); JNIEXPORT jobject JNICALL Java_org_mozilla_jss_crypto_KBKDFDerivedKey_getKeyFromHandle(JNIEnv *env, jobject this, jobject parentKey, jlong mech, jboolean temporary) { JSS_throwMsg(env, UNSUPPORTED_OPERATION_EXCEPTION, "KBKDF Operations aren't supported by the version of NSS that JSS was compiled against."); return NULL; } #else /* ===== KBKDF Data Parameter Wrappers ===== */ PRStatus kbkdf_WrapDataParam(JNIEnv *env, jobject this, jclass *this_class, void *ptr, size_t ptr_length) { jfieldID field_id = NULL; size_t param_length = sizeof(CK_PRF_DATA_PARAM); CK_PRF_DATA_PARAM_PTR param = calloc(1, param_length); jobject ptr_object = NULL; PR_ASSERT(env != NULL && this != NULL && this_class != NULL && param != NULL); if (*this_class == NULL) { *this_class = (*env)->GetObjectClass(env, this); if (*this_class == NULL) { goto failure; } } field_id = (*env)->GetFieldID(env, *this_class, "type", "J"); if (field_id == NULL) { goto failure; } param->type = (CK_PRF_DATA_TYPE)((*env)->GetLongField(env, this, field_id)); param->pValue = ptr; param->ulValueLen = ptr_length; ptr_object = JSS_PR_wrapStaticVoidPointer(env, (void **)¶m); if (ptr_object == NULL) { goto failure; } if (JSS_PR_StoreNativeEnclosure(env, this, ptr_object, param_length) != PR_SUCCESS) { goto failure; } return PR_SUCCESS; failure: memset(param, 0, param_length); free(param); return PR_FAILURE; } PRStatus kbkdf_UnwrapDataParam(JNIEnv *env, jobject this, CK_PRF_DATA_PARAM_PTR *param, size_t *param_length) { jobject ptr_object = NULL; jlong size = 0; PR_ASSERT(env != NULL && this != NULL && param != NULL && param_length != NULL); if (JSS_PR_LoadNativeEnclosure(env, this, &ptr_object, &size) != PR_SUCCESS) { goto failure; } if (JSS_PR_getStaticVoidRef(env, ptr_object, (void **)param) != PR_SUCCESS || *param == NULL) { goto failure; } *param_length = size; return PR_SUCCESS; failure: *param = NULL; *param_length = 0; return PR_FAILURE; } /* ===== KBKDF Byte Array Parameter ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFByteArrayParam_acquireNativeResourcesInternal(JNIEnv *env, jobject this) { jclass this_class = NULL; jfieldID field_id; jbyteArray this_data; uint8_t *array = NULL; size_t length = 0; PR_ASSERT(env != NULL && this != NULL); this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { return; } field_id = (*env)->GetFieldID(env, this_class, "data", "[B"); if (field_id == NULL) { return; } this_data = (*env)->GetObjectField(env, this, field_id); if (this_data == NULL) { return; } if (!JSS_FromByteArray(env, this_data, &array, &length)) { return; } /* From here on out, we need to zero and free our copy of the array before * returning from error cases. */ if (kbkdf_WrapDataParam(env, this, &this_class, array, length) != PR_SUCCESS) { goto failure; } return; failure: memset(array, 0, length); free(array); } JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFByteArrayParam_releaseNativeResourcesInternal(JNIEnv *env, jobject this) { CK_PRF_DATA_PARAM_PTR param; size_t param_size = 0; if (kbkdf_UnwrapDataParam(env, this, ¶m, ¶m_size) != PR_SUCCESS) { return; } PR_ASSERT(param_size = sizeof(CK_PRF_DATA_PARAM)); PR_ASSERT(param->type == CK_SP800_108_BYTE_ARRAY); if (param->pValue != NULL) { memset(param->pValue, 0, param->ulValueLen); } free(param->pValue); if (param != NULL) { memset(param, 0, param_size); } free(param); } /* ===== KBKDF Interation Variable Parameter ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFIterationVariableParam_acquireNativeResources(JNIEnv *env, jobject this) { jclass this_class = NULL; jfieldID field_id; jboolean littleEndian = JNI_FALSE; jlong widthInBits = 0; CK_SP800_108_COUNTER_FORMAT_PTR data = NULL; size_t data_length = 0; this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { return; } field_id = (*env)->GetFieldID(env, this_class, "littleEndian", "Z"); if (field_id == NULL) { return; } littleEndian = (*env)->GetBooleanField(env, this, field_id); field_id = (*env)->GetFieldID(env, this_class, "widthInBits", "J"); if (field_id == NULL) { return; } widthInBits = (*env)->GetLongField(env, this, field_id); if (widthInBits == 0) { return; } if (widthInBits >= 8) { data_length = sizeof(CK_SP800_108_COUNTER_FORMAT); data = calloc(1, data_length); if (data == NULL) { return; } /* From here on out we need to goto failure, freeing data on failure. */ data->bLittleEndian = (littleEndian == JNI_TRUE) ? CK_TRUE : CK_FALSE; data->ulWidthInBits = (CK_ULONG)widthInBits; } if (kbkdf_WrapDataParam(env, this, &this_class, data, data_length) != PR_SUCCESS) { goto failure; } return; failure: memset(data, 0, sizeof(CK_SP800_108_COUNTER_FORMAT)); free(data); } JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFIterationVariableParam_releaseNativeResources(JNIEnv *env, jobject this) { CK_PRF_DATA_PARAM_PTR param; size_t param_size = 0; if (kbkdf_UnwrapDataParam(env, this, ¶m, ¶m_size) != PR_SUCCESS) { return; } PR_ASSERT(param_size = sizeof(CK_PRF_DATA_PARAM)); PR_ASSERT(param->type == CK_SP800_108_ITERATION_VARIABLE); if (param->pValue != NULL) { PR_ASSERT(param->ulValueLen == sizeof(CK_SP800_108_COUNTER_FORMAT)); memset(param->pValue, 0, param->ulValueLen); free(param->pValue); } if (param != NULL) { memset(param, 0, param_size); free(param); } } /* ===== KBKDF Optional Counter Parameter ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFOptionalCounterParam_acquireNativeResources(JNIEnv *env, jobject this) { jclass this_class = NULL; jfieldID field_id; jboolean littleEndian = JNI_FALSE; jlong widthInBits = 0; CK_SP800_108_COUNTER_FORMAT_PTR data = NULL; size_t data_length = 0; this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { return; } field_id = (*env)->GetFieldID(env, this_class, "littleEndian", "Z"); if (field_id == NULL) { return; } littleEndian = (*env)->GetBooleanField(env, this, field_id); field_id = (*env)->GetFieldID(env, this_class, "widthInBits", "J"); if (field_id == NULL) { return; } widthInBits = (*env)->GetLongField(env, this, field_id); if (widthInBits == 0) { return; } data_length = sizeof(CK_SP800_108_COUNTER_FORMAT); data = calloc(1, data_length); if (data == NULL) { return; } /* From here on out we need to goto failure, freeing data on failure. */ data->bLittleEndian = (littleEndian == JNI_TRUE) ? CK_TRUE : CK_FALSE; data->ulWidthInBits = (CK_ULONG)widthInBits; if (kbkdf_WrapDataParam(env, this, &this_class, data, data_length) != PR_SUCCESS) { goto failure; } return; failure: memset(data, 0, sizeof(CK_SP800_108_COUNTER_FORMAT)); free(data); } JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFOptionalCounterParam_releaseNativeResources(JNIEnv *env, jobject this) { CK_PRF_DATA_PARAM_PTR param; size_t param_size = 0; if (kbkdf_UnwrapDataParam(env, this, ¶m, ¶m_size) != PR_SUCCESS) { return; } PR_ASSERT(param_size = sizeof(CK_PRF_DATA_PARAM)); PR_ASSERT(param->type == CK_SP800_108_OPTIONAL_COUNTER); PR_ASSERT(param->ulValueLen == sizeof(CK_SP800_108_COUNTER_FORMAT)); if (param->pValue != NULL) { memset(param->pValue, 0, param->ulValueLen); free(param->pValue); } if (param != NULL) { memset(param, 0, param_size); free(param); } } /* ===== KBKDF DKM Length Parameter ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFDKMLengthParam_acquireNativeResources(JNIEnv *env, jobject this) { jclass this_class = NULL; jfieldID field_id; jlong method = 0; jboolean littleEndian = JNI_FALSE; jlong widthInBits = 0; CK_SP800_108_DKM_LENGTH_FORMAT_PTR data = NULL; size_t data_length = 0; this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { return; } field_id = (*env)->GetFieldID(env, this_class, "lengthMethod", "J"); if (field_id == NULL) { return; } method = (*env)->GetLongField(env, this, field_id); field_id = (*env)->GetFieldID(env, this_class, "littleEndian", "Z"); if (field_id == NULL) { return; } littleEndian = (*env)->GetBooleanField(env, this, field_id); field_id = (*env)->GetFieldID(env, this_class, "widthInBits", "J"); if (field_id == NULL) { return; } widthInBits = (*env)->GetLongField(env, this, field_id); if (widthInBits == 0) { return; } data_length = sizeof(CK_SP800_108_DKM_LENGTH_FORMAT); data = calloc(1, data_length); if (data == NULL) { return; } /* From here on out we need to goto failure, freeing data on failure. */ data->dkmLengthMethod = (CK_SP800_108_DKM_LENGTH_METHOD)method; data->bLittleEndian = (littleEndian == JNI_TRUE) ? CK_TRUE : CK_FALSE; data->ulWidthInBits = (CK_ULONG)widthInBits; if (kbkdf_WrapDataParam(env, this, &this_class, data, data_length) != PR_SUCCESS) { goto failure; } return; failure: memset(data, 0, sizeof(CK_SP800_108_DKM_LENGTH_FORMAT)); free(data); } JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFDKMLengthParam_releaseNativeResources(JNIEnv *env, jobject this) { CK_PRF_DATA_PARAM_PTR param; size_t param_size = 0; if (kbkdf_UnwrapDataParam(env, this, ¶m, ¶m_size) != PR_SUCCESS) { return; } PR_ASSERT(param_size = sizeof(CK_PRF_DATA_PARAM)); PR_ASSERT(param->type == CK_SP800_108_DKM_LENGTH); PR_ASSERT(param->ulValueLen == sizeof(CK_SP800_108_DKM_LENGTH_FORMAT)); if (param->pValue != NULL) { memset(param->pValue, 0, param->ulValueLen); free(param->pValue); } if (param != NULL) { memset(param, 0, param_size); free(param); } } /* ===== KBKDF Derived Keys ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFDerivedKey_acquireNativeResourcesInternal(JNIEnv *env, jobject this) { jclass this_class = NULL; jfieldID field_id = NULL; CK_ATTRIBUTE_PTR attrs = NULL; CK_ULONG num_attrs = 0; CK_OBJECT_HANDLE_PTR key_handle = NULL; CK_DERIVED_KEY_PTR ptr = NULL; jobject ptr_obj = NULL; jobjectArray attrs_array = NULL; this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { goto failure; } field_id = (*env)->GetFieldID(env, this_class, "attrs", "[L" CK_ATTRIBUTE_CLASS_NAME ";"); if (field_id == NULL) { goto failure; } attrs_array = (*env)->GetObjectField(env, this, field_id); if (attrs_array == NULL) { goto failure; } num_attrs = (*env)->GetArrayLength(env, attrs_array); attrs = calloc(num_attrs, sizeof(CK_ATTRIBUTE)); for (size_t offset = 0; offset < num_attrs; offset++) { jobject this_attr_obj; CK_ATTRIBUTE_PTR attr; this_attr_obj = (*env)->GetObjectArrayElement(env, attrs_array, offset); if (this_attr_obj == NULL) { goto failure; } if (JSS_PK11_UnwrapAttribute(env, this_attr_obj, &attr) != PR_SUCCESS) { goto failure; } attrs[offset] = *attr; } key_handle = calloc(1, sizeof(CK_OBJECT_HANDLE)); if (key_handle == NULL) { goto failure; } ptr = calloc(1, sizeof(CK_DERIVED_KEY)); if (ptr == NULL) { goto failure; } ptr->pTemplate = attrs; ptr->ulAttributeCount = num_attrs; ptr->phKey = key_handle; ptr_obj = JSS_PR_wrapStaticVoidPointer(env, (void **)&ptr); if (ptr_obj == NULL) { goto failure; } if (JSS_PR_StoreNativeEnclosure(env, this, ptr_obj, sizeof(CK_DERIVED_KEY)) != PR_SUCCESS) { goto failure; } return; failure: if (attrs != NULL) { memset(attrs, 0, num_attrs * sizeof(CK_ATTRIBUTE)); free(attrs); } if (key_handle != NULL) { memset(key_handle, 0, sizeof(CK_OBJECT_HANDLE)); free(key_handle); } if (ptr != NULL) { memset(ptr, 0, sizeof(CK_DERIVED_KEY)); free(ptr); } } JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFDerivedKey_releaseNativeResourcesInternal(JNIEnv *env, jobject this) { jclass this_class = NULL; jfieldID field_id = NULL; jobject ptr_obj = NULL; jlong size = 0; CK_DERIVED_KEY_PTR ptr = NULL; if (JSS_PR_LoadNativeEnclosure(env, this, &ptr_obj, &size) != PR_SUCCESS) { return; } if (JSS_PR_getStaticVoidRef(env, ptr_obj, (void **)&ptr) != PR_SUCCESS || ptr == NULL) { return; } PR_ASSERT(size == sizeof(CK_DERIVED_KEY)); /* Save off the derived key, if/when possible, before freeing the * underlying CK_DERIVED_KEY struct. */ if (ptr->phKey == NULL) { goto free; } this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { goto free; } field_id = (*env)->GetFieldID(env, this_class, "handle", "J"); if (field_id == NULL) { goto free; } (*env)->SetLongField(env, this, field_id, *(ptr->phKey)); free: if (ptr->pTemplate != NULL) { memset(ptr->pTemplate, 0, ptr->ulAttributeCount * sizeof(CK_ATTRIBUTE)); free(ptr->pTemplate); } if (ptr->phKey != NULL) { memset(ptr->phKey, 0, sizeof(CK_OBJECT_HANDLE)); free(ptr->phKey); } memset(ptr, 0, sizeof(CK_DERIVED_KEY)); free(ptr); } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_crypto_KBKDFDerivedKey_getKeyFromHandle(JNIEnv *env, jobject this, jobject parentKey, jlong mech, jboolean temporary) { jclass this_class = NULL; jfieldID field_id = NULL; CK_OBJECT_HANDLE handle = 0; PK11SymKey *parent = NULL; PK11SlotInfo *slot = NULL; PK11SymKey *key = NULL; PRBool is_perm = (temporary == JNI_TRUE) ? PR_FALSE : PR_TRUE; this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { return NULL; } field_id = (*env)->GetFieldID(env, this_class, "handle", "J"); if (field_id == NULL) { return NULL; } handle = (CK_OBJECT_HANDLE)((*env)->GetLongField(env, this, field_id)); if (JSS_PK11_getSymKeyPtr(env, parentKey, &parent) != PR_SUCCESS || parent == NULL) { return NULL; } slot = PK11_GetSlotFromKey(parent); PK11_FreeSlot(slot); key = PK11_SymKeyFromHandle(slot, parent, PK11_OriginDerive, mech, handle, is_perm, NULL); return JSS_PK11_wrapSymKey(env, &key); } /* ===== KBKDF Parameter Helpers ===== */ PRStatus kbkdf_GetPRFType(JNIEnv *env, jobject this, jclass this_class, CK_SP800_108_PRF_TYPE *prf_type) { jfieldID field_id = NULL; field_id = (*env)->GetFieldID(env, this_class, "prf", "J"); if (field_id == NULL) { return PR_FAILURE; } *prf_type = (*env)->GetLongField(env, this, field_id); return PR_SUCCESS; } PRStatus kbkdf_GetDataParameters(JNIEnv *env, jobject this, jclass this_class, CK_ULONG *num_data_params, CK_PRF_DATA_PARAM_PTR *data_params) { jfieldID field_id = NULL; jobjectArray params_array = NULL; field_id = (*env)->GetFieldID(env, this_class, "params", "[L" KBKDF_DATA_PARAMETER_CLASS_NAME ";"); if (field_id == NULL) { return PR_FAILURE; } params_array = (*env)->GetObjectField(env, this, field_id); if (params_array == NULL) { return PR_FAILURE; } *num_data_params = (*env)->GetArrayLength(env, params_array); *data_params = calloc(*num_data_params, sizeof(CK_PRF_DATA_PARAM)); for (size_t offset = 0; offset < *num_data_params; offset++) { jobject this_param_object = NULL; CK_PRF_DATA_PARAM_PTR this_param = NULL; size_t this_param_size = 0; this_param_object = (*env)->GetObjectArrayElement(env, params_array, offset); if (this_param_object == NULL) { return PR_FAILURE; } if (kbkdf_UnwrapDataParam(env, this_param_object, &this_param, &this_param_size) != PR_SUCCESS) { return PR_FAILURE; } PR_ASSERT(this_param_size == sizeof(CK_PRF_DATA_PARAM)); (*data_params)[offset] = *this_param; } return PR_SUCCESS; } PRStatus kbkdf_GetAdditionalDerivedKeys(JNIEnv *env, jobject this, jclass this_class, CK_ULONG *num_additional_keys, CK_DERIVED_KEY_PTR *additional_keys) { jfieldID field_id = NULL; jobjectArray keys_array = NULL; field_id = (*env)->GetFieldID(env, this_class, "additional_keys", "[L" KBKDF_DERIVED_KEY_CLASS_NAME ";"); if (field_id == NULL) { return PR_FAILURE; } keys_array = (*env)->GetObjectField(env, this, field_id); if (keys_array == NULL) { *num_additional_keys = 0; *additional_keys = NULL; return PR_SUCCESS; } *num_additional_keys = (*env)->GetArrayLength(env, keys_array); *additional_keys = calloc(*num_additional_keys, sizeof(CK_DERIVED_KEY)); for (size_t offset = 0; offset < *num_additional_keys; offset++) { jobject this_key_object = NULL; CK_DERIVED_KEY_PTR this_key = NULL; jobject this_key_ptr = NULL; jlong this_key_size = 0; this_key_object = (*env)->GetObjectArrayElement(env, keys_array, offset); if (this_key_object == NULL) { return PR_FAILURE; } if (JSS_PR_LoadNativeEnclosure(env, this_key_object, &this_key_ptr, &this_key_size) != PR_SUCCESS) { return PR_FAILURE; } if (JSS_PR_getStaticVoidRef(env, this_key_ptr, (void **)&this_key) != PR_SUCCESS || this_key == NULL) { return PR_FAILURE; } PR_ASSERT(this_key_size == sizeof(CK_DERIVED_KEY)); (*additional_keys)[offset] = *this_key; } return PR_SUCCESS; } PRStatus kbkdf_GetInitialValue(JNIEnv *env, jobject this, jclass this_class, CK_ULONG *initial_value_length, CK_BYTE_PTR *initial_value) { jfieldID field_id = NULL; jobjectArray iv_array = NULL; field_id = (*env)->GetFieldID(env, this_class, "initial_value", "[B"); if (field_id == NULL) { return PR_FAILURE; } iv_array = (*env)->GetObjectField(env, this, field_id); if (iv_array == NULL) { *initial_value_length = 0; *initial_value = NULL; return PR_SUCCESS; } if (!JSS_FromByteArray(env, iv_array, initial_value, initial_value_length)) { return PR_FAILURE; } return PR_SUCCESS; } /* ===== KBKDF Counter Parameters ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFCounterParams_acquireNativeResourcesInternal(JNIEnv *env, jobject this) { jclass this_class = NULL; CK_SP800_108_PRF_TYPE prf_type = CKM_INVALID_MECHANISM; CK_ULONG num_data_params = 0; CK_PRF_DATA_PARAM_PTR data_params = NULL; CK_ULONG num_additional_keys = 0; CK_DERIVED_KEY_PTR additional_keys = NULL; CK_SP800_108_KDF_PARAMS_PTR kdf_params = NULL; jobject params_obj; this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { return; } /* Handle PRF Type. */ if (kbkdf_GetPRFType(env, this, this_class, &prf_type) != PR_SUCCESS) { goto failure; } /* Handle Data Parameters. */ if (kbkdf_GetDataParameters(env, this, this_class, &num_data_params, &data_params) != PR_SUCCESS) { goto failure; } /* Handle Additional Derived Keys. */ if (kbkdf_GetAdditionalDerivedKeys(env, this, this_class, &num_additional_keys, &additional_keys) != PR_SUCCESS) { goto failure; } /* Place the values in the actual KDF params struct. */ kdf_params = calloc(1, sizeof(CK_SP800_108_KDF_PARAMS)); kdf_params->prfType = prf_type; kdf_params->ulNumberOfDataParams = num_data_params; kdf_params->pDataParams = data_params; kdf_params->ulAdditionalDerivedKeys = num_additional_keys; kdf_params->pAdditionalDerivedKeys = additional_keys; /* Place it back into this NativeEnclosure. */ params_obj = JSS_PR_wrapStaticVoidPointer(env, (void **)&kdf_params); if (params_obj == NULL) { goto failure; } if (JSS_PR_StoreNativeEnclosure(env, this, params_obj, sizeof(CK_SP800_108_KDF_PARAMS)) != PR_SUCCESS) { goto failure; } return; failure: if (data_params != NULL) { memset(data_params, 0, sizeof(CK_PRF_DATA_PARAM) * num_data_params); free(data_params); } if (additional_keys != NULL) { memset(additional_keys, 0, sizeof(CK_DERIVED_KEY) * num_additional_keys); free(additional_keys); } if (kdf_params != NULL) { memset(kdf_params, 0, sizeof(CK_SP800_108_KDF_PARAMS)); free(kdf_params); } } JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFCounterParams_releaseNativeResourcesInternal(JNIEnv *env, jobject this) { jobject ptr_object = NULL; CK_SP800_108_KDF_PARAMS_PTR kdf_params = NULL; jlong params_length; PR_ASSERT(env != NULL && this != NULL); if (JSS_PR_LoadNativeEnclosure(env, this, &ptr_object, ¶ms_length) != PR_SUCCESS) { return; } if (JSS_PR_getStaticVoidRef(env, ptr_object, (void **)&kdf_params) != PR_SUCCESS || kdf_params == NULL) { return; } PR_ASSERT(params_length == sizeof(CK_SP800_108_KDF_PARAMS)); if (kdf_params->ulNumberOfDataParams != 0 && kdf_params->pDataParams != NULL) { memset(kdf_params->pDataParams, 0, sizeof(CK_PRF_DATA_PARAM) * kdf_params->ulNumberOfDataParams); free(kdf_params->pDataParams); } if (kdf_params->ulAdditionalDerivedKeys != 0 && kdf_params->pAdditionalDerivedKeys != NULL) { memset(kdf_params->pAdditionalDerivedKeys, 0, sizeof(CK_DERIVED_KEY) * kdf_params->ulAdditionalDerivedKeys); free(kdf_params->pAdditionalDerivedKeys); } memset(kdf_params, 0, params_length); free(kdf_params); } /* ===== KBKDF Feedback Parameters ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFFeedbackParams_acquireNativeResourcesInternal(JNIEnv *env, jobject this) { jclass this_class = NULL; CK_SP800_108_PRF_TYPE prf_type = CKM_INVALID_MECHANISM; CK_ULONG num_data_params = 0; CK_PRF_DATA_PARAM_PTR data_params = NULL; CK_ULONG num_additional_keys = 0; CK_DERIVED_KEY_PTR additional_keys = NULL; CK_ULONG initial_value_length = 0; CK_BYTE_PTR initial_value = NULL; CK_SP800_108_FEEDBACK_KDF_PARAMS_PTR kdf_params = NULL; jobject params_obj; this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { return; } /* Handle PRF Type. */ if (kbkdf_GetPRFType(env, this, this_class, &prf_type) != PR_SUCCESS) { goto failure; } /* Handle Data Parameters. */ if (kbkdf_GetDataParameters(env, this, this_class, &num_data_params, &data_params) != PR_SUCCESS) { goto failure; } /* Handle Additional Derived Keys. */ if (kbkdf_GetAdditionalDerivedKeys(env, this, this_class, &num_additional_keys, &additional_keys) != PR_SUCCESS) { goto failure; } /* Handle Initial Value. */ if (kbkdf_GetInitialValue(env, this, this_class, &initial_value_length, &initial_value) != PR_SUCCESS) { goto failure; } /* Place the values in the actual KDF params struct. */ kdf_params = calloc(1, sizeof(CK_SP800_108_FEEDBACK_KDF_PARAMS)); kdf_params->prfType = prf_type; kdf_params->ulNumberOfDataParams = num_data_params; kdf_params->pDataParams = data_params; kdf_params->ulAdditionalDerivedKeys = num_additional_keys; kdf_params->pAdditionalDerivedKeys = additional_keys; kdf_params->ulIVLen = initial_value_length; kdf_params->pIV = initial_value; /* Place it back into this NativeEnclosure. */ params_obj = JSS_PR_wrapStaticVoidPointer(env, (void **)&kdf_params); if (params_obj == NULL) { goto failure; } if (JSS_PR_StoreNativeEnclosure(env, this, params_obj, sizeof(CK_SP800_108_FEEDBACK_KDF_PARAMS)) != PR_SUCCESS) { goto failure; } return; failure: if (data_params != NULL) { memset(data_params, 0, sizeof(CK_PRF_DATA_PARAM) * num_data_params); free(data_params); } if (additional_keys != NULL) { memset(additional_keys, 0, sizeof(CK_DERIVED_KEY) * num_additional_keys); free(additional_keys); } if (initial_value != NULL) { memset(initial_value, 0, sizeof(CK_BYTE) * initial_value_length); free(initial_value); } if (kdf_params != NULL) { memset(kdf_params, 0, sizeof(CK_SP800_108_FEEDBACK_KDF_PARAMS)); free(kdf_params); } } JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFFeedbackParams_releaseNativeResourcesInternal(JNIEnv *env, jobject this) { jobject ptr_object = NULL; CK_SP800_108_FEEDBACK_KDF_PARAMS_PTR kdf_params = NULL; jlong params_length; PR_ASSERT(env != NULL && this != NULL); if (JSS_PR_LoadNativeEnclosure(env, this, &ptr_object, ¶ms_length) != PR_SUCCESS) { return; } if (JSS_PR_getStaticVoidRef(env, ptr_object, (void **)&kdf_params) != PR_SUCCESS || kdf_params == NULL) { return; } PR_ASSERT(params_length == sizeof(CK_SP800_108_FEEDBACK_KDF_PARAMS)); if (kdf_params->ulNumberOfDataParams != 0 && kdf_params->pDataParams != NULL) { memset(kdf_params->pDataParams, 0, sizeof(CK_PRF_DATA_PARAM) * kdf_params->ulNumberOfDataParams); free(kdf_params->pDataParams); } if (kdf_params->ulIVLen != 0 && kdf_params->pIV != NULL) { memset(kdf_params->pIV, 0, sizeof(CK_BYTE) * kdf_params->ulIVLen); free(kdf_params->pIV); } if (kdf_params->ulAdditionalDerivedKeys != 0 && kdf_params->pAdditionalDerivedKeys != NULL) { memset(kdf_params->pAdditionalDerivedKeys, 0, sizeof(CK_DERIVED_KEY) * kdf_params->ulAdditionalDerivedKeys); free(kdf_params->pAdditionalDerivedKeys); } memset(kdf_params, 0, params_length); free(kdf_params); } /* ===== KBKDF Double Pipeline Parameters ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFPipelineParams_acquireNativeResourcesInternal(JNIEnv *env, jobject this) { /* Counter and Double Pipeline modes have the same parameter struct. * This allows us to implement this call via the corresponding call for * Counter mode. */ Java_org_mozilla_jss_crypto_KBKDFCounterParams_acquireNativeResourcesInternal(env, this); } JNIEXPORT void JNICALL Java_org_mozilla_jss_crypto_KBKDFPipelineParams_releaseNativeResourcesInternal(JNIEnv *env, jobject this) { /* Counter and Double Pipeline modes have the same parameter struct. * This allows us to implement this call via the corresponding call for * Counter mode. */ Java_org_mozilla_jss_crypto_KBKDFCounterParams_releaseNativeResourcesInternal(env, this); } #endif jss-4.6.3/org/mozilla/jss/crypto/KBKDFByteArrayParam.java000066400000000000000000000040611362106420000231630ustar00rootroot00000000000000package org.mozilla.jss.crypto; import java.util.Arrays; import org.mozilla.jss.util.NativeEnclosure; import org.mozilla.jss.pkcs11.PKCS11Constants; /** * A KBKDF Byte Array Parameter is a type of KBKDF Data Parameter that * contains a single byte array that gets passed to the KBKDF to be inserted * into the PRF input stream. */ public class KBKDFByteArrayParam extends KBKDFDataParameter { private byte[] data; public KBKDFByteArrayParam() { super(PKCS11Constants.CK_SP800_108_BYTE_ARRAY); } public KBKDFByteArrayParam(byte[] data) throws IllegalArgumentException { this(); setByteArray(data); } public void setByteArray(byte[] data) throws IllegalArgumentException { if (data == null) { throw new IllegalArgumentException("Expected non-null byte array!"); } this.data = Arrays.copyOf(data, data.length); } /** * Zero out the copied contents of the byte array. * * Call this method when the contents of this byte array parameter are * sensitive and they're done being used. Note that this isn't called * during close() as a given byte array parameter may be used multiple * times in different KBKDF calls. */ public void zeroByteArray() { if (data == null) { return; } for (int i = 0; i < data.length; i++) { data[i] = 0; } } protected void acquireNativeResources() throws Exception { if (data == null || data.length == 0) { String msg = "Expected non-null byte array in "; msg += "KBKDFByteArrayParam but was null! Call setByteArray "; msg += "to provide a byte array."; throw new RuntimeException(msg); } acquireNativeResourcesInternal(); } protected void releaseNativeResources() throws Exception { releaseNativeResourcesInternal(); } private native void acquireNativeResourcesInternal() throws Exception; private native void releaseNativeResourcesInternal() throws Exception; } jss-4.6.3/org/mozilla/jss/crypto/KBKDFCounterParams.java000066400000000000000000000062001362106420000230600ustar00rootroot00000000000000package org.mozilla.jss.crypto; import java.security.InvalidKeyException; import javax.crypto.SecretKey; import org.mozilla.jss.pkcs11.PKCS11Constants; public class KBKDFCounterParams extends KBKDFParameterSpec { public KBKDFCounterParams() {} protected void validateParameters() throws IllegalArgumentException { if (prfKey == null) { String msg = "Required parameter KDF key was never set."; throw new IllegalArgumentException(msg); } if (prf != PKCS11Constants.CKM_SHA_1_HMAC && prf != PKCS11Constants.CKM_SHA256_HMAC && prf != PKCS11Constants.CKM_SHA384_HMAC && prf != PKCS11Constants.CKM_SHA512_HMAC && prf != PKCS11Constants.CKM_AES_CMAC) { String msg = "Expected Pseudo-Random Function to be SHA1-HMAC, "; msg += "SHA2-HMAC, or AES-CMAC, but got unknown PKCS#11 "; msg += "constant: " + prf; throw new IllegalArgumentException(msg); } if (params == null || params.length == 0) { String msg = "Expected non-null, non-zero length array of KDF "; msg += "parameters."; throw new IllegalArgumentException(msg); } int index = 0; for (KBKDFDataParameter param : params) { if (param instanceof KBKDFOptionalCounterParam) { String msg = "Got unexpected data parameter at index " + index; msg += ": KBKDF Optional Counter Parameter is forbidden from "; msg += "use with Counter mode KBKDF."; throw new IllegalArgumentException(msg); } if (param instanceof KBKDFIterationVariableParam) { KBKDFIterationVariableParam kivp = (KBKDFIterationVariableParam)param; if (kivp.widthInBits == -1) { String msg = "Got unexpected data in KBKDF Iteration "; msg += "Variable Parameter at index " + index + ": "; msg += "Expected valid counter specification, but got "; msg += "widthInBits of -1. Call setCounterSpec(...) "; msg += "before using this parameter."; throw new IllegalArgumentException(msg); } } if (param instanceof KBKDFDKMLengthParam) { KBKDFDKMLengthParam kdlp = (KBKDFDKMLengthParam)param; if (kdlp.widthInBits == 0) { String msg = "Got unexpected data in KBKDF DKM Length "; msg += "Parameter at index " + index + ": Expected valid "; msg += "length specification, but got widthInBits of 0. "; msg += "Call setLngthSpec(...) before using this "; msg += "parameter."; throw new IllegalArgumentException(msg); } } // Nothing to validate for byte array parameters. index += 1; } } protected native void acquireNativeResourcesInternal() throws Exception; protected native void releaseNativeResourcesInternal() throws Exception; } jss-4.6.3/org/mozilla/jss/crypto/KBKDFDKMLengthParam.java000066400000000000000000000031011362106420000230300ustar00rootroot00000000000000package org.mozilla.jss.crypto; import java.util.Arrays; import org.mozilla.jss.pkcs11.PKCS11Constants; import org.mozilla.jss.util.NativeEnclosure; /** * A KBKDF Optional Counter Parameter is a type of KBKDF Data Parameter that * describes the optional counter variable for Feedback and Pipeline KBKDFs. * * Note that this parameter is illegal in Counter Mode. */ public class KBKDFDKMLengthParam extends KBKDFDataParameter { protected long lengthMethod = 1; protected boolean littleEndian = false; protected long widthInBits = 0; public KBKDFDKMLengthParam() { super(PKCS11Constants.CK_SP800_108_DKM_LENGTH); } public KBKDFDKMLengthParam(long lengthMethod, boolean littleEndian, long widthInBits) throws IllegalArgumentException { this(); setLengthSpec(lengthMethod, littleEndian, widthInBits); } public void setLengthSpec(long lengthMethod, boolean littleEndian, long widthInBits) throws IllegalArgumentException { if (widthInBits < 8 || widthInBits > 64) { throw new IllegalArgumentException("Expected to have width between 8 and 64, but was " + widthInBits); } if ((widthInBits % 8) != 0) { throw new IllegalArgumentException("Expected width to be an even number of bytes, but was " + widthInBits); } this.lengthMethod = lengthMethod; this.littleEndian = littleEndian; this.widthInBits = widthInBits; } protected native void acquireNativeResources() throws Exception; protected native void releaseNativeResources() throws Exception; } jss-4.6.3/org/mozilla/jss/crypto/KBKDFDataParameter.java000066400000000000000000000006341362106420000230140ustar00rootroot00000000000000package org.mozilla.jss.crypto; import org.mozilla.jss.util.NativeEnclosure; /** * A KBKDF Data Parameter is a structure of type CK_PRF_DATA_PARAM, with * three members: a type, a pointer to its data, and the size of the data * field. */ public abstract class KBKDFDataParameter extends NativeEnclosure { public long type; public KBKDFDataParameter(long type) { this.type = type; } } jss-4.6.3/org/mozilla/jss/crypto/KBKDFDerivedKey.java000066400000000000000000000070541362106420000223400ustar00rootroot00000000000000package org.mozilla.jss.crypto; import java.lang.IllegalArgumentException; import java.security.InvalidKeyException; import java.util.Arrays; import java.util.ArrayList; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import org.mozilla.jss.pkcs11.attrs.CKAttribute; import org.mozilla.jss.util.NativeEnclosure; /** * Class for supporting additional derived keys from PKCS#11 v3.0's * SP800-108 KBKDF implementation. */ public class KBKDFDerivedKey extends NativeEnclosure { private CKAttribute[] attrs; private long handle; public KBKDFDerivedKey() {} public KBKDFDerivedKey(CKAttribute[] attrs) throws IllegalArgumentException { setAttributes(attrs); } public void setAttributes(CKAttribute[] attrs) throws IllegalArgumentException { if (attrs == null) { String msg = "Expected populated array of CKAttributes, but "; msg += "was null."; throw new IllegalArgumentException(msg); } this.attrs = attrs; } public void addAttribute(CKAttribute attr) throws IllegalArgumentException { if (attr == null) { String msg = "Expected non-null CKAttribute, but was null."; throw new IllegalArgumentException(msg); } ArrayList ck_attrs; if (attrs == null) { ck_attrs = new ArrayList(1); } else { ck_attrs = new ArrayList(Arrays.asList(attrs)); } ck_attrs.add(attr); this.attrs = ck_attrs.toArray(new CKAttribute[ck_attrs.size()]); } protected void acquireNativeResources() throws Exception { if (attrs == null) { String msg = "Expected non-null attributes when trying to "; msg += "acquire native resources. Call setAttributes(...) "; msg += "or addAttribute(...) before calling open()."; throw new IllegalArgumentException(msg); } for (CKAttribute attr : attrs) { attr.open(); } acquireNativeResourcesInternal(); } protected void releaseNativeResources() throws Exception { if (attrs != null) { for (CKAttribute attr : attrs) { attr.close(); } } releaseNativeResourcesInternal(); } public SecretKey getKey(SecretKey parent, long mech, boolean temporary) throws Exception { SecretKeyFactory skf = SecretKeyFactory.getInstance(parent.getAlgorithm(), "Mozilla-JSS"); SecretKey translated = skf.translateKey(parent); SymmetricKey unwrapped = null; if (translated instanceof SymmetricKey) { unwrapped = (SymmetricKey)translated; } else if (translated instanceof SecretKeyFacade) { unwrapped = ((SecretKeyFacade)translated).key; } else { String msg = "Expected key to become an instance of "; msg += "org.mozilla.jss.crypto.SymmetricKey or "; msg += "org.mozilla.jss.crypto.SecretKeyFacade after "; msg += "translation, but got: "; msg += translated.getClass().getName(); throw new InvalidKeyException(msg); } SymmetricKey key = getKeyFromHandle(unwrapped, mech, temporary); return new SecretKeyFacade(key); } private native SymmetricKey getKeyFromHandle(SymmetricKey parentKey, long mech, boolean temporary) throws Exception; protected native void acquireNativeResourcesInternal() throws Exception; protected native void releaseNativeResourcesInternal() throws Exception; } jss-4.6.3/org/mozilla/jss/crypto/KBKDFFeedbackParams.java000066400000000000000000000105751362106420000231370ustar00rootroot00000000000000package org.mozilla.jss.crypto; import java.util.Arrays; import java.security.InvalidKeyException; import javax.crypto.SecretKey; import org.mozilla.jss.pkcs11.PKCS11Constants; public class KBKDFFeedbackParams extends KBKDFParameterSpec { private byte[] initial_value; public KBKDFFeedbackParams() {} public void setInitialValue(byte[] iv) throws IllegalArgumentException { if (iv == null) { String msg = "Expected non-null initial value!"; throw new IllegalArgumentException(msg); } this.initial_value = Arrays.copyOf(iv, iv.length); } /** * Zero out the copiend contents of the initial value. * * Call this method when the contents of the initial value are sensitive * and they're done being used. Note that this isn't called during * close() as a given KBKDFParameterSpec instance may be reused, updating * relevant parameters between calls. */ public void zeroInitialValue() { if (initial_value == null) { return; } for (int i = 0; i < initial_value.length; i++) { initial_value[i] = 0; } } protected void validateParameters() throws IllegalArgumentException { if (prfKey == null) { String msg = "Required parameter KDF key was never set."; throw new IllegalArgumentException(msg); } if (prf != PKCS11Constants.CKM_SHA_1_HMAC && prf != PKCS11Constants.CKM_SHA256_HMAC && prf != PKCS11Constants.CKM_SHA384_HMAC && prf != PKCS11Constants.CKM_SHA512_HMAC && prf != PKCS11Constants.CKM_AES_CMAC) { String msg = "Expected Pseudo-Random Function to be SHA1-HMAC, "; msg += "SHA2-HMAC, or AES-CMAC, but got unknown PKCS#11 "; msg += "constant: " + prf; throw new IllegalArgumentException(msg); } if (params == null || params.length == 0) { String msg = "Expected non-null, non-zero length array of KDF "; msg += "parameters."; throw new IllegalArgumentException(msg); } int index = 0; for (KBKDFDataParameter param : params) { if (param instanceof KBKDFOptionalCounterParam) { KBKDFOptionalCounterParam kocp = (KBKDFOptionalCounterParam)param; if (kocp.widthInBits == -1) { String msg = "Got unexpected data in KBKDF Optional "; msg += "Counter Parameter at index " + index + ": "; msg += "Expected valid counter specification, but got "; msg += "widthInBits of -1. Call setCounterSpec(...) "; msg += "before using this parameter."; throw new IllegalArgumentException(msg); } } if (param instanceof KBKDFIterationVariableParam) { KBKDFIterationVariableParam kivp = (KBKDFIterationVariableParam)param; if (kivp.widthInBits != -1) { String msg = "Got unexpected data in KBKDF Iteration "; msg += "Variable Parameter at index " + index + ": "; msg += "Expected empty counter specification, but got "; msg += "widthInBits of " + kivp.widthInBits + ". Call "; msg += "the no argument constructor instead to use this "; msg += "parameter."; throw new IllegalArgumentException(msg); } } if (param instanceof KBKDFDKMLengthParam) { KBKDFDKMLengthParam kdlp = (KBKDFDKMLengthParam)param; if (kdlp.widthInBits == 0) { String msg = "Got unexpected data in KBKDF DKM Length "; msg += "Parameter at index " + index + ": Expected valid "; msg += "length specification, but got widthInBits of 0. "; msg += "Call setLngthSpec(...) before using this "; msg += "parameter."; throw new IllegalArgumentException(msg); } } // Nothing to validate for byte array parameters. index += 1; } } protected native void acquireNativeResourcesInternal() throws Exception; protected native void releaseNativeResourcesInternal() throws Exception; } jss-4.6.3/org/mozilla/jss/crypto/KBKDFIterationVariableParam.java000066400000000000000000000035251362106420000246710ustar00rootroot00000000000000package org.mozilla.jss.crypto; import java.util.Arrays; import org.mozilla.jss.pkcs11.PKCS11Constants; import org.mozilla.jss.util.NativeEnclosure; /** * A KBKDF Iteration Variable Parameter is a type of KBKDF Data Parameter that * either references the counter variable or otherwise is a pointer to the * output of the previous PRF invocation. * * Note that in when used with Counter Mode KBKDF, this parameter must be * initialized with the two argument constructor. In other KBKDF modes, * in particular, Feedback and Pipeline modes, this must be initialized with * the no argument constructor. To add an optional counter to the PRF input * stream under Feedback and Pipeline modes, use KBKDFOptionalCounterParam * instead. */ public class KBKDFIterationVariableParam extends KBKDFDataParameter { protected boolean littleEndian = false; protected long widthInBits = -1; public KBKDFIterationVariableParam() { super(PKCS11Constants.CK_SP800_108_ITERATION_VARIABLE); } public KBKDFIterationVariableParam(boolean littleEndian, long widthInBits) throws IllegalArgumentException { this(); setCounterSpec(littleEndian, widthInBits); } public void setCounterSpec(boolean littleEndian, long widthInBits) throws IllegalArgumentException { if (widthInBits < 8 || widthInBits > 64) { throw new IllegalArgumentException("Expected to have width between 8 and 64, but was " + widthInBits); } if ((widthInBits % 8) != 0) { throw new IllegalArgumentException("Expected width to be an even number of bytes, but was " + widthInBits); } this.littleEndian = littleEndian; this.widthInBits = widthInBits; } protected native void acquireNativeResources() throws Exception; protected native void releaseNativeResources() throws Exception; } jss-4.6.3/org/mozilla/jss/crypto/KBKDFOptionalCounterParam.java000066400000000000000000000027301362106420000244070ustar00rootroot00000000000000package org.mozilla.jss.crypto; import java.util.Arrays; import org.mozilla.jss.pkcs11.PKCS11Constants; import org.mozilla.jss.util.NativeEnclosure; /** * A KBKDF Optional Counter Parameter is a type of KBKDF Data Parameter that * describes the optional counter variable for Feedback and Pipeline KBKDFs. * * Note that this parameter is illegal in Counter Mode. */ public class KBKDFOptionalCounterParam extends KBKDFDataParameter { protected boolean littleEndian = false; protected long widthInBits = 0; public KBKDFOptionalCounterParam() { super(PKCS11Constants.CK_SP800_108_OPTIONAL_COUNTER); } public KBKDFOptionalCounterParam(boolean littleEndian, long widthInBits) throws IllegalArgumentException { this(); setCounterSpec(littleEndian, widthInBits); } public void setCounterSpec(boolean littleEndian, long widthInBits) throws IllegalArgumentException { if (widthInBits < 8 || widthInBits > 64) { throw new IllegalArgumentException("Expected to have width between 8 and 64, but was " + widthInBits); } if ((widthInBits % 8) != 0) { throw new IllegalArgumentException("Expected width to be an even number of bytes, but was " + widthInBits); } this.littleEndian = littleEndian; this.widthInBits = widthInBits; } protected native void acquireNativeResources() throws Exception; protected native void releaseNativeResources() throws Exception; } jss-4.6.3/org/mozilla/jss/crypto/KBKDFParameterSpec.java000066400000000000000000000174221362106420000230400ustar00rootroot00000000000000package org.mozilla.jss.crypto; import java.security.InvalidKeyException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import java.util.Arrays; import java.util.ArrayList; import org.mozilla.jss.pkcs11.PK11SymKey; import org.mozilla.jss.util.NativeEnclosure; public abstract class KBKDFParameterSpec extends NativeEnclosure implements AlgorithmParameterSpec, KeySpec { /* Need access from outside; no real protections in setters outside * of additional input types. */ public PK11SymKey prfKey; public long derivedKeyAlgorithm; public int keySize; protected long prf; protected KBKDFDataParameter[] params; protected KBKDFDerivedKey[] additional_keys; /** * Set the underlying pseudo-random function from a PKCS11Algorithm enum * value. */ public void setPRF(PKCS11Algorithm prf) throws IllegalArgumentException { this.prf = prf.getValue(); } /** * Set the underlying pseudo-random function from a DigestAlgorithm * (HMACAlgorithm or CMACAlgorithm) instance. */ public void setPRF(DigestAlgorithm prf) throws IllegalArgumentException { if (!(prf instanceof HMACAlgorithm) && !(prf instanceof CMACAlgorithm)) { String msg = "Unknown pseudo-random function type: expected "; msg += "either HMAC or CMAC algorithms. Got: "; msg += prf.getClass().getName(); throw new IllegalArgumentException(msg); } this.prf = prf.getEnum().getValue(); } /** * Set the underlying pseudo-random function from a PKCS#11 constant; * see org.mozilla.jss.pkcs11.PKCS11Constants for permitted values. */ public void setPRF(long prf) { this.prf = prf; } /** * Set the base key used with the underlying PRF. * * Must be importable to a JSS SymmetricKey or SecretKeyFacade. */ public void setPRFKey(SecretKey key) throws InvalidKeyException { if (key instanceof PK11SymKey) { prfKey = (PK11SymKey)key; return; } if (key instanceof SecretKeyFacade) { setPRFKey(((SecretKeyFacade)key).key); return; } try { SecretKeyFactory skf = SecretKeyFactory.getInstance(key.getAlgorithm(), "Mozilla-JSS"); SecretKey translated = skf.translateKey(key); if (translated instanceof SymmetricKey) { setPRFKey(translated); return; } if (translated instanceof SecretKeyFacade) { setPRFKey(((SecretKeyFacade)translated).key); return; } String msg = "Expected key to become an instance of "; msg += "org.mozilla.jss.crypto.SymmetricKey or "; msg += "org.mozilla.jss.crypto.SecretKeyFacade after "; msg += "translation, but got: "; msg += translated.getClass().getName(); throw new InvalidKeyException(msg); } catch (Exception excep) { throw new InvalidKeyException("Unable to import key: " + excep.getMessage(), excep); } } /** * Set the algorithm for the derived key from a PKCS11Algorithm enum value. */ public void setDerivedKeyAlgorithm(PKCS11Algorithm algo) throws IllegalArgumentException { if (algo == null) { String msg = "Expected non-null PKCS11Algorithm value, but was null."; throw new IllegalArgumentException(msg); } derivedKeyAlgorithm = algo.getValue(); } /** * Sets the algorithm for the derived key from a PKCS#11 value; see * org.mozilla.jss.pkcs11.PKCS11Constants for constant values. */ public void setDerivedKeyAlgorithm(long algo) throws IllegalArgumentException { derivedKeyAlgorithm = algo; } /** * Set the size of the derived key. * * If zero, will attempt to use the derived key algorithm's default key * size. */ public void setKeySize(int keySize) { this.keySize = keySize; } /** * Set parameters for key derivation. * * This overwrites all existing parameters. Note that params cannot be * NULL. */ public void setParameters(KBKDFDataParameter[] params) throws IllegalArgumentException { if (params == null) { String msg = "Expected populated array of KBKDFDataParameters, "; msg += "but was null."; throw new IllegalArgumentException(msg); } this.params = params; } /** * Appends (to the end) a new data parameter. */ public void addParameter(KBKDFDataParameter param) throws IllegalArgumentException { if (param == null) { String msg = "Expected non-null instance of KBKDFDataParameters, "; msg += "but was null."; throw new IllegalArgumentException(msg); } ArrayList data_params; if (this.params == null) { data_params = new ArrayList(1); } else { data_params = new ArrayList(Arrays.asList(this.params)); } data_params.add(param); this.params = data_params.toArray(new KBKDFDataParameter[data_params.size()]); } /** * Set an array of additional derived keys. */ public void setAdditionalDerivedKeys(KBKDFDerivedKey[] additional_keys) throws IllegalArgumentException { if (additional_keys == null) { String msg = "Expected populated array of KBKDFDerivedKey, "; msg += "but was null."; throw new IllegalArgumentException(msg); } this.additional_keys = additional_keys; } /** * Append (to the end) a new derived key. */ public void addAdditionalDerivedKey(KBKDFDerivedKey derived_key) throws IllegalArgumentException { if (derived_key == null) { String msg = "Expected non-null instance of KBKDFDerivedKey, "; msg += "but was null."; throw new IllegalArgumentException(msg); } ArrayList keys; if (additional_keys == null) { keys = new ArrayList(1); } else { keys = new ArrayList(Arrays.asList(additional_keys)); } keys.add(derived_key); additional_keys = keys.toArray(new KBKDFDerivedKey[keys.size()]); } protected void acquireNativeResources() throws Exception { validateParameters(); if (params != null) { for (KBKDFDataParameter param : params) { param.open(); } } if (additional_keys != null) { for (KBKDFDerivedKey key : additional_keys) { key.open(); } } acquireNativeResourcesInternal(); } protected void releaseNativeResources() throws Exception { if (additional_keys != null) { for (KBKDFDerivedKey key : additional_keys) { key.close(); } } if (params != null) { for (KBKDFDataParameter param : params) { param.close(); } } releaseNativeResourcesInternal(); } protected abstract void acquireNativeResourcesInternal() throws Exception; protected abstract void releaseNativeResourcesInternal() throws Exception; /** * Validate all class members prior to acquiring native resources. * * This is implemented by the derived KBKDF modes in an effort to give * useful exceptions before derivation, instead of vague errors during * derivation. */ protected abstract void validateParameters() throws IllegalArgumentException; } jss-4.6.3/org/mozilla/jss/crypto/KBKDFPipelineParams.java000066400000000000000000000067501362106420000232200ustar00rootroot00000000000000package org.mozilla.jss.crypto; import java.security.InvalidKeyException; import javax.crypto.SecretKey; import org.mozilla.jss.pkcs11.PKCS11Constants; public class KBKDFPipelineParams extends KBKDFParameterSpec { public KBKDFPipelineParams() {} protected void validateParameters() throws IllegalArgumentException { if (prfKey == null) { String msg = "Required parameter KDF key was never set."; throw new IllegalArgumentException(msg); } if (prf != PKCS11Constants.CKM_SHA_1_HMAC && prf != PKCS11Constants.CKM_SHA256_HMAC && prf != PKCS11Constants.CKM_SHA384_HMAC && prf != PKCS11Constants.CKM_SHA512_HMAC && prf != PKCS11Constants.CKM_AES_CMAC) { String msg = "Expected Pseudo-Random Function to be SHA1-HMAC, "; msg += "SHA2-HMAC, or AES-CMAC, but got unknown PKCS#11 "; msg += "constant: " + prf; throw new IllegalArgumentException(msg); } if (params == null || params.length == 0) { String msg = "Expected non-null, non-zero length array of KDF "; msg += "parameters."; throw new IllegalArgumentException(msg); } int index = 0; for (KBKDFDataParameter param : params) { if (param instanceof KBKDFOptionalCounterParam) { KBKDFOptionalCounterParam kocp = (KBKDFOptionalCounterParam)param; if (kocp.widthInBits == -1) { String msg = "Got unexpected data in KBKDF Optional "; msg += "Counter Parameter at index " + index + ": "; msg += "Expected valid counter specification, but got "; msg += "widthInBits of -1. Call setCounterSpec(...) "; msg += "before using this parameter."; throw new IllegalArgumentException(msg); } } if (param instanceof KBKDFIterationVariableParam) { KBKDFIterationVariableParam kivp = (KBKDFIterationVariableParam)param; if (kivp.widthInBits != -1) { String msg = "Got unexpected data in KBKDF Iteration "; msg += "Variable Parameter at index " + index + ": "; msg += "Expected empty counter specification, but got "; msg += "widthInBits of " + kivp.widthInBits + ". Call "; msg += "the no argument constructor instead to use this "; msg += "parameter."; throw new IllegalArgumentException(msg); } } if (param instanceof KBKDFDKMLengthParam) { KBKDFDKMLengthParam kdlp = (KBKDFDKMLengthParam)param; if (kdlp.widthInBits == 0) { String msg = "Got unexpected data in KBKDF DKM Length "; msg += "Parameter at index " + index + ": Expected valid "; msg += "length specification, but got widthInBits of 0. "; msg += "Call setLngthSpec(...) before using this "; msg += "parameter."; throw new IllegalArgumentException(msg); } } // Nothing to validate for byte array parameters. index += 1; } } protected native void acquireNativeResourcesInternal() throws Exception; protected native void releaseNativeResourcesInternal() throws Exception; } jss-4.6.3/org/mozilla/jss/crypto/KeyAlreadyImportedException.java000066400000000000000000000016151362106420000251550ustar00rootroot00000000000000/* 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.crypto; /** * This exception is thrown if the user tries to import a * key which is already in the specified token */ public class KeyAlreadyImportedException extends java.lang.Exception { private static final long serialVersionUID = 1L; public KeyAlreadyImportedException() {} public KeyAlreadyImportedException(String mesg) { super(mesg); } public KeyAlreadyImportedException(String mesg, Throwable cause) { super(mesg, cause); } public KeyAlreadyImportedException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/crypto/KeyGenAlgorithm.java000066400000000000000000000177261362106420000226030ustar00rootroot00000000000000/* 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.crypto; import java.security.NoSuchAlgorithmException; import java.util.Hashtable; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; /** * Algorithms that can be used for generating symmetric keys. */ public class KeyGenAlgorithm extends Algorithm { protected static interface KeyStrengthValidator { public boolean isValidKeyStrength(int strength); } protected static class FixedKeyStrengthValidator implements KeyStrengthValidator { private int strength; public FixedKeyStrengthValidator(int strength) { this.strength = strength; } public boolean isValidKeyStrength(int strength) { return this.strength == strength; } } protected static class AnyKeyStrengthValidator implements KeyStrengthValidator { public boolean isValidKeyStrength(int strength) { return true; } } protected KeyGenAlgorithm(int oidTag, String name, KeyStrengthValidator keyStrengthValidator, OBJECT_IDENTIFIER oid, Class paramClass) { super(oidTag, name, oid, paramClass); this.keyStrengthValidator = keyStrengthValidator; if(oid!=null) { oidMap.put(oid, this); } } /////////////////////////////////////////////////////////////////////// // OIDs /////////////////////////////////////////////////////////////////////// private static final OBJECT_IDENTIFIER PKCS5 = OBJECT_IDENTIFIER.PKCS5; private static final OBJECT_IDENTIFIER PKCS12_PBE = OBJECT_IDENTIFIER.PKCS12.subBranch(1); /////////////////////////////////////////////////////////////////////// // OID mapping /////////////////////////////////////////////////////////////////////// private static Hashtable oidMap = new Hashtable<>(); public static KeyGenAlgorithm fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { Object alg = oidMap.get(oid); if( alg == null ) { throw new NoSuchAlgorithmException(oid.toString()); } else { return (KeyGenAlgorithm) alg; } } private KeyStrengthValidator keyStrengthValidator; /** * @param strength Key strength. * @return true if the given strength is valid for this * key generation algorithm. Note that PBE algorithms require * PBEParameterSpecs rather than strengths. It is the responsibility * of the caller to verify this. */ public boolean isValidStrength(int strength) { return keyStrengthValidator.isValidKeyStrength(strength); } ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm GENERIC_SECRET = new KeyGenAlgorithm( CKM_GENERIC_SECRET_KEY_GEN, "GenericSecret", new AnyKeyStrengthValidator(), null, null ); ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm DES = new KeyGenAlgorithm( CKM_DES_KEY_GEN, "DES", new FixedKeyStrengthValidator(56), null, null ); ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm DES3 = new KeyGenAlgorithm( CKM_DES3_KEY_GEN, "DESede", new FixedKeyStrengthValidator(168), null, null ); public static final KeyGenAlgorithm DESede = DES3; ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm RC4 = new KeyGenAlgorithm( CKM_RC4_KEY_GEN, "RC4", new AnyKeyStrengthValidator(), null, null ); ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm PBA_SHA1_HMAC = new KeyGenAlgorithm( CKM_PBA_SHA1_WITH_SHA1_HMAC, "PBA/SHA1/HMAC", new FixedKeyStrengthValidator(160), null, PBEKeyGenParams.class ); public static final KeyGenAlgorithm SHA1_HMAC = new KeyGenAlgorithm( CKM_SHA_1_HMAC, "SHA1/HMAC", new FixedKeyStrengthValidator(160), null, null ); public static final KeyGenAlgorithm SHA256_HMAC = new KeyGenAlgorithm( CKM_SHA256_HMAC, "SHA256/HMAC", new FixedKeyStrengthValidator(256), null, null ); public static final KeyGenAlgorithm SHA384_HMAC = new KeyGenAlgorithm( CKM_SHA384_HMAC, "SHA384/HMAC", new FixedKeyStrengthValidator(384), null, null ); public static final KeyGenAlgorithm SHA512_HMAC = new KeyGenAlgorithm( CKM_SHA512_HMAC, "SHA512/HMAC", new FixedKeyStrengthValidator(512), null, null ); ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm AES = new KeyGenAlgorithm( CKM_AES_KEY_GEN, "AES", new KeyStrengthValidator() { public boolean isValidKeyStrength(int strength) { return strength==128 || strength==192 || strength==256; } }, null, null ); ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm RC2 = new KeyGenAlgorithm( CKM_RC2_KEY_GEN, "RC2", new KeyStrengthValidator() { public boolean isValidKeyStrength(int strength) { // Allow any key of size between 1 byte and 128 bytes return strength>=8 && strength <= (128*8); } }, null, null ); ////////////////////////////////////////////////////////////// /////////////// GENERIC KBKDFs: NIST SP800-108 /////////////// ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm SP800_108_COUNTER_KDF = new KeyGenAlgorithm( CKM_SP800_108_COUNTER_KDF, "SP800_108_COUNTER_KDF", new AnyKeyStrengthValidator(), null, KBKDFCounterParams.class ); public static final KeyGenAlgorithm SP800_108_FEEDBACK_KDF = new KeyGenAlgorithm( CKM_SP800_108_FEEDBACK_KDF, "SP800_108_FEEDBACK_KDF", new AnyKeyStrengthValidator(), null, KBKDFFeedbackParams.class ); public static final KeyGenAlgorithm SP800_108_DOUBLE_PIPELINE_KDF = new KeyGenAlgorithm( CKM_SP800_108_DOUBLE_PIPELINE_KDF, "SP800_108_DOUBLE_PIPELINE_KDF", new AnyKeyStrengthValidator(), null, KBKDFPipelineParams.class ); ////////////////////////////////////////////////////////////// //////////// Data KBKDFs: NSS-only NIST SP800-108 //////////// ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm NSS_SP800_108_COUNTER_KDF_DERIVE_DATA = new KeyGenAlgorithm( CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA, "NSS_SP800_108_COUNTER_KDF_DERIVE_DATA", new AnyKeyStrengthValidator(), null, KBKDFCounterParams.class ); public static final KeyGenAlgorithm NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA = new KeyGenAlgorithm( CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA, "NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA", new AnyKeyStrengthValidator(), null, KBKDFFeedbackParams.class ); public static final KeyGenAlgorithm NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA = new KeyGenAlgorithm( CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA, "NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA", new AnyKeyStrengthValidator(), null, KBKDFPipelineParams.class ); } jss-4.6.3/org/mozilla/jss/crypto/KeyGenerator.java000066400000000000000000000120531362106420000221350ustar00rootroot00000000000000/* 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.crypto; import java.io.CharConversionException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.spec.AlgorithmParameterSpec; /** * Generates symmetric keys for encryption and decryption. */ public interface KeyGenerator { /** * @param strength Key size in bits. Must be evenly divisible by 8. * @throws InvalidAlgorithmParameterException If parameter is invalid. */ public void initialize(int strength) throws InvalidAlgorithmParameterException; public void initialize(AlgorithmParameterSpec parameters) throws InvalidAlgorithmParameterException; /** * @param usages The operations the key will be used for after it is * generated. You have to specify these so that the key can be properly * marked with the operations it supports. Some PKCS #11 tokens require * that a key be marked for an operation before it can perform that * operation. The default is SymmetricKey.Usage.SIGN and * SymmetricKey.Usage.ENCRYPT. */ public void setKeyUsages(SymmetricKey.Usage[] usages); /** * Tells the generator to generate temporary or permanent keys. * Temporary keys are not written permanently to the token. They * are destroyed by the garbage collector. If this method is not * called, the default is temporary keys. * @param temp True to generate temporary key. */ public void temporaryKeys(boolean temp); /** * Tells the generator to generate sensitive or insensitive keys. * Certain attributes of a sensitive key cannot be revealed in * plaintext outside the token. If this method is not called, the * default is token dependent. * @param sensitive True to generate sensitive. */ public void sensitiveKeys(boolean sensitive); /** * Generates a symmetric key. * @return Symmetric key. * @throws IllegalStateException If key generation failed. * @throws TokenException If an error occurred in the token. * @throws CharConversionException If an encoding error occurred. */ public SymmetricKey generate() throws IllegalStateException, TokenException, CharConversionException; /** * Generates an Initialization Vector using a PBE algorithm. * In order to call this method, the algorithm must be a PBE algorithm, * and the KeyGenerator must have been initialized with an instance * of PBEKeyGenParams. * * @return The initialization vector derived from the password and salt * using the PBE algorithm. * @exception IllegalStateException If the algorithm is not a PBE * algorithm, or the KeyGenerator has not been initialized with * an instance of PBEKeyGenParams. * @exception TokenException If an error occurs on the CryptoToken while * generating the IV. * @exception CharConversionException If an encoding error occurred. */ public byte[] generatePBE_IV() throws IllegalStateException, TokenException, CharConversionException; /** * Allows a SymmetricKey to be cloned on a different token. * * @param key Symmetric key. * @return Cloned symmetric key. * @exception SymmetricKey.NotExtractableException If the key material * cannot be extracted from the current token. * @exception InvalidKeyException If the owning token cannot process * the key to be cloned. * @exception TokenException If an error occurred in the token. */ public SymmetricKey clone(SymmetricKey key) throws SymmetricKey.NotExtractableException, InvalidKeyException, TokenException; /** * An interface for converting a password of Java characters into an array * of bytes. This conversion must be performed to provide a byte array * to the low-level crypto engine. The default conversion is UTF8. * Null-termination is not necessary, and indeed is usually incorrect, * since the password is passed to the crypto engine as a byte array, not * a C string. */ public static interface CharToByteConverter { /** * Converts a password of Java characters into a password of * bytes, using some encoding scheme. The input char array must * not be modified. * @param chars Password characters. * @return Password as byte array. * @throws CharConversionException If an error occurred. */ public byte[] convert(char[] chars) throws CharConversionException; } /** * Sets the character to byte converter for passwords. The default * conversion is UTF8 with no null termination. * @param charToByte Character-to-byte converter. */ public void setCharToByteConverter(CharToByteConverter charToByte); } jss-4.6.3/org/mozilla/jss/crypto/KeyPairAlgorithm.java000066400000000000000000000056571362106420000227650ustar00rootroot00000000000000/* 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.crypto; import java.security.NoSuchAlgorithmException; import java.util.Hashtable; /** * Algorithms that can be used for keypair generation. */ public class KeyPairAlgorithm extends Algorithm { protected KeyPairAlgorithm(int oidIndex, String name, Algorithm algFamily) { super(oidIndex, name); this.algFamily = algFamily; nameMap.put(name, this); } /** * Returns the algorithm family for a given key pair generation algorithm. * If a token supports a family and is writable, we can do keypair gen * on the token even if it doesn't support the keypair gen algorithm. * We do this by doing the keypair gen on the internal module and then * moving the key out to the other token. * @return Algorithm family. */ public Algorithm getAlgFamily() { return algFamily; } private static Hashtable nameMap = new Hashtable<>(); /** * Looks up a key pair generation algorithm from its name. The names * are those specified in the JCA spec. For example, "RSA" and "DSA". * * @param algName Algorithm name. * @return Key pair generation algorithm. * @throws NoSuchAlgorithmException If the name of the algorithm is not * recognized as a supported algorithm. */ public static KeyPairAlgorithm fromString(String algName) throws NoSuchAlgorithmException { KeyPairAlgorithm alg = nameMap.get(algName); if( alg == null ) { throw new NoSuchAlgorithmException(); } return alg; } protected Algorithm algFamily; //////////////////////////////////////////////////////////////// // Key-Pair Generation Algorithms //////////////////////////////////////////////////////////////// public static final Algorithm RSAFamily = new Algorithm(SEC_OID_PKCS1_RSA_ENCRYPTION, "RSA"); public static final Algorithm DSAFamily = new Algorithm(SEC_OID_ANSIX9_DSA_SIGNATURE, "DSA"); public static final Algorithm // To support both ECDSA and ECDH, it is best to provide two EC Families; // However, since there is no token that does only CKM_DERIVE to // date, we will just do ECDSA for now as it is sufficient enough today. // This fix will support tokens that do not do ECDH ECFamily = new Algorithm(SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST, "EC"); public static final KeyPairAlgorithm RSA = new KeyPairAlgorithm(CKM_RSA_PKCS_KEY_PAIR_GEN, "RSA", RSAFamily); public static final KeyPairAlgorithm DSA = new KeyPairAlgorithm(CKM_DSA_KEY_PAIR_GEN, "DSA", DSAFamily); public static final KeyPairAlgorithm EC = new KeyPairAlgorithm(CKM_EC_KEY_PAIR_GEN, "EC", ECFamily); } jss-4.6.3/org/mozilla/jss/crypto/KeyPairGenerator.java000066400000000000000000000151511362106420000227530ustar00rootroot00000000000000/* 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.crypto; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; /** * Generates RSA and DSA key pairs. Each CryptoToken provides a * KeyPairGenerator, which can be used to generate key pairs on that token. * A given token may not support all algorithms, and some tokens may not * support any key pair generation. If a token does not support key pair * generation, the Netscape internal token may do it instead. Call * keygenOnInternalToken to find out if this is happening. * * @see org.mozilla.jss.crypto.CryptoToken#getKeyPairGenerator */ public class KeyPairGenerator { /** * Creates a new key pair generator. KeyPairGenerators should * be obtained by calling CryptoToken.getKeyPairGenerator * instead of calling this constructor. * * @param algorithm The type of keys that the generator will be * used to generate. * @param engine The engine object that provides the implementation for * the class. */ public KeyPairGenerator(KeyPairAlgorithm algorithm, KeyPairGeneratorSpi engine) { this.algorithm = algorithm; this.engine = engine; } /** * Generates a new key pair. * * @return A new key pair. The keys reside on the CryptoToken that * provided this KeyPairGenerator. * @exception TokenException If an error occurs on the CryptoToken * in the process of generating the key pair. */ public java.security.KeyPair genKeyPair() throws TokenException { return engine.generateKeyPair(); } /** * @return The type of key that this generator generates. */ public KeyPairAlgorithm getAlgorithm() { return algorithm; } /** * Initializes the generator with algorithm-specific parameters. * The SecureRandom parameters is ignored. * * @param params Algorithm-specific parameters for the key pair generation. * @param random This parameter is ignored. NSS does not accept * an external source of random numbers. * @exception InvalidAlgorithmParameterException If the parameters are * inappropriate for the type of key pair that is being generated, * or they are not supported by this generator. * @see org.mozilla.jss.crypto.RSAParameterSpec * @see java.security.spec.DSAParameterSpec */ public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { engine.initialize(params, random); } /** * Initializes the generator with algorithm-specific parameters. * * @param params Algorithm-specific parameters for the key pair generation. * @exception InvalidAlgorithmParameterException If the parameters are * inappropriate for the type of key pair that is being generated, * or they are not supported by this generator. * @see org.mozilla.jss.crypto.RSAParameterSpec * @see java.security.spec.DSAParameterSpec */ public void initialize(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { engine.initialize(params, null); } /** * Initializes the generator with the strength of the keys. * The SecureRandom parameter is ignored. * * @param strength The strength of the keys that will be generated. * Usually this is the length of the key in bits. * @param random This parameter is ignored. NSS does not accept * an external source of random numbers. */ public void initialize(int strength, SecureRandom random) { engine.initialize(strength, random); } /** * Initializes the generator with the strength of the keys. * * @param strength The strength of the keys that will be generated. * Usually this is the length of the key in bits. */ public void initialize(int strength) { engine.initialize(strength, null); } /** * @return true if the keypair generation will take place on the * internal token rather than the current token. This will * happen if the token does not support keypair generation * but does support this algorithm and is writable. In this * case the keypair will be generated on the Netscape internal * token and then moved to this token. */ public boolean keygenOnInternalToken() { return engine.keygenOnInternalToken(); } /** * Tells the generator to generate temporary or permanent keypairs. * Temporary keys are not written permanently to the token. They * are destroyed by the garbage collector. If this method is not * called, the default is permanent keypairs. * @param temp True to generate temporary keypairs. */ public void temporaryPairs(boolean temp) { engine.temporaryPairs(temp); } /** * Tells the generator to generate sensitive or insensitive keypairs. * Certain attributes of a sensitive key cannot be revealed in * plaintext outside the token. If this method is not called, the * default depends on the temporaryPairs mode for backward * compatibility. The default is sensitive keypairs if the * temporaryPairs mode is false, or insensitive keypairs if the * temporaryPairs mode is true. * @param sensitive To generate sensitive keypairs. */ public void sensitivePairs(boolean sensitive) { engine.sensitivePairs(sensitive); } /** * Tells the generator to generate extractable or unextractable * keypairs. Extractable keys can be extracted from the token after * wrapping. If this method is not called, the default is token * dependent. * @param extractable True to generate extractable keypairs. */ public void extractablePairs(boolean extractable) { engine.extractablePairs(extractable); } public void setKeyPairUsages(KeyPairGeneratorSpi.Usage[] usages, KeyPairGeneratorSpi.Usage[] usages_mask) { engine.setKeyPairUsages(usages,usages_mask); } public int getCurveCodeByName(String curveName) throws InvalidParameterException { return engine.getCurveCodeByName(curveName); } protected KeyPairAlgorithm algorithm; protected KeyPairGeneratorSpi engine; } jss-4.6.3/org/mozilla/jss/crypto/KeyPairGeneratorSpi.java000066400000000000000000000055041362106420000234300ustar00rootroot00000000000000/* 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.crypto; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; public abstract class KeyPairGeneratorSpi { public KeyPairGeneratorSpi() { } public abstract void initialize(int strength, SecureRandom random); public abstract void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException; public abstract KeyPair generateKeyPair() throws TokenException; public abstract int getCurveCodeByName(String curveName) throws InvalidParameterException; public abstract void temporaryPairs(boolean temp); public abstract void sensitivePairs(boolean sensitive); public abstract void extractablePairs(boolean extractable); public abstract boolean keygenOnInternalToken(); /** * In PKCS #11, each keypair can be marked with the operations it will * be used to perform. Some tokens require that a key be marked for * an operation before the key can be used to perform that operation; * other tokens don't care. NSS provides a way to specify a set of * flags and a corresponding mask for these flags. If a specific usage * is desired set the value for that usage. If it is not set, let NSS * behave in it's default fashion. If a behavior is desired, also set * that behavior in the mask as well as the flags. * */ public final static class Usage { private Usage() { } private Usage(int val) { this.val = val;} private int val; public int getVal() { return val; } // these enums must match the // opFlagForUsage listed in PK11KeyPairGenerator.java public static final Usage ENCRYPT = new Usage(0); public static final Usage DECRYPT = new Usage(1); public static final Usage SIGN = new Usage(2); public static final Usage SIGN_RECOVER = new Usage(3); public static final Usage VERIFY = new Usage(4); public static final Usage VERIFY_RECOVER = new Usage(5); public static final Usage WRAP = new Usage(6); public static final Usage UNWRAP = new Usage(7); public static final Usage DERIVE = new Usage(8); } /** * setKeyPairUsages * @param usages Usages. * @param usages_mask Usages mask. */ public abstract void setKeyPairUsages(KeyPairGeneratorSpi.Usage[] usages, KeyPairGeneratorSpi.Usage[] usages_mask); } jss-4.6.3/org/mozilla/jss/crypto/KeyWrapAlgorithm.java000066400000000000000000000132431362106420000227710ustar00rootroot00000000000000/* 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.crypto; import java.security.NoSuchAlgorithmException; import java.util.Hashtable; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; /** * */ public class KeyWrapAlgorithm extends Algorithm { protected KeyWrapAlgorithm(int oidTag, String name, Class paramClass, boolean padded, int blockSize) { super(oidTag, name, null, paramClass); this.padded = padded; this.blockSize = blockSize; if( name != null ) { nameMap.put(name.toLowerCase(), this); } } protected KeyWrapAlgorithm(int oidTag, String name, Class []paramClasses, boolean padded, int blockSize) { super(oidTag, name, null, paramClasses); this.padded = padded; this.blockSize = blockSize; if( name != null ) { nameMap.put(name.toLowerCase(), this); } } private boolean padded; private int blockSize; private static Hashtable nameMap = new Hashtable<>(); public static KeyWrapAlgorithm fromString(String name) throws NoSuchAlgorithmException { Object alg = nameMap.get( name.toLowerCase() ); if( alg == null ) { throw new NoSuchAlgorithmException(); } else { return (KeyWrapAlgorithm) alg; } } public boolean isPadded() { return padded; } public int getBlockSize() { return blockSize; } private static Class[] IVParameterSpecClasses = null; static { IVParameterSpecClasses = new Class[2]; IVParameterSpecClasses[0] = IVParameterSpec.class; IVParameterSpecClasses[1] = IvParameterSpec.class; } public static final KeyWrapAlgorithm DES_ECB = new KeyWrapAlgorithm(SEC_OID_DES_ECB, "DES/ECB", (Class) null, false, 8); public static final KeyWrapAlgorithm DES_CBC = new KeyWrapAlgorithm(SEC_OID_DES_CBC, "DES/CBC", IVParameterSpecClasses, false, 8); public static final KeyWrapAlgorithm DES_CBC_PAD = new KeyWrapAlgorithm(CKM_DES_CBC_PAD, "DES/CBC/Pad", IVParameterSpecClasses, true, 8); public static final KeyWrapAlgorithm DES3_ECB = new KeyWrapAlgorithm(CKM_DES3_ECB, "DES3/ECB", (Class)null, false, 8); public static final KeyWrapAlgorithm DES3_CBC = new KeyWrapAlgorithm(SEC_OID_DES_EDE3_CBC, "DES3/CBC", IVParameterSpecClasses, false, 8); public static final KeyWrapAlgorithm DES3_CBC_PAD = new KeyWrapAlgorithm(CKM_DES3_CBC_PAD, "DES3/CBC/Pad", IVParameterSpecClasses, true, 8); public static final KeyWrapAlgorithm RSA = new KeyWrapAlgorithm(SEC_OID_PKCS1_RSA_ENCRYPTION, "RSA", (Class) null, false, 0); public static final KeyWrapAlgorithm PLAINTEXT = new KeyWrapAlgorithm(0, "Plaintext", (Class) null, false, 0); public static final KeyWrapAlgorithm AES_ECB = new KeyWrapAlgorithm(CKM_AES_ECB, "AES/ECB/NoPadding", (Class) null, false, 16); public static final KeyWrapAlgorithm AES_CBC = new KeyWrapAlgorithm(CKM_AES_CBC, "AES/CBC/NoPadding", IVParameterSpecClasses, false, 16); public static final KeyWrapAlgorithm AES_CBC_PAD = new KeyWrapAlgorithm(CKM_AES_CBC_PAD, "AES/CBC/PKCS5Padding", IVParameterSpecClasses, true, 16); public static final KeyWrapAlgorithm RC2_CBC_PAD = new KeyWrapAlgorithm(CKM_RC2_CBC_PAD, "RC2/CBC/PKCS5Padding", RC2ParameterSpec.class, true, 8); /* * Note: AES_KEY_WRAP is not suitable for wrapping private keys; * Use AES_KEY_WRAP_PAD instead * Also note that although it is mapped to CKM_NSS_AES_KEY_WRAP_* * here, down in PK11KeyWrapper.c, logic exists to map to * CKM_AES_KEY_WRAP_* if it is determined to recognize the mechanism */ public static final KeyWrapAlgorithm AES_KEY_WRAP = new KeyWrapAlgorithm(CKM_NSS_AES_KEY_WRAP, "AES KeyWrap/NoPadding", (Class) null, false, 8); public static final KeyWrapAlgorithm AES_KEY_WRAP_PAD = new KeyWrapAlgorithm(CKM_NSS_AES_KEY_WRAP_PAD, "AES KeyWrap/Padding", (Class) null, true, 8); public static final OBJECT_IDENTIFIER AES_KEY_WRAP_PAD_OID = new OBJECT_IDENTIFIER("2.16.840.1.101.3.4.1.8"); public static final OBJECT_IDENTIFIER AES_KEY_WRAP_OID = new OBJECT_IDENTIFIER("2.16.840.1.101.3.4.1.5"); public static final OBJECT_IDENTIFIER AES_CBC_PAD_OID = new OBJECT_IDENTIFIER("2.16.840.1.101.3.4.1.2"); public static final OBJECT_IDENTIFIER DES3_CBC_PAD_OID = new OBJECT_IDENTIFIER("1.2.840.113549.3.7"); public static final OBJECT_IDENTIFIER DES_CBC_PAD_OID = new OBJECT_IDENTIFIER("1.3.14.3.2.7"); public static KeyWrapAlgorithm fromOID(String wrapOID) throws NoSuchAlgorithmException { OBJECT_IDENTIFIER oid = new OBJECT_IDENTIFIER(wrapOID); if (oid.equals(AES_KEY_WRAP_PAD_OID)) return AES_KEY_WRAP_PAD; if (oid.equals(AES_KEY_WRAP_OID)) return AES_KEY_WRAP; if (oid.equals(AES_CBC_PAD_OID)) return AES_CBC_PAD; if (oid.equals(DES3_CBC_PAD_OID)) return DES3_CBC_PAD; if (oid.equals(DES_CBC_PAD_OID)) return DES_CBC_PAD; throw new NoSuchAlgorithmException("Unknown Algorithm for OID: " + wrapOID); } } jss-4.6.3/org/mozilla/jss/crypto/KeyWrapper.java000066400000000000000000000121571362106420000216340ustar00rootroot00000000000000/* 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.crypto; import java.security.spec.AlgorithmParameterSpec; import java.security.InvalidAlgorithmParameterException; import java.security.PublicKey; import java.security.InvalidKeyException; public interface KeyWrapper { public void initWrap(SymmetricKey wrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException; public void initWrap(PublicKey wrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * For wrapping keys in plaintext. */ public void initWrap() throws InvalidKeyException, InvalidAlgorithmParameterException; public void initUnwrap(SymmetricKey unwrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException; public void initUnwrap(PrivateKey unwrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * For plaintext-wrapped keys. */ public void initUnwrap() throws InvalidKeyException, InvalidAlgorithmParameterException; public byte[] wrap(PrivateKey toBeWrapped) throws InvalidKeyException, IllegalStateException, TokenException; public byte[] wrap(SymmetricKey toBeWrapped) throws InvalidKeyException, IllegalStateException, TokenException; /** * Unwraps a private key, creating a permanent private key object. * A permanent private key object resides on a token until it is * explicitly deleted from the token. * * @param publicKey Used to calculate the key identifier that must be stored * with the private key. Must be a RSAPublicKey or a * DSAPublicKey. * @exception InvalidKeyException If the type of the public key does not * match the type of the private key to be unwrapped. */ public PrivateKey unwrapPrivate(byte[] wrapped, PrivateKey.Type type, PublicKey publicKey) throws TokenException, InvalidKeyException, IllegalStateException; /** * Unwraps a private key, creating a temporary private key object. * A temporary * private key is one that does not permanently reside on a token. * As soon as it is garbage-collected, it is gone forever. * * @param publicKey Used to calculate the key identifier that must be stored * with the private key. Must be a RSAPublicKey or a * DSAPublicKey. * @exception InvalidKeyException If the type of the public key does not * match the type of the private key to be unwrapped. */ public PrivateKey unwrapTemporaryPrivate(byte[] wrapped, PrivateKey.Type type, PublicKey publicKey) throws TokenException, InvalidKeyException, IllegalStateException; /** * @param keyLength The expected length of the key in bytes. This is * only used for variable-length keys (RC4) and non-padding * algorithms. Otherwise, it can be set to anything(like 0). * @param usage The operation the key will be used for after it is * unwrapped. You have to specify this so that the key can be properly * marked with the operation it supports. Some PKCS #11 tokens require * that a key be marked for an operation before it can perform that * operation. */ public SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, SymmetricKey.Usage usage, int keyLength) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException; /** * Unwraps a key and allows it to be used for all operations. * @param keyLength The expected length of the key in bytes. This is * only used for variable-length keys (RC4) and non-padding * algorithms. Otherwise, it can be set to anything(like 0). */ public SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, int keyLength) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException; public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, SymmetricKey.Usage usage, int keyLength) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException; /** * Unwraps a key and allows it to be used for all operations. * @param keyLength The expected length of the key in bytes. This is * only used for variable-length keys (RC4) and non-padding * algorithms. Otherwise, it can be set to anything(like 0). */ public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, int keyLength) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException; } jss-4.6.3/org/mozilla/jss/crypto/NoSuchItemOnTokenException.java000066400000000000000000000015651362106420000247370ustar00rootroot00000000000000/* 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.crypto; /** * Thrown if a cryptographic item does not exist on the token it is * trying to be used on. */ public class NoSuchItemOnTokenException extends Exception { private static final long serialVersionUID = 1L; public NoSuchItemOnTokenException() {} public NoSuchItemOnTokenException(String mesg) { super(mesg); } public NoSuchItemOnTokenException(String mesg, Throwable cause) { super(mesg, cause); } public NoSuchItemOnTokenException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/crypto/NoSuchPaddingException.java000066400000000000000000000007021362106420000241010ustar00rootroot00000000000000/* 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.crypto; /** * This class is a stub for javax.crypto.NoSuchPaddingException until we * move to JDK 1.2. */ public class NoSuchPaddingException extends Exception { private static final long serialVersionUID = 1L; } jss-4.6.3/org/mozilla/jss/crypto/ObjectNotFoundException.java000066400000000000000000000014711362106420000243020ustar00rootroot00000000000000/* 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.crypto; /** * This exception is thrown whenever something isn't implemented. */ public class ObjectNotFoundException extends Exception { private static final long serialVersionUID = 1L; public ObjectNotFoundException() { super(); } public ObjectNotFoundException(String mesg) { super(mesg); } public ObjectNotFoundException(String mesg, Throwable cause) { super(mesg, cause); } public ObjectNotFoundException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/crypto/PBEAlgorithm.java000066400000000000000000000125061362106420000220160ustar00rootroot00000000000000/* 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.crypto; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; /** * Algorithms that can be used for generating symmetric keys from passwords. */ public class PBEAlgorithm extends KeyGenAlgorithm { private EncryptionAlgorithm encAlg; private int saltLength; protected PBEAlgorithm(int oidTag, String name, int validStrength, OBJECT_IDENTIFIER oid, EncryptionAlgorithm encAlg, int saltLength) { super(oidTag, name, new FixedKeyStrengthValidator(validStrength), oid, PBEKeyGenParams.class); this.encAlg = encAlg; this.saltLength = saltLength; } /** * Returns the EncryptionAlgorithm that should be used with keys * generated with this PBEAlgorithm. For example, * PBE_MD2_DES_CBC.getEncryptionAlg() returns * EncryptionAlgorithm.DES_CBC. */ public EncryptionAlgorithm getEncryptionAlg() { return encAlg; } /** * Returns the number of bytes of salt that should be supplied when * generating keys with this algorithm. * *

PKCS #5 algorithms require exactly 8 bytes of salt. PKCS #12 * algorithms take * a variable length, but recommend that the salt length be at least * as long as the output of the hash function. For SHA-1, the output * length is 20 bytes. */ public int getSaltLength() { return saltLength; } /////////////////////////////////////////////////////////////////////// // OIDs /////////////////////////////////////////////////////////////////////// private static final OBJECT_IDENTIFIER PKCS5 = OBJECT_IDENTIFIER.PKCS5; private static final OBJECT_IDENTIFIER PKCS12_PBE = OBJECT_IDENTIFIER.PKCS12.subBranch(1); /////////////////////////////////////////////////////////////////////// // OID mapping /////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // PKCS 5 v2 public static final PBEAlgorithm PBE_PKCS5_PBKDF2 = new PBEAlgorithm( SEC_OID_PKCS5_PBKDF2, "PBKDF2", 128, PKCS5.subBranch(12), EncryptionAlgorithm.AES_128_CBC, 8 ); ////////////////////////////////////////////////////////////// // PKCS 5 v2 public static final PBEAlgorithm PBE_PKCS5_PBES2 = new PBEAlgorithm( SEC_OID_PKCS5_PBES2, "PBES2", 128, PKCS5.subBranch(13), EncryptionAlgorithm.AES_128_CBC, 8 ); ////////////////////////////////////////////////////////////// // PKCS 5 v2 public static final PBEAlgorithm PBE_PKCS5_PBMAC1 = new PBEAlgorithm( SEC_OID_PKCS5_PBMAC1, "PBMAC1", 128, PKCS5.subBranch(14), EncryptionAlgorithm.AES_128_CBC, 8 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_MD2_DES_CBC = new PBEAlgorithm( SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC, "PBE/MD2/DES/CBC", 56, PKCS5.subBranch(1), EncryptionAlgorithm.DES_CBC, 8 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_MD5_DES_CBC = new PBEAlgorithm( SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC, "PBE/MD5/DES/CBC", 56, PKCS5.subBranch(3), EncryptionAlgorithm.DES_CBC, 8 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_DES_CBC = new PBEAlgorithm( SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC, "PBE/SHA1/DES/CBC", 56, PKCS5.subBranch(10), EncryptionAlgorithm.DES_CBC, 8 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_RC4_128 = new PBEAlgorithm( SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4, "PBE/SHA1/RC4-128", 128, PKCS12_PBE.subBranch(1), EncryptionAlgorithm.RC4, 20 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_RC4_40 = new PBEAlgorithm( SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4, "PBE/SHA1/RC4-40", 40, PKCS12_PBE.subBranch(2), EncryptionAlgorithm.RC4, 20 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_DES3_CBC = new PBEAlgorithm( SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC, "PBE/SHA1/DES3/CBC", 168, PKCS12_PBE.subBranch(3), EncryptionAlgorithm.DES3_CBC, 20 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_RC2_128_CBC = new PBEAlgorithm( SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC, "PBE/SHA1/RC2-128", 128, PKCS12_PBE.subBranch(5), EncryptionAlgorithm.RC2_CBC, 20 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_RC2_40_CBC = new PBEAlgorithm( SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC, "PBE/SHA1/RC2-40", 40, PKCS12_PBE.subBranch(6), EncryptionAlgorithm.RC2_CBC, 20 ); } jss-4.6.3/org/mozilla/jss/crypto/PBEKeyGenParams.java000066400000000000000000000106141362106420000224140ustar00rootroot00000000000000/* 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.crypto; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.KeySpec; import org.mozilla.jss.util.Password; public class PBEKeyGenParams implements AlgorithmParameterSpec, KeySpec { private Password pass; private byte[] salt; private int iterations; private EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.DES3_CBC; static private final int DEFAULT_SALT_LENGTH = 8; static private final int DEFAULT_ITERATIONS = 1; /** * Creates PBE parameters. * * @param pass The password. It will be cloned, so the * caller is still responsible for clearing it. It must not be null. * @param salt The salt for the PBE algorithm. Will not be cloned. * Must not be null. It is the responsibility of the caller to * use the right salt length for the algorithm. Most algorithms * use 8 bytes of salt. * @param iterations The iteration count for the PBE algorithm. */ public PBEKeyGenParams(Password pass, byte[] salt, int iterations) { if(pass==null || salt==null) { throw new NullPointerException(); } this.pass = (Password) pass.clone(); this.salt = salt; this.iterations = iterations; } /** * Creates PBE parameters using default encryption algorithm * (DES3_EDE3_CBC). * * @param pass The password. It will be cloned, so the * caller is still responsible for clearing it. It must not be null. * @param salt The salt for the PBE algorithm. Will not be cloned. * Must not be null. It is the responsibility of the caller to * use the right salt length for the algorithm. Most algorithms * use 8 bytes of salt. * @param iterations The iteration count for the PBE algorithm. */ public PBEKeyGenParams(char[] pass, byte[] salt, int iterations) { if(pass==null || salt==null) { throw new NullPointerException(); } this.pass = new Password( pass.clone() ); this.salt = salt; this.iterations = iterations; } /** * Creates PBE parameters using default encryption algorithm * (DES3_EDE3_CBC). * * @param pass The password. It will be cloned, so the * caller is still responsible for clearing it. It must not be null. * @param salt The salt for the PBE algorithm. Will not be cloned. * Must not be null. It is the responsibility of the caller to * use the right salt length for the algorithm. Most algorithms * use 8 bytes of salt. * @param iterations The iteration count for the PBE algorithm. * @param encAlg The encryption algorithm. This is used with SOME * PBE algorithms for determining the KDF output length. */ public PBEKeyGenParams( char[] pass, byte[] salt, int iterations, EncryptionAlgorithm encAlg) { if (pass == null || salt == null) { throw new NullPointerException(); } this.pass = new Password(pass.clone()); this.salt = salt; this.iterations = iterations; if (encAlg != null) this.encryptionAlgorithm = encAlg; } /** * Returns a reference to the password, not a copy. */ public Password getPassword() { return pass; } /** * Returns a reference to the salt. */ public byte[] getSalt() { return salt; } /** * Returns the iteration count. */ public int getIterations() { return iterations; } /** * The encryption algorithm is used with SOME PBE algorithms for * determining the KDF output length. */ public EncryptionAlgorithm getEncryptionAlgorithm() { return encryptionAlgorithm; } /** * Clears the password. This should be called when this object is no * longer needed so the password is not left around in memory. */ public void clear() { pass.clear(); } /** * @deprecated finalize() in Object has been deprecated */ @Deprecated protected void finalize() throws Throwable { pass.clear(); } } jss-4.6.3/org/mozilla/jss/crypto/PKCS11Algorithm.java000066400000000000000000000076421362106420000223170ustar00rootroot00000000000000package org.mozilla.jss.crypto; import org.mozilla.jss.pkcs11.PKCS11Constants; import org.mozilla.jss.crypto.Algorithm; public enum PKCS11Algorithm { CKM_AES_CBC (Algorithm.CKM_AES_CBC, PKCS11Constants.CKM_AES_CBC), CKM_AES_CBC_PAD (Algorithm.CKM_AES_CBC_PAD, PKCS11Constants.CKM_AES_CBC_PAD), CKM_AES_ECB (Algorithm.CKM_AES_ECB, PKCS11Constants.CKM_AES_ECB), CKM_AES_KEY_GEN (Algorithm.CKM_AES_KEY_GEN, PKCS11Constants.CKM_AES_KEY_GEN), CKM_DES3_CBC_PAD (Algorithm.CKM_DES3_CBC_PAD, PKCS11Constants.CKM_DES3_CBC_PAD), CKM_DES3_ECB (Algorithm.CKM_DES3_ECB, PKCS11Constants.CKM_DES3_ECB), CKM_DES3_KEY_GEN (Algorithm.CKM_DES3_KEY_GEN, PKCS11Constants.CKM_DES3_KEY_GEN), CKM_DES_CBC_PAD (Algorithm.CKM_DES_CBC_PAD, PKCS11Constants.CKM_DES_CBC_PAD), CKM_DES_KEY_GEN (Algorithm.CKM_DES_KEY_GEN, PKCS11Constants.CKM_DES_KEY_GEN), CKM_DSA_KEY_PAIR_GEN (Algorithm.CKM_DSA_KEY_PAIR_GEN, PKCS11Constants.CKM_DSA_KEY_PAIR_GEN), CKM_EC_KEY_PAIR_GEN (Algorithm.CKM_EC_KEY_PAIR_GEN, PKCS11Constants.CKM_EC_KEY_PAIR_GEN), CKM_NSS_AES_KEY_WRAP (Algorithm.CKM_NSS_AES_KEY_WRAP, PKCS11Constants.CKM_NSS_AES_KEY_WRAP), CKM_NSS_AES_KEY_WRAP_PAD (Algorithm.CKM_NSS_AES_KEY_WRAP_PAD, PKCS11Constants.CKM_NSS_AES_KEY_WRAP_PAD), CKM_PBA_SHA1_WITH_SHA1_HMAC (Algorithm.CKM_PBA_SHA1_WITH_SHA1_HMAC, PKCS11Constants.CKM_PBA_SHA1_WITH_SHA1_HMAC), CKM_RC2_CBC_PAD (Algorithm.CKM_RC2_CBC_PAD, PKCS11Constants.CKM_RC2_CBC_PAD), CKM_RC2_KEY_GEN (Algorithm.CKM_RC2_KEY_GEN, PKCS11Constants.CKM_RC2_KEY_GEN), CKM_RC4_KEY_GEN (Algorithm.CKM_RC4_KEY_GEN, PKCS11Constants.CKM_RC4_KEY_GEN), CKM_RSA_PKCS_KEY_PAIR_GEN (Algorithm.CKM_RSA_PKCS_KEY_PAIR_GEN, PKCS11Constants.CKM_RSA_PKCS_KEY_PAIR_GEN), CKM_SHA_1_HMAC (Algorithm.CKM_SHA_1_HMAC, PKCS11Constants.CKM_SHA_1_HMAC), CKM_SHA_256_HMAC (Algorithm.CKM_SHA256_HMAC, PKCS11Constants.CKM_SHA256_HMAC), CKM_SHA_384_HMAC (Algorithm.CKM_SHA384_HMAC, PKCS11Constants.CKM_SHA384_HMAC), CKM_SHA_512_HMAC (Algorithm.CKM_SHA512_HMAC, PKCS11Constants.CKM_SHA512_HMAC), CKM_AES_CMAC (Algorithm.CKM_AES_CMAC, PKCS11Constants.CKM_AES_CMAC), CKM_SP800_108_COUNTER_KDF (Algorithm.CKM_SP800_108_COUNTER_KDF, PKCS11Constants.CKM_SP800_108_COUNTER_KDF), CKM_SP800_108_FEEDBACK_KDF (Algorithm.CKM_SP800_108_FEEDBACK_KDF, PKCS11Constants.CKM_SP800_108_FEEDBACK_KDF), CKM_SP800_108_DOUBLE_PIPELINE_KDF (Algorithm.CKM_SP800_108_DOUBLE_PIPELINE_KDF, PKCS11Constants.CKM_SP800_108_DOUBLE_PIPELINE_KDF), CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA (Algorithm.CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA, PKCS11Constants.CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA), CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA (Algorithm.CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA, PKCS11Constants.CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA), CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA (Algorithm.CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA, PKCS11Constants.CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA); // Value from Algorithm's constant -- this is an index into Algorithm's // table. private int alg_index; // Value from PKCS11Constants -- this is a constant defined in PKCS #11. private long pk11_value; private PKCS11Algorithm(int alg_index, long pk11_value) { this.alg_index = alg_index; this.pk11_value = pk11_value; } public int getIndex() { return alg_index; } public long getValue() { return pk11_value; } public static PKCS11Algorithm valueOfIndex(int index) { for (PKCS11Algorithm alg : PKCS11Algorithm.values()) { if (alg.alg_index == index) { return alg; } } return null; } public static PKCS11Algorithm valueOfConstant(long constant) { for (PKCS11Algorithm alg : PKCS11Algorithm.values()) { if (alg.pk11_value == constant) { return alg; } } return null; } } jss-4.6.3/org/mozilla/jss/crypto/PQGParamGenException.java000066400000000000000000000013261362106420000234600ustar00rootroot00000000000000/* 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.crypto; public class PQGParamGenException extends Exception { private static final long serialVersionUID = 1L; public PQGParamGenException() {} public PQGParamGenException(String mesg) { super(mesg); } public PQGParamGenException(String mesg, Throwable cause) { super(mesg, cause); } public PQGParamGenException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/crypto/PQGParams.c000066400000000000000000000243461362106420000206420ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_crypto_PQGParams.h" #include #include #include #include #include /* for PQGParams */ #include #include #include #include #include static jobject generate(JNIEnv *env, jclass PQGParamsClass, jint keySize, jint seedBytes); /********************************************************************** * P Q G P a r a m s . g e n e r a t e ( keysize ) * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_crypto_PQGParams_generateNative__I (JNIEnv *env, jclass PQGParamsClass, jint keySize) { return generate(env, PQGParamsClass, keySize, 0); } /********************************************************************** * P Q G P a r a m s . g e n e r a t e ( keysize, seedBytes ) * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_crypto_PQGParams_generateNative__II (JNIEnv *env, jclass PQGParamsClass, jint keySize, jint seedBytes) { if(seedBytes < 20 || seedBytes > 255) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "Number of bytes in seed must be in range [20,255]"); return NULL; } return generate(env, PQGParamsClass, keySize, seedBytes); } #define ZERO_SECITEM(item) (item).data=NULL; (item).len=0; /********************************************************************** * * g e n e r a t e * * INPUTS * env * The JNI environment. * this * Reference to a Java PQGGenerator object. * keySize * The size of the key, which is actually the size of P in bits. * seedBytes * The length of the seed in bytes, or 0 to let the algorithm * figure it out. * RETURNS * A new PQGParams object. */ static jobject generate(JNIEnv *env, jclass PQGParamsClass, jint keySize, jint seedBytes) { int keySizeIndex; jobject newObject = NULL; SECStatus status; PQGParams *pParams=NULL; PQGVerify *pVfy=NULL; jbyteArray bytes; jclass BigIntegerClass; jmethodID BigIntegerConstructor; jmethodID PQGParamsConstructor; /*----PQG parameters and friends----*/ SECItem P; /* prime */ SECItem Q; /* subPrime */ SECItem G; /* base */ SECItem H; SECItem seed; unsigned int counter; /*----Java versions of the PQG parameters----*/ jobject jP; jobject jQ; jobject jG; jobject jH; jint jcounter; jobject jSeed; /* basic argument validation */ PR_ASSERT(env!=NULL && PQGParamsClass!=NULL); /* clear the SECItems so we can free them indiscriminately at the end */ ZERO_SECITEM(P); ZERO_SECITEM(Q); ZERO_SECITEM(G); ZERO_SECITEM(H); ZERO_SECITEM(seed); /*********************************************************************** * PK11_PQG_ParamGen doesn't take a key size, it takes an index that * points to a valid key size. */ keySizeIndex = PQG_PBITS_TO_INDEX(keySize); if(keySizeIndex == -1 || keySize<512 || keySize>1024) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "DSA key size must be a multiple of 64 between 512 " "and 1024, inclusive"); goto finish; } /*********************************************************************** * Do the actual parameter generation. */ if(seedBytes == 0) { status = PK11_PQG_ParamGen(keySizeIndex, &pParams, &pVfy); } else { status = PK11_PQG_ParamGenSeedLen(keySizeIndex, seedBytes, &pParams, &pVfy); } if(status != SECSuccess) { JSS_throw(env, PQG_PARAM_GEN_EXCEPTION); goto finish; } /********************************************************************** * NOTE: the new PQG parameters will be verified at the Java level. */ /********************************************************************** * Get ready for the BigIntegers */ BigIntegerClass = (*env)->FindClass(env, BIG_INTEGER_CLASS_NAME); if(BigIntegerClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } BigIntegerConstructor = (*env)->GetMethodID(env, BigIntegerClass, BIG_INTEGER_CONSTRUCTOR_NAME, BIG_INTEGER_CONSTRUCTOR_SIG); if(BigIntegerConstructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /*********************************************************************** * Convert the parameters to Java types. */ if( PK11_PQG_GetPrimeFromParams( pParams, &P) || PK11_PQG_GetSubPrimeFromParams( pParams, &Q) || PK11_PQG_GetBaseFromParams( pParams, &G) || PK11_PQG_GetHFromVerify( pVfy, &H) || PK11_PQG_GetSeedFromVerify( pVfy, &seed) ) { JSS_throw(env, PQG_PARAM_GEN_EXCEPTION); goto finish; } counter = PK11_PQG_GetCounterFromVerify(pVfy); /* * construct P */ bytes = JSS_OctetStringToByteArray(env, &P); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } jP = (*env)->NewObject(env, BigIntegerClass, BigIntegerConstructor, bytes); if(jP==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * construct Q */ bytes = JSS_OctetStringToByteArray(env, &Q); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } jQ = (*env)->NewObject(env, BigIntegerClass, BigIntegerConstructor, bytes); if(jQ==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * construct G */ bytes = JSS_OctetStringToByteArray(env, &G); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } jG = (*env)->NewObject(env, BigIntegerClass, BigIntegerConstructor, bytes); if(jG==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * construct seed */ bytes = JSS_OctetStringToByteArray(env, &seed); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } jSeed = (*env)->NewObject(env, BigIntegerClass, BigIntegerConstructor, bytes); if(jSeed==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * construct H */ bytes = JSS_OctetStringToByteArray(env, &H); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } jH = (*env)->NewObject(env, BigIntegerClass, BigIntegerConstructor, bytes); if(jH==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * construct counter */ jcounter = counter; /********************************************************************** * Construct the PQGParams object */ PQGParamsConstructor = (*env)->GetMethodID( env, PQGParamsClass, PQG_PARAMS_CONSTRUCTOR_NAME, PQG_PARAMS_CONSTRUCTOR_SIG); if(PQGParamsConstructor==NULL) { ASSERT_OUTOFMEM(env); goto finish; } newObject = (*env)->NewObject( env, PQGParamsClass, PQGParamsConstructor, jP, jQ, jG, jSeed, jcounter, jH); finish: if(pParams!=NULL) { PK11_PQG_DestroyParams(pParams); } if(pVfy!=NULL) { PK11_PQG_DestroyVerify(pVfy); } SECITEM_FreeItem(&P, PR_FALSE /*don't free P itself*/); SECITEM_FreeItem(&Q, PR_FALSE); SECITEM_FreeItem(&G, PR_FALSE); SECITEM_FreeItem(&H, PR_FALSE); SECITEM_FreeItem(&seed, PR_FALSE); return newObject; } /********************************************************************** * * P Q G P a r a m s . p a r a m s A r e V a l i d * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_crypto_PQGParams_paramsAreValidNative (JNIEnv *env, jobject this, jbyteArray jP, jbyteArray jQ, jbyteArray jG, jbyteArray jSeed, jint jCounter, jbyteArray jH) { jboolean valid=JNI_FALSE; PQGParams *pParams=NULL; PQGVerify *pVfy=NULL; SECStatus verifyResult; /*---PQG and verification params in C---*/ SECItem P; SECItem Q; SECItem G; SECItem seed; SECItem H; unsigned int counter; PR_ASSERT(env!=NULL && this!=NULL); /* clear the SECItems so we can free them indiscriminately later */ ZERO_SECITEM(P); ZERO_SECITEM(Q); ZERO_SECITEM(G); ZERO_SECITEM(seed); ZERO_SECITEM(H); /********************************************************************** * Extract the Java parameters */ if( JSS_ByteArrayToOctetString(env, jP, &P) || JSS_ByteArrayToOctetString(env, jQ, &Q) || JSS_ByteArrayToOctetString(env, jG, &G) || JSS_ByteArrayToOctetString(env, jSeed, &seed) || JSS_ByteArrayToOctetString(env, jH, &H) ) { goto finish; } counter = jCounter; /*********************************************************************** * Construct PQGParams and PQGVerify structures. */ pParams = PK11_PQG_NewParams(&P, &Q, &G); pVfy = PK11_PQG_NewVerify(counter, &seed, &H); if(pParams==NULL || pVfy==NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /*********************************************************************** * Perform the verification. */ if( PK11_PQG_VerifyParams(pParams, pVfy, &verifyResult) != SECSuccess) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } if(verifyResult == SECSuccess) { valid = JNI_TRUE; } finish: SECITEM_FreeItem(&P, PR_FALSE /*don't free P itself*/); SECITEM_FreeItem(&Q, PR_FALSE); SECITEM_FreeItem(&G, PR_FALSE); SECITEM_FreeItem(&seed, PR_FALSE); SECITEM_FreeItem(&H, PR_FALSE); PK11_PQG_DestroyParams(pParams); PK11_PQG_DestroyVerify(pVfy); return valid; } jss-4.6.3/org/mozilla/jss/crypto/PQGParams.java000066400000000000000000000177261362106420000213450ustar00rootroot00000000000000/* 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.crypto; import java.math.BigInteger; import java.security.spec.DSAParameterSpec; import org.mozilla.jss.util.Assert; /** * PQG parameters for DSA key generation, along with the seed, counter, * and H values for verification. *

This class has two main purposes: * generating PQG parameters and verifying PQG parameters. To generate * PQG parameters, call one of the static generate methods. * They will return a new set of PQG parameters. To verify existing PQG * parameters, create a new PQGParams object with the * constructor and call paramsAreValid on the object. * *

It is necessary to call CryptoManager.initialize before * using this class. * */ public class PQGParams extends DSAParameterSpec { /** * Creates a PQGParams object from a set of pre-computed DSA * parameters. * * @param P The DSA prime parameter. * @param Q The DSA sub-prime parameter. * @param G The DSA base parameter. * @param seed The Seed used to calculate P, Q, and G. * @param counter The Counter (C) used to calculate P, Q, and G. * @param H The H value used to generate P, Q, and G. */ public PQGParams(BigInteger P, BigInteger Q, BigInteger G, BigInteger seed, int counter, BigInteger H) { super(P, Q, G); this.seed = seed; this.counter = counter; this.H = H; } /** * Generates P, Q, and G parameters for DSA key generation. Also * provides the seed, counter, and H values for verification of the * P, Q, and G. The parameters are generated and then verified * before being returned. The length of the Seed will equal the * length of P. * * It is necessary to call one of the * CryptoManager.initialize functions before calling * this method. * * @param keySize The size of P in bits. Keys generated by these P, * Q, and G values will have this length. Valid key sizes * are multiples of 64 in the closed interval [512,1024]. * This also dictates the length of H and Seed. * @return A new set of P, Q, and G parameters, along with the Seed, * Counter, and H values used to generate them. * @exception java.security.InvalidParameterException If the keySize * is outside the bounds described by the DSA key pair * generation algorithm. * @exception org.mozilla.jss.crypto.PQGParamGenException If an error * occurs during the generation process. * @see org.mozilla.jss.CryptoManager#initialize */ public static PQGParams generate(int keySize) throws java.security.InvalidParameterException, PQGParamGenException { PQGParams pqg = generateNative(keySize); if( ! pqg.paramsAreValid() ) { throw new PQGParamGenException( "Generated parameters did not verify correctly"); } return pqg; } /** * Does the actual work of generation, but does not verify. */ private static native PQGParams generateNative(int keySize) throws java.security.InvalidParameterException, PQGParamGenException; /** * Generates P, Q, and G parameters for DSA key generation. Also * provides the seed, counter, and H values for verification of the * P, Q, and G. The parameters are generated and then verified * before being returned. * * It is necessary to call one of the * CryptoManager.initialize functions before calling * this method. * * @param keySize The size of P in bits. Keys generated by these P, * Q, and G values will have this length. Valid key sizes * are multiples of 64 in the closed interval [512,1024]. * This also dictates the length of H. * @param seedBytes The number of bytes in the Seed value used to * generate P, Q, and G. seedBytes must be * from the closed interval [20,255]. * @return A new set of P, Q, and G parameters, along with the Seed, * Counter, and H values used to generate them. * @exception java.security.InvalidParameterException If the keySize * or number of seed bytes is outside the bounds described by the * DSA key pair generation algorithm. * @exception org.mozilla.jss.crypto.PQGParamGenException If an error * occurs during the generation process. * @see org.mozilla.jss.CryptoManager#initialize */ public static PQGParams generate(int keySize, int seedBytes) throws java.security.InvalidParameterException, PQGParamGenException { PQGParams pqg = generateNative(keySize, seedBytes); if( ! pqg.paramsAreValid() ) { throw new PQGParamGenException( "Generated parameters did not verify correctly"); } return pqg; } /** * Does the actual work of generation, but does not verify. */ private static native PQGParams generateNative(int keySize, int seedBytes) throws java.security.InvalidParameterException, PQGParamGenException; /** * Produces an unsigned byte-array representation of a BigInteger. * *

BigInteger adds an extra sign bit to the beginning of its byte * array representation. In some cases this will cause the size * of the byte array to increase, which may be unacceptable for some * applications. This function returns a minimal byte array representing * the BigInteger without extra sign bits. * * @return An unsigned, big-endian byte array representation * of a BigInteger. */ public static byte[] BigIntegerToUnsignedByteArray(BigInteger big) { byte[] ret; // big must not be negative assert(big.signum() != -1); // bitLength is the size of the data without the sign bit. If // it exactly fills an integral number of bytes, that means a whole // new byte will have to be added to accomodate the sign bit. In // this case we need to remove the first byte. if(big.bitLength() % 8 == 0) { byte[] array = big.toByteArray(); // The first byte should just be sign bits assert( array[0] == 0 ); ret = new byte[array.length-1]; System.arraycopy(array, 1, ret, 0, ret.length); } else { ret = big.toByteArray(); } return ret; } /** * Verifies the PQG parameters using the seed, counter, and H values. * @return true if the parameters verified correctly, false if they * did not verify. */ public boolean paramsAreValid() { return paramsAreValidNative(BigIntegerToUnsignedByteArray( getP() ), BigIntegerToUnsignedByteArray( getQ() ), BigIntegerToUnsignedByteArray( getG() ), BigIntegerToUnsignedByteArray( seed ), counter, BigIntegerToUnsignedByteArray( H )); } private native boolean paramsAreValidNative(byte[] P, byte[] Q, byte[]G, byte[] seed, int counter, byte[] H); /** * @return The Seed used to generate P, Q, and G. */ public BigInteger getSeed() { return seed; } /** * @return The Counter (C) used to generate P, Q, and G. */ public int getCounter() { return counter; } /** * @return The H value used to generate P, Q, and G. */ public BigInteger getH() { return H; } private BigInteger seed; private int counter; private BigInteger H; } jss-4.6.3/org/mozilla/jss/crypto/Policy.c000066400000000000000000000023051362106420000202750ustar00rootroot00000000000000#include "_jni/org_mozilla_jss_crypto_Policy.h" #include #include #include jint nearest_power_of_two(jint value) { for (jint exponent = 8; exponent < 20; exponent++) { if ((1 << exponent) >= value) { return 1 << exponent; } } return value; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_crypto_Policy_getRSAMinimumKeySize(JNIEnv *env, jclass clazz) { PRInt32 value = 0; SECStatus ret = NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &value); if (ret != SECSuccess) { PR_ASSERT(PR_FALSE); } return nearest_power_of_two(value); } JNIEXPORT jint JNICALL Java_org_mozilla_jss_crypto_Policy_getDHMinimumKeySize(JNIEnv *env, jclass clazz) { PRInt32 value = 0; SECStatus ret = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &value); if (ret != SECSuccess) { PR_ASSERT(PR_FALSE); } return nearest_power_of_two(value); } JNIEXPORT jint JNICALL Java_org_mozilla_jss_crypto_Policy_getDSAMinimumKeySize(JNIEnv *env, jclass clazz) { PRInt32 value = 0; SECStatus ret = NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &value); if (ret != SECSuccess) { PR_ASSERT(PR_FALSE); } return nearest_power_of_two(value); } jss-4.6.3/org/mozilla/jss/crypto/Policy.java000066400000000000000000000043261362106420000210010ustar00rootroot00000000000000package org.mozilla.jss.crypto; import java.math.BigInteger; import org.mozilla.jss.ssl.SSLProtocolVariant; import org.mozilla.jss.ssl.SSLSocket; import org.mozilla.jss.ssl.SSLVersion; import org.mozilla.jss.ssl.SSLVersionRange; /** * This class helps JSS callers align with local system cryptographic policy. * * In the event of a policy violation, applications can override policy by * writing to the desired variable. */ public class Policy { /** * Whether or not this JSS instance is enforcing local crypto-policy, * with respect to key sizes. * * Defaults to false; this lets applications use whatever key sizes are * supported by NSS, at the risk of performing non-compliant operations. * Set to true to enable enforcement, where it exists. */ public static boolean ENFORCING_KEY_SIZES = false; /** * Minimum RSA key length in bits permitted by local policy. */ public static int RSA_MINIMUM_KEY_SIZE = getRSAMinimumKeySize(); /** * Minimum RSA public exponent allowed by JSS. */ public static BigInteger RSA_MINIMUM_PUBLIC_EXPONENT = BigInteger.valueOf(65537); /** * Minimum DH key length in bits permitted by local policy. */ public static int DH_MINIMUM_KEY_SIZE = getDHMinimumKeySize(); /** * Minimum DSA key length in bits permitted by local policy. */ public static int DSA_MINIMUM_KEY_SIZE = getDSAMinimumKeySize(); public static SSLVersionRange TLS_VERSION_RANGE = getTLSVersionRange(); public static SSLVersion TLS_MINIMUM_VERSION = TLS_VERSION_RANGE.getMinVersion(); public static SSLVersion TLS_MAXIMUM_VERSION = TLS_VERSION_RANGE.getMaxVersion(); private static SSLVersionRange getTLSVersionRange() { SSLVersionRange range = new SSLVersionRange(SSLVersion.minSupported(), SSLVersion.maxSupported()); try { return SSLSocket.boundSSLVersionRange(SSLProtocolVariant.STREAM, range); } catch (Exception e) { return range; } } private static native int getRSAMinimumKeySize(); private static native int getDHMinimumKeySize(); private static native int getDSAMinimumKeySize(); } jss-4.6.3/org/mozilla/jss/crypto/PrivateKey.java000066400000000000000000000071101362106420000216170ustar00rootroot00000000000000/* 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.crypto; import java.security.NoSuchAlgorithmException; import java.util.Hashtable; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.util.Assert; /** * Private Keys used by JSS. All the private keys handled by JSS are * of this type, which is a subtype of java.security.PrivateKey. */ public interface PrivateKey extends java.security.PrivateKey { public static final Type RSA = Type.RSA; public static final Type DSA = Type.DSA; public static final Type EC = Type.EC; public static final Type DiffieHellman = Type.DiffieHellman; /** * Returns the type (RSA or DSA) of this private key. */ public Type getType(); /** * Returns the unique ID of this key. Unique IDs can be used to match * certificates to keys. * * @see org.mozilla.jss.crypto.TokenCertificate#getUniqueID */ public byte[] getUniqueID() throws TokenException; /** * Returns the size, in bits, of the modulus of an RSA key. * Returns -1 for other types of keys. */ public int getStrength(); /** * Returns the CryptoToken that owns this private key. Cryptographic * operations with this key may only be performed on the token that * owns the key. */ public CryptoToken getOwningToken(); public static final class Type { private OBJECT_IDENTIFIER oid; private String name; private int pkcs11Type; private Type() { } private Type(OBJECT_IDENTIFIER oid, String name, int pkcs11Type) { this.oid = oid; this.name = name; Object old = oidMap.put(oid, this); this.pkcs11Type = pkcs11Type; assert( old == null ); } private static Hashtable oidMap = new Hashtable<>(); public static Type fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { Object obj = oidMap.get(oid); if( obj == null ) { throw new NoSuchAlgorithmException(); } return (Type) obj; } /** * Returns a string representation of the algorithm, such as * "RSA", "DSA", or "EC". */ public String toString() { return name; } public OBJECT_IDENTIFIER toOID() { return oid; } public int getPKCS11Type() { return pkcs11Type; } // OID for DiffieHellman, from RFC 2459 7.3.2. public static OBJECT_IDENTIFIER DH_OID = new OBJECT_IDENTIFIER( new long[] {1, 2, 840, 10046, 2, 1} ); // From PKCS #11 private static int CKK_RSA = 0x0; private static int CKK_DSA = 0x1; private static int CKK_DH = 0x2; private static int CKK_EC = 0x3; private static int CKK_X9_42_DH = 0x4; private static int CKK_KEA = 0x5; public static final Type RSA = new Type( OBJECT_IDENTIFIER.PKCS1.subBranch(1), "RSA", CKK_RSA ); public static final Type DSA = new Type( Algorithm.ANSI_X9_ALGORITHM.subBranch(1), "DSA", CKK_DSA); public static final Type EC = new Type( Algorithm.ANSI_X962_OID.subBranch(2).subBranch(1), "EC", CKK_EC); public static final Type DiffieHellman = new Type( DH_OID, "DiffieHellman", CKK_DH ); } } jss-4.6.3/org/mozilla/jss/crypto/RSAParameterSpec.java000066400000000000000000000020051362106420000226330ustar00rootroot00000000000000/* 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.crypto; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.RSAKeyGenParameterSpec; import java.math.BigInteger; /** * This class specifies the parameters used for generating an RSA key pair. */ public class RSAParameterSpec extends RSAKeyGenParameterSpec { /** * Creates a new RSAParameterSpec with the specified parameter values. * @param keySize The size of the modulus in bits. * @param publicExponent The public exponent e. Common values * are 3, 17, and 65537. 65537 is recommended. */ public RSAParameterSpec(int keySize, BigInteger publicExponent) { super(keySize, publicExponent); } /** * Returns the size of the modulus in bits. */ public int getKeySize() { return getKeysize(); } } jss-4.6.3/org/mozilla/jss/crypto/SecretDecoderRing.c000066400000000000000000000037141362106420000223760ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_crypto_SecretDecoderRing.h" #include #include #include #include #include typedef enum {SDR_ENCRYPT, SDR_DECRYPT} SDROp; static jbyteArray doSDR(JNIEnv *env, jobject this, jbyteArray inputBA, SDROp optype) { SECStatus status; jbyteArray outputBA = NULL; SECItem keyID = {siBuffer, NULL, 0}; SECItem *input= NULL; SECItem output = {siBuffer, NULL, 0}; /* convert input to SECItem */ if( inputBA == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } input = JSS_ByteArrayToSECItem(env, inputBA); if( input == NULL) { /* exception was thrown */ goto finish; } /* perform the operation*/ if( optype == SDR_ENCRYPT ) { status = PK11SDR_Encrypt(&keyID, input, &output, NULL /*cx*/); } else { PR_ASSERT( optype == SDR_DECRYPT); status = PK11SDR_Decrypt(input, &output, NULL /*cx*/); } if(status != SECSuccess) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Operation failed"); goto finish; } /* convert output to byte array */ outputBA = JSS_SECItemToByteArray(env, &output); finish: if( input != NULL) { SECITEM_FreeItem(input, PR_TRUE /* freeit */); } SECITEM_FreeItem(&output, PR_FALSE /*freeit*/); return outputBA; } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_crypto_SecretDecoderRing_encrypt( JNIEnv *env, jobject this, jbyteArray plaintextBA) { return doSDR(env, this, plaintextBA, SDR_ENCRYPT); } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_crypto_SecretDecoderRing_decrypt( JNIEnv *env, jobject this, jbyteArray ciphertextBA) { return doSDR(env, this, ciphertextBA, SDR_DECRYPT); } jss-4.6.3/org/mozilla/jss/crypto/SecretDecoderRing.java000066400000000000000000000053671362106420000231030ustar00rootroot00000000000000/* 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.crypto; import java.io.UnsupportedEncodingException; /** * This is a special-purpose interface for NSS. It is used for encrypting * data with a secret key stored in the NSS key database (which is in turn * protected with a password). It thus provides a quick, convenient way * to encrypt stuff your application wants to keep around for its own use: * for example, the list of web passwords stored in the web browser. * *

A dedicated key is used to encrypt all SecretDecoderRing data. * The same key is used for all SDR data, and not for any other data. * This key will be generated the first time it is needed. * *

The cipher used is DES3-EDE (Triple-DES) in CBC mode. The ciphertext * is DER-encoded in the following ASN.1 data structure: *

 *    SEQUENCE {
 *      keyid       OCTET STRING,
 *      alg         AlgorithmIdentifier,
 *      ciphertext  OCTET STRING }
 * 
* *

You must set the password on the Internal Key Storage Token * (aka software token, key3.db) before you use the SecretDecoderRing. */ public class SecretDecoderRing { public static final String encodingFormat = "UTF-8"; /** * Encrypts the given plaintext with the Secret Decoder Ring key stored * in the NSS key database. */ public native byte[] encrypt(byte[] plaintext) throws TokenException; /** * Encrypts the given plaintext string with the Secret Decoder Ring key * stored in the NSS key database. */ public byte[] encrypt(String plaintext) throws TokenException { try { return encrypt(plaintext.getBytes(encodingFormat)); } catch(UnsupportedEncodingException e) { // this shouldn't happen, because we use a universally-supported // charset throw new RuntimeException(e.getMessage()); } } /** * Decrypts the given ciphertext with the Secret Decoder Ring key stored * in the NSS key database. */ public native byte[] decrypt(byte[] ciphertext) throws TokenException; /** * Decrypts the given ciphertext with the Secret Decoder Ring key stored * in the NSS key database, returning the original plaintext string. */ public String decryptToString(byte[] ciphertext) throws TokenException { try { return new String(decrypt(ciphertext), encodingFormat); } catch(UnsupportedEncodingException e) { // this shouldn't happen, because we use a universally-supported // charset throw new RuntimeException(e.getMessage()); } } } jss-4.6.3/org/mozilla/jss/crypto/SecretKeyFacade.java000066400000000000000000000012551362106420000225220ustar00rootroot00000000000000/* 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.crypto; public class SecretKeyFacade implements javax.crypto.SecretKey { private static final long serialVersionUID = 1L; public SymmetricKey key; public SecretKeyFacade(SymmetricKey symk) { key = symk; } public String getAlgorithm() { return key.getAlgorithm(); } public byte[] getEncoded() { return key.getEncoded(); } public String getFormat() { return key.getFormat(); } } jss-4.6.3/org/mozilla/jss/crypto/ShortBufferException.java000066400000000000000000000007061362106420000236500ustar00rootroot00000000000000/* 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.crypto; /** * This class is a placeholder for javax.crypto.ShortBufferException until * we move to JDK 1.2. */ public class ShortBufferException extends Exception { private static final long serialVersionUID = 1L; } jss-4.6.3/org/mozilla/jss/crypto/Signature.java000066400000000000000000000136621362106420000215060ustar00rootroot00000000000000/* 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.crypto; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Provider; import java.security.PublicKey; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; /** * A class for producing and verifying digital signatures. * Instances of this class can be obtain from CryptoTokens. * * @see org.mozilla.jss.crypto.CryptoToken#getSignatureContext */ public class Signature { protected Signature() { } Signature(SignatureAlgorithm algorithm, SignatureSpi engine) { this.algorithm = algorithm; this.engine = engine; } /** * This is not supported yet. */ public Provider getProvider() { throw new RuntimeException("Signature.getProvider() is not yet implemented"); } /** * Supplying sources of randoms is not supported yet. public void initSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException, TokenException { engine.engineInitSign(privateKey, random); } */ /** * Initialize the signature context for signing. * @param privateKey The private key with which to sign. * @exception InvalidKeyException If the key is the wrong type for the * algorithm or does not exist on the token of this signature * context. * @exception TokenException If an error occurred on the token. */ public void initSign(PrivateKey privateKey) throws InvalidKeyException, TokenException { engine.engineInitSign(privateKey); } /** * Initialize the signature context for verifying. * @param publicKey The public key with which to verify the signature. * @exception InvalidKeyException If the key is the wrong type for the * algorithm. * @exception TokenException If an error occurs on the token. */ public void initVerify(PublicKey publicKey) throws InvalidKeyException, TokenException { engine.engineInitVerify(publicKey); } /** * Set parameters for the signing algorithm. This is currently not * supported or needed. * @param params Parameters for the signing algorithm. * @exception InvalidAlgorithmParameterException If there is something wrong * with the parameters. * @exception TokenException If an error occurs on the token. */ public void setParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException, TokenException { engine.engineSetParameter(params); } /** * Finish a signing operation and return the signature. * @exception SignatureException If an error occurs with the signing * operation. * @exception TokenException If an error occurs on the token. * @return The signature. */ public byte[] sign() throws SignatureException, TokenException { return engine.engineSign(); } /** * Finish a signing operation and store the signature in the provided * buffer. * @param outbuf Buffer to hold the signature * @param offset Offset in buffer at which to store signature. * @param len Number of bytes of buffer available for signature. * @return int The number of bytes placed into outbuf. * @exception SignatureException If an error occurred while signing, or * len was insufficient to contain the signature. * @exception TokenException If an error occurred on the token. */ public int sign(byte[] outbuf, int offset, int len) throws SignatureException, TokenException { return engine.engineSign(outbuf, offset, len); } /** * Finish a verification operation. * @param signature The signature to be verified. * @return true if the signature is valid, false if it is invalid. * @exception SignatureException If an error occurred with the verification * operation * @exception TokenException If an error occurred on the token. */ public boolean verify(byte[] signature) throws SignatureException, TokenException { return engine.engineVerify(signature); } /** * Provide more data for a signature or verification operation. * @param b A byte to be signed or verified. * @exception SignatureException If an error occurs in the * signature/verifcation. * @exception TokenException If an error occurs on the token. */ public void update(byte b) throws SignatureException, TokenException { engine.engineUpdate(b); } /** * Provide more data for a signature or verification operation. * @param data An array of bytes to be signed or verified. * @exception SignatureException If an error occurs in the * signature/verifcation. * @exception TokenException If an error occurs on the token. */ public void update(byte[] data) throws SignatureException, TokenException { engine.engineUpdate(data, 0, data.length); } /** * Provide more data for a signature or verification operation. * @param data An array of bytes, some of which will be signed or verified. * @param off The beginning offset of the bytes to be signed/verified. * @param len The number of bytes to be signed/verified. * @exception SignatureException If an error occurs in the * signature/verification. * @exception TokenException If an error occurs on the token. */ public void update(byte[] data, int off, int len) throws SignatureException, TokenException { engine.engineUpdate(data, off, len); } /** * Returns the name of the algorithm to be used for signing. */ public String getAlgorithm() { return algorithm.toString(); } /** * Returns the algorithm to be used for signing. */ public SignatureAlgorithm getAlgorithmID() { return algorithm; } /** * Cloning is not supported yet */ protected Object clone() throws CloneNotSupportedException { // no cloning for now throw new CloneNotSupportedException(); } protected SignatureAlgorithm algorithm; protected SignatureSpi engine; } jss-4.6.3/org/mozilla/jss/crypto/SignatureAlgorithm.java000066400000000000000000000165121362106420000233520ustar00rootroot00000000000000/* 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.crypto; import java.security.NoSuchAlgorithmException; import java.util.Hashtable; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; /** * Algorithms that can be used for signing. */ public class SignatureAlgorithm extends Algorithm { private static Hashtable oidMap = new Hashtable<>(); protected SignatureAlgorithm(int oidIndex, String name, SignatureAlgorithm signingAlg, DigestAlgorithm digestAlg, OBJECT_IDENTIFIER oid) { super(oidIndex, name, oid); if(signingAlg == null) { this.signingAlg = this; } else { this.signingAlg = signingAlg; } this.digestAlg = digestAlg; oidMap.put(oid, this); } /** * Looks up the signature algorithm with the given OID. * @exception NoSuchAlgorithmException If no algorithm is found with this * OID. */ public static SignatureAlgorithm fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { Object alg = oidMap.get(oid); if( alg == null ) { throw new NoSuchAlgorithmException(); } return (SignatureAlgorithm) alg; } /** * The raw encryption portion of the signature algorithm. For example, * SignatureAlgorithm.RSASignatureWithMD2Digest.getSigningAlg == * SignatureAlgorithm.RSASignature. */ public Algorithm getSigningAlg() { return signingAlg; } public SignatureAlgorithm getRawAlg() { return signingAlg; } private SignatureAlgorithm signingAlg; /** * The digest portion of the signature algorithm. */ public DigestAlgorithm getDigestAlg() throws NoSuchAlgorithmException { if( digestAlg == null ) { throw new NoSuchAlgorithmException(); } return digestAlg; } private DigestAlgorithm digestAlg; ////////////////////////////////////////////////////////////////////// // Signature Algorithms ////////////////////////////////////////////////////////////////////// /********************************************************************** * Raw RSA signing. This algorithm does not do any hashing, it merely * encrypts its input, which should be a hash. */ public static final SignatureAlgorithm RSASignature = new SignatureAlgorithm(SEC_OID_PKCS1_RSA_ENCRYPTION, "RSA", null, null, OBJECT_IDENTIFIER.PKCS1.subBranch(1) ); /********************************************************************** * Raw DSA signing. This algorithm does not do any hashing, it merely * operates on its input, which should be a hash. */ public static final SignatureAlgorithm DSASignature = new SignatureAlgorithm(SEC_OID_ANSIX9_DSA_SIGNATURE, "DSA", null, null, ANSI_X9_ALGORITHM.subBranch(1) ); /********************************************************************** * Raw EC signing. This algorithm does not do any hashing, it merely * operates on its input, which should be a hash. */ public static final SignatureAlgorithm ECSignature = new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST, "EC", null, null, ANSI_X962_OID.subBranch(2).subBranch(1) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithMD2Digest = new SignatureAlgorithm(SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION, "RSASignatureWithMD2Digest", RSASignature, DigestAlgorithm.MD2, OBJECT_IDENTIFIER.PKCS1.subBranch(2) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithMD5Digest = new SignatureAlgorithm(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, "RSASignatureWithMD5Digest", RSASignature, DigestAlgorithm.MD5, OBJECT_IDENTIFIER.PKCS1.subBranch(4) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithSHA1Digest = new SignatureAlgorithm(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, "RSASignatureWithSHA1Digest", RSASignature, DigestAlgorithm.SHA1, OBJECT_IDENTIFIER.PKCS1.subBranch(5) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm DSASignatureWithSHA1Digest = new SignatureAlgorithm(SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST, "DSASignatureWithSHA1Digest", DSASignature, DigestAlgorithm.SHA1, ANSI_X9_ALGORITHM.subBranch(3) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm ECSignatureWithSHA1Digest = new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE, "ECSignatureWithSHA1Digest", ECSignature, DigestAlgorithm.SHA1, ANSI_X962_OID.subBranch(4).subBranch(1) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm ECSignatureWithSHA256Digest = new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, "ECSignatureWithSHA256Digest", ECSignature, DigestAlgorithm.SHA256, ANSI_X962_OID.subBranch(4).subBranch(3).subBranch(2) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm ECSignatureWithSHA384Digest = new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE, "ECSignatureWithSHA384Digest", ECSignature, DigestAlgorithm.SHA384, ANSI_X962_OID.subBranch(4).subBranch(3).subBranch(3) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm ECSignatureWithSHA512Digest = new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE, "ECSignatureWithSHA512Digest", ECSignature, DigestAlgorithm.SHA512, ANSI_X962_OID.subBranch(4).subBranch(3).subBranch(4) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithSHA256Digest = new SignatureAlgorithm(SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION, "RSASignatureWithSHA256Digest", RSASignature, DigestAlgorithm.SHA256, OBJECT_IDENTIFIER.PKCS1.subBranch(11)); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithSHA384Digest = new SignatureAlgorithm(SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION, "RSASignatureWithSHA384Digest", RSASignature, DigestAlgorithm.SHA384, OBJECT_IDENTIFIER.PKCS1.subBranch(12)); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithSHA512Digest = new SignatureAlgorithm(SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION, "RSASignatureWithSHA512Digest", RSASignature, DigestAlgorithm.SHA512, OBJECT_IDENTIFIER.PKCS1.subBranch(13)); } jss-4.6.3/org/mozilla/jss/crypto/SignatureSpi.java000066400000000000000000000026501362106420000221550ustar00rootroot00000000000000/* 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.crypto; import java.security.*; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; /** * You don't need to use this unless you are hacking JSS. */ public abstract class SignatureSpi { public abstract void engineInitVerify(PublicKey publicKey) throws InvalidKeyException, TokenException; public abstract void engineInitSign(PrivateKey privateKey) throws InvalidKeyException, TokenException; public abstract void engineInitSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException, TokenException; public abstract void engineUpdate(byte b) throws SignatureException, TokenException; public abstract void engineUpdate(byte[] b, int off, int len) throws SignatureException, TokenException; public abstract byte[] engineSign() throws SignatureException, TokenException; public abstract int engineSign(byte[] outbuf, int offset, int len) throws SignatureException, TokenException; public abstract boolean engineVerify(byte[] sigBytes) throws SignatureException, TokenException; public abstract void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException, TokenException; } jss-4.6.3/org/mozilla/jss/crypto/SymmetricKey.java000066400000000000000000000150121362106420000221610ustar00rootroot00000000000000/* 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.crypto; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Hashtable; import org.mozilla.jss.pkcs11.PKCS11Constants; import org.mozilla.jss.pkcs11.KeyType; public interface SymmetricKey extends javax.crypto.SecretKey { public static final Type GENERIC_SECRET = Type.GENERIC_SECRET; public static final Type DES = Type.DES; public static final Type DES3 = Type.DES3; public static final Type RC4 = Type.RC4; public static final Type RC2 = Type.RC2; public static final Type SHA1_HMAC = Type.SHA1_HMAC; public static final Type SHA256_HMAC = Type.SHA256_HMAC; public static final Type SHA384_HMAC = Type.SHA384_HMAC; public static final Type SHA512_HMAC = Type.SHA512_HMAC; public static final Type AES = Type.AES; public Type getType(); public CryptoToken getOwningToken(); public int getStrength(); public int getLength(); public byte[] getKeyData() throws NotExtractableException; public static class NotExtractableException extends Exception { private static final long serialVersionUID = 1L; public NotExtractableException() { super(); } public NotExtractableException(String mesg) { super(mesg); } } String getAlgorithm(); byte[] getEncoded(); String getFormat(); String getNickName(); void setNickName(String nickName); public final static class Type { // all names converted to lowercase for case insensitivity private static Hashtable nameMap = new Hashtable<>(); private static ArrayList allTypes = new ArrayList<>(); private String[] names; private KeyGenAlgorithm keyGenAlg; private KeyType keyType; private Type() { } private Type(String[] names, KeyGenAlgorithm keyGenAlg, KeyType keyType) { this.names = names; this.keyGenAlg = keyGenAlg; this.keyType = keyType; for (String name : names) { nameMap.put(name.toLowerCase(), this); } allTypes.add(this); } public static final Type GENERIC_SECRET = new Type(new String[]{ "GenericSecret", "GENERIC_SECRET" }, KeyGenAlgorithm.GENERIC_SECRET, KeyType.GENERIC_SECRET); public static final Type DES = new Type(new String[]{ "DES" }, KeyGenAlgorithm.DES, KeyType.DES); public static final Type DES3 = new Type(new String[] { "DESede", "TDES", "3DES", "DES3" }, KeyGenAlgorithm.DES3, KeyType.DES3); public static final Type DESede = DES3; public static final Type RC4 = new Type(new String[]{ "RC4" }, KeyGenAlgorithm.RC4, KeyType.RC4); public static final Type RC2 = new Type(new String[]{ "RC2" }, KeyGenAlgorithm.RC2, KeyType.RC4); public static final Type SHA1_HMAC = new Type(new String[]{ "SHA1_HMAC", "SHA1-HMAC", "SHA1HMAC", "HMAC_SHA1", "HMAC-SHA1", "HMACSHA1" }, KeyGenAlgorithm.SHA1_HMAC, KeyType.SHA1_HMAC); public static final Type SHA256_HMAC = new Type(new String[]{ "SHA256_HMAC", "SHA256-HMAC", "SHA256HMAC", "HMAC_SHA256", "HMAC-SHA256", "HMACSHA256" }, KeyGenAlgorithm.SHA256_HMAC, KeyType.SHA256_HMAC); public static final Type SHA384_HMAC = new Type(new String[]{ "SHA384_HMAC", "SHA384-HMAC", "SHA384HMAC", "HMAC_SHA384", "HMAC-SHA384", "HMACSHA384" }, KeyGenAlgorithm.SHA384_HMAC, KeyType.SHA384_HMAC); public static final Type SHA512_HMAC = new Type(new String[]{ "SHA512_HMAC", "SHA512-HMAC", "SHA512HMAC", "HMAC_SHA512", "HMAC-SHA512", "HMACSHA512" }, KeyGenAlgorithm.SHA512_HMAC, KeyType.SHA512_HMAC); public static final Type PBA_SHA1_HMAC = new Type(new String[]{ "PBA_SHA1_HMAC" }, KeyGenAlgorithm.PBA_SHA1_HMAC, null); public static final Type AES = new Type(new String[]{ "AES" }, KeyGenAlgorithm.AES, KeyType.AES); public String toString() { return names[0]; } public String[] getAliases() { return names; } public KeyGenAlgorithm getKeyGenAlg() throws NoSuchAlgorithmException { if (keyGenAlg == null) { throw new NoSuchAlgorithmException(names[0]); } return keyGenAlg; } public KeyType getKeyType() { return keyType; } public static Type fromName(String name) throws NoSuchAlgorithmException { Object type = nameMap.get(name.toLowerCase()); if (type == null) { throw new NoSuchAlgorithmException(); } else { return (Type) type; } } public static Type fromKeyType(KeyType type) { for (Type current : allTypes) { if (current.getKeyType() == type) { return current; } } return null; } } /** * In PKCS #11, each key can be marked with the operations it will * be used to perform. Some tokens require that a key be marked for * an operation before the key can be used to perform that operation; * other tokens don't care. * *

When you unwrap a symmetric key, you must specify which one of these * operations it will be used to perform. */ public final static class Usage { private Usage() { } private Usage(int val, long pk11_val) { this.val = val; this.pk11_val = pk11_val; } private int val; private long pk11_val; public int getVal() { return val; } public long getPKCS11Constant() { return pk11_val; } // these enums must match the JSS_symkeyUsage list in Algorithm.c // and the opFlagForUsage list in PK11KeyGenerator.java public static final Usage ENCRYPT = new Usage(0, PKCS11Constants.CKA_ENCRYPT); public static final Usage DECRYPT = new Usage(1, PKCS11Constants.CKA_DECRYPT); public static final Usage WRAP = new Usage(2, PKCS11Constants.CKA_WRAP); public static final Usage UNWRAP = new Usage(3, PKCS11Constants.CKA_UNWRAP); public static final Usage SIGN = new Usage(4, PKCS11Constants.CKA_SIGN); public static final Usage VERIFY = new Usage(5, PKCS11Constants.CKA_VERIFY); } } jss-4.6.3/org/mozilla/jss/crypto/SymmetricKeyDeriver.java000066400000000000000000000060741362106420000235120ustar00rootroot00000000000000/* ***** 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.crypto; import java.security.InvalidKeyException; public interface SymmetricKeyDeriver { /* Use with the encrypt type mechanisms Example: initDerive( symKey, (PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA) 4354L, derivationData, null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE, 16); */ public abstract void initDerive(SymmetricKey baseKey, long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize) throws InvalidKeyException; /* Use with key extraction and key concatanation mechanisms Example: param: byte array that has the bit position of where to extract initDerive( derivedKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,8); initDerive( baseSymKey,secondarySymKey, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY,null,null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,0); */ public abstract void initDerive(SymmetricKey baseKey, SymmetricKey secondaryKey, long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize) throws InvalidKeyException; public abstract SymmetricKey derive() throws TokenException; } jss-4.6.3/org/mozilla/jss/crypto/TokenCertificate.java000066400000000000000000000017571362106420000227720ustar00rootroot00000000000000/* 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.crypto; /** * An X509 Certificate that lives on a PKCS #11 token. * Many of the X509Certificates returned by JSS calls are actually * TokenCertificates. * To find out if an X509Certificate is a TokenCertificate, use * instanceof. */ public interface TokenCertificate extends X509Certificate { /** * Returns the unique ID of this key. Unique IDs can be used to match * certificates to keys. * * @see org.mozilla.jss.crypto.PrivateKey#getUniqueID */ public abstract byte[] getUniqueID(); /** * Returns the CryptoToken that owns this certificate. Cryptographic * operations with this key may only be performed on the token that * owns the key. */ public abstract CryptoToken getOwningToken(); } jss-4.6.3/org/mozilla/jss/crypto/TokenException.java000066400000000000000000000017401362106420000224760ustar00rootroot00000000000000/* 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.crypto; /** * This class indicates that an unknown error occurred on a CryptoToken. * The nature of CryptoTokens makes such unpredictable errors possible. * For example, a smartcard could be yanked out of its slot in the middle * of a cryptographic operation. */ public class TokenException extends Exception { private static final long serialVersionUID = 1L; public TokenException() { super(); } public TokenException(String mesg) { super(mesg); } public TokenException(String mesg, Throwable cause) { super(mesg, cause); } public TokenException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/crypto/TokenRuntimeException.java000066400000000000000000000020121362106420000240330ustar00rootroot00000000000000/* 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.crypto; /** * This class indicates that an unknown error occurred on a CryptoToken. * The nature of CryptoTokens makes such unpredictable errors possible. * For example, a smartcard could be yanked out of its slot in the middle * of a cryptographic operation. */ public class TokenRuntimeException extends RuntimeException { private static final long serialVersionUID = 1L; public TokenRuntimeException() { super(); } public TokenRuntimeException(String mesg) { super(mesg); } public TokenRuntimeException(String mesg, Throwable cause) { super(mesg, cause); } public TokenRuntimeException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/crypto/TokenSupplier.java000066400000000000000000000014111362106420000223360ustar00rootroot00000000000000/* 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.crypto; /** * An interface that allows providers to access CryptoManager without actually * knowing about CryptoManager. This is necessary to prevent cyclic * dependencies. CryptoManager knows about the providers, so the providers * can't know about CryptoManager. Instead, CryptoManager implements * this interface. */ public interface TokenSupplier { public CryptoToken getInternalCryptoToken(); public JSSSecureRandom getSecureRNG(); public CryptoToken getThreadToken(); public void setThreadToken(CryptoToken token); } jss-4.6.3/org/mozilla/jss/crypto/TokenSupplierManager.java000066400000000000000000000016441362106420000236410ustar00rootroot00000000000000/* 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.crypto; /** * The org.mozilla.jss.provider package comes before CryptoManager in * the dependency list, so this class is used to allow them to access * CryptoManager sneakily. When CryptoManager initializes, it registers * itself as a token supplier with setTokenSupplier. Then * the providers call getTokenSupplier when they need to use * CryptoManager. CryptoManager implements the TokenSupplier interface. */ public class TokenSupplierManager { static private TokenSupplier supplier; static public void setTokenSupplier(TokenSupplier ts) { supplier = ts; } static public TokenSupplier getTokenSupplier() { return supplier; } } jss-4.6.3/org/mozilla/jss/crypto/Tunnel.java000066400000000000000000000011271362106420000210030ustar00rootroot00000000000000/* 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.crypto; /** * This is a private JSS class that allows the pkcs11 package access * to some of the * package methods in the crypto package. A friend declaration would * have been ideal. */ public class Tunnel { protected static Signature ConstructSignature( SignatureAlgorithm alg, SignatureSpi engine) { return new Signature(alg, engine); } } jss-4.6.3/org/mozilla/jss/crypto/X509Certificate.java000066400000000000000000000027411362106420000223510ustar00rootroot00000000000000/* 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.crypto; import java.math.BigInteger; import java.security.Principal; import java.security.cert.CertificateEncodingException; /** * Certificates handled by JSS. All certificates handled by JSS are * of this type. */ public interface X509Certificate { /** * @return The DER encoding of this certificate. * @throws CertificateEncodingException If an error occurred. */ public byte[] getEncoded() throws CertificateEncodingException; /** * @return The nickname of this certificate (could be null). */ public abstract String getNickname(); /** * @return The Public Key from this certificate. */ public abstract java.security.PublicKey getPublicKey(); /** * @return The RFC 1485 ASCII encoding of the Subject Name. */ public abstract Principal getSubjectDN(); /** * @return The RFC 1485 ASCII encoding of the issuer's Subject Name. */ public abstract Principal getIssuerDN(); /** * @return The serial number of this certificate. */ public abstract BigInteger getSerialNumber(); /** * @return the version number of this X.509 certificate. * 0 means v1, 1 means v2, 2 means v3. */ public abstract int getVersion(); } jss-4.6.3/org/mozilla/jss/crypto/package.html000066400000000000000000000004751362106420000211610ustar00rootroot00000000000000 Generic cryptographic operations, such as signing and key pair generation. jss-4.6.3/org/mozilla/jss/netscape/000077500000000000000000000000001362106420000171545ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/netscape/security/000077500000000000000000000000001362106420000210235ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/netscape/security/acl/000077500000000000000000000000001362106420000215625ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/netscape/security/acl/AclEntryImpl.java000066400000000000000000000131621362106420000247730ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.acl; import java.security.Principal; import java.security.acl.AclEntry; import java.security.acl.Group; import java.security.acl.Permission; import java.util.Enumeration; import java.util.Vector; /** * This is a class that describes one entry that associates users * or groups with permissions in the ACL. * The entry may be used as a way of granting or denying permissions. * * @author Satish Dharmaraj */ public class AclEntryImpl implements AclEntry { private Principal user = null; private Vector permissionSet = new Vector(10, 10); private boolean negative = false; /** * Construct an ACL entry that associates a user with permissions * in the ACL. * * @param user The user that is associated with this entry. */ public AclEntryImpl(Principal user) { this.user = user; } /** * Construct a null ACL entry */ public AclEntryImpl() { } /** * Sets the principal in the entity. If a group or a * principal had already been set, a false value is * returned, otherwise a true value is returned. * * @param user The user that is associated with this entry. * @return true if the principal is set, false if there is * one already. */ public boolean setPrincipal(Principal user) { if (this.user != null) return false; this.user = user; return true; } /** * This method sets the ACL to have negative permissions. * That is the user or group is denied the permission set * specified in the entry. */ public void setNegativePermissions() { negative = true; } /** * Returns true if this is a negative ACL. */ public boolean isNegative() { return negative; } /** * A principal or a group can be associated with multiple * permissions. This method adds a permission to the ACL entry. * * @param permission The permission to be associated with * the principal or the group in the entry. * @return true if the permission was added, false if the * permission was already part of the permission set. */ public boolean addPermission(Permission permission) { if (permissionSet.contains(permission)) return false; permissionSet.addElement(permission); return true; } /** * The method disassociates the permission from the Principal * or the Group in this ACL entry. * * @param permission The permission to be disassociated with * the principal or the group in the entry. * @return true if the permission is removed, false if the * permission is not part of the permission set. */ public boolean removePermission(Permission permission) { return permissionSet.removeElement(permission); } /** * Checks if the passed permission is part of the allowed * permission set in this entry. * * @param permission The permission that has to be part of * the permission set in the entry. * @return true if the permission passed is part of the * permission set in the entry, false otherwise. */ public boolean checkPermission(Permission permission) { return permissionSet.contains(permission); } /** * return an enumeration of the permissions in this ACL entry. */ public Enumeration permissions() { return permissionSet.elements(); } /** * Return a string representation of the contents of the ACL entry. * @deprecated Group and Permission in java.security.acl have been deprecated and marked for removal */ @Deprecated public String toString() { StringBuffer s = new StringBuffer(); if (negative) s.append("-"); else s.append("+"); if (user instanceof Group) s.append("Group."); else s.append("User."); s.append(user + "="); Enumeration e = permissions(); while (e.hasMoreElements()) { @Deprecated Permission p = e.nextElement(); s.append(p); if (e.hasMoreElements()) s.append(","); } return new String(s); } /** * Clones an AclEntry. */ public synchronized Object clone() { AclEntryImpl cloned; cloned = new AclEntryImpl(user); cloned.permissionSet = new Vector(permissionSet); cloned.negative = negative; return cloned; } /** * Return the Principal associated in this ACL entry. * The method returns null if the entry uses a group * instead of a principal. */ public Principal getPrincipal() { return user; } } jss-4.6.3/org/mozilla/jss/netscape/security/acl/AclImpl.java000066400000000000000000000362711362106420000237570ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.acl; import java.security.Principal; import java.security.acl.Acl; import java.security.acl.AclEntry; import java.security.acl.Group; import java.security.acl.NotOwnerException; import java.security.acl.Permission; import java.util.Enumeration; import java.util.Hashtable; import java.util.NoSuchElementException; import java.util.Vector; /** * An Access Control List (ACL) is encapsulated by this class. * * @author Satish Dharmaraj * @deprecated Owner in java.security.acl has been deprecated and marked for removal */ @Deprecated public class AclImpl extends OwnerImpl implements Acl { // // Maintain four tables. one each for positive and negative // ACLs. One each depending on whether the entity is a group // or principal. // private Hashtable allowedUsersTable = new Hashtable(23); private Hashtable allowedGroupsTable = new Hashtable(23); private Hashtable deniedUsersTable = new Hashtable(23); private Hashtable deniedGroupsTable = new Hashtable(23); private String aclName = null; private Vector zeroSet = new Vector(1, 1); /** * Constructor for creating an empty ACL. */ public AclImpl(Principal owner, String name) { super(owner); try { setName(owner, name); } catch (Exception e) { } } /** * Sets the name of the ACL. * * @param caller the principal who is invoking this method. * @param name the name of the ACL. * @exception NotOwnerException if the caller principal is * not on the owners list of the Acl. */ public void setName(Principal caller, String name) throws NotOwnerException { if (!isOwner(caller)) throw new NotOwnerException(); aclName = name; } /** * Returns the name of the ACL. * * @return the name of the ACL. */ public String getName() { return aclName; } /** * Adds an ACL entry to this ACL. An entry associates a * group or a principal with a set of permissions. Each * user or group can have one positive ACL entry and one * negative ACL entry. If there is one of the type (negative * or positive) already in the table, a false value is returned. * The caller principal must be a part of the owners list of * the ACL in order to invoke this method. * * @param caller the principal who is invoking this method. * @param entry the ACL entry that must be added to the ACL. * @return true on success, false if the entry is already present. * @exception NotOwnerException if the caller principal * is not on the owners list of the Acl. */ public synchronized boolean addEntry(Principal caller, AclEntry entry) throws NotOwnerException { if (!isOwner(caller)) throw new NotOwnerException(); Hashtable aclTable = findTable(entry); Principal key = entry.getPrincipal(); if (aclTable.get(key) != null) return false; aclTable.put(key, entry); return true; } /** * Removes an ACL entry from this ACL. * The caller principal must be a part of the owners list of the ACL * in order to invoke this method. * * @param caller the principal who is invoking this method. * @param entry the ACL entry that must be removed from the ACL. * @return true on success, false if the entry is not part of the ACL. * @exception NotOwnerException if the caller principal is not * the owners list of the Acl. */ public synchronized boolean removeEntry(Principal caller, AclEntry entry) throws NotOwnerException { if (!isOwner(caller)) throw new NotOwnerException(); Hashtable aclTable = findTable(entry); Object key = entry.getPrincipal(); Object o = aclTable.remove(key); return (o != null); } /** * This method returns the set of allowed permissions for the * specified principal. This set of allowed permissions is calculated * as follows: * * If there is no entry for a group or a principal an empty permission * set is assumed. * * The group positive permission set is the union of all * the positive permissions of each group that the individual belongs to. * The group negative permission set is the union of all * the negative permissions of each group that the individual belongs to. * If there is a specific permission that occurs in both * the postive permission set and the negative permission set, * it is removed from both. The group positive and negatoive permission * sets are calculated. * * The individial positive permission set and the individual negative * permission set is then calculated. Again abscence of an entry means * the empty set. * * The set of permissions granted to the principal is then calculated using * the simple rule: Individual permissions always override the Group permissions. * Specifically, individual negative permission set (specific * denial of permissions) overrides the group positive permission set. * And the individual positive permission set override the group negative * permission set. * * @param user the principal for which the ACL entry is returned. * @return The resulting permission set that the principal is allowed. * @deprecated Permission in java.security.acl has been deprecated and marked for removal */ @Deprecated public synchronized Enumeration getPermissions(Principal user) { Enumeration individualPositive; Enumeration individualNegative; Enumeration groupPositive; Enumeration groupNegative; // // canonicalize the sets. That is remove common permissions from // positive and negative sets. // groupPositive = subtract(getGroupPositive(user), getGroupNegative(user)); groupNegative = subtract(getGroupNegative(user), getGroupPositive(user)); individualPositive = subtract(getIndividualPositive(user), getIndividualNegative(user)); individualNegative = subtract(getIndividualNegative(user), getIndividualPositive(user)); // // net positive permissions is individual positive permissions // plus (group positive - individual negative). // Enumeration temp1 = subtract(groupPositive, individualNegative); Enumeration netPositive = union(individualPositive, temp1); // recalculate the enumeration since we lost it in performing the // subtraction // individualPositive = subtract(getIndividualPositive(user), getIndividualNegative(user)); individualNegative = subtract(getIndividualNegative(user), getIndividualPositive(user)); // // net negative permissions is individual negative permissions // plus (group negative - individual positive). // temp1 = subtract(groupNegative, individualPositive); Enumeration netNegative = union(individualNegative, temp1); return subtract(netPositive, netNegative); } /** * This method checks whether or not the specified principal * has the required permission. If permission is denied * permission false is returned, a true value is returned otherwise. * This method does not authenticate the principal. It presumes that * the principal is a valid authenticated principal. * * @param principal the name of the authenticated principal * @param permission the permission that the principal must have. * @return true of the principal has the permission desired, false * otherwise. */ public boolean checkPermission(Principal principal, Permission permission) { Enumeration permSet = getPermissions(principal); while (permSet.hasMoreElements()) { Permission p = permSet.nextElement(); if (p.equals(permission)) return true; } return false; } /** * returns an enumeration of the entries in this ACL. */ public synchronized Enumeration entries() { return new AclEnumerator(this, allowedUsersTable, allowedGroupsTable, deniedUsersTable, deniedGroupsTable); } /** * return a stringified version of the * ACL. */ public String toString() { StringBuffer sb = new StringBuffer(); Enumeration entries = entries(); while (entries.hasMoreElements()) { AclEntry entry = entries.nextElement(); sb.append(entry.toString().trim()); sb.append("\n"); } return sb.toString(); } // // Find the table that this entry belongs to. There are 4 // tables that are maintained. One each for postive and // negative ACLs and one each for groups and users. // This method figures out which // table is the one that this AclEntry belongs to. // private Hashtable findTable(AclEntry entry) { Hashtable aclTable = null; Principal p = entry.getPrincipal(); if (p instanceof Group) { if (entry.isNegative()) aclTable = deniedGroupsTable; else aclTable = allowedGroupsTable; } else { if (entry.isNegative()) aclTable = deniedUsersTable; else aclTable = allowedUsersTable; } return aclTable; } // // returns the set e1 U e2. // private Enumeration union(Enumeration e1, Enumeration e2) { Vector v = new Vector(20, 20); while (e1.hasMoreElements()) v.addElement(e1.nextElement()); while (e2.hasMoreElements()) { T o = e2.nextElement(); if (!v.contains(o)) v.addElement(o); } return v.elements(); } // // returns the set e1 - e2. // private Enumeration subtract(Enumeration e1, Enumeration e2) { Vector v = new Vector(20, 20); while (e1.hasMoreElements()) v.addElement(e1.nextElement()); while (e2.hasMoreElements()) { T o = e2.nextElement(); if (v.contains(o)) v.removeElement(o); } return v.elements(); } /** * @deprecated Permission in java.security.acl has been deprecated and marked for removal */ @Deprecated private Enumeration getGroupPositive(Principal user) { Enumeration groupPositive = zeroSet.elements(); Enumeration e = allowedGroupsTable.keys(); while (e.hasMoreElements()) { Group g = (Group) e.nextElement(); if (g.isMember(user)) { AclEntry ae = allowedGroupsTable.get(g); groupPositive = union(ae.permissions(), groupPositive); } } return groupPositive; } /** * @deprecated Permission in java.security.acl has been deprecated and marked for removal */ @Deprecated private Enumeration getGroupNegative(Principal user) { Enumeration groupNegative = zeroSet.elements(); Enumeration e = deniedGroupsTable.keys(); while (e.hasMoreElements()) { Group g = (Group) e.nextElement(); if (g.isMember(user)) { AclEntry ae = deniedGroupsTable.get(g); groupNegative = union(ae.permissions(), groupNegative); } } return groupNegative; } /** * @deprecated Permission in java.security.acl has been deprecated and marked for removal */ @Deprecated private Enumeration getIndividualPositive(Principal user) { Enumeration individualPositive = zeroSet.elements(); AclEntry ae = allowedUsersTable.get(user); if (ae != null) individualPositive = ae.permissions(); return individualPositive; } /** * @deprecated Permission in java.security.acl has been deprecated and marked for removal */ @Deprecated private Enumeration getIndividualNegative(Principal user) { Enumeration individualNegative = zeroSet.elements(); AclEntry ae = deniedUsersTable.get(user); if (ae != null) individualNegative = ae.permissions(); return individualNegative; } } /** * @deprecated Acl in java.security.acl has been deprecated and marked for removal * @deprecated AclEntry in java.security.acl has been deprecated and marked for removal */ @Deprecated final class AclEnumerator implements Enumeration { @Deprecated Acl acl; Enumeration u1, u2, g1, g2; /** * @deprecated AclEntry in java.security.acl has been deprecated and marked for removal * @deprecated Acl in java.security.acl has been deprecated and marked for removal */ @Deprecated AclEnumerator(Acl acl, Hashtable u1, Hashtable g1, Hashtable u2, Hashtable g2) { this.acl = acl; this.u1 = u1.elements(); this.u2 = u2.elements(); this.g1 = g1.elements(); this.g2 = g2.elements(); } public boolean hasMoreElements() { synchronized (acl) { return (u1.hasMoreElements() || u2.hasMoreElements() || g1.hasMoreElements() || g2.hasMoreElements()); } } public AclEntry nextElement() { synchronized (acl) { if (u1.hasMoreElements()) return u1.nextElement(); if (u2.hasMoreElements()) return u2.nextElement(); if (g1.hasMoreElements()) return g1.nextElement(); if (g2.hasMoreElements()) return g2.nextElement(); } throw new NoSuchElementException("Acl Enumerator"); } } jss-4.6.3/org/mozilla/jss/netscape/security/acl/AllPermissionsImpl.java000066400000000000000000000026201362106420000262130ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.acl; import java.security.acl.Permission; /** * This class implements the principal interface for the set of all permissions. * * @author Satish Dharmaraj */ public class AllPermissionsImpl extends PermissionImpl { public AllPermissionsImpl(String s) { super(s); } /** * This function returns true if the permission passed matches the permission represented in * this interface. * * @param another The Permission object to compare with. * @return true always */ public boolean equals(Permission another) { return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/acl/GroupImpl.java000066400000000000000000000135371362106420000243540ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.acl; import java.security.Principal; import java.security.acl.Group; import java.util.Enumeration; import java.util.Vector; /** * This class implements a group of principals. * * @author Satish Dharmaraj * @deprecated Group in java.security.acl has been deprecated and marked for removal */ @Deprecated public class GroupImpl implements Group { private Vector groupMembers = new Vector(50, 100); private String group; /** * Constructs a Group object with no members. * * @param groupName the name of the group */ public GroupImpl(String groupName) { this.group = groupName; } /** * adds the specified member to the group. * * @param user The principal to add to the group. * @return true if the member was added - false if the * member could not be added. */ public boolean addMember(Principal user) { if (groupMembers.contains(user)) return false; // do not allow groups to be added to itself. if (group.equals(user.toString())) throw new IllegalArgumentException(); groupMembers.addElement(user); return true; } /** * removes the specified member from the group. * * @param user The principal to remove from the group. * @return true if the principal was removed false if * the principal was not a member */ public boolean removeMember(Principal user) { return groupMembers.removeElement(user); } /** * returns the enumeration of the members in the group. */ public Enumeration members() { return groupMembers.elements(); } /** * This function returns true if the group passed matches * the group represented in this interface. * * @param another The group to compare this group to. * @deprecated Group in java.security.acl has been deprecated and marked for removal */ @Deprecated public boolean equals(Group another) { return group.equals(another.toString()); } /** * Prints a stringified version of the group. */ public String toString() { return group; } /** * return a hashcode for the principal. */ public int hashCode() { return group.hashCode(); } /** * returns true if the passed principal is a member of the group. * * @param member The principal whose membership must be checked for. * @return true if the principal is a member of this group, * false otherwise * @deprecated Group in java.security.acl has been deprecated and marked for removal */ @Deprecated public boolean isMember(Principal member) { // // if the member is part of the group (common case), return true. // if not, recursively search depth first in the group looking for the // principal. // if (groupMembers.contains(member)) { return true; } else { Vector alreadySeen = new Vector(10); return isMemberRecurse(member, alreadySeen); } } /** * return the name of the principal. */ public String getName() { return group; } /** * This function is the recursive search of groups for this * implementation of the Group. The search proceeds building up * a vector of already seen groups. Only new groups are considered, * thereby avoiding loops. * * @deprecated Group in java.security.acl has been deprecated and marked for removal */ @Deprecated boolean isMemberRecurse(Principal member, Vector alreadySeen) { Enumeration e = members(); while (e.hasMoreElements()) { boolean mem = false; Principal p = e.nextElement(); // if the member is in this collection, return true if (p.equals(member)) { return true; } else if (p instanceof GroupImpl) { // // if not recurse if the group has not been checked already. // Can call method in this package only if the object is an // instance of this class. Otherwise call the method defined // in the interface. (This can lead to a loop if a mixture of // implementations form a loop, but we live with this improbable // case rather than clutter the interface by forcing the // implementation of this method.) // @Deprecated GroupImpl g = (GroupImpl) p; alreadySeen.addElement(this); if (!alreadySeen.contains(g)) mem = g.isMemberRecurse(member, alreadySeen); } else if (p instanceof Group) { @Deprecated Group g = (Group) p; if (!alreadySeen.contains(g)) mem = g.isMember(member); } if (mem) return mem; } return false; } } jss-4.6.3/org/mozilla/jss/netscape/security/acl/OwnerImpl.java000066400000000000000000000103721362106420000243440ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.acl; import java.security.Principal; import java.security.acl.Group; import java.security.acl.LastOwnerException; import java.security.acl.NotOwnerException; import java.security.acl.Owner; import java.util.Enumeration; /** * Class implementing the Owner interface. The * initial owner principal is configured as * part of the constructor. * * @author Satish Dharmaraj * @deprecated Owner in java.security.acl has been deprecated and marked for removal */ @Deprecated public class OwnerImpl implements Owner { @Deprecated private Group ownerGroup; public OwnerImpl(Principal owner) { ownerGroup = new GroupImpl("AclOwners"); ownerGroup.addMember(owner); } /** * Adds an owner. Owners can modify ACL contents and can disassociate * ACLs from the objects they protect in the AclConfig interface. * The caller principal must be a part of the owners list of the ACL in * order to invoke this method. The initial owner is configured * at ACL construction time. * * @param caller the principal who is invoking this method. * @param owner The owner that should be added to the owners list. * @return true if success, false if already an owner. * @exception NotOwnerException if the caller principal is not on * the owners list of the Acl. * @deprecated LastOwnerException in java.security.acl has been deprecated and marked for removal */ @Deprecated public synchronized boolean addOwner(Principal caller, Principal owner) throws NotOwnerException { if (!isOwner(caller)) throw new NotOwnerException(); ownerGroup.addMember(owner); return false; } /** * Delete owner. If this is the last owner in the ACL, an exception is * raised. * The caller principal must be a part of the owners list of the ACL in * order to invoke this method. * * @param caller the principal who is invoking this method. * @param owner The owner to be removed from the owners list. * @return true if the owner is removed, false if the owner is not part * of the owners list. * @exception NotOwnerException if the caller principal is not on * the owners list of the Acl. * @exception LastOwnerException if there is only one owner left in the group, then * deleteOwner would leave the ACL owner-less. This exception is raised in such a case. * @deprecated LastOwnerException in java.security.acl has been deprecated and marked for removal */ @Deprecated public synchronized boolean deleteOwner(Principal caller, Principal owner) throws NotOwnerException, LastOwnerException { if (!isOwner(caller)) throw new NotOwnerException(); Enumeration e = ownerGroup.members(); // // check if there is atleast 2 members left. // e.nextElement(); // consume next element if (e.hasMoreElements()) return ownerGroup.removeMember(owner); else throw new LastOwnerException(); } /** * returns if the given principal belongs to the owner list. * * @param owner The owner to check if part of the owners list * @return true if the passed principal is in the owner list, false if not. */ public synchronized boolean isOwner(Principal owner) { return ownerGroup.isMember(owner); } } jss-4.6.3/org/mozilla/jss/netscape/security/acl/PermissionImpl.java000066400000000000000000000043371362106420000254060ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.acl; import java.security.acl.Permission; /** * The PermissionImpl class implements the permission * interface for permissions that are strings. * * @author Satish Dharmaraj */ public class PermissionImpl implements Permission { private String permission; /** * Construct a permission object using a string. * * @param permission the stringified version of the permission. */ public PermissionImpl(String permission) { this.permission = permission; } /** * This function returns true if the object passed matches the permission * represented in this interface. * * @param another The Permission object to compare with. * @return true if the Permission objects are equal, false otherwise */ public boolean equals(Object another) { if (another instanceof Permission) { Permission p = (Permission) another; return permission.equals(p.toString()); } else { return false; } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((permission == null) ? 0 : permission.hashCode()); return result; } /** * Prints a stringified version of the permission. * * @return the string representation of the Permission. */ public String toString() { return permission; } } jss-4.6.3/org/mozilla/jss/netscape/security/acl/PrincipalImpl.java000066400000000000000000000041751362106420000251770ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.acl; import java.security.Principal; /** * This class implements the principal interface. * * @author Satish Dharmaraj */ public class PrincipalImpl implements Principal { private String user; /** * Construct a principal from a string user name. * * @param user The string form of the principal name. */ public PrincipalImpl(String user) { this.user = user; } /** * This function returns true if the object passed matches * the principal represented in this implementation * * @param another the Principal to compare with. * @return true if the Principal passed is the same as that * encapsulated in this object, false otherwise */ public boolean equals(Object another) { if (another instanceof PrincipalImpl) { PrincipalImpl p = (PrincipalImpl) another; return user.equals(p.toString()); } else return false; } /** * Prints a stringified version of the principal. */ public String toString() { return user; } /** * return a hashcode for the principal. */ public int hashCode() { return user.hashCode(); } /** * return the name of the principal. */ public String getName() { return user; } } jss-4.6.3/org/mozilla/jss/netscape/security/acl/WorldGroupImpl.java000066400000000000000000000031761362106420000253620ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.acl; import java.security.Principal; /** * This class implements a group of principals. * * @author Satish Dharmaraj * @deprecated GroupImpl in org.mozilla.jss.netscape.security.acl has been deprecated */ @Deprecated public class WorldGroupImpl extends GroupImpl { /** * @deprecated GroupImpl in org.mozilla.jss.netscape.security.acl has been deprecated */ @Deprecated public WorldGroupImpl(String s) { super(s); } /** * returns true for all passed principals * * @param member The principal whose membership must be checked in this Group. * @return true always since this is the "world" group. * @deprecated isMember(Principal) in GroupImpl has been deprecated */ @Deprecated public boolean isMember(Principal member) { return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/000077500000000000000000000000001362106420000232225ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/netscape/security/extensions/AccessDescription.java000066400000000000000000000047701362106420000275020ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.IOException; import java.io.Serializable; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.GeneralName; public class AccessDescription implements Serializable { ObjectIdentifier mOID = null; GeneralName mLocation = null; AccessDescription(ObjectIdentifier oid, GeneralName location) { mOID = oid; mLocation = location; } public ObjectIdentifier getMethod() { return mOID; } public GeneralName getLocation() { return mLocation; } /** * For serialization: * Note that GeneralName is not serializable. That is * why we need to define our own serialization method. */ private void writeObject(java.io.ObjectOutputStream out) throws IOException { try (DerOutputStream seq = new DerOutputStream(); DerOutputStream tmp = new DerOutputStream()) { tmp.putOID(mOID); mLocation.encode(tmp); seq.write(DerValue.tag_Sequence, tmp); out.write(seq.toByteArray()); } } /** * For serialization * Note that GeneralName is not serializable. That is * why we need to define our own serialization method. */ private void readObject(java.io.ObjectInputStream in) throws IOException { DerValue val = new DerValue(in); DerValue seq = val.data.getDerValue(); mOID = seq.getOID(); DerValue derLoc = val.data.getDerValue(); mLocation = new GeneralName(derLoc); } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/AuthInfoAccessExtension.java000066400000000000000000000221321362106420000306210ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.CertAttrSet; import org.mozilla.jss.netscape.security.x509.Extension; import org.mozilla.jss.netscape.security.x509.GeneralName; import org.mozilla.jss.netscape.security.x509.URIName; import org.mozilla.jss.netscape.security.util.Utils; /** * This represents the authority information access extension * as defined in RFC2459. * * id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) * internet(1) security(5) mechanisms(5) * pkix(7) } } * id-pe OBJECT IDENTIFIER ::= { id-pkix 1 } * id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 } * AuthorityInfoAccessSyntax ::= SEQUENCE SIZE (1..MAX) OF AccessDescription * AccessDescription ::= SEQUENCE { * accessMethod OBJECT IDENTIFIER, * accessLocation GeneralName * } * id-ad OBJECT IDENTIFIER ::= { id-pkix 48 } * id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 } * id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 } * * Need to make sure the following is added to CMS.cfg: * oidmap.auth_info_access.class=com.netscape.certsrv.cert.AuthInfoAccessExtension * oidmap.auth_info_access.oid=1.3.6.1.5.5.7.1.1 * * @author thomask * @version $Revision$, $Date$ */ public class AuthInfoAccessExtension extends Extension implements CertAttrSet { private static final long serialVersionUID = 7373316523212538446L; public static final String NAME = "AuthInfoAccessExtension"; public static final String NAME2 = "AuthorityInformationAccess"; public static final int OID_OCSP[] = { 1, 3, 6, 1, 5, 5, 7, 48, 1 }; public static final ObjectIdentifier METHOD_OCSP = new ObjectIdentifier(OID_OCSP); public static final int OID_CA_ISSUERS[] = { 1, 3, 6, 1, 5, 5, 7, 48, 2 }; public static final ObjectIdentifier METHOD_CA_ISSUERS = new ObjectIdentifier(OID_CA_ISSUERS); public static final int OID[] = { 1, 3, 6, 1, 5, 5, 7, 1, 1 }; public static final ObjectIdentifier ID = new ObjectIdentifier(OID); private Vector mDesc = new Vector(); /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. */ public AuthInfoAccessExtension(boolean critical) { this.extensionId = ID; this.critical = critical; this.extensionValue = null; // build this when encodeThis() is called } /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public AuthInfoAccessExtension(Boolean critical, Object value) throws IOException { this.extensionId = ID; this.critical = critical.booleanValue(); this.extensionValue = ((byte[]) value).clone(); decodeThis(); } /** * Sets extension attribute. */ public void set(String name, Object obj) throws CertificateException { // NOT USED } /** * Retrieves extension attribute. */ public Object get(String name) throws CertificateException { // NOT USED return null; } /** * Deletes attribute. */ public void delete(String name) throws CertificateException { // NOT USED } /** * Decodes this extension. */ public void decode(InputStream in) throws IOException { // NOT USED } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { // NOT USED return null; } /** * Return the name of this attribute. */ public String getName() { return NAME; } /** * Adds Access Description. */ public void addAccessDescription( ObjectIdentifier method, GeneralName gn) { clearValue(); mDesc.addElement(new AccessDescription(method, gn)); } public AccessDescription getAccessDescription(int pos) { return mDesc.elementAt(pos); } /** * Returns the number of access description. */ public int numberOfAccessDescription() { return mDesc.size(); } private void decodeThis() throws IOException { DerValue val = new DerValue(this.extensionValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding of AuthInfoAccess extension"); } while (val.data.available() != 0) { DerValue seq = val.data.getDerValue(); ObjectIdentifier method = seq.data.getDerValue().getOID(); GeneralName gn = new GeneralName(seq.data.getDerValue()); addAccessDescription(method, gn); } } private void encodeThis() throws IOException { try (DerOutputStream seq = new DerOutputStream(); DerOutputStream tmp = new DerOutputStream()) { for (int i = 0; i < mDesc.size(); i++) { DerOutputStream tmp0 = new DerOutputStream(); AccessDescription ad = mDesc.elementAt(i); tmp0.putOID(ad.getMethod()); ad.getLocation().encode(tmp0); tmp.write(DerValue.tag_Sequence, tmp0); } seq.write(DerValue.tag_Sequence, tmp); this.extensionValue = seq.toByteArray(); } } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Returns a printable representation of the AuthInfoAccess. */ public String toString() { StringBuffer s = new StringBuffer(); String b = super.toString() + "AuthInfoAccess [\n"; s.append(b); for (int i = 0; i < mDesc.size(); i++) { AccessDescription ad = mDesc.elementAt(i); s.append("(" + i + ")"); s.append(" "); s.append(ad.getMethod().toString() + " " + ad.getLocation().toString()); } return (s.toString() + "]\n"); } public static void main(String[] argv) { AuthInfoAccessExtension aia = new AuthInfoAccessExtension(false); GeneralName ocspName = new GeneralName(new URIName("http://ocsp.netscape.com")); aia.addAccessDescription(METHOD_OCSP, ocspName); GeneralName caIssuersName = new GeneralName(new URIName("http://ocsp.netscape.com")); aia.addAccessDescription(METHOD_CA_ISSUERS, caIssuersName); ByteArrayOutputStream os = new ByteArrayOutputStream(); try { aia.encode(os); System.out.println(Utils.base64encode(os.toByteArray(), true)); } catch (IOException e) { System.out.println(e.toString()); } try { // test serialization ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(aia); ByteArrayInputStream bis = new ByteArrayInputStream( bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); AuthInfoAccessExtension clone = (AuthInfoAccessExtension) ois.readObject(); System.out.println(clone); } catch (Exception e) { System.out.println(e.toString()); } } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/CertInfo.java000066400000000000000000000117241362106420000256030ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.IOException; import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.util.Date; import org.mozilla.jss.netscape.security.x509.AlgorithmId; import org.mozilla.jss.netscape.security.x509.CertificateAlgorithmId; import org.mozilla.jss.netscape.security.x509.CertificateIssuerName; import org.mozilla.jss.netscape.security.x509.CertificateSerialNumber; import org.mozilla.jss.netscape.security.x509.CertificateSubjectName; import org.mozilla.jss.netscape.security.x509.CertificateValidity; import org.mozilla.jss.netscape.security.x509.CertificateVersion; import org.mozilla.jss.netscape.security.x509.X500Name; import org.mozilla.jss.netscape.security.x509.X509CertInfo; /** * Extends X509CertInfo class so that minimal fields are initialized at * creation time so an object of this type is always serializable. */ public class CertInfo extends X509CertInfo { /** * */ private static final long serialVersionUID = -2883888348288591989L; public static final CertificateSubjectName SERIALIZE_SUBJECT; public static final CertificateIssuerName SERIALIZE_ISSUER; public static final CertificateValidity SERIALIZE_VALIDITY; public static final CertificateSerialNumber SERIALIZE_SERIALNO; public static final CertificateAlgorithmId SERIALIZE_ALGOR; public static final CertificateVersion FORCE_VERSION_3; static { try { // force version 3 FORCE_VERSION_3 = new CertificateVersion(CertificateVersion.V3); SERIALIZE_SUBJECT = new CertificateSubjectName( new X500Name("cn=uninitialized")); SERIALIZE_ISSUER = new CertificateIssuerName( new X500Name("cn=uninitialized")); SERIALIZE_VALIDITY = new CertificateValidity(new Date(0), new Date(0)); SERIALIZE_SERIALNO = new CertificateSerialNumber(new BigInteger("0")); SERIALIZE_ALGOR = new CertificateAlgorithmId(AlgorithmId.get("MD5withRSA")); } catch (IOException e) { // should never happen. If does, system is hosed. System.out.println("**** Impossible Error encountered ****"); throw new RuntimeException(e.toString()); } catch (NoSuchAlgorithmException e) { // should never happen. If does, system is hosed. System.out.println("**** Impossible Error encountered ****"); throw new RuntimeException(e.toString()); } } /** * Initializes most fields required by der encoding so object will * serialize properly. */ // XXX should write a class to use something else for serialization // but this is faster and done now for the time crunch. public CertInfo() { super(); makeSerializable(this); } public static void makeSerializable(X509CertInfo certinfo) { try { // force version 3. certinfo.set(X509CertInfo.VERSION, FORCE_VERSION_3); if (certinfo.get(X509CertInfo.SERIAL_NUMBER) == null) { certinfo.set(X509CertInfo.SERIAL_NUMBER, SERIALIZE_SERIALNO); } if (certinfo.get(X509CertInfo.ALGORITHM_ID) == null) { certinfo.set(X509CertInfo.ALGORITHM_ID, SERIALIZE_ALGOR); } if (certinfo.get(X509CertInfo.ISSUER) == null) { certinfo.set(X509CertInfo.ISSUER, SERIALIZE_ISSUER); } if (certinfo.get(X509CertInfo.VALIDITY) == null) { certinfo.set(X509CertInfo.VALIDITY, SERIALIZE_VALIDITY); } // set subject name anyway - it'll get overwritten. if (certinfo.get(X509CertInfo.SUBJECT) == null) { certinfo.set(X509CertInfo.SUBJECT, SERIALIZE_SUBJECT); } // key is set later in the request. } // these exceptions shouldn't happen here unless the // whole process is hosed. catch (CertificateException e) { } catch (IOException e) { } } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/CertificateRenewalWindowExtension.java000066400000000000000000000131261362106420000327150ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Date; import java.util.Enumeration; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.CertAttrSet; import org.mozilla.jss.netscape.security.x509.Extension; /** * This represents the CertificateRenewalWindow extension * as defined in draft-thayes-cert-renewal-00 * * CertificateRenewalWindow ::= SEQUENCE { * beginTime GeneralizedTime, * endTime GeneralizedTime OPTIONAL } * * @author thomask * @version $Revision$, $Date$ */ public class CertificateRenewalWindowExtension extends Extension implements CertAttrSet { private static final long serialVersionUID = 4470220533545299271L; public static final String NAME = "CertificateRenewalWindow"; public static final int OID[] = { 2, 16, 840, 1, 113730, 1, 15 }; public static final ObjectIdentifier ID = new ObjectIdentifier(OID); private Date mBeginTime = null; private Date mEndTime = null; // optional public CertificateRenewalWindowExtension(boolean critical, Date beginTime, Date endTime) throws IOException { this.extensionId = ID; this.critical = critical; mBeginTime = beginTime; mEndTime = endTime; encodeThis(); } public CertificateRenewalWindowExtension(boolean critical) { this.extensionId = ID; this.critical = critical; this.extensionValue = null; // build this when encodeThis() is called } public CertificateRenewalWindowExtension(Boolean critical, Object value) throws IOException { this.extensionId = ID; this.critical = critical.booleanValue(); this.extensionValue = ((byte[]) value).clone(); decodeThis(); } public String getName() { return NAME; } /** * Sets extension attribute. */ public void set(String name, Object obj) throws CertificateException { // NOT USED } /** * Retrieves extension attribute. */ public Object get(String name) throws CertificateException { // NOT USED return null; } /** * Deletes attribute. */ public void delete(String name) throws CertificateException { // NOT USED } /** * Decodes this extension. */ public void decode(InputStream in) throws IOException { // NOT USED } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { // NOT USED return null; } public Date getBeginTime() { return mBeginTime; } public Date getEndTime() { return mEndTime; } public void setBeginTime(Date d) { mBeginTime = d; } public void setEndTime(Date d) { mEndTime = d; } private void decodeThis() throws IOException { DerValue val = new DerValue(this.extensionValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding of CertificateWindow extension"); } while (val.data.available() != 0) { if (mBeginTime == null) { mBeginTime = val.data.getGeneralizedTime(); } else { mEndTime = val.data.getGeneralizedTime(); } } } private void encodeThis() throws IOException { try (DerOutputStream seq = new DerOutputStream(); DerOutputStream tmp = new DerOutputStream()) { tmp.putGeneralizedTime(mBeginTime); if (mEndTime != null) { tmp.putGeneralizedTime(mEndTime); } seq.write(DerValue.tag_Sequence, tmp); this.extensionValue = seq.toByteArray(); } } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Returns a printable representation of the CertificateRenewalWindow. */ public String toString() { String s = super.toString() + "CertificateRenewalWindow [\n"; s += "BeginTime: " + mBeginTime + "\n"; if (mEndTime != null) { s += "EndTime: " + mEndTime; } return (s + "]\n"); } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/CertificateScopeEntry.java000066400000000000000000000056741362106420000303370ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.IOException; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.x509.GeneralName; /** * This represents the CertificateScopeOfUse extension * as defined in draft-thayes-cert-scope-00 * * CertificateScopeEntry ::= SEQUENCE { * name GeneralName, -- pattern, as for NameConstraints * portNumber INTEGER OPTIONAL * } * CertificateScopeOfUse ::= SEQUENCE OF CertificateScopeEntry * * @author thomask * @version $Revision$, $Date$ */ public class CertificateScopeEntry { private GeneralName mGn = null; private BigInt mPort = null; /** * Constructs scope with der value. */ public CertificateScopeEntry(DerValue val) throws IOException { if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for PolicyQualifierInfo."); } DerValue gn = val.data.getDerValue(); mGn = new GeneralName(gn); if (val.data.available() != 0) { mPort = val.data.getInteger(); } } /** * Constructs scope wit */ public CertificateScopeEntry(GeneralName gn, BigInt port) { mGn = gn; mPort = port; // optional } public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); mGn.encode(tmp); if (mPort != null) { tmp.putInteger(mPort); } out.write(DerValue.tag_Sequence, tmp); } /** * Returns a GeneralName */ public GeneralName getGeneralName() { return mGn; } /** * Returns a port */ public BigInt getPort() { return mPort; } /** * Returns a printable representation of the CertificateRenewalWindow. */ public String toString() { String s = super.toString() + "CertificateScopeEntry [\n"; s += "GeneralName: " + mGn; if (mPort != null) { s += "PortNumber: " + mPort; } return (s + "]\n"); } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/CertificateScopeOfUseExtension.java000066400000000000000000000140221362106420000321370ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.CertAttrSet; import org.mozilla.jss.netscape.security.x509.Extension; import org.mozilla.jss.netscape.security.x509.OIDMap; /** * This represents the CertificateScopeOfUse extension * as defined in draft-thayes-cert-scope-00 * * CertificateScopeEntry ::= SEQUENCE { * name GeneralName, -- pattern, as for NameConstraints * portNumber INTEGER OPTIONAL * } * CertificateScopeOfUse ::= SEQUENCE OF CertificateScopeEntry * * @author thomask * @version $Revision$, $Date$ */ public class CertificateScopeOfUseExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 2143292831971567770L; public static final String NAME = "CertificateScopeOfUse"; public static final int OID[] = { 2, 16, 840, 1, 113730, 1, 17 }; public static final ObjectIdentifier ID = new ObjectIdentifier(OID); private Vector mEntries = null; static { try { OIDMap.addAttribute(CertificateScopeOfUseExtension.class.getName(), ID.toString(), NAME); } catch (CertificateException e) { } } public CertificateScopeOfUseExtension(boolean critical, Vector scopeEntries) throws IOException { this.extensionId = ID; this.critical = critical; this.extensionValue = null; // build this when encodeThis() is called mEntries = scopeEntries; encodeThis(); } public CertificateScopeOfUseExtension(boolean critical) { this.extensionId = ID; this.critical = critical; this.extensionValue = null; // build this when encodeThis() is called } public CertificateScopeOfUseExtension(Boolean critical, Object value) throws IOException { this.extensionId = ID; this.critical = critical.booleanValue(); this.extensionValue = ((byte[]) value).clone(); decodeThis(); } public String getName() { return NAME; } public Vector getCertificateScopeEntries() { return mEntries; } /** * Sets extension attribute. */ public void set(String name, Object obj) throws CertificateException { // NOT USED } /** * Retrieves extension attribute. */ public Object get(String name) throws CertificateException { // NOT USED return null; } /** * Deletes attribute. */ public void delete(String name) throws CertificateException { // NOT USED } /** * Decodes this extension. */ public void decode(InputStream in) throws IOException { // NOT USED } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { // NOT USED return null; } private void decodeThis() throws IOException { DerValue val = new DerValue(this.extensionValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding of CertificateWindow extension"); } mEntries = new Vector(); while (val.data.available() != 0) { mEntries.addElement(new CertificateScopeEntry( val.data.getDerValue())); } } private void encodeThis() throws IOException { try (DerOutputStream seq = new DerOutputStream(); DerOutputStream tmp = new DerOutputStream()) { if (mEntries == null) throw new IOException("Invalid Scope Entries"); for (int i = 0; i < mEntries.size(); i++) { CertificateScopeEntry se = mEntries.elementAt(i); se.encode(tmp); } seq.write(DerValue.tag_Sequence, tmp); this.extensionValue = seq.toByteArray(); } } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Returns a printable representation of the CertificateRenewalWindow. */ public String toString() { StringBuffer s = new StringBuffer(super.toString() + "CertificateUseOfScope [\n"); if (mEntries != null) { for (int i = 0; i < mEntries.size(); i++) { CertificateScopeEntry se = mEntries.elementAt(i); s.append(se.toString()); } } return (s.toString() + "]\n"); } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/ExtendedKeyUsageExtension.java000066400000000000000000000155131362106420000311650ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.CertAttrSet; import org.mozilla.jss.netscape.security.x509.Extension; import org.mozilla.jss.netscape.security.x509.OIDMap; /** * This represents the extended key usage extension. */ public class ExtendedKeyUsageExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 765403075764697489L; public static final String OID = "2.5.29.37"; public static final String NAME = OIDMap.EXT_KEY_USAGE_NAME; public static final String OID_OCSPSigning = "1.3.6.1.5.5.7.3.9"; public static final String OID_CODESigning = "1.3.6.1.5.5.7.3.3"; public static final int OID_OCSP_SIGNING_STR[] = { 1, 3, 6, 1, 5, 5, 7, 3, 9 }; public static final ObjectIdentifier OID_OCSP_SIGNING = new ObjectIdentifier(OID_OCSP_SIGNING_STR); public static final int OID_CODE_SIGNING_STR[] = { 1, 3, 6, 1, 5, 5, 7, 3, 3 }; public static final ObjectIdentifier OID_CODE_SIGNING = new ObjectIdentifier(OID_OCSP_SIGNING_STR); private Vector oidSet = null; private byte mCached[] = null; static { try { OIDMap.addAttribute(ExtendedKeyUsageExtension.class.getName(), OID, ExtendedKeyUsageExtension.NAME); } catch (CertificateException e) { } } public ExtendedKeyUsageExtension() throws IOException { this(false, null); } public ExtendedKeyUsageExtension(boolean crit, Vector oids) throws IOException { try { extensionId = ObjectIdentifier.getObjectIdentifier(OID); } catch (IOException e) { // never here } critical = crit; if (oids != null) { oidSet = new Vector(oids); } else { oidSet = new Vector(); } encodeExtValue(); } public ExtendedKeyUsageExtension(Boolean crit, Object byteVal) throws IOException { extensionId = ObjectIdentifier.getObjectIdentifier(OID); critical = crit.booleanValue(); extensionValue = ((byte[]) byteVal).clone(); decodeThis(); } public void setCritical(boolean newValue) { if (critical != newValue) { critical = newValue; mCached = null; } } public Enumeration getOIDs() { if (oidSet == null) return null; return oidSet.elements(); } public void deleteAllOIDs() { if (oidSet == null) return; oidSet.clear(); } public void addOID(ObjectIdentifier oid) { if (oidSet == null) { oidSet = new Vector(); } if (oidSet.contains(oid)) return; oidSet.addElement(oid); mCached = null; } public void encode(DerOutputStream out) throws IOException { if (mCached == null) { encodeExtValue(); super.encode(out); mCached = out.toByteArray(); } } @Override public String toString() { String presentation = "oid=" + ExtendedKeyUsageExtension.OID + " "; if (critical) { presentation += "critical=true"; } if (extensionValue != null) { StringBuffer extByteValue = new StringBuffer(" val="); for (int i = 0; i < extensionValue.length; i++) { extByteValue.append(extensionValue[i] + " "); } presentation += extByteValue.toString(); } return presentation; } public void decode(InputStream in) throws CertificateException, IOException { } public void encode(OutputStream out) throws CertificateException, IOException { if (mCached == null) { DerOutputStream temp = new DerOutputStream(); encode(temp); } out.write(mCached); } public void set(String name, Object obj) throws CertificateException, IOException { // NOT USED } public Object get(String name) throws CertificateException, IOException { // NOT USED return null; } public Enumeration getAttributeNames() { return null; } public String getName() { return NAME; } public void delete(String name) throws CertificateException, IOException { // NOT USED } private void decodeThis() throws IOException { DerValue val = new DerValue(this.extensionValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding of AuthInfoAccess extension"); } if (oidSet == null) oidSet = new Vector(); while (val.data.available() != 0) { DerValue oidVal = val.data.getDerValue(); oidSet.addElement(oidVal.getOID()); } } private void encodeExtValue() throws IOException { DerOutputStream out = new DerOutputStream(); DerOutputStream temp = new DerOutputStream(); if (!oidSet.isEmpty()) { Enumeration oidList = oidSet.elements(); try { while (oidList.hasMoreElements()) { temp.putOID(oidList.nextElement()); } } catch (IOException ex) { ex.printStackTrace(); } } try { out.write(DerValue.tag_Sequence, temp); } catch (IOException ex) { } finally { out.close(); } extensionValue = out.toByteArray(); } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/GenericASN1Extension.java000066400000000000000000000367431362106420000277760ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.security.cert.CertificateException; import java.text.DateFormat; import java.text.ParseException; import java.util.Enumeration; import java.util.Hashtable; import java.util.StringTokenizer; import java.util.Vector; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.CertAttrSet; import org.mozilla.jss.netscape.security.x509.Extension; import org.mozilla.jss.netscape.security.x509.OIDMap; /** * Represent the AsnInteger Extension. */ public class GenericASN1Extension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 8047548816784949009L; protected static final int MAX_ATTR = 10; protected static final String PROP_CRITICAL = "critical"; protected static final String PROP_NAME = "name"; protected static final String PROP_OID = "oid"; protected static final String PROP_PATTERN = "pattern"; protected static final String PROP_ATTRIBUTE = "attribute"; protected static final String PROP_TYPE = "type"; protected static final String PROP_SOURCE = "source"; protected static final String PROP_VALUE = "value"; protected static final String PROP_PREDICATE = "predicate"; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ private String name; public String OID = null; public static Hashtable mConfig = null; public String pattern = null; private int index = 0; // Encode this value private void encodeThis() throws IOException, ParseException { this.extensionValue = encodePattern(); } // Encode pattern private byte[] encodePattern() throws IOException, ParseException { DerOutputStream tmp = new DerOutputStream(); String type = null; String value = null; String source = null; while (index < pattern.length()) { char ch = pattern.charAt(index); switch (ch) { case '{': index++; byte[] buff = encodePattern(); tmp.putDerValue(new DerValue(buff)); break; case '}': try (DerOutputStream os = new DerOutputStream()) { os.write(DerValue.tag_Sequence, tmp); return os.toByteArray(); } default: type = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_TYPE); if (type.equalsIgnoreCase("integer")) { int num = Integer.parseInt(mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE)); PutInteger(tmp, num); } else if (type.equalsIgnoreCase("ia5string")) { source = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE); value = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); if (source.equalsIgnoreCase("file")) PutIA5String(tmp, getFromFile(value)); else PutIA5String(tmp, value); } else if (type.equalsIgnoreCase("octetstring")) { source = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE); value = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); // It should be colon seperated ASCII Hexdecimal String if (source.equalsIgnoreCase("file")) PutOctetString(tmp, getFromFile(value)); else PutOctetString(tmp, value); } else if (type.equalsIgnoreCase("bmpstring")) { source = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE); value = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); if (source.equalsIgnoreCase("file")) PutBMPString(tmp, getFromFile(value)); else PutBMPString(tmp, value); } else if (type.equalsIgnoreCase("printablestring")) { source = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE); value = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); if (source.equalsIgnoreCase("file")) PutPrintableString(tmp, getFromFile(value)); else PutPrintableString(tmp, value); } else if (type.equalsIgnoreCase("visiblestring")) { source = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE); value = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); if (source.equalsIgnoreCase("file")) PutVisibleString(tmp, getFromFile(value)); else PutVisibleString(tmp, value); } else if (type.equalsIgnoreCase("utctime")) { value = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); PutUTCtime(tmp, value); } else if (type.equalsIgnoreCase("oid")) { value = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); PutOID(tmp, value); } else if (type.equalsIgnoreCase("boolean")) { boolean bool = false; String b = mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); if (b.equalsIgnoreCase("true")) bool = true; else bool = false; PutBoolean(tmp, bool); } else if (type.equalsIgnoreCase("null")) { tmp.putNull(); } else { throw new ParseException("Unknown Attribute Type", 0); } } index++; } return tmp.toByteArray(); } /** * Create a GenericASN1Extension with the value and oid. * The criticality is set to false. * * @param name the name of this extension * @param oid the object identifier of this extension * @param pattern to use for encoding this extension * @param critical true if the extension should be treated as critical * @param config additional configuration for this extension */ public GenericASN1Extension(String name, String oid, String pattern, boolean critical, Hashtable config) throws IOException, ParseException { ObjectIdentifier tmpid = new ObjectIdentifier(oid); this.name = name; OID = oid; mConfig = config; this.pattern = pattern; try { if (OIDMap.getName(tmpid) == null) OIDMap.addAttribute("org.mozilla.jss.netscape.security.x509.GenericASN1Extension", oid, name); } catch (CertificateException e) { } this.extensionId = tmpid; this.critical = critical; encodeThis(); } /** * Create a GenericASN1Extension with the value and oid. * The criticality is set to false. * * @param config the values to be set for the extension. */ public GenericASN1Extension(Hashtable config) throws IOException, ParseException { mConfig = config; ObjectIdentifier tmpid = new ObjectIdentifier(mConfig.get(PROP_OID)); name = mConfig.get(PROP_NAME); OID = mConfig.get(PROP_OID); pattern = mConfig.get(PROP_PATTERN); try { if (OIDMap.getName(tmpid) == null) OIDMap.addAttribute("GenericASN1Extension", OID, name); } catch (CertificateException e) { } this.extensionId = tmpid; this.critical = false; String b = mConfig.get(PROP_CRITICAL); if (b.equalsIgnoreCase("true")) this.critical = true; else this.critical = false; encodeThis(); } /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public GenericASN1Extension(Boolean critical, Object value) throws IOException { this.extensionId = new ObjectIdentifier(OID); this.critical = critical.booleanValue(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { throw new IOException("Method not to be called directly."); } /** * Get the attribute value. */ public Object get(String name) throws IOException { return null; } /** * Delete the attribute value. */ public void delete(String name) throws IOException { throw new IOException("Method not to be called directly."); } /** * Returns a printable representation of the GenericASN1Extension. */ @Override public String toString() { return (null); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); try { if (this.extensionValue == null) { this.extensionId = new ObjectIdentifier(OID); this.critical = true; encodeThis(); } } catch (ParseException e) { } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Return the name of this attribute. */ public String getName() { return name; } /** * Set the name of this attribute. */ public void setName(String name) { this.name = name; } /** * Return the OID of this attribute. */ public String getOID() { return OID; } /** * Set the OID of this attribute. */ public void setOID(String oid) { OID = oid; } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement("octet"); return (elements.elements()); } private void PutInteger(DerOutputStream os, int number) throws IOException, ParseException { os.putInteger(new BigInt(number)); return; } private void PutIA5String(DerOutputStream os, String value) throws IOException, ParseException { os.putIA5String(value); return; } private void PutOctetString(DerOutputStream os, String value) throws IOException, ParseException { StringTokenizer token = new StringTokenizer(value, ":"); byte[] octets = new byte[token.countTokens()]; for (int i = 0; token.hasMoreElements(); i++) { String num = (String) token.nextElement(); octets[i] = (byte) Integer.parseInt(num, 16); } os.putOctetString(octets); return; } private void PutBMPString(DerOutputStream os, String value) throws IOException, ParseException { os.putBMPString(value); return; } private void PutPrintableString(DerOutputStream os, String value) throws IOException, ParseException { os.putPrintableString(value); return; } private void PutVisibleString(DerOutputStream os, String value) throws IOException, ParseException { os.putVisibleString(value); return; } private void PutUTCtime(DerOutputStream os, String value) throws IOException, ParseException { DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); os.putUTCTime(df.parse(value)); return; } private void PutOID(DerOutputStream os, String value) throws IOException, ParseException { os.putOID(new ObjectIdentifier(value)); return; } private void PutBoolean(DerOutputStream os, boolean value) throws IOException, ParseException { os.putBoolean(value); return; } private String getFromFile(String fname) throws IOException { String s = null; byte[] buff = null; int i = 0; int j = 0; if ((fname == null) || (fname.equals(""))) { throw new IOException("File name is not provided."); } FileInputStream fis = null; try { fis = new FileInputStream(fname); int n = 0; while ((n = fis.available()) > 0) { buff = new byte[n]; int result = fis.read(buff); if (result == -1) break; s = new String(buff); } } finally { if (fis != null) { fis.close(); } } if (s == null) { return ""; } for (i = 0, j = 0; j < s.length(); j++) { int ch = s.charAt(j); if (ch == 10 || ch == 13 || ch == 9) continue; i++; } buff = new byte[i]; for (i = 0, j = 0; j < s.length(); j++) { int ch = s.charAt(j); if (ch == 10 || ch == 13 || ch == 9) continue; buff[i++] = (byte) ch; } s = new String(buff); return s; } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/InhibitAnyPolicyExtension.java000066400000000000000000000124741362106420000312100ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.security.cert.CertificateException; import java.util.Enumeration; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.CertAttrSet; import org.mozilla.jss.netscape.security.x509.Extension; import org.mozilla.jss.netscape.security.x509.OIDMap; /** * RFC3280: * * id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } * * InhibitAnyPolicy ::= SkipCerts * * SkipCerts ::= INTEGER (0..MAX) */ public class InhibitAnyPolicyExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -8963439897419343166L; public static final String OID = "2.5.29.54"; public static final String NAME = OIDMap.EXT_INHIBIT_ANY_POLICY_NAME; private BigInt mSkipCerts = new BigInt(-1); static { try { OIDMap.addAttribute(InhibitAnyPolicyExtension.class.getName(), OID, NAME); } catch (CertificateException e) { } } public InhibitAnyPolicyExtension() throws IOException { this(false, null); } public InhibitAnyPolicyExtension(boolean crit, BigInt skipCerts) throws IOException { try { extensionId = ObjectIdentifier.getObjectIdentifier(OID); } catch (IOException e) { // never here } critical = crit; mSkipCerts = skipCerts; encodeExtValue(); } public InhibitAnyPolicyExtension(Boolean crit, Object value) throws IOException { extensionId = ObjectIdentifier.getObjectIdentifier(OID); critical = crit.booleanValue(); //extensionValue = (byte[]) ((byte[]) byteVal).clone(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } extensionValue = extValue; decodeThis(); } public void setCritical(boolean newValue) { if (critical != newValue) { critical = newValue; } } public BigInt getSkipCerts() { return mSkipCerts; } @Override public String toString() { String presentation = "ObjectId: " + OID + " "; if (critical) { presentation += "Criticality=true"; } else { presentation += "Criticality=false"; } if (extensionValue != null) { String extByteValue = " skipCerts=" + mSkipCerts; presentation += extByteValue; } return presentation; } public void decode(InputStream in) throws CertificateException, IOException { } public void set(String name, Object obj) throws CertificateException, IOException { // NOT USED } public Object get(String name) throws CertificateException, IOException { // NOT USED return null; } public Enumeration getAttributeNames() { return null; } public String getName() { return NAME; } public void delete(String name) throws CertificateException, IOException { // NOT USED } private void decodeThis() throws IOException { DerValue val = new DerValue(this.extensionValue); mSkipCerts = val.getInteger(); } public void encode(OutputStream out) throws IOException { try (DerOutputStream os = new DerOutputStream()) { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { try { extensionId = ObjectIdentifier.getObjectIdentifier(OID); } catch (IOException e) { // never here } os.putInteger(mSkipCerts); this.extensionValue = os.toByteArray(); } super.encode(tmp); out.write(tmp.toByteArray()); } } private void encodeExtValue() throws IOException { DerOutputStream out = new DerOutputStream(); try { out.putInteger(mSkipCerts); } catch (IOException e) { } finally { out.close(); } extensionValue = out.toByteArray(); } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/KerberosName.java000066400000000000000000000113671362106420000264520ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Vector; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * This represents a KerberosName as defined in * RFC 1510. * * KerberosName ::= SEQUENCE { * realm [0] Realm, * principalName [1] CertPrincipalName -- defined above * } * * CertPrincipalName ::= SEQUENCE { * name-type[0] INTEGER, * name-string[1] SEQUENCE OF UTF8String * } * * @author thomask * @version $Revision$, $Date$ */ public class KerberosName { public static final int OID[] = { 1, 3, 6, 1, 5, 2, 2 }; public static final ObjectIdentifier KRB5_PRINCIPAL_NAME = new ObjectIdentifier(OID); private String m_realm = null; private int m_name_type = 0; private Vector m_name_strings = null; public KerberosName(String realm, int name_type, Vector name_strings) { m_realm = realm; m_name_type = name_type; m_name_strings = name_strings; } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { try (DerOutputStream seq = new DerOutputStream()) { DerOutputStream tmp = new DerOutputStream(); DerOutputStream realm = new DerOutputStream(); realm.putGeneralString(m_realm); tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), realm); DerOutputStream seq1 = new DerOutputStream(); DerOutputStream tmp1 = new DerOutputStream(); DerOutputStream name_type = new DerOutputStream(); name_type.putInteger(new BigInt(m_name_type)); tmp1.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), name_type); DerOutputStream name_strings = new DerOutputStream(); DerOutputStream name_string = new DerOutputStream(); for (int i = 0; i < m_name_strings.size(); i++) { name_string.putGeneralString(m_name_strings.elementAt(i)); } name_strings.write(DerValue.tag_SequenceOf, name_string); tmp1.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 1), name_strings); seq1.write(DerValue.tag_Sequence, tmp1); tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 1), seq1); seq.write(DerValue.tag_Sequence, tmp); out.write(seq.toByteArray()); } } public byte[] toByteArray() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); encode(bos); return bos.toByteArray(); } public String toString() { String strings = null; for (int i = 0; i < m_name_strings.size(); i++) { if (strings == null) { strings = m_name_strings.elementAt(i); } else { strings += ","; strings += m_name_strings.elementAt(i); } } return "Realm: " + m_realm + " Name Type: " + m_name_type + " Name String(s):" + strings; } public static void main(String[] argv) { Vector strings = new Vector(); strings.addElement("name"); KerberosName k = new KerberosName("realm", 0, strings); System.out.println(k.toString()); try { FileOutputStream os = new FileOutputStream("/tmp/out.der"); k.encode(os); os.close(); } catch (Exception e) { System.out.println(e.toString()); } } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/NSCertTypeExtension.java000066400000000000000000000263221362106420000277670ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.BitArray; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.CertAttrSet; import org.mozilla.jss.netscape.security.x509.Extension; /** * NSCertTypeExtension * Represents Netscape Certificate Type Extension * *

* This deprecated extension, if present, defines both the purpose (e.g., encipherment, signature, certificate signing) * and the application (e.g., SSL, S/Mime or Object Signing of the key contained in the certificate. * * @author galperin * @version $Revision$, $Date$ */ public class NSCertTypeExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 1856407688086284397L; // The object identifiers private static final int CertType_data[] = { 2, 16, 840, 1, 113730, 1, 1 }; /** * Identifies the particular public key used to sign the certificate. */ public static final ObjectIdentifier CertType_Id = new ObjectIdentifier(CertType_data); /** * Attribute names. */ public static final String NAME = "NSCertType"; public static final String SSL_CLIENT = "ssl_client"; public static final String SSL_SERVER = "ssl_server"; public static final String EMAIL = "email"; public static final String OBJECT_SIGNING = "object_signing"; public static final String SSL_CA = "ssl_ca"; public static final String EMAIL_CA = "email_ca"; public static final String OBJECT_SIGNING_CA = "object_signing_ca"; /** * Attribute names. */ public static final int SSL_CLIENT_BIT = 0; public static final int SSL_SERVER_BIT = 1; public static final int EMAIL_BIT = 2; public static final int OBJECT_SIGNING_BIT = 3; // 4 is reserved. public static final int SSL_CA_BIT = 5; public static final int EMAIL_CA_BIT = 6; public static final int OBJECT_SIGNING_CA_BIT = 7; public static final int NBITS = 8; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.NSCertType"; // Private data members private byte[] mBitString; private static class MapEntry { String mName; int mPosition; MapEntry(String name, int position) { mName = name; mPosition = position; } } private static MapEntry[] mMapData = { new MapEntry(SSL_CLIENT, 0), new MapEntry(SSL_SERVER, 1), new MapEntry(EMAIL, 2), new MapEntry(OBJECT_SIGNING, 3), // note that bit 4 is reserved new MapEntry(SSL_CA, 5), new MapEntry(EMAIL_CA, 6), new MapEntry(OBJECT_SIGNING_CA, 7), }; private static Vector mAttributeNames = new Vector(); static { for (int i = 0; i < mMapData.length; ++i) { mAttributeNames.addElement(mMapData[i].mName); } } private static int getPosition(String name) throws CertificateException { for (int i = 0; i < mMapData.length; ++i) { if (name.equalsIgnoreCase(mMapData[i].mName)) return mMapData[i].mPosition; } throw new CertificateException("Attribute name [" + name + "] not recognized by" + " CertAttrSet:NSCertType."); } // Encode this extension value private void encodeThis() throws IOException { try (DerOutputStream os = new DerOutputStream()) { os.putUnalignedBitString(mBitString); this.extensionValue = os.toByteArray(); } } /** * Check if bit is set. * * @param position the position in the bit string to check. */ public boolean isSet(int position) { int index = position / 8; byte pos = (byte) (1 << (7 - (position % 8))); if (mBitString.length <= index) return false; return ((mBitString[index] & pos) != 0); } /** * Set the bit at the specified position. */ public void set(int position, boolean val) { int index = position / 8; byte pos = (byte) (1 << (7 - (position % 8))); if (index >= mBitString.length) { byte[] tmp = new byte[index + 1]; System.arraycopy(mBitString, 0, tmp, 0, mBitString.length); mBitString = tmp; } if (val) { mBitString[index] |= pos; } else { mBitString[index] &= ~pos; } } /** * Create NSCertTypeExtension from boolean array. * The criticality is set to false. */ public NSCertTypeExtension(boolean critical, boolean[] bits) { this.extensionId = CertType_Id; this.critical = critical; this.mBitString = new byte[0]; for (int i = 0; i < bits.length && i < 8; i++) { set(i, bits[i]); } } public NSCertTypeExtension(boolean[] bits) { this.extensionId = CertType_Id; this.critical = false; this.mBitString = new byte[0]; for (int i = 0; i < bits.length && i < 8; i++) { set(i, bits[i]); } } /** * Create a NSCertTypeExtension with the passed bit settings. * The criticality is set to false. * * @param bitString the bits to be set for the extension. */ public NSCertTypeExtension(boolean critical, byte[] bitString) throws IOException { this.mBitString = bitString; this.extensionId = CertType_Id; this.critical = critical; encodeThis(); } public NSCertTypeExtension(byte[] bitString) throws IOException { this.mBitString = bitString; this.extensionId = CertType_Id; this.critical = false; encodeThis(); } /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public NSCertTypeExtension(Boolean critical, Object value) throws IOException { /** * logger.trace("NSCertTypeExtension"); * this.mBitString = new byte[1]; * this.mBitString[0] = (byte)0x00; * return; **/ this.extensionId = CertType_Id; this.critical = critical.booleanValue(); byte[] extValue = ((byte[]) value).clone(); this.extensionValue = extValue; DerValue val = new DerValue(extValue); BitArray bitArray = val.getUnalignedBitString(); if (bitArray == null) { throw new IOException("Invalid Encoded DER Value"); } this.mBitString = bitArray.toByteArray(); } /** * Create a default key usage. */ public NSCertTypeExtension() { this.extensionId = CertType_Id; this.critical = false; this.mBitString = new byte[0]; try { encodeThis(); } catch (Exception e) { } } /** * Set the attribute value. */ public void set(String name, Object obj) throws CertificateException { if (!(obj instanceof Boolean)) { throw new CertificateException("Attribute must be of type Boolean."); } boolean val = ((Boolean) obj).booleanValue(); set(getPosition(name), val); } /** * Get the attribute value. */ public Object get(String name) throws CertificateException { return Boolean.valueOf(isSet(getPosition(name))); } /** * Delete the attribute value. */ public void delete(String name) throws CertificateException { set(getPosition(name), false); } /** * Returns a printable representation of the NSCertType. */ public String toString() { String s = super.toString() + "NSCertType [\n"; try { if (isSet(getPosition(SSL_CLIENT))) { s += " SSL client"; } if (isSet(getPosition(SSL_SERVER))) { s += " SSL server"; } if (isSet(getPosition(EMAIL))) { s += " Email"; } if (isSet(getPosition(OBJECT_SIGNING))) { s += " Object Signing"; } if (isSet(getPosition(SSL_CA))) { s += " SSL CA"; } if (isSet(getPosition(EMAIL_CA))) { s += " Email CA"; } if (isSet(getPosition(OBJECT_SIGNING_CA))) { s += " Object Signing CA"; } } catch (Exception e) { // this is reached only if there is a bug throw new IllegalArgumentException(e.getMessage()); } s += "]\n"; return (s); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); encodeThis(); if (this.extensionValue == null) { this.extensionId = CertType_Id; this.critical = true; } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { return mAttributeNames.elements(); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } public static void main(String[] argv) { } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/OCSPNoCheckExtension.java000066400000000000000000000107711362106420000277670ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.CertAttrSet; import org.mozilla.jss.netscape.security.x509.Extension; import org.mozilla.jss.netscape.security.x509.OIDMap; /** * This represents the OCSPNoCheck extension. */ public class OCSPNoCheckExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -4692759557964594790L; public static final String OID = "1.3.6.1.5.5.7.48.1.5"; public static final String NAME = "OCSPNoCheckExtension"; private byte mCached[] = null; static { try { OIDMap.addAttribute(OCSPNoCheckExtension.class.getName(), OID, NAME); } catch (CertificateException e) { } } public OCSPNoCheckExtension() throws IOException { this(Boolean.FALSE); } public OCSPNoCheckExtension(Boolean crit) throws IOException { try { extensionId = ObjectIdentifier.getObjectIdentifier(OCSPNoCheckExtension.OID); } catch (IOException e) { // never here } critical = crit.booleanValue(); DerOutputStream tmpD = new DerOutputStream(); try { tmpD.putNull(); } catch (IOException ex) { } finally { tmpD.close(); } extensionValue = tmpD.toByteArray(); } public OCSPNoCheckExtension(Boolean crit, Object byteVal) { try { extensionId = ObjectIdentifier.getObjectIdentifier(OCSPNoCheckExtension.OID); } catch (IOException e) { // never here } critical = crit.booleanValue(); extensionValue = ((byte[]) byteVal).clone(); } public void setCritical(boolean newValue) { if (critical != newValue) { critical = newValue; mCached = null; } } public void encode(DerOutputStream out) throws IOException { if (mCached == null) { super.encode(out); mCached = out.toByteArray(); } } @Override public String toString() { String presentation = "oid=" + OID + " "; if (critical) { presentation += "critical=true"; } if (extensionValue != null) { StringBuffer extByteValue = new StringBuffer(" val="); for (int i = 0; i < extensionValue.length; i++) { extByteValue.append(extensionValue[i] + " "); } presentation += extByteValue.toString(); } return presentation; } public void decode(InputStream in) throws CertificateException, IOException { // NOT USED } public void encode(OutputStream out) throws CertificateException, IOException { if (mCached == null) { DerOutputStream temp = new DerOutputStream(); encode(temp); } out.write(mCached); } public void set(String name, Object obj) throws CertificateException, IOException { // NOT USED } public Object get(String name) throws CertificateException, IOException { // NOT USED return null; } public Enumeration getAttributeNames() { // NOT USED return null; } public String getName() { return NAME; } public void delete(String name) throws CertificateException, IOException { // NOT USED } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/PresenceServerExtension.java000066400000000000000000000244731362106420000307270ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.CertAttrSet; import org.mozilla.jss.netscape.security.x509.Extension; public class PresenceServerExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -6333109673043357921L; private boolean mCritical; private int mVersion = 0; private String mStreetAddress = null; private String mTelephoneNumber = null; private String mRFC822Name = null; private String mID = null; private String mHostName = null; private int mPortNumber = 0; private int mMaxUsers = 0; private int mServiceLevel = 0; public static final String OID = "2.16.840.1.113730.1.18"; /* public PresenceServerExtension() { } */ public PresenceServerExtension(Boolean critical, Object value) throws IOException { this.extensionId = new ObjectIdentifier(OID); this.critical = critical.booleanValue(); this.extensionValue = ((byte[]) value).clone(); decodeThis(); } public PresenceServerExtension( boolean critical, int version, String streetAddress, String telephoneNumber, String rfc822Name, String ID, String hostName, int portNumber, int maxUsers, int serviceLevel) throws IOException { mCritical = critical; mVersion = version; mStreetAddress = streetAddress; mTelephoneNumber = telephoneNumber; mRFC822Name = rfc822Name; mID = ID; mHostName = hostName; mPortNumber = portNumber; mMaxUsers = maxUsers; mServiceLevel = serviceLevel; this.extensionId = new ObjectIdentifier(OID); this.critical = mCritical; encodeThis(); } public int getVersion() { return mVersion; } public String getStreetAddress() { return mStreetAddress; } public String getTelephoneNumber() { return mTelephoneNumber; } public String getRFC822() { return mRFC822Name; } public String getID() { return mID; } public String getHostName() { return mHostName; } public int getPortNumber() { return mPortNumber; } public int getMaxUsers() { return mMaxUsers; } public int getServiceLevel() { return mServiceLevel; } public void encodeThis() throws IOException { try (DerOutputStream out = new DerOutputStream()) { DerOutputStream temp = new DerOutputStream(); temp.putInteger(new BigInt(mVersion)); temp.putOctetString(mStreetAddress.getBytes()); temp.putOctetString(mTelephoneNumber.getBytes()); temp.putOctetString(mRFC822Name.getBytes()); temp.putOctetString(mID.getBytes()); temp.putOctetString(mHostName.getBytes()); temp.putInteger(new BigInt(mPortNumber)); temp.putInteger(new BigInt(mMaxUsers)); temp.putInteger(new BigInt(mServiceLevel)); out.write(DerValue.tag_Sequence, temp); this.extensionValue = out.toByteArray(); } } public void decodeThis() throws IOException { DerInputStream val = new DerInputStream(this.extensionValue); byte data[] = null; DerValue seq[] = val.getSequence(0); mVersion = seq[0].getInteger().toInt(); data = null; if (seq[1].length() > 0) { data = seq[1].getOctetString(); } if (data == null) { mStreetAddress = ""; } else { mStreetAddress = new String(data); } data = null; if (seq[2].length() > 0) data = seq[2].getOctetString(); if (data == null) { mTelephoneNumber = ""; } else { mTelephoneNumber = new String(data); } data = null; if (seq[3].length() > 0) data = seq[3].getOctetString(); if (data == null) { mRFC822Name = ""; } else { mRFC822Name = new String(data); } data = null; if (seq[4].length() > 0) data = seq[4].getOctetString(); if (data == null) { mID = ""; } else { mID = new String(data); } data = null; if (seq[5].length() > 0) data = seq[5].getOctetString(); if (data == null) { mHostName = ""; } else { mHostName = new String(data); } mPortNumber = seq[6].getInteger().toInt(); mMaxUsers = seq[7].getInteger().toInt(); mServiceLevel = seq[8].getInteger().toInt(); } public void decode(InputStream in) throws CertificateException, IOException { } public void encode(OutputStream out) throws CertificateException, IOException { DerOutputStream dos = new DerOutputStream(); super.encode(dos); out.write(dos.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { throw new IOException("Method not to be called directly."); } /** * Get the attribute value. */ public Object get(String name) throws IOException { return null; } /** * Delete the attribute value. */ public void delete(String name) throws IOException { throw new IOException("Method not to be called directly."); } public Enumeration getAttributeNames() { return null; } /** * Return the name of this attribute. */ public String getName() { return "PresenceServerExtension"; } /** * Set the name of this attribute. */ public void setName(String name) { } /** * Return the OID of this attribute. */ public String getOID() { return OID; } /** * Set the OID of this attribute. */ public void setOID(String oid) { } public static void main(String args[]) { /* 0 30 115: SEQUENCE { 2 06 9: OBJECT IDENTIFIER '2 16 840 1 113730 1 100' 13 04 102: OCTET STRING, encapsulates { 15 30 100: SEQUENCE { 17 02 1: INTEGER 0 20 04 31: OCTET STRING : 34 30 31 45 20 4D 69 64 64 6C 65 66 69 65 6C 64 : 20 52 64 2E 2C 4D 56 2C 43 41 39 34 30 34 31 53 04 12: OCTET STRING : 36 35 30 2D 31 31 31 2D 31 31 31 31 67 04 18: OCTET STRING : 61 64 6D 69 6E 40 6E 65 74 73 63 61 70 65 2E 63 : 6F 6D 87 04 10: OCTET STRING : 70 73 2D 63 61 70 69 74 6F 6C 99 04 7: OCTET STRING : 63 61 70 69 74 6F 6C 108 02 1: INTEGER 80 111 02 1: INTEGER 10 114 02 1: INTEGER 1 : } : } : } */ ByteArrayOutputStream dos = null; FileOutputStream fos = null; try { boolean critical = false; int version = 1; String streetAddress = "401E Middlefield Rd.,MV,CA94041"; String telephoneNumber = "650-111-1111"; String rfc822Name = "admin@netscape.com"; String ID = "ps-capitol"; String hostName = "capitol"; int portNumber = 80; int maxUsers = 10; int serviceLevel = 1; PresenceServerExtension ext = new PresenceServerExtension( critical, version, streetAddress, telephoneNumber, rfc822Name, ID, hostName, portNumber, maxUsers, serviceLevel); // encode dos = new ByteArrayOutputStream(); ext.encode(dos); fos = new FileOutputStream("pse.der"); fos.write(dos.toByteArray()); Extension ext1 = new Extension(new DerValue(dos.toByteArray())); @SuppressWarnings("unused") PresenceServerExtension ext2 = new PresenceServerExtension( Boolean.valueOf(false), ext1.getExtensionValue()); } catch (IOException e) { e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } finally { if (dos != null) { try { dos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } } jss-4.6.3/org/mozilla/jss/netscape/security/extensions/SubjectInfoAccessExtension.java000066400000000000000000000203701362106420000313210ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.extensions; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.util.Utils; import org.mozilla.jss.netscape.security.x509.CertAttrSet; import org.mozilla.jss.netscape.security.x509.Extension; import org.mozilla.jss.netscape.security.x509.GeneralName; import org.mozilla.jss.netscape.security.x509.URIName; /** * This represents the subject information access extension * as defined in RFC3280. * * @author thomask * @version $Revision$, $Date$ */ public class SubjectInfoAccessExtension extends Extension implements CertAttrSet { private static final long serialVersionUID = 7237321566602583325L; public static final String NAME = "SubjectInfoAccessExtension"; public static final int OID_OCSP[] = { 1, 3, 6, 1, 5, 5, 7, 48, 1 }; public static final ObjectIdentifier METHOD_OCSP = new ObjectIdentifier(OID_OCSP); public static final int OID_CA_ISSUERS[] = { 1, 3, 6, 1, 5, 5, 7, 48, 2 }; public static final ObjectIdentifier METHOD_CA_ISSUERS = new ObjectIdentifier(OID_CA_ISSUERS); public static final int OID[] = { 1, 3, 6, 1, 5, 5, 7, 1, 11 }; public static final ObjectIdentifier ID = new ObjectIdentifier(OID); private Vector mDesc = new Vector(); /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. */ public SubjectInfoAccessExtension(boolean critical) { this.extensionId = ID; this.critical = critical; this.extensionValue = null; // build this when encodeThis() is called } /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public SubjectInfoAccessExtension(Boolean critical, Object value) throws IOException { this.extensionId = ID; this.critical = critical.booleanValue(); this.extensionValue = ((byte[]) value).clone(); decodeThis(); } /** * Sets extension attribute. */ public void set(String name, Object obj) throws CertificateException { // NOT USED } /** * Retrieves extension attribute. */ public Object get(String name) throws CertificateException { // NOT USED return null; } /** * Deletes attribute. */ public void delete(String name) throws CertificateException { // NOT USED } /** * Decodes this extension. */ public void decode(InputStream in) throws IOException { // NOT USED } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { // NOT USED return null; } /** * Return the name of this attribute. */ public String getName() { return NAME; } /** * Adds Access Description. */ public void addAccessDescription( ObjectIdentifier method, GeneralName gn) { clearValue(); mDesc.addElement(new AccessDescription(method, gn)); } public AccessDescription getAccessDescription(int pos) { return mDesc.elementAt(pos); } /** * Returns the number of access description. */ public int numberOfAccessDescription() { return mDesc.size(); } private void decodeThis() throws IOException { DerValue val = new DerValue(this.extensionValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding of AuthInfoAccess extension"); } while (val.data.available() != 0) { DerValue seq = val.data.getDerValue(); ObjectIdentifier method = seq.data.getDerValue().getOID(); GeneralName gn = new GeneralName(seq.data.getDerValue()); addAccessDescription(method, gn); } } private void encodeThis() throws IOException { try (DerOutputStream seq = new DerOutputStream(); DerOutputStream tmp = new DerOutputStream()) { for (int i = 0; i < mDesc.size(); i++) { DerOutputStream tmp0 = new DerOutputStream(); AccessDescription ad = mDesc.elementAt(i); tmp0.putOID(ad.getMethod()); ad.getLocation().encode(tmp0); tmp.write(DerValue.tag_Sequence, tmp0); } seq.write(DerValue.tag_Sequence, tmp); this.extensionValue = seq.toByteArray(); } } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Returns a printable representation of the AuthInfoAccess. */ public String toString() { StringBuffer s=new StringBuffer(super.toString() + "AuthInfoAccess [\n"); for (int i = 0; i < mDesc.size(); i++) { AccessDescription ad = mDesc.elementAt(i); s.append( "(" + i + ")"); s.append(" "); s.append(ad.getMethod().toString() + " " + ad.getLocation().toString()); } return (s.toString() + "]\n"); } public static void main(String[] argv) { AuthInfoAccessExtension aia = new AuthInfoAccessExtension(false); GeneralName ocspName = new GeneralName(new URIName("http://ocsp.netscape.com")); aia.addAccessDescription(METHOD_OCSP, ocspName); GeneralName caIssuersName = new GeneralName(new URIName("http://ocsp.netscape.com")); aia.addAccessDescription(METHOD_CA_ISSUERS, caIssuersName); ByteArrayOutputStream os = new ByteArrayOutputStream(); try { aia.encode(os); System.out.println(Utils.base64encode(os.toByteArray(), true)); } catch (IOException e) { System.out.println(e.toString()); } try { // test serialization ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(aia); ByteArrayInputStream bis = new ByteArrayInputStream( bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); AuthInfoAccessExtension clone = (AuthInfoAccessExtension) ois.readObject(); System.out.println(clone); } catch (Exception e) { System.out.println(e.toString()); } } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/000077500000000000000000000000001362106420000217635ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/ContentInfo.java000066400000000000000000000122361362106420000250600ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * A ContentInfo type, as defined in PKCS#7. * * @version 1.12 * @author Benjamin Renaud */ public class ContentInfo { // pkcs7 pre-defined content types private static int[] pkcs7 = { 1, 2, 840, 113549, 1, 7 }; private static int[] data = { 1, 2, 840, 113549, 1, 7, 1 }; private static int[] sdata = { 1, 2, 840, 113549, 1, 7, 2 }; private static int[] edata = { 1, 2, 840, 113549, 1, 7, 3 }; private static int[] sedata = { 1, 2, 840, 113549, 1, 7, 4 }; private static int[] ddata = { 1, 2, 840, 113549, 1, 7, 5 }; private static int[] crdata = { 1, 2, 840, 113549, 1, 7, 6 }; public static final ObjectIdentifier PKCS7_OID = new ObjectIdentifier(pkcs7); public static final ObjectIdentifier DATA_OID = new ObjectIdentifier(data); public static final ObjectIdentifier SIGNED_DATA_OID = new ObjectIdentifier(sdata); public static final ObjectIdentifier ENVELOPED_DATA_OID = new ObjectIdentifier(edata); public static final ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID = new ObjectIdentifier(sedata); public static final ObjectIdentifier DIGESTED_DATA_OID = new ObjectIdentifier(ddata); public static final ObjectIdentifier ENCRYPTED_DATA_OID = new ObjectIdentifier(crdata); ObjectIdentifier contentType; DerValue content; // OPTIONAL public ContentInfo(ObjectIdentifier contentType, DerValue content) { this.contentType = contentType; this.content = content; } /** * Make a contentInfo of type data. */ public ContentInfo(byte[] bytes) { DerValue octetString = new DerValue(DerValue.tag_OctetString, bytes); this.contentType = DATA_OID; this.content = octetString; } public ContentInfo(DerInputStream derin) throws IOException, ParsingException { DerInputStream disType; DerInputStream disTaggedContent; DerValue type; DerValue taggedContent; DerValue[] typeAndContent; DerValue[] contents; typeAndContent = derin.getSequence(2); // Parse the content type type = typeAndContent[0]; disType = new DerInputStream(type.toByteArray()); contentType = disType.getOID(); // Parse the content (OPTIONAL field). // Skip the [0] EXPLICIT tag by pretending that the content is the one // and only element in an implicitly tagged set if (typeAndContent.length > 1) { // content is OPTIONAL taggedContent = typeAndContent[1]; disTaggedContent = new DerInputStream(taggedContent.toByteArray()); contents = disTaggedContent.getSet(1, true); content = contents[0]; } } public DerValue getContent() { return content; } public byte[] getData() throws IOException { if (contentType.equals(DATA_OID)) { return content.getOctetString(); } throw new IOException("content type is not DATA: " + contentType); } public void encode(DerOutputStream out) throws IOException { DerOutputStream contentDerCode; DerOutputStream seq; DerValue taggedContent; contentDerCode = new DerOutputStream(); content.encode(contentDerCode); // Add the [0] EXPLICIT tag in front of the content encoding taggedContent = new DerValue((byte) 0xA0, contentDerCode.toByteArray()); seq = new DerOutputStream(); seq.putOID(contentType); seq.putDerValue(taggedContent); out.write(DerValue.tag_Sequence, seq); } /** * Returns a byte array representation of the data held in * the content field. */ public byte[] getContentBytes() throws IOException { DerInputStream dis = new DerInputStream(content.toByteArray()); return dis.getOctetString(); } public String toString() { String out = ""; out += "Content Info Sequence\n\tContent type: " + contentType + "\n"; out += "\tContent: " + content; return out; } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/EncodingException.java000066400000000000000000000025651362106420000262430ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; public class EncodingException extends Exception { /** * */ private static final long serialVersionUID = -6126764125859196917L; public EncodingException() { super(); } public EncodingException(String mesg) { super(mesg); } public EncodingException(String mesg, Throwable cause) { super(mesg, cause); } public EncodingException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/PKCS10.java000066400000000000000000000321061362106420000235310ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.io.IOException; import java.io.PrintStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CertificateException; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.Cert; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.Utils; import org.mozilla.jss.netscape.security.x509.AlgorithmId; import org.mozilla.jss.netscape.security.x509.X500Name; import org.mozilla.jss.netscape.security.x509.X500Signer; import org.mozilla.jss.netscape.security.x509.X509Key; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * PKCS #10 certificate requests are created and sent to Certificate * Authorities, which then create X.509 certificates and return them to * the entity which created the certificate request. These cert requests * basically consist of the subject's X.500 name and public key, signed * using the corresponding private key. * * The ASN.1 syntax for a Certification Request is: * *

 * CertificationRequest ::= SEQUENCE {
 *    certificationRequestInfo CertificationRequestInfo,
 *    signatureAlgorithm       SignatureAlgorithmIdentifier,
 *    signature                Signature
 *  }
 *
 * SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
 * Signature ::= BIT STRING
 *
 * CertificationRequestInfo ::= SEQUENCE {
 *    version                 Version,
 *    subject                 Name,
 *    subjectPublicKeyInfo    SubjectPublicKeyInfo,
 *    attributes [0] IMPLICIT Attributes
 * }
 * Attributes ::= SET OF Attribute
 * 
* * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.28 */ public class PKCS10 { public static Logger logger = LoggerFactory.getLogger(PKCS10.class); /** * Constructs an unsigned PKCS #10 certificate request. Before this * request may be used, it must be encoded and signed. Then it * must be retrieved in some conventional format (e.g. string). * * @param publicKey the public key that should be placed * into the certificate generated by the CA. */ public PKCS10(X509Key publicKey) { subjectPublicKeyInfo = publicKey; attributeSet = new PKCS10Attributes(); } /** * Constructs an unsigned PKCS #10 certificate request. Before this * request may be used, it must be encoded and signed. Then it * must be retrieved in some conventional format (e.g. string). * * @param publicKey the public key that should be placed * into the certificate generated by the CA. * @param attributes additonal set of PKCS10 attributes requested * for in the certificate. */ public PKCS10(X509Key publicKey, PKCS10Attributes attributes) { subjectPublicKeyInfo = publicKey; if (attributes != null) attributeSet = attributes; else attributeSet = new PKCS10Attributes(); } /** * Parses an encoded, signed PKCS #10 certificate request, verifying * the request's signature as it does so. This constructor would * typically be used by a Certificate Authority, from which a new * certificate would then be constructed. * * @param data the DER-encoded PKCS #10 request. * @param sigver boolean specifies signature verification enabled or not * @exception IOException for low level errors reading the data * @exception SignatureException when the signature is invalid * @exception NoSuchAlgorithmException when the signature * algorithm is not supported in this environment */ public PKCS10(byte data[], boolean sigver) throws IOException, SignatureException, NoSuchAlgorithmException, java.security.NoSuchProviderException { DerInputStream in; DerValue seq[]; AlgorithmId id; byte sigData[]; Signature sig; String msg = ""; logger.debug("PKCS10: begins"); if (data == null) { throw new IllegalArgumentException("Missing PKCS #10 data"); } certificateRequest = data; // // Outer sequence: request, signature algorithm, signature. // Parse, and prepare to verify later. // in = new DerInputStream(data); seq = in.getSequence(3); if (seq == null) { throw new IllegalArgumentException("in.getSequence null"); } if (seq.length != 3) { throw new IllegalArgumentException("Invalid PKCS #10 request"); } data = seq[0].toByteArray(); // reusing this variable certRequestInfo = seq[0].toByteArray(); // make a copy id = AlgorithmId.parse(seq[1]); sigData = seq[2].getBitString(); // // Inner sequence: version, name, key, attributes // @SuppressWarnings("unused") BigInt serial = seq[0].data.getInteger(); // consume serial /* if (serial.toInt () != 0) throw new IllegalArgumentException ("not PKCS #10 v1"); */ subject = new X500Name(seq[0].data); msg = "Request Subject: " + subject + ": "; byte val1[] = seq[0].data.getDerValue().toByteArray(); subjectPublicKeyInfo = X509Key.parse(new DerValue(val1)); PublicKey publicKey = X509Key.parsePublicKey(new DerValue(val1)); if (publicKey == null) { logger.error("PKCS10: " + msg + "publicKey null"); throw new SignatureException(msg + "publicKey null"); } // Cope with a somewhat common illegal PKCS #10 format if (seq[0].data.available() != 0) { attributeSet = new PKCS10Attributes(seq[0].data); } else { attributeSet = new PKCS10Attributes(); } // // OK, we parsed it all ... validate the signature using the // key and signature algorithm we found. // temporary commented out try { String idName = id.getName(); if (idName.equals("MD5withRSA")) idName = "MD5/RSA"; else if (idName.equals("MD2withRSA")) idName = "MD2/RSA"; else if (idName.equals("SHA1withRSA")) idName = "SHA1/RSA"; else if (idName.equals("SHA1withDSA")) idName = "SHA1/DSA"; else if (idName.equals("SHA256withRSA")) idName = "SHA256/RSA"; else if (idName.equals("SHA384withRSA")) idName = "SHA384/RSA"; else if (idName.equals("SHA512withRSA")) idName = "SHA512/RSA"; else if (idName.equals("SHA1withEC")) idName = "SHA1/EC"; else if (idName.equals("SHA256withEC")) idName = "SHA256/EC"; else if (idName.equals("SHA384withEC")) idName = "SHA384/EC"; else if (idName.equals("SHA512withEC")) idName = "SHA512/EC"; if (sigver) { sig = Signature.getInstance(idName, "Mozilla-JSS"); sig.initVerify(publicKey); sig.update(data); if (!sig.verify(sigData)) { logger.error("PKCS10: " + msg + "sig.verify() failed"); throw new SignatureException(msg + "Invalid PKCS #10 signature"); } } } catch (InvalidKeyException e) { logger.error("PKCS10: " + msg + e.getMessage()); throw new SignatureException(msg + "invalid key", e); } logger.debug("PKCS10: ends"); } public PKCS10(byte data[]) throws IOException, SignatureException, NoSuchAlgorithmException, java.security.NoSuchProviderException { this(data, true); } /** * Create the signed certificate request. This will later be * retrieved in either string or binary format. * * @param requester identifies the signer (by X.500 name) * and provides the private key used to sign. * @exception IOException on errors. * @exception CertificateException on certificate handling errors. * @exception SignatureException on signature handling errors. */ public void encodeAndSign(X500Signer requester) throws CertificateException, IOException, SignatureException { DerOutputStream out, scratch; byte certificateRequestInfo[]; byte sig[]; if (certificateRequest != null) throw new SignatureException("request is already signed"); subject = requester.getSigner(); /* * Encode cert request info, wrap in a sequence for signing */ scratch = new DerOutputStream(); scratch.putInteger(new BigInt(0)); // version zero subject.encode(scratch); // X.500 name subjectPublicKeyInfo.encode(scratch); // public key attributeSet.encode(scratch); out = new DerOutputStream(); out.write(DerValue.tag_Sequence, scratch); // wrap it! certificateRequestInfo = out.toByteArray(); scratch = out; /* * Sign it ... */ requester.update(certificateRequestInfo, 0, certificateRequestInfo.length); sig = requester.sign(); /* * Build guts of SIGNED macro */ requester.getAlgorithmId().encode(scratch); // sig algorithm scratch.putBitString(sig); // sig /* * Wrap those guts in a sequence */ out = new DerOutputStream(); out.write(DerValue.tag_Sequence, scratch); certificateRequest = out.toByteArray(); } /** * Returns the subject's name. */ public X500Name getSubjectName() { return subject; } /** * Returns the subject's public key. */ public X509Key getSubjectPublicKeyInfo() { return subjectPublicKeyInfo; } /** * Returns the additional attributes requested. */ public PKCS10Attributes getAttributes() { return attributeSet; } /** * Returns the encoded and signed certificate request as a * DER-encoded byte array. * * @return the certificate request, or null if encodeAndSign() * has not yet been called. */ public byte[] toByteArray() { return certificateRequest; } /** * Prints an E-Mailable version of the certificate request on the print * stream passed. The format is a common base64 encoded one, supported * by most Certificate Authorities because Netscape web servers have * used this for some time. Some certificate authorities expect some * more information, in particular contact information for the web * server administrator. * * @param out the print stream where the certificate request * will be printed. * @exception IOException when an output operation failed * @exception SignatureException when the certificate request was * not yet signed. */ public void print(PrintStream out) throws IOException, SignatureException { if (certificateRequest == null) throw new SignatureException("Cert request was not signed"); out.println(Cert.REQUEST_HEADER); out.print(Utils.base64encode(certificateRequest, true)); out.println(Cert.REQUEST_FOOTER); } /** * Provides a short description of this request. */ public String toString() { return "[PKCS #10 certificate request:\n" + subjectPublicKeyInfo.toString() + " subject: <" + subject + ">" + "\n" + " attributes: " + attributeSet.toString() + "\n]"; } /** * Retrieve the PKCS10 CertificateRequestInfo as a byte array */ public byte[] getCertRequestInfo() { return certRequestInfo; } private X500Name subject; private X509Key subjectPublicKeyInfo; private PKCS10Attributes attributeSet; private byte certificateRequest[]; // signed private byte certRequestInfo[]; // inner content signed } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/PKCS10Attribute.java000066400000000000000000000205301362106420000254130ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.security.cert.CertificateException; import org.mozilla.jss.netscape.security.util.DerEncoder; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.ACertAttrSet; import org.mozilla.jss.netscape.security.x509.CertAttrSet; import org.mozilla.jss.netscape.security.x509.Extensions; import org.mozilla.jss.netscape.security.x509.OIDMap; /** * Represent a PKCS Attribute. * *

* Attributes are addiitonal attributes which can be inserted in a PKCS certificate request. For example a * "Driving License Certificate" could have the driving license number as a attribute. * *

* Attributes are represented as a sequence of the attribute identifier (Object Identifier) and a set of DER encoded * attribute values. The current implementation only supports one value per attribute. * * ASN.1 definition of Attribute: * *

 * Attribute :: SEQUENCE {
 *    type    AttributeValue,
 *    values  SET OF AttributeValue
 * }
 * AttributeValue ::= ANY
 * 
* * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.13 */ public class PKCS10Attribute implements DerEncoder, Serializable { private static final long serialVersionUID = 2002480042340316170L; protected ObjectIdentifier attributeId = null; protected CertAttrSet attributeValue = null; /** * Default constructor. Used only by sub-classes. */ public PKCS10Attribute() { } /** * Constructs an attribute from a DER encoded array of bytes. */ public PKCS10Attribute(DerValue derVal) throws IOException { if (derVal.tag != DerValue.tag_Sequence) { throw new IOException("Sequence tag missing for PKCS10Attribute."); } DerInputStream in = derVal.toDerInputStream(); // Object identifier attributeId = in.getOID(); // System.out.println("attribute ID in pkcs10 "+attributeId.toString()); // Rest of the stuff is attribute value(s), wrapped in a SET. // For now, assume there is only one attribute value present. DerValue[] inAttrValues = in.getSet(1); int attrValueNum = inAttrValues.length; if (attrValueNum > 1) { throw new IOException("More than one value per attribute not supported"); } // Read the first attribute value DerValue inAttrValue = inAttrValues[0]; if (attributeId.equals(PKCS9Attribute.EXTENSION_REQUEST_OID)) { //pkcs9 extensionAttr try { // remove the tag //DerValue dv = inAttrValue.data.getDerValue(); // hack. toDerInputStream only gives one extension. DerInputStream fi = new DerInputStream(inAttrValue.toByteArray()); attributeValue = new Extensions(fi); //CertificateExtensions(fi); return; } catch (Exception e) { throw new IOException(e.toString()); } } byte[] val = inAttrValue.toByteArray(); Class[] params = { Object.class }; try { @SuppressWarnings("unchecked") Class extClass = (Class) OIDMap.getClass(attributeId); if (extClass != null) { Constructor cons = extClass.getConstructor(params); Object value = Array.newInstance(byte.class, val.length); for (int i = 0; i < val.length; i++) { Array.setByte(value, i, val[i]); } Object[] passed = new Object[] { value }; attributeValue = cons.newInstance(passed); } else { // attribute classes are usable for PKCS10 attributes. // this is used where the attributes are not actual // implemented extensions. attributeValue = new ACertAttrSet(inAttrValue); } } catch (InvocationTargetException invk) { throw new IOException(invk.getTargetException().getMessage(), invk); } catch (Exception e) { throw new IOException(e.toString()); } } /** * Constructs an attribute from individual components of ObjectIdentifier * and the DER encoded value. * * @param attributeId the ObjectIdentifier of the attribute. * @param attributeValue the CertAttrSet. */ public PKCS10Attribute(ObjectIdentifier attributeId, CertAttrSet attributeValue) { this.attributeId = attributeId; this.attributeValue = attributeValue; } /** * Constructs an attribute from another attribute. To be used for * creating decoded subclasses. * * @param attr the attribute to create from. */ public PKCS10Attribute(PKCS10Attribute attr) { this.attributeId = attr.attributeId; this.attributeValue = attr.attributeValue; } /** * Write the output to the DerOutputStream. * * @param out the OutputStream to write the attribute to. * @exception CertificateException on certificate encoding errors. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws CertificateException, IOException { try (DerOutputStream tmp = new DerOutputStream()) { // Encode the attribute value DerOutputStream outAttrValue = new DerOutputStream(); attributeValue.encode(outAttrValue); // Wrap the encoded attribute value into a SET DerValue outAttrValueSet = new DerValue(DerValue.tag_Set, outAttrValue.toByteArray()); // Create the attribute DerOutputStream outAttr = new DerOutputStream(); outAttr.putOID(attributeId); outAttr.putDerValue(outAttrValueSet); // Wrap the OID and the set of attribute values into a SEQUENCE tmp.write(DerValue.tag_Sequence, outAttr); // write the results to out out.write(tmp.toByteArray()); } } /** * DER encode this object onto an output stream. * Implements the DerEncoder interface. * * @param out * the OutputStream on which to write the DER encoding. * * @exception IOException on encoding errors. */ public void derEncode(OutputStream out) throws IOException { try { encode(out); } catch (CertificateException ce) { IOException ioe = new IOException(ce.toString()); ioe.fillInStackTrace(); throw ioe; } } /** * Returns the ObjectIdentifier of the attribute. */ public ObjectIdentifier getAttributeId() { return (attributeId); } /** * Returns the attribute value as an byte array for further processing. */ public CertAttrSet getAttributeValue() { return (attributeValue); } /** * Returns the attribute in user readable form. */ public String toString() { String s = "AttributeId: " + attributeId.toString() + "\n"; s += "AttributeValue: " + attributeValue.toString(); return (s); } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/PKCS10Attributes.java000066400000000000000000000124651362106420000256060ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.io.IOException; import java.io.OutputStream; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerEncoder; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the PKCS10 attributes for the request. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.10 */ public class PKCS10Attributes extends Vector implements DerEncoder { /** * */ private static final long serialVersionUID = 1362260612357629542L; private Hashtable map; /** * Default constructor for the certificate attribute. */ public PKCS10Attributes() { map = new Hashtable(); } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the attributes from. * @exception IOException on decoding errors. */ public PKCS10Attributes(DerInputStream in) throws IOException { map = new Hashtable(); DerValue[] attrs = in.getSet(5, true); if (attrs != null) { for (int i = 0; i < attrs.length; i++) { PKCS10Attribute attr = new PKCS10Attribute(attrs[i]); addElement(attr); System.out.println("PKCS10Attributes: adding attribute: " + attr.getAttributeValue().getName()); map.put(attr.getAttributeValue().getName(), attr); } } } /** * Encode the attributes in DER form to the stream. * * @param out the OutputStream to marshal the contents to. * * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { derEncode(out); } /** * Encode the attributes in DER form to the stream. * Implements the DerEncoder interface. * * @param out the OutputStream to marshal the contents to. * @exception IOException on encoding errors. */ public void derEncode(OutputStream out) throws IOException { try (DerOutputStream attrOut = new DerOutputStream()) { // first copy the elements into an array PKCS10Attribute[] attribs = new PKCS10Attribute[size()]; copyInto(attribs); attrOut.putOrderedSetOf(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), attribs); out.write(attrOut.toByteArray()); } catch (IOException e) { throw e; } } /** * Set the attribute value. */ public void setAttribute(String name, PKCS10Attribute attr) throws IOException { map.put(name, attr); addElement(attr); } /** * Get the attribute value. */ public PKCS10Attribute getAttribute(String name) throws IOException { PKCS10Attribute attr = map.get(name); /* if (attr == null) { throw new IOException("No attribute found with name " + name); } */ return (attr); } /** * Delete the attribute value. */ public void deleteAttribute(String name) throws IOException { PKCS10Attribute attr = map.get(name); if (attr == null) { throw new IOException("No attribute found with name " + name); } map.remove(name); removeElement(attr); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getElements() { return map.elements(); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((map == null) ? 0 : map.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; PKCS10Attributes other = (PKCS10Attributes) obj; if (map == null) { if (other.map != null) return false; } else if (!map.equals(other.map)) return false; return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/PKCS12.java000066400000000000000000000157301362106420000235370ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2016 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; public class PKCS12 { // PKI OID: 2.16.840.1.113730.5 public final static OBJECT_IDENTIFIER PKI_OID = new OBJECT_IDENTIFIER("2.16.840.1.113730.5"); // PKCS #12 OID: 2.16.840.1.113730.5.1 public final static OBJECT_IDENTIFIER PKCS12_OID = PKI_OID.subBranch(1); // PKCS #12 attributes OID: 2.16.840.1.113730.5.1.1 public final static OBJECT_IDENTIFIER PKCS12_ATTRIBUTES_OID = PKCS12_OID.subBranch(1); // Certificate trust flags OID: 2.16.840.1.113730.5.1.1.1 public final static OBJECT_IDENTIFIER CERT_TRUST_FLAGS_OID = PKCS12_ATTRIBUTES_OID.subBranch(1); // based on certdb.h in NSS public final static int TERMINAL_RECORD = 1 << 0; public final static int TRUSTED = 1 << 1; public final static int SEND_WARN = 1 << 2; public final static int VALID_CA = 1 << 3; public final static int TRUSTED_CA = 1 << 4; public final static int NS_TRUSTED_CA = 1 << 5; public final static int USER = 1 << 6; public final static int TRUSTED_CLIENT_CA = 1 << 7; public final static int INVISIBLE_CA = 1 << 8; public final static int GOVT_APPROVED_CA = 1 << 9; public static boolean isFlagEnabled(int flag, int flags) { return (flag & flags) > 0; } // based on printflags() in secutil.c in NSS public static String encodeFlags(int flags) { StringBuffer sb = new StringBuffer(); if (isFlagEnabled(VALID_CA, flags) && !isFlagEnabled(TRUSTED_CA, flags) && !isFlagEnabled(TRUSTED_CLIENT_CA, flags)) sb.append("c"); if (isFlagEnabled(TERMINAL_RECORD, flags) && !isFlagEnabled(TRUSTED, flags)) sb.append("p"); if (isFlagEnabled(TRUSTED_CA, flags)) sb.append("C"); if (isFlagEnabled(TRUSTED_CLIENT_CA, flags)) sb.append("T"); if (isFlagEnabled(TRUSTED, flags)) sb.append("P"); if (isFlagEnabled(USER, flags)) sb.append("u"); if (isFlagEnabled(SEND_WARN, flags)) sb.append("w"); if (isFlagEnabled(INVISIBLE_CA, flags)) sb.append("I"); if (isFlagEnabled(GOVT_APPROVED_CA, flags)) sb.append("G"); return sb.toString(); } // based on CERT_DecodeTrustString() in certdb.c in NSS public static int decodeFlags(String flags) throws Exception { int value = 0; for (char c : flags.toCharArray()) { switch (c) { case 'p': value = value | TERMINAL_RECORD; break; case 'P': value = value | TRUSTED | TERMINAL_RECORD; break; case 'w': value = value | SEND_WARN; break; case 'c': value = value | VALID_CA; break; case 'T': value = value | TRUSTED_CLIENT_CA | VALID_CA; break; case 'C' : value = value | TRUSTED_CA | VALID_CA; break; case 'u': value = value | USER; break; case 'i': value = value | INVISIBLE_CA; break; case 'g': value = value | GOVT_APPROVED_CA; break; default: throw new Exception("Invalid trust flag: " + c); } } return value; } Map keyInfosByID = new LinkedHashMap(); Map certInfosByID = new LinkedHashMap(); Map certInfosByKeyID = new LinkedHashMap(); public PKCS12() { } public Collection getKeyInfos() { return keyInfosByID.values(); } public void addKeyInfo(PKCS12KeyInfo keyInfo) { keyInfosByID.put(new BigInteger(1, keyInfo.getID()), keyInfo); } public PKCS12KeyInfo getKeyInfoByID(byte[] id) { return keyInfosByID.get(new BigInteger(1, id)); } public PKCS12KeyInfo removeKeyInfoByID(byte[] id) { return keyInfosByID.remove(new BigInteger(1, id)); } public Collection getCertInfos() { return certInfosByID.values(); } public void addCertInfo(PKCS12CertInfo certInfo, boolean replace) { BigInteger id = new BigInteger(1, certInfo.getID()); if (!replace && certInfosByID.containsKey(id)) return; certInfosByID.put(id, certInfo); byte[] keyID = certInfo.getKeyID(); if (keyID == null) return; certInfosByKeyID.put(new BigInteger(1, keyID), certInfo); } public PKCS12CertInfo getCertInfoByID(byte[] id) { return certInfosByID.get(new BigInteger(1, id)); } public PKCS12CertInfo getCertInfoByKeyID(byte[] keyID) { return certInfosByKeyID.get(new BigInteger(1, keyID)); } public Collection getCertInfosByFriendlyName(String friendlyName) { Collection result = new ArrayList(); for (PKCS12CertInfo certInfo : certInfosByID.values()) { if (!friendlyName.equals(certInfo.getFriendlyName())) continue; result.add(certInfo); } return result; } public void removeCertInfoByFriendlyName(String friendlyName) throws Exception { Collection result = getCertInfosByFriendlyName(friendlyName); if (result.isEmpty()) { throw new Exception("Certificate not found: " + friendlyName); } for (PKCS12CertInfo certInfo : result) { BigInteger id = new BigInteger(1, certInfo.getID()); certInfosByID.remove(id); byte[] keyID = certInfo.getKeyID(); if (keyID == null) continue; certInfosByKeyID.remove(new BigInteger(1, keyID)); keyInfosByID.remove(new BigInteger(1, keyID)); } } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/PKCS12CertInfo.java000066400000000000000000000034711362106420000251700ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2016 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import org.mozilla.jss.netscape.security.x509.X509CertImpl; public class PKCS12CertInfo { private byte[] id; private X509CertImpl cert; private String friendlyName; private String trustFlags; private byte[] keyID; public PKCS12CertInfo() { } public byte[] getID() { return id; } public void setID(byte[] id) { this.id = id; } public X509CertImpl getCert() { return cert; } public void setCert(X509CertImpl cert) { this.cert = cert; } public String getFriendlyName() { return friendlyName; } public void setFriendlyName(String friendlyName) { this.friendlyName = friendlyName; } public String getTrustFlags() { return trustFlags; } public void setTrustFlags(String trustFlags) { this.trustFlags = trustFlags; } public byte[] getKeyID() { return keyID; } public void setKeyID(byte[] keyID) { this.keyID = keyID; } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/PKCS12KeyInfo.java000066400000000000000000000045231362106420000250220ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2016 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import org.mozilla.jss.crypto.PrivateKey; /** * This object is used for carrying key info around. * * It does not handle raw key material (but it used to). * * FIXME: A clear refactoring opportunity exists. The 'privateKey' * field (and associated constructor) is only used during export, * and the 'epkiBytes' field (and associated constructor) is only * used during import. Therefore this should be two different * types. */ public class PKCS12KeyInfo { private PrivateKey privateKey; private byte[] epkiBytes; private byte[] id; private String friendlyName; public PKCS12KeyInfo() { } /** * Construct with a PrivateKey. This constructor is used * for moving the PrivateKey handle around during export. */ public PKCS12KeyInfo(PrivateKey k) { this.privateKey = k; } /** Construct with a (serialised) EncrypedPrivateKeyInfo. This * constructor is used for moving the EPKI data around during * import. */ public PKCS12KeyInfo(byte[] epkiBytes) { this.epkiBytes = epkiBytes; } public PrivateKey getPrivateKey() { return this.privateKey; } public byte[] getEncryptedPrivateKeyInfoBytes() { return epkiBytes; } public byte[] getID() { return id; } public void setID(byte[] id) { this.id = id; } public String getFriendlyName() { return friendlyName; } public void setFriendlyName(String friendlyName) { this.friendlyName = friendlyName; } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/PKCS12Util.java000066400000000000000000001026621362106420000243760ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2016 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.MessageDigest; import java.security.Principal; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.ArrayList; import org.apache.commons.lang.StringUtils; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BMPString; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.crypto.CryptoStore; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.InternalCertificate; import org.mozilla.jss.crypto.NoSuchItemOnTokenException; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.pkcs11.PK11Store; import org.mozilla.jss.pkcs12.AuthenticatedSafes; import org.mozilla.jss.pkcs12.CertBag; import org.mozilla.jss.pkcs12.PFX; import org.mozilla.jss.pkcs12.PasswordConverter; import org.mozilla.jss.pkcs12.SafeBag; import org.mozilla.jss.pkix.primitive.Attribute; import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo; import org.mozilla.jss.util.Password; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; import javax.naming.InvalidNameException; import org.mozilla.jss.netscape.security.util.Utils; import org.mozilla.jss.netscape.security.x509.X509CertImpl; public class PKCS12Util { private static Logger logger = LoggerFactory.getLogger(PKCS12Util.class); public final static String NO_ENCRYPTION = "none"; public final static List SUPPORTED_CERT_ENCRYPTIONS = Arrays.asList(new PBEAlgorithm[] { null, // none PBEAlgorithm.PBE_SHA1_RC2_40_CBC }); public final static List SUPPORTED_KEY_ENCRYPTIONS = Arrays.asList(new PBEAlgorithm[] { PBEAlgorithm.PBE_PKCS5_PBES2, PBEAlgorithm.PBE_SHA1_DES3_CBC }); public final static PBEAlgorithm DEFAULT_CERT_ENCRYPTION = SUPPORTED_CERT_ENCRYPTIONS.get(0); public final static String DEFAULT_CERT_ENCRYPTION_NAME = NO_ENCRYPTION; public final static PBEAlgorithm DEFAULT_KEY_ENCRYPTION = SUPPORTED_KEY_ENCRYPTIONS.get(0); public final static String DEFAULT_KEY_ENCRYPTION_NAME = DEFAULT_KEY_ENCRYPTION.toString(); SecureRandom random; PBEAlgorithm certEncryption = DEFAULT_CERT_ENCRYPTION; PBEAlgorithm keyEncryption = DEFAULT_KEY_ENCRYPTION; boolean trustFlagsEnabled = true; public PKCS12Util() throws Exception { random = SecureRandom.getInstance("pkcs11prng", "Mozilla-JSS"); } public void setCertEncryption(String name) throws Exception { for (PBEAlgorithm algorithm : SUPPORTED_CERT_ENCRYPTIONS) { if (algorithm == null) { if (NO_ENCRYPTION.equals(name)) { this.certEncryption = null; return; } } else if (algorithm.toString().equals(name)) { this.certEncryption = algorithm; return; } } throw new Exception("Unsupported certificate encryption: " + name); } public void setCertEncryption(PBEAlgorithm algorithm) throws Exception { this.certEncryption = algorithm; } public PBEAlgorithm getCertEncryption() { return certEncryption; } public void setKeyEncryption(String name) throws Exception { for (PBEAlgorithm algorithm : SUPPORTED_KEY_ENCRYPTIONS) { if (algorithm == null) { if (NO_ENCRYPTION.equals(name)) { this.keyEncryption = null; return; } } else if (algorithm.toString().equals(name)) { this.keyEncryption = algorithm; return; } } throw new Exception("Unsupported key encryption: " + name); } public void setKeyEncryption(PBEAlgorithm algorithm) throws Exception { this.keyEncryption = algorithm; } public PBEAlgorithm getKeyEncryption() { return keyEncryption; } public boolean isTrustFlagsEnabled() { return trustFlagsEnabled; } public void setTrustFlagsEnabled(boolean trustFlagsEnabled) { this.trustFlagsEnabled = trustFlagsEnabled; } public String getTrustFlags(X509Certificate cert) { InternalCertificate icert = (InternalCertificate) cert; StringBuilder sb = new StringBuilder(); sb.append(PKCS12.encodeFlags(icert.getSSLTrust())); sb.append(","); sb.append(PKCS12.encodeFlags(icert.getEmailTrust())); sb.append(","); sb.append(PKCS12.encodeFlags(icert.getObjectSigningTrust())); return sb.toString(); } public void setTrustFlags(X509Certificate cert, String trustFlags) throws Exception { InternalCertificate icert = (InternalCertificate) cert; String[] flags = trustFlags.split(",", -1); // don't remove empty string if (flags.length < 3) throw new Exception("Invalid trust flags: " + trustFlags); icert.setSSLTrust(PKCS12.decodeFlags(flags[0])); icert.setEmailTrust(PKCS12.decodeFlags(flags[1])); icert.setObjectSigningTrust(PKCS12.decodeFlags(flags[2])); } /** * Add a private key to the PKCS #12 object. * * The PKCS12KeyInfo object received comes about in two * different scenarios: * * - The private key could be in encrypted byte[] form (e.g. * when we have merely loaded a PKCS #12 file for inspection * or e.g. to delete a certificate and its associated key). * In this case we simply re-use this encrypted private key * info byte[]. * * - The private key could be a be an NSS PrivateKey handle. In * this case we must export the PrivateKey from the token to * obtain the EncryptedPrivateKeyInfo. * * The common final step is to add the encrypted private key * data to a "Shrouded Key Bag" to the PKCS #12 object. * Unencrypted key material is never seen. */ public void addKeyBag(PKCS12KeyInfo keyInfo, Password password, SEQUENCE encSafeContents) throws Exception { byte[] keyID = keyInfo.getID(); logger.debug(" - Key ID: " + Utils.HexEncode(keyID)); ASN1Value content; byte[] epkiBytes = keyInfo.getEncryptedPrivateKeyInfoBytes(); if (epkiBytes != null) { // private key already encrypted content = new ANY(epkiBytes); } else { PrivateKey privateKey = keyInfo.getPrivateKey(); if (privateKey == null) { throw new Exception("Missing private key for " + keyInfo.getFriendlyName()); } CryptoToken token = CryptoManager.getInstance().getInternalKeyStorageToken(); if (keyEncryption == PBEAlgorithm.PBE_SHA1_DES3_CBC) { content = create_EPKI_with_PBE_SHA1_DES3_CBC(token, privateKey, password); } else if (keyEncryption == PBEAlgorithm.PBE_PKCS5_PBES2) { content = create_EPKI_with_PBE_PKCS5_PBES2(token, privateKey, password); } else { throw new Exception("Unsupported key encryption: " + keyEncryption); } } SET keyAttrs = createKeyBagAttrs(keyInfo); SafeBag safeBag = new SafeBag(SafeBag.PKCS8_SHROUDED_KEY_BAG, content, keyAttrs); encSafeContents.addElement(safeBag); } public ASN1Value create_EPKI_with_PBE_SHA1_DES3_CBC(CryptoToken token, PrivateKey privateKey, Password password) throws Exception { // Use the same salt size and number of iterations as in pk12util. byte[] salt = new byte[16]; random.nextBytes(salt); return EncryptedPrivateKeyInfo.createPBE( PBEAlgorithm.PBE_SHA1_DES3_CBC, password, salt, 100000, // iterations new PasswordConverter(), privateKey, token); } public ASN1Value create_EPKI_with_PBE_PKCS5_PBES2(CryptoToken token, PrivateKey privateKey, Password password) throws Exception { CryptoStore store = token.getCryptoStore(); byte[] bytes = store.getEncryptedPrivateKeyInfo( // For compatibility with OpenSSL and NSS >= 3.31, // do not BMPString-encode the passphrase when using // non-PKCS #12 PBE scheme such as PKCS #5 PBES2. // // The resulting PKCS #12 is not compatible with // NSS < 3.31. null, // password converter password, // NSS has a bug that causes any AES CBC encryption // to use AES-256, but AlgorithmID contains chosen // alg. To avoid mismatch, use AES_256_CBC. EncryptionAlgorithm.AES_256_CBC, 0, // iterations (default) privateKey); return new ANY(bytes); } public void addCertBag(PKCS12CertInfo certInfo, SEQUENCE safeContents) throws Exception { byte[] id = certInfo.getID(); logger.debug(" - Certificate ID: " + Utils.HexEncode(id)); X509CertImpl cert = certInfo.getCert(); ASN1Value certAsn1 = new OCTET_STRING(cert.getEncoded()); CertBag certBag = new CertBag(CertBag.X509_CERT_TYPE, certAsn1); SET certAttrs = createCertBagAttrs(certInfo); SafeBag safeBag = new SafeBag(SafeBag.CERT_BAG, certBag, certAttrs); safeContents.addElement(safeBag); } BigInteger createLocalID(X509Certificate cert) throws Exception { // SHA1 hash of the X509Cert DER encoding return createLocalID(cert.getEncoded()); } BigInteger createLocalID(byte[] bytes) throws Exception { MessageDigest md = MessageDigest.getInstance("SHA"); md.update(bytes); return new BigInteger(1, md.digest()); } SET createKeyBagAttrs(PKCS12KeyInfo keyInfo) throws Exception { SET attrs = new SET(); String friendlyName = keyInfo.getFriendlyName(); logger.debug(" Friendly name: " + friendlyName); SEQUENCE subjectAttr = new SEQUENCE(); subjectAttr.addElement(SafeBag.FRIENDLY_NAME); SET subjectSet = new SET(); subjectSet.addElement(new BMPString(friendlyName)); subjectAttr.addElement(subjectSet); attrs.addElement(subjectAttr); byte[] keyID = keyInfo.getID(); SEQUENCE localKeyAttr = new SEQUENCE(); localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID); SET localKeySet = new SET(); localKeySet.addElement(new OCTET_STRING(keyID)); localKeyAttr.addElement(localKeySet); attrs.addElement(localKeyAttr); return attrs; } SET createCertBagAttrs(PKCS12CertInfo certInfo) throws Exception { SET attrs = new SET(); String friendlyName = certInfo.getFriendlyName(); logger.debug(" Friendly name: " + friendlyName); SEQUENCE nicknameAttr = new SEQUENCE(); nicknameAttr.addElement(SafeBag.FRIENDLY_NAME); SET nicknameSet = new SET(); nicknameSet.addElement(new BMPString(friendlyName)); nicknameAttr.addElement(nicknameSet); attrs.addElement(nicknameAttr); String trustFlags = certInfo.getTrustFlags(); if (trustFlags != null && trustFlagsEnabled) { logger.debug(" Trust flags: " + trustFlags); SEQUENCE trustFlagsAttr = new SEQUENCE(); trustFlagsAttr.addElement(PKCS12.CERT_TRUST_FLAGS_OID); SET trustFlagsSet = new SET(); trustFlagsSet.addElement(new BMPString(trustFlags)); trustFlagsAttr.addElement(trustFlagsSet); attrs.addElement(trustFlagsAttr); } byte[] keyID = certInfo.getKeyID(); if (keyID != null) { logger.debug(" Key ID: " + Utils.HexEncode(keyID)); SEQUENCE localKeyAttr = new SEQUENCE(); localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID); SET localKeySet = new SET(); localKeySet.addElement(new OCTET_STRING(keyID)); localKeyAttr.addElement(localKeySet); attrs.addElement(localKeyAttr); } return attrs; } public void loadFromNSS(PKCS12 pkcs12) throws Exception { loadFromNSS(pkcs12, true, true); } public void loadFromNSS(PKCS12 pkcs12, boolean includeKey, boolean includeChain) throws Exception { logger.info("Loading certificates and keys from NSS database"); CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalKeyStorageToken(); CryptoStore store = token.getCryptoStore(); for (X509Certificate cert : store.getCertificates()) { loadCertFromNSS(pkcs12, cert, includeKey, includeChain); } } public void loadCertFromNSS( PKCS12 pkcs12, String nickname, boolean includeKey, boolean includeChain) throws Exception { loadCertFromNSS(pkcs12, nickname, includeKey, includeChain, null); } public void loadCertFromNSS( PKCS12 pkcs12, String nickname, boolean includeKey, boolean includeChain, String friendlyName) throws Exception { CryptoManager cm = CryptoManager.getInstance(); X509Certificate[] certs = cm.findCertsByNickname(nickname); if (certs == null || certs.length == 0) { throw new Exception("Certificate not found: " + nickname); } for (X509Certificate cert : certs) { loadCertFromNSS(pkcs12, cert, includeKey, includeChain, friendlyName); } } public void loadCertFromNSS( PKCS12 pkcs12, X509Certificate cert, boolean includeKey, boolean includeChain) throws Exception { loadCertFromNSS(pkcs12, cert, includeKey, includeChain, null); } public void loadCertFromNSS( PKCS12 pkcs12, X509Certificate cert, boolean includeKey, boolean includeChain, String friendlyName) throws Exception { CryptoManager cm = CryptoManager.getInstance(); PKCS12CertInfo certInfo = createCertInfoFromNSS(cert, friendlyName); pkcs12.addCertInfo(certInfo, true); byte[] id = certInfo.getID(); logger.debug(" - Certificate ID: " + Utils.HexEncode(id)); logger.debug(" Friendly name: " + certInfo.getFriendlyName()); logger.debug(" Trust flags: " + certInfo.getTrustFlags()); if (includeKey) { // load key info if exists try { PrivateKey privateKey = cm.findPrivKeyByCert(cert); PKCS12KeyInfo keyInfo = createKeyInfoFromNSS(cert, privateKey, friendlyName); pkcs12.addKeyInfo(keyInfo); byte[] keyID = keyInfo.getID(); certInfo.setKeyID(keyID); logger.debug(" Key ID: " + Utils.HexEncode(keyID)); } catch (ObjectNotFoundException e) { logger.debug("Certificate has no private key"); } } if (includeChain) { // load cert chain X509Certificate[] certChain = cm.buildCertificateChain(cert); if (certChain.length > 1) { logger.debug(" Certificate Chain:"); } for (int i = 1; i < certChain.length; i++) { X509Certificate caCert = certChain[i]; PKCS12CertInfo caCertInfo = createCertInfoFromNSS(caCert); pkcs12.addCertInfo(caCertInfo, false); byte[] caCertID = caCertInfo.getID(); logger.debug(" - Certificate ID: " + Utils.HexEncode(caCertID)); logger.debug(" Friendly name: " + caCertInfo.getFriendlyName()); logger.debug(" Trust flags: " + caCertInfo.getTrustFlags()); } } } public PKCS12CertInfo createCertInfoFromNSS( X509Certificate cert) throws Exception { return createCertInfoFromNSS(cert, null); } public PKCS12CertInfo createCertInfoFromNSS( X509Certificate cert, String friendlyName) throws Exception { // generate cert ID from SHA-1 hash of cert data byte[] id = SafeBag.getLocalKeyIDFromCert(cert.getEncoded()); if (friendlyName == null) { friendlyName = cert.getNickname(); } X509CertImpl certImpl = new X509CertImpl(cert.getEncoded()); String trustFlags = getTrustFlags(cert); PKCS12CertInfo certInfo = new PKCS12CertInfo(); certInfo.setID(id); certInfo.setFriendlyName(friendlyName); certInfo.setCert(certImpl); certInfo.setTrustFlags(trustFlags); return certInfo; } public PKCS12KeyInfo createKeyInfoFromNSS( X509Certificate cert, PrivateKey privateKey) throws Exception { return createKeyInfoFromNSS(cert, privateKey, null); } public PKCS12KeyInfo createKeyInfoFromNSS( X509Certificate cert, PrivateKey privateKey, String friendlyName) throws Exception { byte[] keyID = privateKey.getUniqueID(); if (friendlyName == null) { friendlyName = cert.getNickname(); } PKCS12KeyInfo keyInfo = new PKCS12KeyInfo(privateKey); keyInfo.setID(keyID); keyInfo.setFriendlyName(friendlyName); return keyInfo; } public PFX generatePFX(PKCS12 pkcs12, Password password) throws Exception { logger.info("Generating PKCS #12 data"); AuthenticatedSafes authSafes = new AuthenticatedSafes(); Collection keyInfos = pkcs12.getKeyInfos(); Collection certInfos = pkcs12.getCertInfos(); if (!keyInfos.isEmpty()) { SEQUENCE keySafeContents = new SEQUENCE(); for (PKCS12KeyInfo keyInfo : keyInfos) { addKeyBag(keyInfo, password, keySafeContents); } authSafes.addSafeContents(keySafeContents); } if (!certInfos.isEmpty()) { SEQUENCE certSafeContents = new SEQUENCE(); for (PKCS12CertInfo certInfo : certInfos) { addCertBag(certInfo, certSafeContents); } if (certEncryption == null) { authSafes.addSafeContents(certSafeContents); } else if (certEncryption == PBEAlgorithm.PBE_SHA1_RC2_40_CBC) { byte[] salt = new byte[16]; random.nextBytes(salt); authSafes.addEncryptedSafeContents( certEncryption, password, salt, 100000, // iterations certSafeContents); } else { throw new Exception("Unsupported certificate encryption: " + certEncryption); } } PFX pfx = new PFX(authSafes); // Use the same salt size and number of iterations as in pk12util. byte[] salt = new byte[16]; random.nextBytes(salt); pfx.computeMacData(password, salt, 100000); return pfx; } public void storeIntoFile(PKCS12 pkcs12, String filename, Password password) throws Exception { PFX pfx = generatePFX(pkcs12, password); logger.info("Storing PKCS #12 data into " + filename); ByteArrayOutputStream bos = new ByteArrayOutputStream(); pfx.encode(bos); byte[] data = bos.toByteArray(); try (FileOutputStream fos = new FileOutputStream(filename)) { fos.write(data); } } /** * Loads key bags (for IMPORT and other operations on existing * PKCS #12 files). Does not decrypt EncryptedPrivateKeyInfo * values, but stores them in PKCS12KeyInfo objects for possible * later use. */ public PKCS12KeyInfo getKeyInfo(SafeBag bag, Password password) throws Exception { PKCS12KeyInfo keyInfo = new PKCS12KeyInfo(bag.getBagContent().getEncoded()); // get key attributes SET bagAttrs = bag.getBagAttributes(); for (int i = 0; bagAttrs != null && i < bagAttrs.size(); i++) { Attribute attr = (Attribute) bagAttrs.elementAt(i); OBJECT_IDENTIFIER oid = attr.getType(); if (oid.equals(SafeBag.FRIENDLY_NAME)) { SET values = attr.getValues(); ANY value = (ANY) values.elementAt(0); ByteArrayInputStream bis = new ByteArrayInputStream(value.getEncoded()); BMPString friendlyName = (BMPString) new BMPString.Template().decode(bis); keyInfo.setFriendlyName(friendlyName.toString()); logger.debug(" Friendly name: " + keyInfo.getFriendlyName()); } else if (oid.equals(SafeBag.LOCAL_KEY_ID)) { SET values = attr.getValues(); ANY value = (ANY) values.elementAt(0); ByteArrayInputStream bis = new ByteArrayInputStream(value.getEncoded()); OCTET_STRING keyIdAsn1 = (OCTET_STRING) new OCTET_STRING.Template().decode(bis); byte[] keyID = keyIdAsn1.toByteArray(); keyInfo.setID(keyID); } else { logger.warn(" " + oid + ": " + attr.getValues()); } } return keyInfo; } public PKCS12CertInfo getCertInfo(SafeBag bag) throws Exception { PKCS12CertInfo certInfo = new PKCS12CertInfo(); CertBag certBag = (CertBag) bag.getInterpretedBagContent(); OCTET_STRING certStr = (OCTET_STRING) certBag.getInterpretedCert(); byte[] x509cert = certStr.toByteArray(); // generate cert ID from SHA-1 hash of cert data byte[] id = SafeBag.getLocalKeyIDFromCert(x509cert); certInfo.setID(id); logger.debug(" Certificate ID: " + Utils.HexEncode(id)); X509CertImpl cert = new X509CertImpl(x509cert); certInfo.setCert(cert); Principal subjectDN = cert.getSubjectDN(); logger.debug(" Subject DN: " + subjectDN); SET bagAttrs = bag.getBagAttributes(); for (int i = 0; bagAttrs != null && i < bagAttrs.size(); i++) { Attribute attr = (Attribute) bagAttrs.elementAt(i); OBJECT_IDENTIFIER oid = attr.getType(); if (oid.equals(SafeBag.FRIENDLY_NAME)) { SET values = attr.getValues(); ANY value = (ANY) values.elementAt(0); ByteArrayInputStream bis = new ByteArrayInputStream(value.getEncoded()); BMPString friendlyName = (BMPString) (new BMPString.Template()).decode(bis); certInfo.setFriendlyName(friendlyName.toString()); logger.debug(" Friendly name: " + certInfo.getFriendlyName()); } else if (oid.equals(SafeBag.LOCAL_KEY_ID)) { SET values = attr.getValues(); ANY value = (ANY) values.elementAt(0); ByteArrayInputStream bis = new ByteArrayInputStream(value.getEncoded()); OCTET_STRING keyIdAsn1 = (OCTET_STRING) new OCTET_STRING.Template().decode(bis); byte[] keyID = keyIdAsn1.toByteArray(); certInfo.setKeyID(keyID); logger.debug(" Key ID: " + Utils.HexEncode(keyID)); } else if (oid.equals(PKCS12.CERT_TRUST_FLAGS_OID) && trustFlagsEnabled) { SET values = attr.getValues(); ANY value = (ANY) values.elementAt(0); ByteArrayInputStream is = new ByteArrayInputStream(value.getEncoded()); BMPString trustFlagsAsn1 = (BMPString) (new BMPString.Template()).decode(is); String trustFlags = trustFlagsAsn1.toString(); certInfo.setTrustFlags(trustFlags); logger.debug(" Trust flags: " + trustFlags); } else { logger.warn(" " + oid + ": " + attr.getValues()); } } if (certInfo.getFriendlyName() == null) { logger.debug(" Generating new friendly name"); LdapName dn = new LdapName(subjectDN.getName()); ArrayList values = new ArrayList(); // The getRdns method returns the list in reverse order // therefore, we must traverse in reverse order. List rdns = dn.getRdns(); for (int i = rdns.size() - 1; i >= 0; i--) { Rdn rdn = rdns.get(i); values.add(rdn.getValue().toString()); } String friendlyName = StringUtils.join(values, " - "); certInfo.setFriendlyName(friendlyName); logger.debug(" Friendly name: " + friendlyName); } return certInfo; } public void getKeyInfos(PKCS12 pkcs12, PFX pfx, Password password) throws Exception { logger.debug("Load encrypted private keys:"); AuthenticatedSafes safes = pfx.getAuthSafes(); for (int i = 0; i < safes.getSize(); i++) { SEQUENCE contents = safes.getSafeContentsAt(password, i); for (int j = 0; j < contents.size(); j++) { SafeBag bag = (SafeBag) contents.elementAt(j); OBJECT_IDENTIFIER oid = bag.getBagType(); if (!oid.equals(SafeBag.PKCS8_SHROUDED_KEY_BAG)) continue; logger.debug(" - Private key:"); PKCS12KeyInfo keyInfo = getKeyInfo(bag, password); pkcs12.addKeyInfo(keyInfo); } } } public void getCertInfos(PKCS12 pkcs12, PFX pfx, Password password) throws Exception { logger.debug("Loading certificates:"); AuthenticatedSafes safes = pfx.getAuthSafes(); for (int i = 0; i < safes.getSize(); i++) { SEQUENCE contents = safes.getSafeContentsAt(password, i); for (int j = 0; j < contents.size(); j++) { SafeBag bag = (SafeBag) contents.elementAt(j); OBJECT_IDENTIFIER oid = bag.getBagType(); if (!oid.equals(SafeBag.CERT_BAG)) continue; logger.debug(" - Certificate:"); PKCS12CertInfo certInfo = getCertInfo(bag); pkcs12.addCertInfo(certInfo, true); } } } public PKCS12 loadFromFile(String filename, Password password) throws Exception { logger.info("Loading PKCS #12 file"); Path path = Paths.get(filename); byte[] b = Files.readAllBytes(path); return loadFromByteArray(b, password); } public PKCS12 loadFromByteArray(byte[] b, Password password) throws Exception { ByteArrayInputStream bis = new ByteArrayInputStream(b); PFX pfx = (PFX) (new PFX.Template()).decode(bis); PKCS12 pkcs12 = new PKCS12(); StringBuffer reason = new StringBuffer(); boolean valid = pfx.verifyAuthSafes(password, reason); if (!valid) { throw new Exception("Unable to validate PKCS #12 file: " + reason); } getKeyInfos(pkcs12, pfx, password); getCertInfos(pkcs12, pfx, password); return pkcs12; } public PKCS12 loadFromFile(String filename) throws Exception { return loadFromFile(filename, null); } public PrivateKey.Type getPrivateKeyType(PublicKey publicKey) { if (publicKey.getAlgorithm().equals("EC")) { return PrivateKey.Type.EC; } return PrivateKey.Type.RSA; } public PKCS12CertInfo getCertBySubjectDN(PKCS12 pkcs12, String subjectDN) throws CertificateException { for (PKCS12CertInfo certInfo : pkcs12.getCertInfos()) { Principal certSubjectDN = certInfo.getCert().getSubjectDN(); try { LdapName certSubjdn = new LdapName(certSubjectDN.toString()); LdapName subjDn = new LdapName(subjectDN); if(certSubjdn.equals(subjDn)) return certInfo; } catch (InvalidNameException e) { return null; } } return null; } public void importKey( PKCS12 pkcs12, Password password, String nickname, PKCS12KeyInfo keyInfo) throws Exception { PKCS12CertInfo certInfo = pkcs12.getCertInfoByKeyID(keyInfo.getID()); if (certInfo == null) { logger.debug("Private key has no certificate, ignore"); return; } CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalKeyStorageToken(); PK11Store store = (PK11Store)token.getCryptoStore(); X509CertImpl certImpl = certInfo.getCert(); X509Certificate cert = cm.importCACertPackage(certImpl.getEncoded()); // get public key PublicKey publicKey = cert.getPublicKey(); byte[] epkiBytes = keyInfo.getEncryptedPrivateKeyInfoBytes(); if (epkiBytes == null) { logger.debug( "No EncryptedPrivateKeyInfo for key '" + keyInfo.getFriendlyName() + "'; skipping key"); } try { // first true without BMPString-encoding the passphrase. store.importEncryptedPrivateKeyInfo( null, password, nickname, publicKey, epkiBytes); } catch (Exception e) { // if that failed, try again with BMPString-encoded // passphrase. This is required for PKCS #12 PBE // schemes and for PKCS #12 files using PBES2 generated // by NSS < 3.31 store.importEncryptedPrivateKeyInfo( new PasswordConverter(), password, nickname, publicKey, epkiBytes); } // delete the cert again (it will be imported again later // with the correct nickname) try { store.deleteCertOnly(cert); } catch (NoSuchItemOnTokenException e) { // this is OK } } /** * Store a certificate (and key, if present) in NSSDB. */ public void storeCertIntoNSS( PKCS12 pkcs12, Password password, PKCS12CertInfo certInfo, boolean overwrite) throws Exception { CryptoManager cm = CryptoManager.getInstance(); CryptoToken ct = cm.getInternalKeyStorageToken(); CryptoStore store = ct.getCryptoStore(); String nickname = certInfo.getFriendlyName(); for (X509Certificate cert : cm.findCertsByNickname(nickname)) { if (!overwrite) { return; } store.deleteCert(cert); } X509CertImpl certImpl = certInfo.getCert(); X509Certificate cert; byte[] keyID = certInfo.getKeyID(); if (keyID != null) { // cert has key logger.debug("Importing private key for " + certInfo.getFriendlyName()); PKCS12KeyInfo keyInfo = pkcs12.getKeyInfoByID(keyID); importKey(pkcs12, password, certInfo.getFriendlyName(), keyInfo); logger.debug("Importing user certificate " + certInfo.getFriendlyName()); cert = cm.importUserCACertPackage( certImpl.getEncoded(), certInfo.getFriendlyName()); } else { // cert has no key logger.debug("Importing CA certificate " + certInfo.getFriendlyName()); // Note: JSS does not preserve CA certificate nickname cert = cm.importCACertPackage(certImpl.getEncoded()); } String trustFlags = certInfo.getTrustFlags(); if (trustFlags != null && trustFlagsEnabled) { setTrustFlags(cert, trustFlags); } } public void storeCertIntoNSS(PKCS12 pkcs12, Password password, String nickname, boolean overwrite) throws Exception { Collection certInfos = pkcs12.getCertInfosByFriendlyName(nickname); for (PKCS12CertInfo certInfo : certInfos) { storeCertIntoNSS(pkcs12, password, certInfo, overwrite); } } public void storeIntoNSS( PKCS12 pkcs12, Password password, boolean overwrite) throws Exception { logger.info("Storing data into NSS database"); for (PKCS12CertInfo certInfo : pkcs12.getCertInfos()) { storeCertIntoNSS(pkcs12, password, certInfo, overwrite); } } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/PKCS7.java000066400000000000000000000413571362106420000234670ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Vector; import org.mozilla.jss.netscape.security.util.Utils; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.AlgorithmId; import org.mozilla.jss.netscape.security.x509.X500Name; import org.mozilla.jss.netscape.security.x509.X509CertImpl; /** * PKCS7 as defined in RSA Laboratories PKCS7 Technical Note. Profile * Supports only SignedData ContentInfo * type, where to the type of data signed is plain Data. * For signedData, crls, attributes and * PKCS#6 Extended Certificates are not supported. * * @version 1.33 97/12/10 * @author Benjamin Renaud */ public class PKCS7 { public final static String HEADER = "-----BEGIN PKCS7-----"; public final static String FOOTER = "-----END PKCS7-----"; private ObjectIdentifier contentType; // the ASN.1 members for a signedData (and other) contentTypes private BigInt version; private AlgorithmId[] digestAlgorithmIds; private ContentInfo contentInfo; private X509Certificate[] certificates; private SignerInfo[] signerInfos; /** * Unmarshals a PKCS7 block from its encoded form, parsing the * encoded bytes from the InputStream. * * @param in an input stream holding at least one PKCS7 block. * @exception ParsingException on parsing errors. * @exception IOException on other errors. */ public PKCS7(InputStream in) throws ParsingException, IOException { DataInputStream dis = new DataInputStream(in); int len = 0; byte[] newbuf = new byte[len]; byte[] oldbuf = new byte[len]; byte[] data = new byte[len]; do { newbuf = new byte[dis.available()]; len += dis.available(); dis.readFully(newbuf); data = new byte[len]; System.arraycopy(oldbuf, 0, data, 0, oldbuf.length); System.arraycopy(newbuf, 0, data, oldbuf.length, newbuf.length); oldbuf = new byte[len]; System.arraycopy(data, 0, oldbuf, 0, data.length); } while (dis.available() > 0); parse(new DerInputStream(data)); } /** * Unmarshals a PKCS7 block from its encoded form, parsing the * encoded bytes from the DerInputStream. * * @param derin a DerInputStream holding at least one PKCS7 block. * @exception ParsingException on parsing errors. */ public PKCS7(DerInputStream derin) throws ParsingException { parse(derin); } /** * Unmarshals a PKCS7 block from its encoded form, parsing the * encoded bytes. * * @param bytes the encoded bytes. * @exception ParsingException on parsing errors. */ public PKCS7(byte[] bytes) throws ParsingException { DerInputStream derin = new DerInputStream(bytes); parse(derin); } /** * Unmarshals a PKCS7 block from PEM format. * * @param input the PKCS7 block in PEM format. * @exception ParsingException on parsing errors. */ public PKCS7(String input) throws ParsingException, IOException { StringBuilder sb = new StringBuilder(); try (StringReader sr = new StringReader(input.trim()); BufferedReader in = new BufferedReader(sr)) { String line; // skip everything up to header String header = null; while ((line = in.readLine()) != null) { if (HEADER.equals(line)) { header = line; break; } } if (header == null) { throw new ParsingException("Missing PKCS #7 header"); } // store everything up to footer String footer = null; while ((line = in.readLine()) != null) { if (FOOTER.equals(line)) { footer = line; break; } sb.append(line); } if (footer == null) { throw new ParsingException("Missing PKCS #7 footer"); } } byte[] bytes = Utils.base64decode(sb.toString()); parse(new DerInputStream(bytes)); } private void parse(DerInputStream derin) throws ParsingException { try { ContentInfo contentInfo = new ContentInfo(derin); contentType = contentInfo.contentType; if (contentType.equals(ContentInfo.SIGNED_DATA_OID)) { parseSignedData(contentInfo.getContent()); } else { throw new ParsingException("content type " + contentType + " not supported."); } } catch (IOException e) { ParsingException pe = new ParsingException("IOException: " + e.getMessage()); pe.fillInStackTrace(); throw pe; } } /** * Construct an initialized PKCS7 block. * * @param digestAlgorithmIds the message digest algorithm identifiers. * @param contentInfo the content information. * @param certificates an array of X.509 certificates. * @param signerInfos an array of signer information. */ public PKCS7(AlgorithmId[] digestAlgorithmIds, ContentInfo contentInfo, X509Certificate[] certificates, SignerInfo[] signerInfos) { version = new BigInt(1); this.digestAlgorithmIds = digestAlgorithmIds; this.contentInfo = contentInfo; this.certificates = certificates; this.signerInfos = signerInfos; } private void parseSignedData(DerValue val) throws ParsingException, IOException { DerInputStream dis = val.toDerInputStream(); // Version version = dis.getInteger(); // digestAlgorithmIds DerValue[] digestAlgorithmIdVals = dis.getSet(1); int len = digestAlgorithmIdVals.length; digestAlgorithmIds = new AlgorithmId[len]; try { for (int i = 0; i < len; i++) { DerValue oid = digestAlgorithmIdVals[i]; digestAlgorithmIds[i] = AlgorithmId.parse(oid); } } catch (IOException e) { ParsingException pe = new ParsingException("Error parsing digest AlgorithmId IDs: " + e.getMessage()); pe.fillInStackTrace(); throw pe; } // contentInfo contentInfo = new ContentInfo(dis); /* * check if certificates (implicit tag) are provided * (certificates are OPTIONAL) */ if ((byte) (dis.peekByte()) == (byte) 0xA0) { DerValue[] certificateVals = dis.getSet(2, true); len = certificateVals.length; certificates = new X509Certificate[len]; for (int i = 0; i < len; i++) { try { X509Certificate cert = new X509CertImpl(certificateVals[i]); certificates[i] = cert; } catch (CertificateException e) { ParsingException pe = new ParsingException("CertificateException: " + e.getMessage()); pe.fillInStackTrace(); throw pe; } } } // check if crls (implicit tag) are provided (crls are OPTIONAL) if ((byte) (dis.peekByte()) == (byte) 0xA1) { dis.getSet(0, true); } // signerInfos DerValue[] signerInfoVals = dis.getSet(1); len = signerInfoVals.length; signerInfos = new SignerInfo[len]; for (int i = 0; i < len; i++) { DerInputStream in = signerInfoVals[i].toDerInputStream(); signerInfos[i] = new SignerInfo(in); } } /** * Encodes the signed data to an output stream. * * @param out the output stream to write the encoded data to. * @exception IOException on encoding errors. */ public void encodeSignedData(OutputStream out) throws IOException { DerOutputStream derout = new DerOutputStream(); encodeSignedData(derout, true); out.write(derout.toByteArray()); } /** * Like method above but not sorted. */ public void encodeSignedData(OutputStream out, boolean sort) throws IOException { DerOutputStream derout = new DerOutputStream(); encodeSignedData(derout, sort); out.write(derout.toByteArray()); } /** * encode signed data, sort certs by default. */ public void encodeSignedData(DerOutputStream out) throws IOException { encodeSignedData(out, true); } /** * Encodes the signed data to a DerOutputStream. * * @param out the DerOutputStream to write the encoded data to. * @exception IOException on encoding errors. */ public void encodeSignedData(DerOutputStream out, boolean sort) throws IOException { DerOutputStream signedData = new DerOutputStream(); // version signedData.putInteger(version); // digestAlgorithmIds signedData.putOrderedSetOf(DerValue.tag_Set, digestAlgorithmIds); // contentInfo contentInfo.encode(signedData); // cast to X509CertImpl[] since X509CertImpl implements DerEncoder X509CertImpl implCerts[] = new X509CertImpl[certificates.length]; try { for (int i = 0; i < certificates.length; i++) { implCerts[i] = (X509CertImpl) certificates[i]; } } catch (ClassCastException e) { IOException ioe = new IOException("Certificates in PKCS7 " + "must be of class " + "org.mozilla.jss.netscape.security.X509CertImpl"); ioe.fillInStackTrace(); } // Add the certificate set (tagged with [0] IMPLICIT) // to the signed data if (sort) { signedData.putOrderedSetOf((byte) 0xA0, implCerts); } else { signedData.putSet((byte) 0xA0, implCerts); } // no crls (OPTIONAL field) // signerInfos signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos); // making it a signed data block DerValue signedDataSeq = new DerValue(DerValue.tag_Sequence, signedData.toByteArray()); // making it a content info sequence ContentInfo block = new ContentInfo(ContentInfo.SIGNED_DATA_OID, signedDataSeq); // writing out the contentInfo sequence block.encode(out); } /** * This verifies a given SignerInfo. * * @param info the signer information. * @param bytes the DER encoded content information. * * @exception NoSuchAlgorithmException on unrecognized algorithms. * @exception SignatureException on signature handling errors. */ public SignerInfo verify(SignerInfo info, byte[] bytes) throws NoSuchAlgorithmException, SignatureException { return info.verify(this, bytes); } /** * Returns all signerInfos which self-verify. * * @param bytes the DER encoded content information. * * @exception NoSuchAlgorithmException on unrecognized algorithms. * @exception SignatureException on signature handling errors. */ public SignerInfo[] verify(byte[] bytes) throws NoSuchAlgorithmException, SignatureException { Vector intResult = new Vector(); for (int i = 0; i < signerInfos.length; i++) { SignerInfo signerInfo = verify(signerInfos[i], bytes); if (signerInfo != null) { intResult.addElement(signerInfo); } } if (intResult.size() != 0) { SignerInfo[] result = new SignerInfo[intResult.size()]; intResult.copyInto(result); return result; } return null; } /** * Returns all signerInfos which self-verify. * * @exception NoSuchAlgorithmException on unrecognized algorithms. * @exception SignatureException on signature handling errors. */ public SignerInfo[] verify() throws NoSuchAlgorithmException, SignatureException { return verify(null); } /** * Returns the version number of this PKCS7 block. */ public BigInt getVersion() { return version; } /** * Returns the message digest algorithms specified in this PKCS7 block. */ public AlgorithmId[] getDigestAlgorithmIds() { return digestAlgorithmIds; } /** * Returns the content information specified in this PKCS7 block. */ public ContentInfo getContentInfo() { return contentInfo; } /** * Returns the X.509 certificates listed in this PKCS7 block. */ public X509Certificate[] getCertificates() { return certificates; } /** * Returns the signer's information specified in this PKCS7 block. */ public SignerInfo[] getSignerInfos() { return signerInfos; } /** * Returns the X.509 certificate listed in this PKCS7 block * which has a matching serial number and Issuer name, or * null if one is not found. * * @param serial the serial number of the certificate to retrieve. * @param name the Distinguished Name of the Issuer. */ public X509Certificate getCertificate(BigInt serial, X500Name name) { for (int i = 0; i < certificates.length; i++) { X509Certificate cert = certificates[i]; X500Name thisName = (X500Name) cert.getIssuerDN(); BigInteger tmpSerial = cert.getSerialNumber(); BigInt thisSerial = new BigInt(tmpSerial); if (serial.equals(thisSerial) && name.equals(thisName)) { return cert; } } return null; } public byte[] getBytes() throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); encodeSignedData(out); return out.toByteArray(); } public String toPEMString() throws IOException { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw, true); pw.println(HEADER); pw.print(Utils.base64encode(getBytes(), true)); pw.println(FOOTER); return sw.toString(); } /** * Returns the PKCS7 block in a printable string form. */ public String toString() { StringBuffer out = new StringBuffer("PKCS7 :: version: " + version + "\n"); out.append("PKCS7 :: digest AlgorithmIds: " + "\n"); for (int i = 0; i < digestAlgorithmIds.length; i++) { out.append("\t" + digestAlgorithmIds[i] + "\n"); } out.append(contentInfo + "\n"); out.append("PKCS7 :: certificates: " + "\n"); for (int i = 0; i < certificates.length; i++) { out.append("\t" + i + ". " + certificates[i] + "\n"); } out.append("PKCS7 :: signer infos: " + "\n"); for (int i = 0; i < signerInfos.length; i++) { out.append("\t" + i + ". " + signerInfos[i] + "\n"); } return out.toString(); } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/PKCS8Key.java000066400000000000000000000345101362106420000241320ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.Provider; import java.security.Security; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.lang.reflect.InvocationTargetException; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.x509.AlgorithmId; /** * Holds a PKCS#8 key, for example a private key * * @version 1.30, 97/12/10 * @author Dave Brownell * @author Benjamin Renaud */ public class PKCS8Key implements PrivateKey { /** use serialVersionUID from JDK 1.1. for interoperability */ private static final long serialVersionUID = -3836890099307167124L; /* The algorithm information (name, parameters, etc). */ protected AlgorithmId algid; /* The key bytes, without the algorithm information */ protected byte[] key; /* The encoded for the key. */ protected byte[] encodedKey; /* The version for this key */ public static final BigInteger VERSION = BigInteger.valueOf(0); /** * Default constructor. The key constructed must have its key * and algorithm initialized before it may be used, for example * by using decode. */ public PKCS8Key() { } /** * Construct PKCS#8 subject public key from a DER value. If * the runtime environment is configured with a specific class for * this kind of key, a subclass is returned. Otherwise, a generic * PKCS8Key object is returned. * *

* This mechanism gurantees that keys (and algorithms) may be freely manipulated and transferred, without risk of * losing information. Also, when a key (or algorithm) needs some special handling, that specific need can be * accomodated. * * @param in the DER-encoded SubjectPublicKeyInfo value * @exception IOException on data format errors */ public static PKCS8Key parse(DerValue in) throws IOException { AlgorithmId algorithm; PKCS8Key subjectKey; if (in.tag != DerValue.tag_Sequence) throw new IOException("corrupt private key"); BigInteger parsedVersion = in.data.getInteger().toBigInteger(); if (!VERSION.equals(parsedVersion)) { throw new IOException("version mismatch: (supported: " + VERSION + ", parsed: " + parsedVersion); } algorithm = AlgorithmId.parse(in.data.getDerValue()); try { subjectKey = buildPKCS8Key(algorithm, in.data.getOctetString()); } catch (InvalidKeyException e) { throw new IOException("corrupt private key"); } if (in.data.available() != 0) throw new IOException("excess private key"); return subjectKey; } /** * Parse the key bits. This may be redefined by subclasses to take * advantage of structure within the key. For example, RSA public * keys encapsulate two unsigned integers (modulus and exponent) as * DER values within the key bits; Diffie-Hellman and * DSS/DSA keys encapsulate a single unsigned integer. * *

* This function is called when creating PKCS#8 SubjectPublicKeyInfo values using the PKCS8Key member functions, * such as parse and decode. * * @exception IOException if a parsing error occurs. * @exception InvalidKeyException if the key encoding is invalid. */ protected void parseKeyBits() throws IOException, InvalidKeyException { encode(); } /* * Factory interface, building the kind of key associated with this * specific algorithm ID or else returning this generic base class. * See the description above. */ public static PKCS8Key buildPKCS8Key(AlgorithmId algid, byte[] key) throws IOException, InvalidKeyException { /* * Use the algid and key parameters to produce the ASN.1 encoding * of the key, which will then be used as the input to the * key factory. */ DerOutputStream pkcs8EncodedKeyStream = new DerOutputStream(); encode(pkcs8EncodedKeyStream, algid, key); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pkcs8EncodedKeyStream.toByteArray()); try { // Instantiate the key factory of the appropriate algorithm KeyFactory keyFac = KeyFactory.getInstance(algid.getName()); // Generate the private key PrivateKey privKey = keyFac.generatePrivate(pkcs8KeySpec); if (privKey instanceof PKCS8Key) { /* * Return specialized PKCS8Key, where the structure within the * key has been parsed */ return (PKCS8Key) privKey; } } catch (NoSuchAlgorithmException e) { // Return generic PKCS8Key with opaque key data (see below) } catch (InvalidKeySpecException e) { // Return generic PKCS8Key with opaque key data (see below) } /* * Try again using JDK1.1-style for backwards compatibility. */ String classname = ""; try { Provider sunProvider; sunProvider = Security.getProvider("SUN"); if (sunProvider == null) throw new InstantiationException(); classname = sunProvider.getProperty("PrivateKey.PKCS#8." + algid.getName()); if (classname == null) { throw new InstantiationException(); } Class keyClass = Class.forName(classname); Object inst; PKCS8Key result; inst = keyClass.getConstructor().newInstance(); if (inst instanceof PKCS8Key) { result = (PKCS8Key) inst; result.algid = algid; result.key = key; result.parseKeyBits(); return result; } } catch (ClassNotFoundException e) { } catch (InstantiationException e) { } catch (IllegalAccessException e) { throw new IOException("IllegalAccessException : " + e.getMessage(), e); } catch (NoSuchMethodException e) { } catch (InvocationTargetException e) { throw new IOException("InvocationTargetException : " + e.getMessage(), e); } PKCS8Key result = new PKCS8Key(); result.algid = algid; result.key = key; return result; } /** * Returns the algorithm to be used with this key. */ public String getAlgorithm() { return algid.getName(); } /** * Returns the algorithm ID to be used with this key. */ public AlgorithmId getAlgorithmId() { return algid; } /** * PKCS#8 sequence on the DER output stream. */ public final void encode(DerOutputStream out) throws IOException { encode(out, this.algid, this.key); } /** * Returns the DER-encoded form of the key as a byte array. */ public synchronized byte[] getEncoded() { byte[] result = null; try { result = encode(); } catch (InvalidKeyException e) { } return result; } /** * Returns the format for this key: "PKCS#8" */ public String getFormat() { return "PKCS#8"; } /** * Returns the DER-encoded form of the key as a byte array. * * @exception InvalidKeyException if an encoding error occurs. */ public byte[] encode() throws InvalidKeyException { if (encodedKey == null) { try { DerOutputStream out; out = new DerOutputStream(); encode(out); encodedKey = out.toByteArray(); } catch (IOException e) { throw new InvalidKeyException("IOException : " + e.getMessage()); } } return copyEncodedKey(encodedKey); } /* * Returns a printable representation of the key */ public String toString() { org.mozilla.jss.netscape.security.util.PrettyPrintFormat pp = new org.mozilla.jss.netscape.security.util.PrettyPrintFormat(" ", 20); String keybits = pp.toHexString(key); return "algorithm = " + algid.toString() + ", unparsed keybits = \n" + keybits; } /** * Initialize an PKCS8Key object from an input stream. The data * on that input stream must be encoded using DER, obeying the * PKCS#8 format: a sequence consisting of a version, an algorithm * ID and a bit string which holds the key. (That bit string is * often used to encapsulate another DER encoded sequence.) * *

* Subclasses should not normally redefine this method; they should instead provide a parseKeyBits * method to parse any fields inside the key member. * * @param in an input stream with a DER-encoded PKCS#8 * SubjectPublicKeyInfo value * * @exception InvalidKeyException if a parsing error occurs. */ public void decode(InputStream in) throws InvalidKeyException { DerValue val; try { val = new DerValue(in); if (val.tag != DerValue.tag_Sequence) throw new InvalidKeyException("invalid key format"); BigInteger version = val.data.getInteger().toBigInteger(); if (!version.equals(PKCS8Key.VERSION)) { throw new IOException("version mismatch: (supported: " + PKCS8Key.VERSION + ", parsed: " + version); } algid = AlgorithmId.parse(val.data.getDerValue()); key = val.data.getOctetString(); parseKeyBits(); if (val.data.available() != 0) throw new InvalidKeyException("excess key data"); } catch (IOException e) { // e.printStackTrace (); throw new InvalidKeyException("IOException : " + e.getMessage()); } } public void decode(byte[] encodedKey) throws InvalidKeyException { decode(new ByteArrayInputStream(encodedKey)); } /** * Serialization write ... PKCS#8 keys serialize as * themselves, and they're parsed when they get read back. */ private void writeObject(java.io.ObjectOutputStream stream) throws IOException { stream.write(getEncoded()); } /** * Serialization read ... PKCS#8 keys serialize as * themselves, and they're parsed when they get read back. */ private void readObject(ObjectInputStream stream) throws IOException { try { decode(stream); } catch (InvalidKeyException e) { e.printStackTrace(); throw new IOException("deserialized key is invalid: " + e.getMessage()); } } /* * Make a copy of the encoded key. */ private byte[] copyEncodedKey(byte[] encodedKey) { int len = encodedKey.length; byte[] copy = new byte[len]; System.arraycopy(encodedKey, 0, copy, 0, len); return copy; } /* * Produce PKCS#8 encoding from algorithm id and key material. */ static void encode(DerOutputStream out, AlgorithmId algid, byte[] key) throws IOException { DerOutputStream tmp = new DerOutputStream(); tmp.putInteger(new BigInt(VERSION.toByteArray())); algid.encode(tmp); tmp.putOctetString(key); out.write(DerValue.tag_Sequence, tmp); } /** * Compares two private keys. This returns false if the object with which * to compare is not of type Key. * Otherwise, the encoding of this key object is compared with the * encoding of the given key object. * * @param object the object with which to compare * @return true if this key has the same encoding as the * object argument; false otherwise. */ public boolean equals(Object object) { if (this == object) { return true; } if (object instanceof Key) { // this encoding byte[] b1; if (encodedKey != null) { b1 = encodedKey; } else { b1 = getEncoded(); } // that encoding byte[] b2 = ((Key) object).getEncoded(); // do the comparison int i; if (b1.length != b2.length) return false; for (i = 0; i < b1.length; i++) { if (b1[i] != b2[i]) { return false; } } return true; } return false; } /** * Calculates a hash code value for this object. Objects * which are equal will also have the same hashcode. */ public int hashCode() { int retval = 0; byte[] b1 = getEncoded(); for (int i = 1; i < b1.length; i++) { retval += b1[i] * i; } return (retval); } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/PKCS9Attribute.java000066400000000000000000001061041362106420000253450ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.io.IOException; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Date; import java.util.Hashtable; import org.mozilla.jss.netscape.security.util.DerEncoder; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.CertificateExtensions; /** * Class supporting any PKCS9 attribute except * ExtendedCertificateAttribute. Supports DER decoding and access to * attribute values, but not DER encoding or setting of values. * * @version 1.2 97/12/10 * @author Douglas Hoover */ public class PKCS9Attribute implements DerEncoder { /* * OIDs of PKCS #9 attribute types. */ private static final String RSADSI_str = "1.2.840.113549"; private static final String PKCS_str = RSADSI_str + ".1"; private static final String PKCS9_str = PKCS_str + ".9"; /** * Array of attribute OIDs defined in PKCS9, by number. */ static final ObjectIdentifier[] PKCS9_OIDS = //new ObjectIdentifier[10]; // There are some Obsolete(?) attribute identifiers. // This is mainly for extensionRequest (14) in pkcs10. // We just add the other 4 as by products. new ObjectIdentifier[15]; static { // static initializer for PKCS9_OIDS for (int i = 1; i < PKCS9_OIDS.length; i++) { PKCS9_OIDS[i] = new ObjectIdentifier(PKCS9_str + "." + i); } } public static final ObjectIdentifier EMAIL_ADDRESS_OID = PKCS9_OIDS[1]; public static final ObjectIdentifier UNSTRUCTURED_NAME_OID = PKCS9_OIDS[2]; public static final ObjectIdentifier CONTENT_TYPE_OID = PKCS9_OIDS[3]; public static final ObjectIdentifier MESSAGE_DIGEST_OID = PKCS9_OIDS[4]; public static final ObjectIdentifier SIGNING_TIME_OID = PKCS9_OIDS[5]; public static final ObjectIdentifier COUNTERSIGNATURE_OID = PKCS9_OIDS[6]; public static final ObjectIdentifier CHALLENGE_PASSWORD_OID = PKCS9_OIDS[7]; public static final ObjectIdentifier UNSTRUCTURED_ADDRESS_OID = PKCS9_OIDS[8]; public static final ObjectIdentifier EXTENDED_CERTIFICATE_ATTRIBUTES_OID = PKCS9_OIDS[9]; public static final ObjectIdentifier ISSUER_AND_SERIALNUMBER_OID = PKCS9_OIDS[10]; public static final ObjectIdentifier PASSWORD_CHECK_OID = PKCS9_OIDS[11]; public static final ObjectIdentifier PUBLIC_KEY_OID = PKCS9_OIDS[12]; public static final ObjectIdentifier SIGNING_DESCRIPTION_OID = PKCS9_OIDS[13]; public static final ObjectIdentifier EXTENSION_REQUEST_OID = PKCS9_OIDS[14]; public static final String EMAIL_ADDRESS_STR = "EmailAddress"; public static final String UNSTRUCTURED_NAME_STR = "UnstructuredName"; public static final String CONTENT_TYPE_STR = "ContentType"; public static final String MESSAGE_DIGEST_STR = "MessageDigest"; public static final String SIGNING_TIME_STR = "SigningTime"; public static final String COUNTERSIGNATURE_STR = "Countersignature"; public static final String CHALLENGE_PASSWORD_STR = "ChallengePassword"; public static final String UNSTRUCTURED_ADDRESS_STR = "UnstructuredAddress"; public static final String EXTENDED_CERTIFICATE_ATTRIBUTES_STR = "ExtendedCertificateAttributes"; public static final String ISSUER_AND_SERIALNUMBER_STR = "IssuerAndSerialNumber"; public static final String PASSWORD_CHECK_STR = "PasswordCheck"; public static final String PUBLIC_KEY_STR = "PublicKey"; public static final String SIGNING_DESCRIPTION_STR = "SigningDescription"; public static final String EXTENSION_REQUEST_STR = "ExtensionRequest"; /** * Hashtable mapping names and variant names of supported * attributes to their OIDs. This table contains all name forms * that occur in PKCS9, in lower case. */ private static final Hashtable NAME_OID_TABLE = new Hashtable( 28); static { // static initializer for PCKS9_NAMES NAME_OID_TABLE.put("emailaddress", PKCS9_OIDS[1]); NAME_OID_TABLE.put("unstructuredname", PKCS9_OIDS[2]); NAME_OID_TABLE.put("contenttype", PKCS9_OIDS[3]); NAME_OID_TABLE.put("messagedigest", PKCS9_OIDS[4]); NAME_OID_TABLE.put("signingtime", PKCS9_OIDS[5]); NAME_OID_TABLE.put("countersignature", PKCS9_OIDS[6]); NAME_OID_TABLE.put("challengepassword", PKCS9_OIDS[7]); NAME_OID_TABLE.put("unstructuredaddress", PKCS9_OIDS[8]); NAME_OID_TABLE.put("extendedcertificateattributes", PKCS9_OIDS[9]); NAME_OID_TABLE.put("issuerandserialNumber", PKCS9_OIDS[10]); NAME_OID_TABLE.put("passwordcheck", PKCS9_OIDS[11]); NAME_OID_TABLE.put("publickey", PKCS9_OIDS[12]); NAME_OID_TABLE.put("signingdescription", PKCS9_OIDS[13]); NAME_OID_TABLE.put("extensionrequest", PKCS9_OIDS[14]); }; /** * Hashtable mapping attribute OIDs defined in PKCS9 to the * corresponding attribute value type. */ private static final Hashtable OID_NAME_TABLE = new Hashtable( 14); static { OID_NAME_TABLE.put(PKCS9_OIDS[1], EMAIL_ADDRESS_STR); OID_NAME_TABLE.put(PKCS9_OIDS[2], UNSTRUCTURED_NAME_STR); OID_NAME_TABLE.put(PKCS9_OIDS[3], CONTENT_TYPE_STR); OID_NAME_TABLE.put(PKCS9_OIDS[4], MESSAGE_DIGEST_STR); OID_NAME_TABLE.put(PKCS9_OIDS[5], SIGNING_TIME_STR); OID_NAME_TABLE.put(PKCS9_OIDS[6], COUNTERSIGNATURE_STR); OID_NAME_TABLE.put(PKCS9_OIDS[7], CHALLENGE_PASSWORD_STR); OID_NAME_TABLE.put(PKCS9_OIDS[8], UNSTRUCTURED_ADDRESS_STR); OID_NAME_TABLE.put(PKCS9_OIDS[9], EXTENDED_CERTIFICATE_ATTRIBUTES_STR); OID_NAME_TABLE.put(PKCS9_OIDS[10], ISSUER_AND_SERIALNUMBER_STR); OID_NAME_TABLE.put(PKCS9_OIDS[11], PASSWORD_CHECK_STR); OID_NAME_TABLE.put(PKCS9_OIDS[12], PUBLIC_KEY_STR); OID_NAME_TABLE.put(PKCS9_OIDS[13], SIGNING_DESCRIPTION_STR); OID_NAME_TABLE.put(PKCS9_OIDS[14], EXTENSION_REQUEST_STR); } /** * Acceptable ASN.1 tags for DER encodings of values of PKCS9 * attributes, by index in PKCS9_OIDS. * Sets of acceptable tags are represented as arrays. */ private static final Byte[][] PKCS9_VALUE_TAGS = { null, { Byte.valueOf(DerValue.tag_IA5String) }, // EMailAddress { Byte.valueOf(DerValue.tag_IA5String) }, // UnstructuredName { Byte.valueOf(DerValue.tag_ObjectId) }, // ContentType { Byte.valueOf(DerValue.tag_OctetString) }, // MessageDigest { Byte.valueOf(DerValue.tag_UtcTime) }, // SigningTime { Byte.valueOf(DerValue.tag_Sequence) }, // Countersignature { Byte.valueOf(DerValue.tag_PrintableString), Byte.valueOf(DerValue.tag_T61String) }, // ChallengePassword { Byte.valueOf(DerValue.tag_PrintableString), Byte.valueOf(DerValue.tag_T61String) }, // UnstructuredAddress { Byte.valueOf(DerValue.tag_SetOf) }, // ExtendedCertificateAttributes null, //IssuerAndSerialNumber null, //PasswordCheck null, //PublicKey null, //SigningDescription { Byte.valueOf(DerValue.tag_Sequence) } //ExtensionRequest }; /** * Class types required for values for a given PKCS9 * attribute type. * *

* The following table shows the correspondence between attribute types and value component classes. * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
OIDAttribute Type NameKindValue Class
1.2.840.113549.1.9.1EmailAddressMultiple-valuedString[]
1.2.840.113549.1.9.2UnstructuredNameMultiple-valuedString
1.2.840.113549.1.9.3ContentTypeSingle-valuedObjectIdentifier
1.2.840.113549.1.9.4MessageDigestSingle-valuedbyte[]
1.2.840.113549.1.9.5SigningTimeSingle-valuedDate
1.2.840.113549.1.9.6CountersignatureMultiple-valuedSignerInfo
1.2.840.113549.1.9.7ChallengePasswordSingle-valuedString
1.2.840.113549.1.9.8UnstructuredAddressSingle-valuedString
1.2.840.113549.1.9.9ExtendedCertificateAttributesMultiple-valued(not supported)
1.2.840.113549.1.9.10IssuerAndSerialNumberSingle-valued(not supported)
1.2.840.113549.1.9.11PasswordCheckSingle-valued(not supported)
1.2.840.113549.1.9.12PublicKeySingle-valued(not supported)
1.2.840.113549.1.9.13SigningDescriptionSingle-valued(not supported)
1.2.840.113549.1.9.14ExtensionRequestSingle-valuedSequence
*/ private static final Class[] VALUE_CLASSES = new Class[15]; static { VALUE_CLASSES[0] = null; // not used VALUE_CLASSES[1] = String[].class; // EMailAddress VALUE_CLASSES[2] = String[].class; // UnstructuredName VALUE_CLASSES[3] = ObjectIdentifier.class; // ContentType VALUE_CLASSES[4] = byte[].class; // MessageDigest (byte[]) VALUE_CLASSES[5] = Date.class; // SigningTime VALUE_CLASSES[6] = SignerInfo[].class; // Countersignature VALUE_CLASSES[7] = String.class; // ChallengePassword VALUE_CLASSES[8] = String[].class; // UnstructuredAddress VALUE_CLASSES[9] = null; // ExtendedCertificateAttributes VALUE_CLASSES[10] = null; // IssuerAndSerialNumber VALUE_CLASSES[11] = null; // PasswordCheck VALUE_CLASSES[12] = null; // PublicKey VALUE_CLASSES[13] = null; // SigningDescription VALUE_CLASSES[14] = CertificateExtensions.class; // ExtensionRequest } /** * Array indicating which PKCS9 attributes are single-valued, * by index in PKCS9_OIDS. */ private static final boolean[] SINGLE_VALUED = { false, false, // EMailAddress false, // UnstructuredName true, // ContentType true, // MessageDigest true, // SigningTime false, // Countersignature true, // ChallengePassword false, // UnstructuredAddress false, // ExtendedCertificateAttributes true, // IssuerAndSerialNumber true, // PasswordCheck true, // PublicKey true, // SigningDescription true // ExtensionRequest }; /** * The OID of this attribute is PKCS9_OIDS[index]. */ private int index; /** * Value set of this attribute. Its class is given by VALUE_CLASSES[index]. */ private Object value; /** * Construct an attribute object from the attribute's OID and * value. If the attribute is single-valued, provide only one * value. If the attribute is * multiple-valued, provide an array containing all the values. * Arrays of length zero are accepted, though probably useless. * *

* The following table gives the class that value must have for a given attribute. * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
OIDAttribute Type NameKindValue Class
1.2.840.113549.1.9.1EmailAddressMultiple-valuedString[]
1.2.840.113549.1.9.2UnstructuredNameMultiple-valuedString[]
1.2.840.113549.1.9.3ContentTypeSingle-valuedObjectIdentifier
1.2.840.113549.1.9.4MessageDigestSingle-valuedbyte[]
1.2.840.113549.1.9.5SigningTimeSingle-valuedDate
1.2.840.113549.1.9.6CountersignatureMultiple-valuedSignerInfo[]
1.2.840.113549.1.9.7ChallengePasswordSingle-valuedString
1.2.840.113549.1.9.8UnstructuredAddressSingle-valuedString[]
1.2.840.113549.1.9.9ExtendedCertificateAttributesMultiple-valued(not supported)
1.2.840.113549.1.9.10IssuerAndSerialNumberSingle-valued(not supported)
1.2.840.113549.1.9.11PasswordCheckSingle-valued(not supported)
1.2.840.113549.1.9.12PublicKeySingle-valued(not supported)
1.2.840.113549.1.9.13SigningDescriptionSingle-valued(not supported)
1.2.840.113549.1.9.14ExtensionRequestSingle-valuedSequence
*/ public PKCS9Attribute(ObjectIdentifier oid, Object value) throws IllegalArgumentException { init(oid, value); } /** * Construct an attribute object from the attribute's name and * value. If the attribute is single-valued, provide only one * value. If the attribute is * multiple-valued, provide an array containing all the values. * Arrays of length zero are accepted, though probably useless. * *

* The following table gives the class that value must have for a given attribute. Reasonable variants * of these attributes are accepted; in particular, case does not matter. * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
OIDAttribute Type NameKindValue Class
1.2.840.113549.1.9.1EmailAddressMultiple-valuedString[]
1.2.840.113549.1.9.2UnstructuredNameMultiple-valuedString[]
1.2.840.113549.1.9.3ContentTypeSingle-valuedObjectIdentifier
1.2.840.113549.1.9.4MessageDigestSingle-valuedbyte[]
1.2.840.113549.1.9.5SigningTimeSingle-valuedDate
1.2.840.113549.1.9.6CountersignatureMultiple-valuedSignerInfo[]
1.2.840.113549.1.9.7ChallengePasswordSingle-valuedString
1.2.840.113549.1.9.8UnstructuredAddressSingle-valuedString[]
1.2.840.113549.1.9.9ExtendedCertificateAttributesMultiple-valued(not supported)
1.2.840.113549.1.9.10IssuerAndSerialNumberSingle-valued(not supported)
1.2.840.113549.1.9.11PasswordCheckSingle-valued(not supported)
1.2.840.113549.1.9.12PublicKeySingle-valued(not supported)
1.2.840.113549.1.9.13SigningDescriptionSingle-valued(not supported)
1.2.840.113549.1.9.14ExtensionRequestSingle-valuedSequence
* * @exception IllegalArgumentException * if the name is not recognized of the value has the wrong type. */ public PKCS9Attribute(String name, Object value) throws IllegalArgumentException { ObjectIdentifier oid = getOID(name); if (oid == null) throw new IllegalArgumentException( "Unrecognized attribute name " + name + " constructing PKCS9Attribute."); init(oid, value); } private void init(ObjectIdentifier oid, Object value) throws IllegalArgumentException { index = indexOf(oid, PKCS9_OIDS, 1); if (index == -1) throw new IllegalArgumentException( "Unsupported OID " + oid + " constructing PKCS9Attribute."); if (!VALUE_CLASSES[index].isInstance(value)) throw new IllegalArgumentException( "Wrong value class " + " for attribute " + oid + " constructing PKCS9Attribute; was " + value.getClass().toString() + ", should be " + VALUE_CLASSES[index].toString()); this.value = value; } /** * Construct a PKCS9Attribute from its encoding on an input * stream. * * @exception IOException on parsing error. */ public PKCS9Attribute(DerValue derVal) throws IOException { decode(derVal); } /** * Decode a PKCS9 attribute. * * @param val * the DerValue representing the DER encoding of the attribute. */ private void decode(DerValue derVal) throws IOException { DerInputStream derIn = new DerInputStream(derVal.toByteArray()); DerValue[] val = derIn.getSequence(2); if (derIn.available() != 0) throw new IOException("Excess data parsing PKCS9Attribute"); if (val.length != 2) throw new IOException("PKCS9Attribute doesn't have two components"); DerValue[] elems; // get the oid ObjectIdentifier oid = val[0].getOID(); index = indexOf(oid, PKCS9_OIDS, 1); Byte tag; if (index == -1) throw new IOException("Invalid OID for PKCS9 attribute: " + oid); elems = new DerInputStream(val[1].toByteArray()).getSet(1); // check single valued have only one value if (SINGLE_VALUED[index] && elems.length > 1) throwSingleValuedException(); // check for illegal element tags for (int i = 0; i < elems.length; i++) { tag = Byte.valueOf(elems[i].tag); if (indexOf(tag, PKCS9_VALUE_TAGS[index], 0) == -1) throwTagException(tag); } switch (index) { case 1: // email address case 2: // unstructured name case 8: // unstructured address { // open scope String[] values = new String[elems.length]; for (int i = 0; i < elems.length; i++) values[i] = elems[i].getAsString(); value = values; } // close scope break; case 3: // content type value = elems[0].getOID(); break; case 4: // message digest value = elems[0].getOctetString(); break; case 5: // signing time value = (new DerInputStream(elems[0].toByteArray())).getUTCTime(); break; case 6: // countersignature { // open scope SignerInfo[] values = new SignerInfo[elems.length]; for (int i = 0; i < elems.length; i++) values[i] = new SignerInfo(elems[i].toDerInputStream()); value = values; } // close scope break; case 7: // challenge password value = elems[0].getAsString(); break; case 9: // extended-certificate attribute -- not // supported throw new IOException("PKCS9 extended-certificate " + "attribute not supported."); case 10: // IssuerAndSerialNumber attribute -- not // supported throw new IOException("PKCS9 IssuerAndSerialNumber " + "attribute not supported."); case 11: // passwordCheck attribute -- not // supported throw new IOException("PKCS9 passwordCheck " + "attribute not supported."); case 12: // PublicKey attribute -- not // supported throw new IOException("PKCS9 PublicKey " + "attribute not supported."); case 13: // SigningDescription attribute -- not // supported throw new IOException("PKCS9 SigningDescription " + "attribute not supported."); case 14: // ExtensionRequest attribute value = new CertificateExtensions(elems[0].toDerInputStream()); // break unnecessary default: // can't happen } } /** * Write the DER encoding of this attribute to an output stream. * *

* N.B.: This method always encodes values of ChallengePassword and UnstructuredAddress attributes as ASN.1 * PrintableStrings, without checking whether they should be encoded as T61Strings. */ public void derEncode(OutputStream out) throws IOException { try (DerOutputStream temp = new DerOutputStream(); DerOutputStream temp2 = new DerOutputStream(); DerOutputStream derOut = new DerOutputStream()) { temp.putOID(getOID()); switch (index) { case 1: // email address case 2: // unstructured name { // open scope String[] values = (String[]) value; DerOutputStream[] temps = new DerOutputStream[values.length]; for (int i = 0; i < values.length; i++) { temps[i] = new DerOutputStream(); temps[i].putIA5String(values[i]); } temp.putOrderedSetOf(DerValue.tag_Set, temps); } // close scope break; case 3: // content type { temp2.putOID((ObjectIdentifier) value); temp.write(DerValue.tag_Set, temp2.toByteArray()); } break; case 4: // message digest { temp2.putOctetString((byte[]) value); temp.write(DerValue.tag_Set, temp2.toByteArray()); } break; case 5: // signing time { temp2.putUTCTime((Date) value); temp.write(DerValue.tag_Set, temp2.toByteArray()); } break; case 6: // countersignature temp.putOrderedSetOf(DerValue.tag_Set, (DerEncoder[]) value); break; case 7: // challenge password { temp2.putPrintableString((String) value); temp.write(DerValue.tag_Set, temp2.toByteArray()); } break; case 8: // unstructured address { // open scope String[] values = (String[]) value; DerOutputStream[] temps = new DerOutputStream[values.length]; for (int i = 0; i < values.length; i++) { temps[i] = new DerOutputStream(); temps[i].putPrintableString(values[i]); } temp.putOrderedSetOf(DerValue.tag_Set, temps); } // close scope break; case 9: // extended-certificate attribute -- not // supported throw new IOException("PKCS9 extended-certificate " + "attribute not supported."); case 10: // IssuerAndSerialNumber attribute -- not // supported throw new IOException("PKCS9 IssuerAndSerialNumber " + "attribute not supported."); case 11: // passwordCheck attribute -- not // supported throw new IOException("PKCS9 passwordCheck " + "attribute not supported."); case 12: // PublicKey attribute -- not // supported throw new IOException("PKCS9 PublicKey " + "attribute not supported."); case 13: // SigningDescription attribute -- not // supported throw new IOException("PKCS9 SigningDescription " + "attribute not supported."); case 14: // ExtensionRequest attribute try { //temp2.putSequence((CertificateExtensions) value); ((CertificateExtensions) value).encode(temp2); temp.write(DerValue.tag_Sequence, temp2.toByteArray()); } catch (CertificateException e) { throw new IOException("PKCS9 extension attributes not encoded"); } // break unnecessary default: // can't happen } derOut.write(DerValue.tag_Sequence, temp.toByteArray()); out.write(derOut.toByteArray()); } } /** * Get the value of this attribute. If the attribute is * single-valued, return just the one value. If the attribute is * multiple-valued, return an array containing all the values. * It is possible for this array to be of length 0. * *

* The following table gives the class of the value returned, depending on the type of this attribute. * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
OIDAttribute Type NameKindValue Class
1.2.840.113549.1.9.1EmailAddressMultiple-valuedString[]
1.2.840.113549.1.9.2UnstructuredNameMultiple-valuedString[]
1.2.840.113549.1.9.3ContentTypeSingle-valuedObjectIdentifier
1.2.840.113549.1.9.4MessageDigestSingle-valuedbyte[]
1.2.840.113549.1.9.5SigningTimeSingle-valuedDate
1.2.840.113549.1.9.6CountersignatureMultiple-valuedSignerInfo[]
1.2.840.113549.1.9.7ChallengePasswordSingle-valuedString
1.2.840.113549.1.9.8UnstructuredAddressSingle-valuedString[]
1.2.840.113549.1.9.9ExtendedCertificateAttributesMultiple-valued(not supported)
1.2.840.113549.1.9.10IssuerAndSerialNumberSingle-valued(not supported)
1.2.840.113549.1.9.11PasswordCheckSingle-valued(not supported)
1.2.840.113549.1.9.12PublicKeySingle-valued(not supported)
1.2.840.113549.1.9.13SigningDescriptionSingle-valued(not supported)
1.2.840.113549.1.9.14ExtensionRequestSingle-valuedSequence
* */ public Object getValue() { return value; } /** * Show whether this attribute is single-valued. */ public boolean isSingleValued() { return SINGLE_VALUED[index]; } /** * Return the OID of this attribute. */ public ObjectIdentifier getOID() { return PKCS9_OIDS[index]; } /** * Return the name of this attribute. */ public String getName() { return OID_NAME_TABLE.get(PKCS9_OIDS[index]); } /** * Return the OID for a given attribute name or null if we don't recognize * the name. */ public static ObjectIdentifier getOID(String name) { return NAME_OID_TABLE.get(name.toLowerCase()); } /** * Return the attribute name for a given OID or null if we don't recognize * the oid. */ public static String getName(ObjectIdentifier oid) { return OID_NAME_TABLE.get(oid); } /** * Returns a string representation of this attribute. */ public String toString() { StringBuffer buf = new StringBuffer(100); buf.append("["); buf.append(OID_NAME_TABLE.get(PKCS9_OIDS[index])); buf.append(": "); if (SINGLE_VALUED[index]) { if (value instanceof byte[]) { // special case for octet string org.mozilla.jss.netscape.security.util.PrettyPrintFormat pp = new org.mozilla.jss.netscape.security.util.PrettyPrintFormat(" ", 20); String valuebits = pp.toHexString(((byte[]) value)); buf.append(valuebits); } else { buf.append(value.toString()); } buf.append("]"); return buf.toString(); } else { // multiple-valued boolean first = true; Object[] values = (Object[]) value; for (int j = 0; j < values.length; j++) { if (first) first = false; else buf.append(", "); buf.append(values[j].toString()); } return buf.toString(); } } /** * Beginning the search at start, find the first * index i such that a[i] = obj. * * @return the index, if found, and -1 otherwise. */ static int indexOf(Object obj, Object[] a, int start) { for (int i = start; i < a.length; i++) { if (obj.equals(a[i])) return i; } return -1; } /** * Throw an exception when there are multiple values for * a single-valued attribute. */ private void throwSingleValuedException() throws IOException { throw new IOException("Single-value attribute " + getOID() + " (" + getName() + ")" + " has multiple values."); } /** * Throw an exception when the tag on a value encoding is * wrong for the attribute whose value it is. */ private void throwTagException(Byte tag) throws IOException { Byte[] expectedTags = PKCS9_VALUE_TAGS[index]; StringBuffer msg = new StringBuffer(100); msg.append("Value of attribute "); msg.append(getOID().toString()); msg.append(" ("); msg.append(getName()); msg.append(") has wrong tag: "); msg.append(tag.toString()); msg.append(". Expected tags: "); msg.append(expectedTags[0].toString()); for (int i = 1; i < expectedTags.length; i++) { msg.append(", "); msg.append(expectedTags[i].toString()); } msg.append("."); throw new IOException(msg.toString()); } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/PKCS9Attributes.java000066400000000000000000000235531362106420000255360ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.io.IOException; import java.io.OutputStream; import java.util.Hashtable; import org.mozilla.jss.netscape.security.util.DerEncoder; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * A set of attributes of class PKCS9Attribute. * * @version 1.2 97/12/10 * @author Douglas Hoover */ public class PKCS9Attributes { /** * Attributes in this set indexed by OID. */ private final Hashtable attributes = new Hashtable(3); /** * The keys of this hashtable are the OIDs of permitted attributes. */ private final Hashtable permittedAttributes; /** * The DER encoding of this attribute set. The tag byte must be * DerValue.tag_SetOf. */ private final byte[] derEncoding; /** * Construct a set of PKCS9 Attributes from its * DER encoding on a DerInputStream, accepting only attributes * with OIDs on the given * list. If the array is null, accept all attributes supported by * class PKCS9Attribute. * * @param permittedAttributes * Array of attribute OIDs that will be accepted. * @param in * the contents of the DER encoding of the attribute set. * * @exception IOException * on i/o error, encoding syntax error, unacceptable or * unsupported attribute, or duplicate attribute. * * @see PKCS9Attribute */ public PKCS9Attributes(ObjectIdentifier[] permittedAttributes, DerInputStream in) throws IOException { if (permittedAttributes != null) { this.permittedAttributes = new Hashtable(permittedAttributes.length); for (int i = 0; i < permittedAttributes.length; i++) this.permittedAttributes.put(permittedAttributes[i], permittedAttributes[i]); } else { this.permittedAttributes = null; } // derEncoding initialized in decode() derEncoding = decode(in); } /** * Construct a set of PKCS9 Attributes from its contents of its * DER encoding on a DerInputStream. Accept all attributes * supported by class PKCS9Attribute. * * @exception IOException * on i/o error, encoding syntax error, or unsupported or * duplicate attribute. * * @see PKCS9Attribute */ public PKCS9Attributes(DerInputStream in) throws IOException { // anything goes // derEncoding initialized in decode() derEncoding = decode(in); permittedAttributes = null; } /** * Construct a set of PKCS9 Attributes from the given array of * PCK9 attributes. * DER encoding on a DerInputStream. All attributes in attribs must be * supported by class PKCS9Attribute. * * @exception IOException * on i/o error, encoding syntax error, or unsupported or * duplicate attribute. * * @see PKCS9Attribute */ public PKCS9Attributes(PKCS9Attribute[] attribs) throws IllegalArgumentException, IOException { ObjectIdentifier oid; for (int i = 0; i < attribs.length; i++) { oid = attribs[i].getOID(); if (attributes.containsKey(oid)) throw new IllegalArgumentException( "PKCSAttribute " + attribs[i].getOID() + " duplicated while constructing " + "PKCS9Attributes."); attributes.put(oid, attribs[i]); } derEncoding = generateDerEncoding(); permittedAttributes = null; } /** * Decode this set of PKCS9 attribute set from the contents of its * DER encoding. * * @param buf * the contents of the DER encoding of the attribute set. * * @exception IOException * on i/o error, encoding syntax error, unacceptable or * unsupported attribute, or duplicate attribute. */ private byte[] decode(DerInputStream in) throws IOException { DerValue val = in.getDerValue(); // save the DER encoding with its proper tag byte. byte[] derEncoding = val.toByteArray(); derEncoding[0] = DerValue.tag_SetOf; DerInputStream derIn = new DerInputStream(derEncoding); DerValue[] derVals = derIn.getSet(3, true); PKCS9Attribute attrib; ObjectIdentifier oid; for (int i = 0; i < derVals.length; i++) { attrib = new PKCS9Attribute(derVals[i]); oid = attrib.getOID(); if (attributes.get(oid) != null) throw new IOException("Duplicate PKCS9 attribute: " + oid); if (permittedAttributes != null && !permittedAttributes.containsKey(oid)) throw new IOException("Attribute " + oid + " not permitted in this attribute set"); attributes.put(oid, attrib); } return derEncoding; } /** * Put the DER encoding of this PKCS9 attribute set on an * DerOutputStream, tagged with the given implicit tag. * * @param tag the implicit tag to use in the DER encoding. * @param out the output stream on which to put the DER encoding. * * @exception IOException on output error. */ public void encode(byte tag, OutputStream out) throws IOException { out.write(tag); out.write(derEncoding, 1, derEncoding.length - 1); } private byte[] generateDerEncoding() throws IOException { try (DerOutputStream out = new DerOutputStream()) { Object[] attribVals = attributes.values().toArray(); out.putOrderedSetOf(DerValue.tag_SetOf, castToDerEncoder(attribVals)); return out.toByteArray(); } } /** * Return the DER encoding of this attribute set, tagged with * DerValue.tag_SetOf. */ public byte[] getDerEncoding() throws IOException { return derEncoding.clone(); } /** * Get an attribute from this set. */ public PKCS9Attribute getAttribute(ObjectIdentifier oid) { return attributes.get(oid); } /** * Get an attribute from this set. */ public PKCS9Attribute getAttribute(String name) { return attributes.get(PKCS9Attribute.getOID(name)); } /** * Get an array of all attributes in this set, in order of OID. */ public PKCS9Attribute[] getAttributes() { PKCS9Attribute[] attribs = new PKCS9Attribute[attributes.size()]; int j = 0; for (int i = 1; i < PKCS9Attribute.PKCS9_OIDS.length && j < attribs.length; i++) { attribs[j] = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); if (attribs[j] != null) j++; } return attribs; } /** * Get an attribute value by OID. */ public Object getAttributeValue(ObjectIdentifier oid) throws IOException { try { Object value = getAttribute(oid).getValue(); return value; } catch (NullPointerException ex) { throw new IOException("No value found for attribute " + oid); } } /** * Get an attribute value by type name. */ public Object getAttributeValue(String name) throws IOException { ObjectIdentifier oid = PKCS9Attribute.getOID(name); if (oid == null) throw new IOException("Attribute name " + name + " not recognized or not supported."); return getAttributeValue(oid); } /** * Returns the PKCS9 block in a printable string form. */ public String toString() { StringBuffer buf = new StringBuffer(200); buf.append("PKCS9 Attributes: [\n\t"); PKCS9Attribute value; boolean first = true; for (int i = 1; i < PKCS9Attribute.PKCS9_OIDS.length; i++) { value = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); if (value == null) continue; // we have a value; print it if (first) first = false; else buf.append(";\n\t"); buf.append(value.toString()); } buf.append("\n\t] (end PKCS9 Attributes)"); return buf.toString(); } /** * Cast an object array whose components are DerEncoders to DerEncoder[]. */ static DerEncoder[] castToDerEncoder(Object[] objs) { DerEncoder[] encoders = new DerEncoder[objs.length]; for (int i = 0; i < encoders.length; i++) encoders[i] = (DerEncoder) objs[i]; return encoders; } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/ParsingException.java000066400000000000000000000024361362106420000261150ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.io.IOException; public class ParsingException extends IOException { /** * */ private static final long serialVersionUID = -8135726194372647410L; public ParsingException() { super(); } public ParsingException(String mesg) { super(mesg); } public ParsingException(String mesg, Throwable cause) { super(mesg, cause); } public ParsingException(Throwable cause) { super(cause); } } jss-4.6.3/org/mozilla/jss/netscape/security/pkcs/SignerInfo.java000066400000000000000000000276021362106420000247000ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.pkcs; import java.io.IOException; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.X509Certificate; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerEncoder; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.AlgorithmId; import org.mozilla.jss.netscape.security.x509.X500Name; /** * A SignerInfo, as defined in PKCS#7's signedData type. * * @author Benjamin Renaud * @version 1.27 97/12/10 */ public class SignerInfo implements DerEncoder { BigInt version; X500Name issuerName; BigInt certificateSerialNumber; AlgorithmId digestAlgorithmId; AlgorithmId digestEncryptionAlgorithmId; byte[] encryptedDigest; PKCS9Attributes authenticatedAttributes; PKCS9Attributes unauthenticatedAttributes; public SignerInfo(X500Name issuerName, BigInt serial, AlgorithmId digestAlgorithmId, AlgorithmId digestEncryptionAlgorithmId, byte[] encryptedDigest) { this.version = new BigInt(1); this.issuerName = issuerName; this.certificateSerialNumber = serial; this.digestAlgorithmId = digestAlgorithmId; this.digestEncryptionAlgorithmId = digestEncryptionAlgorithmId; this.encryptedDigest = encryptedDigest; } public SignerInfo(X500Name issuerName, BigInt serial, AlgorithmId digestAlgorithmId, PKCS9Attributes authenticatedAttributes, AlgorithmId digestEncryptionAlgorithmId, byte[] encryptedDigest, PKCS9Attributes unauthenticatedAttributes) { this.version = new BigInt(1); this.issuerName = issuerName; this.certificateSerialNumber = serial; this.digestAlgorithmId = digestAlgorithmId; this.authenticatedAttributes = authenticatedAttributes; this.digestEncryptionAlgorithmId = digestEncryptionAlgorithmId; this.encryptedDigest = encryptedDigest; this.unauthenticatedAttributes = unauthenticatedAttributes; } public SignerInfo(DerInputStream derin) throws IOException, ParsingException { // version version = derin.getInteger(); // issuerAndSerialNumber DerValue[] issuerAndSerialNumber = derin.getSequence(2); byte[] issuerBytes = issuerAndSerialNumber[0].toByteArray(); issuerName = new X500Name(new DerValue(DerValue.tag_Sequence, issuerBytes)); certificateSerialNumber = issuerAndSerialNumber[1].getInteger(); // digestAlgorithmId DerValue tmp = derin.getDerValue(); digestAlgorithmId = AlgorithmId.parse(tmp); /* * check if set of auth attributes (implicit tag) is provided * (auth attributes are OPTIONAL) */ if ((byte) (derin.peekByte()) == (byte) 0xA0) { authenticatedAttributes = new PKCS9Attributes(derin); } // digestEncryptionAlgorithmId - little RSA naming scheme - // signature == encryption... tmp = derin.getDerValue(); digestEncryptionAlgorithmId = AlgorithmId.parse(tmp); // encryptedDigest encryptedDigest = derin.getOctetString(); /* * check if set of unauth attributes (implicit tag) is provided * (unauth attributes are OPTIONAL) */ if (derin.available() != 0 && (byte) (derin.peekByte()) == (byte) 0xA1) { unauthenticatedAttributes = new PKCS9Attributes(derin); } // all done if (derin.available() != 0) { throw new ParsingException("extra data at the end"); } } public void encode(DerOutputStream out) throws IOException { derEncode(out); } /** * DER encode this object onto an output stream. * Implements the DerEncoder interface. * * @param out * the output stream on which to write the DER encoding. * * @exception IOException on encoding error. */ public void derEncode(OutputStream out) throws IOException { try (DerOutputStream tmp = new DerOutputStream()) { DerOutputStream seq = new DerOutputStream(); seq.putInteger(version); DerOutputStream issuerAndSerialNumber = new DerOutputStream(); issuerName.encode(issuerAndSerialNumber); issuerAndSerialNumber.putInteger(certificateSerialNumber); seq.write(DerValue.tag_Sequence, issuerAndSerialNumber); digestAlgorithmId.encode(seq); // encode authenticated attributes if there are any if (authenticatedAttributes != null) authenticatedAttributes.encode((byte) 0xA0, seq); digestEncryptionAlgorithmId.encode(seq); seq.putOctetString(encryptedDigest); // encode unauthenticated attributes if there are any if (unauthenticatedAttributes != null) unauthenticatedAttributes.encode((byte) 0xA1, seq); tmp.write(DerValue.tag_Sequence, seq); out.write(tmp.toByteArray()); } } public X509Certificate getCertificate(PKCS7 block) throws IOException { return block.getCertificate(certificateSerialNumber, issuerName); } /* Returns null if verify fails, this signerInfo if verify succeeds. */ SignerInfo verify(PKCS7 block, byte[] data) throws NoSuchAlgorithmException, SignatureException { try { ContentInfo content = block.getContentInfo(); if (data == null) { data = content.getContentBytes(); } String digestAlgname = getDigestAlgorithmId().getName(); byte[] dataSigned; // if there are authenticate attributes, get the message // digest and compare it with the digest of data if (authenticatedAttributes == null) { dataSigned = data; } else { // first, check content type ObjectIdentifier contentType = (ObjectIdentifier) authenticatedAttributes.getAttributeValue( PKCS9Attribute.CONTENT_TYPE_OID); if (contentType == null || !contentType.equals(content.contentType)) return null; // contentType does not match, bad SignerInfo // now, check message digest byte[] messageDigest = (byte[]) authenticatedAttributes.getAttributeValue( PKCS9Attribute.MESSAGE_DIGEST_OID); if (messageDigest == null) // fail if there is no message digest return null; MessageDigest md = MessageDigest.getInstance(digestAlgname); byte[] computedMessageDigest = md.digest(data); if (messageDigest.length != computedMessageDigest.length) return null; for (int i = 0; i < messageDigest.length; i++) { if (messageDigest[i] != computedMessageDigest[i]) return null; } // message digest attribute matched // digest of original data // the data actually signed is the DER encoding of // the authenticated attributes (tagged with // the "SET OF" tag, not 0xA0). dataSigned = authenticatedAttributes.getDerEncoding(); } // put together digest algorithm and encryption algorithm // to form signing algorithm String encryptionAlgname = getDigestEncryptionAlgorithmId().getName(); String algname; if (encryptionAlgname.equals("DSA") || encryptionAlgname.equals("SHA1withDSA")) { algname = "DSA"; } else { algname = digestAlgname + "/" + encryptionAlgname; } Signature sig = Signature.getInstance(algname); X509Certificate cert = getCertificate(block); if (cert == null) { return null; } PublicKey key = cert.getPublicKey(); sig.initVerify(key); sig.update(dataSigned); if (sig.verify(encryptedDigest)) { return this; } } catch (IOException e) { throw new SignatureException("IO error verifying signature:\n" + e.getMessage()); } catch (InvalidKeyException e) { throw new SignatureException("InvalidKey: " + e.getMessage()); } return null; } /* Verify the content of the pkcs7 block. */ SignerInfo verify(PKCS7 block) throws NoSuchAlgorithmException, SignatureException { return verify(block, null); } public BigInt getVersion() { return version; } public X500Name getIssuerName() { return issuerName; } public BigInt getCertificateSerialNumber() { return certificateSerialNumber; } public AlgorithmId getDigestAlgorithmId() { return digestAlgorithmId; } public PKCS9Attributes getAuthenticatedAttributes() { return authenticatedAttributes; } public AlgorithmId getDigestEncryptionAlgorithmId() { return digestEncryptionAlgorithmId; } public byte[] getEncryptedDigest() { return encryptedDigest; } public PKCS9Attributes getUnauthenticatedAttributes() { return unauthenticatedAttributes; } public String toString() { org.mozilla.jss.netscape.security.util.PrettyPrintFormat pp = new org.mozilla.jss.netscape.security.util.PrettyPrintFormat(" ", 20); String digestbits = pp.toHexString(encryptedDigest); String out = ""; out += "Signer Info for (issuer): " + issuerName + "\n"; out += "\tversion: " + version + "\n"; out += "\tcertificateSerialNumber: " + certificateSerialNumber + "\n"; out += "\tdigestAlgorithmId: " + digestAlgorithmId + "\n"; if (authenticatedAttributes != null) { out += "\tauthenticatedAttributes: " + authenticatedAttributes + "\n"; } out += "\tdigestEncryptionAlgorithmId: " + digestEncryptionAlgorithmId + "\n"; out += "\tencryptedDigest: " + "\n" + digestbits + "\n"; if (unauthenticatedAttributes != null) { out += "\tunauthenticatedAttributes: " + unauthenticatedAttributes + "\n"; } return out; } } jss-4.6.3/org/mozilla/jss/netscape/security/provider/000077500000000000000000000000001362106420000226555ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/netscape/security/provider/CMS.java000066400000000000000000000032211362106420000241400ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.provider; import java.security.AccessController; import java.security.Provider; /** * The CMS Security Provider. */ public final class CMS extends Provider { /** * */ private static final long serialVersionUID = 1065207998900104219L; private static final String INFO = "CMS [X.509 certificates]"; public CMS() { /* We are the CMS provider */ super("CMS", 1.0, INFO); AccessController.doPrivileged(new java.security.PrivilegedAction() { public Object run() { /* * Certificates */ put("CertificateFactory.X.509", "org.mozilla.jss.netscape.security.provider.X509CertificateFactory"); put("Alg.Alias.CertificateFactory.X.509", "X.509"); return null; } }); } } jss-4.6.3/org/mozilla/jss/netscape/security/provider/DSAKeyFactory.java000066400000000000000000000220131362106420000261260ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.provider; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactorySpi; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.DSAParams; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; /** * This class implements the DSA key factory of the Sun provider. * * @author Jan Luehe * * @version 1.8, 97/12/10 * * @since JDK1.2 */ public class DSAKeyFactory extends KeyFactorySpi { /** * Generates a public key object from the provided key specification * (key material). * * @param keySpec the specification (key material) of the public key * * @return the public key * * @exception InvalidKeySpecException if the given key specification * is inappropriate for this key factory to produce a public key. */ protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { try { if (keySpec instanceof DSAPublicKeySpec) { DSAPublicKeySpec dsaPubKeySpec = (DSAPublicKeySpec) keySpec; return new DSAPublicKey(dsaPubKeySpec.getY(), dsaPubKeySpec.getP(), dsaPubKeySpec.getQ(), dsaPubKeySpec.getG()); } else if (keySpec instanceof X509EncodedKeySpec) { return new DSAPublicKey(((X509EncodedKeySpec) keySpec).getEncoded()); } else { throw new InvalidKeySpecException("Inappropriate key specification"); } } catch (InvalidKeyException e) { throw new InvalidKeySpecException("Inappropriate key specification: " + e.getMessage()); } } /** * Generates a private key object from the provided key specification * (key material). * * @param keySpec the specification (key material) of the private key * * @return the private key * * @exception InvalidKeySpecException if the given key specification * is inappropriate for this key factory to produce a private key. */ protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { try { if (keySpec instanceof DSAPrivateKeySpec) { DSAPrivateKeySpec dsaPrivKeySpec = (DSAPrivateKeySpec) keySpec; return new DSAPrivateKey(dsaPrivKeySpec.getX(), dsaPrivKeySpec.getP(), dsaPrivKeySpec.getQ(), dsaPrivKeySpec.getG()); } else if (keySpec instanceof PKCS8EncodedKeySpec) { return new DSAPrivateKey(((PKCS8EncodedKeySpec) keySpec).getEncoded()); } else { throw new InvalidKeySpecException("Inappropriate key specification"); } } catch (InvalidKeyException e) { throw new InvalidKeySpecException("Inappropriate key specification: " + e.getMessage()); } } /** * Returns a specification (key material) of the given key object * in the requested format. * * @param key the key * * @param keySpec the requested format in which the key material shall be * returned * * @return the underlying key specification (key material) in the * requested format * * @exception InvalidKeySpecException if the requested key specification is * inappropriate for the given key, or the given key cannot be processed * (e.g., the given key has an unrecognized algorithm or format). */ @SuppressWarnings("unchecked") protected T engineGetKeySpec(Key key, Class keySpec) throws InvalidKeySpecException { DSAParams params; try { if (key instanceof java.security.interfaces.DSAPublicKey) { // Determine valid key specs Class dsaPubKeySpec = Class.forName ("java.security.spec.DSAPublicKeySpec"); Class x509KeySpec = Class.forName ("java.security.spec.X509EncodedKeySpec"); if (dsaPubKeySpec.isAssignableFrom(keySpec)) { java.security.interfaces.DSAPublicKey dsaPubKey = (java.security.interfaces.DSAPublicKey) key; params = dsaPubKey.getParams(); return (T) new DSAPublicKeySpec(dsaPubKey.getY(), params.getP(), params.getQ(), params.getG()); } else if (x509KeySpec.isAssignableFrom(keySpec)) { return (T) new X509EncodedKeySpec(key.getEncoded()); } else { throw new InvalidKeySpecException("Inappropriate key specification"); } } else if (key instanceof java.security.interfaces.DSAPrivateKey) { // Determine valid key specs Class dsaPrivKeySpec = Class.forName ("java.security.spec.DSAPrivateKeySpec"); Class pkcs8KeySpec = Class.forName ("java.security.spec.PKCS8EncodedKeySpec"); if (dsaPrivKeySpec.isAssignableFrom(keySpec)) { java.security.interfaces.DSAPrivateKey dsaPrivKey = (java.security.interfaces.DSAPrivateKey) key; params = dsaPrivKey.getParams(); return (T) new DSAPrivateKeySpec(dsaPrivKey.getX(), params.getP(), params.getQ(), params.getG()); } else if (pkcs8KeySpec.isAssignableFrom(keySpec)) { return (T) new PKCS8EncodedKeySpec(key.getEncoded()); } else { throw new InvalidKeySpecException("Inappropriate key specification"); } } else { throw new InvalidKeySpecException("Inappropriate key type"); } } catch (ClassNotFoundException e) { throw new InvalidKeySpecException("Unsupported key specification: " + e.getMessage()); } } /** * Translates a key object, whose provider may be unknown or potentially * untrusted, into a corresponding key object of this key factory. * * @param key the key whose provider is unknown or untrusted * * @return the translated key * * @exception InvalidKeyException if the given key cannot be processed by * this key factory. */ protected Key engineTranslateKey(Key key) throws InvalidKeyException { try { if (key instanceof java.security.interfaces.DSAPublicKey) { // Check if key originates from this factory if (key instanceof org.mozilla.jss.netscape.security.provider.DSAPublicKey) { return key; } // Convert key to spec DSAPublicKeySpec dsaPubKeySpec = engineGetKeySpec(key, DSAPublicKeySpec.class); // Create key from spec, and return it return engineGeneratePublic(dsaPubKeySpec); } else if (key instanceof java.security.interfaces.DSAPrivateKey) { // Check if key originates from this factory if (key instanceof org.mozilla.jss.netscape.security.provider.DSAPrivateKey) { return key; } // Convert key to spec DSAPrivateKeySpec dsaPrivKeySpec = engineGetKeySpec(key, DSAPrivateKeySpec.class); // Create key from spec, and return it return engineGeneratePrivate(dsaPrivKeySpec); } else { throw new InvalidKeyException("Wrong algorithm type"); } } catch (InvalidKeySpecException e) { throw new InvalidKeyException("Cannot translate key: " + e.getMessage()); } } } jss-4.6.3/org/mozilla/jss/netscape/security/provider/DSAParameters.java000066400000000000000000000110341362106420000261520ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.provider; import java.io.IOException; import java.math.BigInteger; import java.security.AlgorithmParametersSpi; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAParameterSpec; import java.security.spec.InvalidParameterSpecException; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class implements the parameter set used by the * Digital Signature Algorithm as specified in the FIPS 186 * standard. * * @author Jan Luehe * * @version 1.8, 97/12/10 * * @since JDK1.2 */ public class DSAParameters extends AlgorithmParametersSpi { // the prime (p) protected BigInteger p; // the sub-prime (q) protected BigInteger q; // the base (g) protected BigInteger g; protected void engineInit(AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof DSAParameterSpec)) { throw new InvalidParameterSpecException("Inappropriate parameter specification"); } this.p = ((DSAParameterSpec) paramSpec).getP(); this.q = ((DSAParameterSpec) paramSpec).getQ(); this.g = ((DSAParameterSpec) paramSpec).getG(); } protected void engineInit(byte[] params) throws IOException { DerValue encodedParams = new DerValue(params); if (encodedParams.tag != DerValue.tag_Sequence) { throw new IOException("DSA params parsing error"); } encodedParams.data.reset(); this.p = encodedParams.data.getInteger().toBigInteger(); this.q = encodedParams.data.getInteger().toBigInteger(); this.g = encodedParams.data.getInteger().toBigInteger(); if (encodedParams.data.available() != 0) { throw new IOException("encoded params have " + encodedParams.data.available() + " extra bytes"); } } protected void engineInit(byte[] params, String decodingMethod) throws IOException { engineInit(params); } @SuppressWarnings("unchecked") protected T engineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException { try { Class dsaParamSpec = Class.forName ("java.security.spec.DSAParameterSpec"); if (dsaParamSpec.isAssignableFrom(paramSpec)) { return (T) new DSAParameterSpec(this.p, this.q, this.g); } else { throw new InvalidParameterSpecException("Inappropriate parameter Specification"); } } catch (ClassNotFoundException e) { throw new InvalidParameterSpecException("Unsupported parameter specification: " + e.getMessage()); } } protected byte[] engineGetEncoded() throws IOException { try (DerOutputStream out = new DerOutputStream()) { DerOutputStream bytes = new DerOutputStream(); bytes.putInteger(new BigInt(p.toByteArray())); bytes.putInteger(new BigInt(q.toByteArray())); bytes.putInteger(new BigInt(g.toByteArray())); out.write(DerValue.tag_Sequence, bytes); return out.toByteArray(); } } protected byte[] engineGetEncoded(String encodingMethod) throws IOException { return engineGetEncoded(); } /* * Returns a formatted string describing the parameters. */ protected String engineToString() { return "\n\tp: " + new BigInt(p).toString() + "\n\tq: " + new BigInt(q).toString() + "\n\tg: " + new BigInt(g).toString() + "\n"; } } jss-4.6.3/org/mozilla/jss/netscape/security/provider/DSAPrivateKey.java000066400000000000000000000116641362106420000261430ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.provider; import java.io.IOException; import java.io.Serializable; import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.interfaces.DSAParams; import java.security.spec.DSAParameterSpec; import java.security.spec.InvalidParameterSpecException; import org.mozilla.jss.netscape.security.pkcs.PKCS8Key; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.x509.AlgIdDSA; /** * A PKCS#8 private key for the Digital Signature Algorithm. * * @author Benjamin Renaud * * @version 1.47, 97/12/10 * * @see DSAPublicKey * @see AlgIdDSA */ public final class DSAPrivateKey extends PKCS8Key implements java.security.interfaces.DSAPrivateKey, Serializable { /** use serialVersionUID from JDK 1.1. for interoperability */ private static final long serialVersionUID = -3244453684193605938L; /* the private key */ private BigInteger x; /* * Keep this constructor for backwards compatibility with JDK1.1. */ public DSAPrivateKey() { } /** * Make a DSA private key out of a private key and three parameters. */ public DSAPrivateKey(BigInteger x, BigInteger p, BigInteger q, BigInteger g) throws InvalidKeyException { this.x = x; algid = new AlgIdDSA(p, q, g); try { key = new DerValue(DerValue.tag_Integer, x.toByteArray()).toByteArray(); encode(); } catch (IOException e) { throw new InvalidKeyException("could not DER encode x: " + e.getMessage()); } } /** * Make a DSA private key from its DER encoding (PKCS #8). */ public DSAPrivateKey(byte[] encoded) throws InvalidKeyException { clearOldKey(); decode(encoded); } /** * Returns the DSA parameters associated with this key, or null if the * parameters could not be parsed. */ public DSAParams getParams() { try { if (algid instanceof DSAParams) { return (DSAParams) algid; } else { AlgorithmParameters algParams = algid.getParameters(); if (algParams == null) { return null; } return algParams.getParameterSpec(DSAParameterSpec.class); } } catch (InvalidParameterSpecException e) { return null; } } /** * Get the raw private key, x, without the parameters. * */ public BigInteger getX() { return x; } private void clearOldKey() { int i; if (this.encodedKey != null) { for (i = 0; i < this.encodedKey.length; i++) { this.encodedKey[i] = (byte) 0x00; } } if (this.key != null) { for (i = 0; i < this.key.length; i++) { this.key[i] = (byte) 0x00; } } } public String toString() { return "Sun DSA Private Key \nparameters:" + algid + "\nx: " + x.toString(16) + "\n"; } protected void parseKeyBits() throws InvalidKeyException { DerInputStream in = new DerInputStream(key); try { x = in.getInteger().toBigInteger(); } catch (IOException e) { throw new InvalidKeyException(e.getMessage()); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((x == null) ? 0 : x.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; DSAPrivateKey other = (DSAPrivateKey) obj; if (x == null) { if (other.x != null) return false; } else if (!x.equals(other.x)) return false; return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/provider/DSAPublicKey.java000066400000000000000000000113731362106420000257440ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.provider; import java.io.IOException; import java.io.Serializable; import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.interfaces.DSAParams; import java.security.spec.DSAParameterSpec; import java.security.spec.InvalidParameterSpecException; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.x509.AlgIdDSA; import org.mozilla.jss.netscape.security.x509.X509Key; /** * An X.509 public key for the Digital Signature Algorithm. * * @author Benjamin Renaud * * @version 1.52, 97/12/10 * * @see DSAPrivateKey * @see AlgIdDSA */ public final class DSAPublicKey extends X509Key implements java.security.interfaces.DSAPublicKey, Serializable { /** use serialVersionUID from JDK 1.1. for interoperability */ private static final long serialVersionUID = -2994193307391104133L; /* the public key */ private BigInteger y; /* * Keep this constructor for backwards compatibility with JDK1.1. */ public DSAPublicKey() { } /** * Make a DSA public key out of a public key and three parameters. */ public DSAPublicKey(BigInteger y, BigInteger p, BigInteger q, BigInteger g) throws InvalidKeyException { this.y = y; algid = new AlgIdDSA(p, q, g); try { key = new DerValue(DerValue.tag_Integer, y.toByteArray()).toByteArray(); encode(); } catch (IOException e) { throw new InvalidKeyException("could not DER encode y: " + e.getMessage()); } } /** * Make a DSA public key from its DER encoding (X.509). */ public DSAPublicKey(byte[] encoded) throws InvalidKeyException { decode(encoded); } /** * Returns the DSA parameters associated with this key, or null if the * parameters could not be parsed. */ public DSAParams getParams() { try { if (algid instanceof DSAParams) { return (DSAParams) algid; } else { DSAParameterSpec paramSpec; AlgorithmParameters algParams = algid.getParameters(); if (algParams == null) { return null; } paramSpec = algParams.getParameterSpec (DSAParameterSpec.class); return paramSpec; } } catch (InvalidParameterSpecException e) { return null; } } /** * Get the raw public value, y, without the parameters. * */ public BigInteger getY() { return y; } public String toString() { return "Sun DSA Public Key\n Parameters:" + algid + "\n y:\n" + (new BigInt(y)).toString() + "\n"; } protected void parseKeyBits() throws InvalidKeyException { try { DerInputStream in = new DerInputStream(key); y = in.getInteger().toBigInteger(); } catch (IOException e) { throw new InvalidKeyException("Invalid key: y value\n" + e.getMessage()); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((y == null) ? 0 : y.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; DSAPublicKey other = (DSAPublicKey) obj; if (y == null) { if (other.y != null) return false; } else if (!y.equals(other.y)) return false; return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/provider/RSAPublicKey.java000066400000000000000000000136121362106420000257600ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.provider; import java.io.IOException; import java.io.Serializable; import java.security.InvalidKeyException; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.x509.AlgorithmId; import org.mozilla.jss.netscape.security.x509.X509Key; /** * An X.509 public key for the RSA Algorithm. * * @author galperin * * @version $Revision$, $Date$ * */ public final class RSAPublicKey extends X509Key implements Serializable { /* XXX This currently understands only PKCS#1 RSA Encryption OID and parameter format Later we may consider adding X509v3 OID for RSA keys. Besides different OID it also has a parameter equal to modulus size in bits (redundant!) */ /** * */ private static final long serialVersionUID = 7764823589128565374L; private static final ObjectIdentifier ALGORITHM_OID = AlgorithmId.RSAEncryption_oid; private BigInt modulus; private BigInt publicExponent; /* * Keep this constructor for backwards compatibility with JDK1.1. */ public RSAPublicKey() { } /** * Make a RSA public key out of a public exponent and modulus */ public RSAPublicKey(BigInt modulus, BigInt publicExponent) throws InvalidKeyException { this.modulus = modulus; this.publicExponent = publicExponent; this.algid = new AlgorithmId(ALGORITHM_OID); try (DerOutputStream out = new DerOutputStream()) { out.putInteger(modulus); out.putInteger(publicExponent); key = (new DerValue(DerValue.tag_Sequence, out.toByteArray())).toByteArray(); encode(); } catch (IOException ex) { throw new InvalidKeyException("could not DER encode : " + ex.getMessage()); } } /** * Make a RSA public key from its DER encoding (X.509). */ public RSAPublicKey(byte[] encoded) throws InvalidKeyException { decode(encoded); } /** * Get key size as number of bits in modulus * (Always rounded up to a multiple of 8) * */ public int getKeySize() { return this.modulus.byteLength() * 8; } /** * Get the raw public exponent * */ public BigInt getPublicExponent() { return this.publicExponent; } /** * Get the raw modulus * */ public BigInt getModulus() { return this.modulus; } public String toString() { return "RSA Public Key\n Algorithm: " + algid + "\n modulus:\n" + this.modulus.toString() + "\n" + "\n publicExponent:\n" + this.publicExponent.toString() + "\n"; } protected void parseKeyBits() throws InvalidKeyException { if (!this.algid.getOID().equals(ALGORITHM_OID) && !this.algid.getOID().equals(AlgorithmId.RSA_oid)) { throw new InvalidKeyException("Key algorithm OID is not RSA"); } try { DerValue val = new DerValue(key); if (val.tag != DerValue.tag_Sequence) { throw new InvalidKeyException("Invalid RSA public key format:" + " must be a SEQUENCE"); } DerInputStream in = val.data; this.modulus = in.getInteger(); this.publicExponent = in.getInteger(); } catch (IOException e) { throw new InvalidKeyException("Invalid RSA public key: " + e.getMessage()); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((modulus == null) ? 0 : modulus.hashCode()); result = prime * result + ((publicExponent == null) ? 0 : publicExponent.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; RSAPublicKey other = (RSAPublicKey) obj; if (modulus == null) { if (other.modulus != null) return false; } else if (!modulus.equals(other.modulus)) return false; if (publicExponent == null) { if (other.publicExponent != null) return false; } else if (!publicExponent.equals(other.publicExponent)) return false; return true; } public boolean bigIntEquals(BigInt x, BigInt y) { if (x == null) { if (y != null) { return false; } } else { if (!x.equals(y)) { return false; } } return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/provider/Sun.java000066400000000000000000000060111362106420000242630ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.provider; import java.security.Provider; /** * The SUN Security Provider. * * @author Benjamin Renaud * * @version 1.24, 97/12/10 */ /** * Defines the SUN provider. * * Algorithm supported, and their names: * * - SHA-1 is the message digest scheme decribed FIPS 180-1. * Aliases for SHA-1 are SHA. * * - DSA is the signature scheme described in FIPS 186. (SHA used in * DSA is SHA-1: FIPS 186 with Change No 1.) Aliases for DSA are * SHA/DSA, SHA-1/DSA, SHA1/DSA, DSS and the object identifier * strings "OID.1.3.14.3.2.13", "OID.1.3.14.3.2.27" and * "OID.1.2.840.10040.4.3". * * - DSA is the key generation scheme as described in FIPS 186. * Aliases for DSA include the OID strings "OID.1.3.14.3.2.12" * and "OID.1.2.840.10040.4.1". * * - MD5 is the message digest scheme described in RFC 1321. * There are no aliases for MD5. * * Notes: The name of algorithm described in FIPS-180 is SHA-0, and is * not supported by the SUN provider.) */ public final class Sun extends Provider { /** * */ private static final long serialVersionUID = 9134942296334703727L; private static String info = "SUN Security Provider v1.0, " + "DSA signing and key generation, SHA-1 and MD5 message digests."; public Sun() { /* We are the SUN provider */ super("SUN", 1.0, info); try { // AccessController.beginPrivileged(); // the following are not according to our formal spec but // are still supported put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA"); put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA"); /* * Algorithm Parameter engines */ put("AlgorithmParameters.DSA", "org.mozilla.jss.netscape.security.provider.DSAParameters"); put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA"); put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1", "DSA"); /* * Key factories */ put("KeyFactory.DSA", "org.mozilla.jss.netscape.security.provider.DSAKeyFactory"); } finally { // AccessController.endPrivileged(); } } } jss-4.6.3/org/mozilla/jss/netscape/security/provider/X509CertificateFactory.java000066400000000000000000000040501362106420000276570ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.provider; import java.io.InputStream; import java.security.cert.CRL; import java.security.cert.CRLException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactorySpi; import java.util.Collection; import org.mozilla.jss.netscape.security.x509.X509CRLImpl; import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.mozilla.jss.netscape.security.x509.X509ExtensionException; public class X509CertificateFactory extends CertificateFactorySpi { public Certificate engineGenerateCertificate(InputStream inStream) throws CertificateException { return new X509CertImpl(inStream); } public Collection engineGenerateCertificates(InputStream inStream) throws CertificateException { return null; } public CRL engineGenerateCRL(InputStream inStream) throws CRLException { X509CRLImpl crl = null; try { crl = new X509CRLImpl(inStream); } catch (X509ExtensionException e) { ; } return crl; } public Collection engineGenerateCRLs(InputStream inStream) throws CRLException { return null; } } jss-4.6.3/org/mozilla/jss/netscape/security/util/000077500000000000000000000000001362106420000220005ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/netscape/security/util/ASN1CharStrConvMap.java000066400000000000000000000123211362106420000261170ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * Maps a ASN.1 character string type to a charset encoder and decoder. * The converter is used to convert a DerValue of a ASN.1 character string type * from bytes to unicode characters and vice versa. * *

* A global default ASN1CharStrConvMap is created when the class is initialized. The global default map is extensible. * * @author Lily Hsiao * @author Slava Galperin * */ public class ASN1CharStrConvMap { // public constructors /** * Constructs a ASN1CharStrConvMap. */ public ASN1CharStrConvMap() { } /** * Get an encoder for the specified DER tag. * * @param tag A DER tag of a ASN.1 character string type, * for example DerValue.tag_PrintableString. * * @return An encoder for the DER tag. */ public CharsetEncoder getEncoder(byte tag) { Charset charset = charsets.get(tag); if (charset == null) return null; return charset.newEncoder(); } /** * Get a decoder for the given DER tag. * * @param tag A DER tag of a ASN.1 character string type, * for example DerValue.tag_PrintableString. * * @return A decoder for the DER tag. */ public CharsetDecoder getDecoder(byte tag) { Charset charset = charsets.get(tag); if (charset == null) return null; return charset.newDecoder(); } /** * Add a tag-charset entry in the map. * * @param tag A DER tag of a ASN.1 character string type, * ex. DerValue.tag_IA5String * @param charset A charset for the tag. */ public void addEntry(byte tag, Charset charset) { Charset currentCharset = charsets.get(tag); if (currentCharset != null) { if (currentCharset != charset) { throw new IllegalArgumentException( "a DER tag to converter entry already exists."); } else { return; } } charsets.put(tag, charset); } /** * Get an iterator of all tags in the map. * * @return An Iterator of DER tags in the map as Bytes. */ public Iterator getTags() { return charsets.keySet().iterator(); } // static public methods. /** * Get the global ASN1CharStrConvMap. * * @return The global default ASN1CharStrConvMap. */ static public ASN1CharStrConvMap getDefault() { return defaultMap; } /** * Set the global default ASN1CharStrConvMap. * * @param newDefault The new default ASN1CharStrConvMap. */ static public void setDefault(ASN1CharStrConvMap newDefault) { if (newDefault == null) throw new IllegalArgumentException( "Cannot set a null default Der Tag Converter map"); defaultMap = newDefault; } // private methods and variables. private Map charsets = new HashMap(); private static ASN1CharStrConvMap defaultMap; /** * Create the default converter map on initialization */ static { ASN1CharsetProvider provider = new ASN1CharsetProvider(); defaultMap = new ASN1CharStrConvMap(); defaultMap.addEntry(DerValue.tag_PrintableString, provider.charsetForName("ASN.1-Printable")); defaultMap.addEntry(DerValue.tag_VisibleString, provider.charsetForName("ASN.1-Printable")); defaultMap.addEntry(DerValue.tag_IA5String, provider.charsetForName("ASN.1-IA5")); defaultMap.addEntry(DerValue.tag_BMPString, Charset.forName("UnicodeBig")); defaultMap.addEntry(DerValue.tag_UniversalString, provider.charsetForName("ASN.1-Universal")); // XXX this is an oversimplified implementation of T.61 strings, it // doesn't handle all cases defaultMap.addEntry(DerValue.tag_T61String, Charset.forName("ISO-8859-1")); // UTF8String added to ASN.1 in 1998 defaultMap.addEntry(DerValue.tag_UTF8String, Charset.forName("UTF-8")); defaultMap.addEntry(DerValue.tag_GeneralString, Charset.forName("UTF-8")); }; }; jss-4.6.3/org/mozilla/jss/netscape/security/util/ASN1CharsetProvider.java000066400000000000000000000014331362106420000263730ustar00rootroot00000000000000package org.mozilla.jss.netscape.security.util; import java.nio.charset.Charset; import java.nio.charset.spi.CharsetProvider; import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class ASN1CharsetProvider extends CharsetProvider { protected Map charsets = new HashMap(); public ASN1CharsetProvider() { addCharset(new PrintableCharset()); addCharset(new IA5Charset()); addCharset(new UniversalCharset()); } public Iterator charsets() { return charsets.values().iterator(); } public Charset charsetForName(String charsetName) { return charsets.get(charsetName); } public void addCharset(Charset cs) { charsets.put(cs.name(), cs); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/BigInt.java000066400000000000000000000153421362106420000240240ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.io.Serializable; import java.math.BigInteger; import java.util.Arrays; /** * A low-overhead arbitrary-precision unsigned integer. * This is intended for use with ASN.1 parsing, and printing of * such parsed values. Convert to "BigInteger" if you need to do * arbitrary precision arithmetic, rather than just represent * the number as a wrapped array of bytes. * *

* NOTE: This class may eventually disappear, to * be supplanted by big-endian byte arrays which hold both signed * and unsigned arbitrary-precision integers. * * @version 1.23 * @author David Brownell */ public final class BigInt implements Serializable { private static final long serialVersionUID = 705094142021888265L; // Big endian -- MSB first. private byte[] places; /** * Constructs a "Big" integer from a set of (big-endian) bytes. * Leading zeroes should be stripped off. * * @param data a sequence of bytes, most significant bytes/digits * first. CONSUMED. */ public BigInt(byte[] data) { places = data.clone(); } /** * Constructs a "Big" integer from a "BigInteger", which must be * positive (or zero) in value. */ public BigInt(BigInteger i) { byte[] temp = i.toByteArray(); if ((temp[0] & 0x80) != 0) throw new IllegalArgumentException("negative BigInteger"); // XXX we assume exactly _one_ sign byte is used... if (temp[0] != 0) places = temp; else { // Note that if i = new BigInteger("0"), // i.toByteArray() contains only 1 zero. if (temp.length == 1) { places = new byte[1]; places[0] = (byte) 0; } else { places = new byte[temp.length - 1]; for (int j = 1; j < temp.length; j++) places[j - 1] = temp[j]; } } } /** * Constructs a "Big" integer from a normal Java integer. * * @param i the java primitive integer */ public BigInt(int i) { if (i < (1 << 8)) { places = new byte[1]; places[0] = (byte) i; } else if (i < (1 << 16)) { places = new byte[2]; places[0] = (byte) (i >> 8); places[1] = (byte) i; } else if (i < (1 << 24)) { places = new byte[3]; places[0] = (byte) (i >> 16); places[1] = (byte) (i >> 8); places[2] = (byte) i; } else { places = new byte[4]; places[0] = (byte) (i >> 24); places[1] = (byte) (i >> 16); places[2] = (byte) (i >> 8); places[3] = (byte) i; } } /** * Converts the "big" integer to a java primitive integer. * * @exception NumberFormatException if 32 bits is insufficient. */ public int toInt() { if (places.length > 4) throw new NumberFormatException("BigInt.toInt, too big"); int retval = 0, i = 0; for (; i < places.length; i++) retval = (retval << 8) + (places[i] & 0xff); return retval; } /** * Returns a hexadecimal printed representation. The value is * formatted to fit on lines of at least 75 characters, with * embedded newlines. Words are separated for readability, * with eight words (32 bytes) per line. */ public String toString() { return hexify(); } /** * Returns a BigInteger value which supports many arithmetic * operations. Assumes negative values will never occur. */ public BigInteger toBigInteger() { return new BigInteger(1, places); } /** * Returns the length of the data as a byte array. */ public int byteLength() { return places.length; } /** * Returns the data as a byte array. The most significant bit * of the array is bit zero (as in java.math.BigInteger). */ public byte[] toByteArray() { if (places.length == 0) { byte zero[] = new byte[1]; zero[0] = (byte) 0; return zero; } else { return places.clone(); } } private static final String digits = "0123456789abcdef"; private String hexify() { if (places.length == 0) return " 0 "; StringBuffer buf = new StringBuffer(places.length * 2); buf.append(" "); // four spaces for (int i = 0; i < places.length; i++) { buf.append(digits.charAt((places[i] >> 4) & 0x0f)); buf.append(digits.charAt(places[i] & 0x0f)); if (((i + 1) % 32) == 0) { if ((i + 1) != places.length) buf.append("\n "); // line after four words } else if (((i + 1) % 4) == 0) buf.append(' '); // space between words } return buf.toString(); } /** * Returns true iff the parameter is a numerically equivalent * BigInt. * * @param other the object being compared with this one. */ public boolean equals(Object other) { if (other instanceof BigInt) return equals((BigInt) other); return false; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(places); return result; } /** * Returns true iff the parameter is numerically equivalent. * * @param other the BigInt being compared with this one. */ public boolean equals(BigInt other) { if (this == other) return true; byte[] otherPlaces = other.toByteArray(); if (places.length != otherPlaces.length) return false; for (int i = 0; i < places.length; i++) if (places[i] != otherPlaces[i]) return false; return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/util/BitArray.java000066400000000000000000000173761362106420000243760ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.io.ByteArrayOutputStream; /** * A packed array of booleans. * * @author Joshua Bloch * @author Douglas Hoover * @version 1.2 97/12/10 */ public class BitArray { private byte[] repn; private int length; private static final int BITS_PER_UNIT = 8; private static int subscript(int idx) { return idx / BITS_PER_UNIT; } private static int position(int idx) { // bits big-endian in each unit return 1 << (BITS_PER_UNIT - 1 - (idx % BITS_PER_UNIT)); } /** * Creates a BitArray of the specified size, initialized to zeros. */ public BitArray(int length) throws IllegalArgumentException { if (length < 0) { throw new IllegalArgumentException("Negative length for BitArray"); } this.length = length; repn = new byte[(length + BITS_PER_UNIT - 1) / BITS_PER_UNIT]; } /** * Creates a BitArray of the specified size, initialized from the * specified byte array. The most significant bit of a[0] gets * index zero in the BitArray. The array a must be large enough * to specify a value for every bit in the BitArray. In other words, * {@code 8*a.length >= length}. */ public BitArray(int length, byte[] a) throws IllegalArgumentException { if (length < 0) { throw new IllegalArgumentException("Negative length for BitArray"); } if (a.length * BITS_PER_UNIT < length) { throw new IllegalArgumentException("Byte array too short to represent " + "bit array of given length"); } this.length = length; int repLength = ((length + BITS_PER_UNIT - 1) / BITS_PER_UNIT); int unusedBits = repLength * BITS_PER_UNIT - length; byte bitMask = (byte) (0xFF << unusedBits); /* normalize the representation: 1. discard extra bytes 2. zero out extra bits in the last byte */ repn = new byte[repLength]; System.arraycopy(a, 0, repn, 0, repLength); if (repn.length > 0) repn[repn.length - 1] = (byte) (repn[repn.length - 1] & bitMask); } /** * Create a BitArray whose bits are those of the given array * of Booleans. */ public BitArray(boolean[] bits) { length = bits.length; repn = new byte[(length + 7) / 8]; for (int i = 0; i < length; i++) { set(i, bits[i]); } } /** * Copy constructor (for cloning). */ private BitArray(BitArray ba) { length = ba.length; repn = ba.repn.clone(); } /** * Returns the indexed bit in this BitArray. */ public boolean get(int index) throws ArrayIndexOutOfBoundsException { if (index < 0 || index >= length) { throw new ArrayIndexOutOfBoundsException(Integer.toString(index)); } return (repn[subscript(index)] & position(index)) != 0; } /** * Sets the indexed bit in this BitArray. */ public void set(int index, boolean value) throws ArrayIndexOutOfBoundsException { if (index < 0 || index >= length) { throw new ArrayIndexOutOfBoundsException(Integer.toString(index)); } int idx = subscript(index); int bit = position(index); if (value) { repn[idx] |= bit; } else { repn[idx] &= ~bit; } } /** * Returns the length of this BitArray. */ public int length() { return length; } /** * Returns a Byte array containing the contents of this BitArray. * The bit stored at index zero in this BitArray will be copied * into the most significant bit of the zeroth element of the * returned byte array. The last byte of the returned byte array * will be contain zeros in any bits that do not have corresponding * bits in the BitArray. (This matters only if the BitArray's size * is not a multiple of 8.) */ public byte[] toByteArray() { return repn.clone(); } public boolean equals(Object obj) { if (obj == this) return true; if (obj == null || !(obj instanceof BitArray)) return false; BitArray ba = (BitArray) obj; if (ba.length != length) return false; for (int i = 0; i < repn.length; i += 1) { if (repn[i] != ba.repn[i]) return false; } return true; } /** * Return a boolean array with the same bit values a this BitArray. */ public boolean[] toBooleanArray() { boolean[] bits = new boolean[length]; for (int i = 0; i < length; i++) { bits[i] = get(i); } return bits; } /** * Returns a hash code value for this bit array. * * @return a hash code value for this bit array. */ public int hashCode() { int hashCode = 0; for (int i = 0; i < repn.length; i++) hashCode = 31 * hashCode + repn[i]; return hashCode ^ length; } public Object clone() { return new BitArray(this); } private static final byte[][] NYBBLE = { { (byte) '0', (byte) '0', (byte) '0', (byte) '0' }, { (byte) '0', (byte) '0', (byte) '0', (byte) '1' }, { (byte) '0', (byte) '0', (byte) '1', (byte) '0' }, { (byte) '0', (byte) '0', (byte) '1', (byte) '1' }, { (byte) '0', (byte) '1', (byte) '0', (byte) '0' }, { (byte) '0', (byte) '1', (byte) '0', (byte) '1' }, { (byte) '0', (byte) '1', (byte) '1', (byte) '0' }, { (byte) '0', (byte) '1', (byte) '1', (byte) '1' }, { (byte) '1', (byte) '0', (byte) '0', (byte) '0' }, { (byte) '1', (byte) '0', (byte) '0', (byte) '1' }, { (byte) '1', (byte) '0', (byte) '1', (byte) '0' }, { (byte) '1', (byte) '0', (byte) '1', (byte) '1' }, { (byte) '1', (byte) '1', (byte) '0', (byte) '0' }, { (byte) '1', (byte) '1', (byte) '0', (byte) '1' }, { (byte) '1', (byte) '1', (byte) '1', (byte) '0' }, { (byte) '1', (byte) '1', (byte) '1', (byte) '1' } }; private static final int BYTES_PER_LINE = 8; /** * Returns a string representation of this BitArray. */ public String toString() { ByteArrayOutputStream out = new ByteArrayOutputStream(); for (int i = 0; i < repn.length - 1; i++) { out.write(NYBBLE[(repn[i] >> 4) & 0x0F], 0, 4); out.write(NYBBLE[repn[i] & 0x0F], 0, 4); if (i % BYTES_PER_LINE == BYTES_PER_LINE - 1) { out.write('\n'); } else { out.write(' '); } } // in last byte of repn, use only the valid bits for (int i = BITS_PER_UNIT * (repn.length - 1); i < length; i++) { out.write(get(i) ? '1' : '0'); } return new String(out.toByteArray()); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/ByteArrayLexOrder.java000066400000000000000000000041641362106420000262170ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.util.Comparator; /** * Compare two byte arrays in lexicographical order. * * @version 1.4 97/12/10 * @author D. N. Hoover */ public class ByteArrayLexOrder implements Comparator, java.io.Serializable { private static final long serialVersionUID = 1897537410212918669L; /** * Perform lexicographical comparison of two byte arrays, * regarding each byte as unsigned. That is, compare array entries * in order until they differ--the array with the smaller entry * is "smaller". If array entries are * equal till one array ends, then the longer array is "bigger". * * @param bytes1 first byte array to compare. * @param bytes2 second byte array to compare. * @return negative number if {@literal bytes1 < bytes2}, 0 if bytes1 == bytes2, * positive number if {@literal bytes1 > bytes2}. */ public final int compare(byte[] bytes1, byte[] bytes2) { int diff; for (int i = 0; i < bytes1.length && i < bytes2.length; i++) { diff = (bytes1[i] & 0xFF) - (bytes2[i] & 0xFF); if (diff != 0) { return diff; } } // if array entries are equal till the first ends, then the // longer is "bigger" return bytes1.length - bytes2.length; } } jss-4.6.3/org/mozilla/jss/netscape/security/util/ByteArrayTagOrder.java000066400000000000000000000032741362106420000262030ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.util.Comparator; public class ByteArrayTagOrder implements Comparator, java.io.Serializable { private static final long serialVersionUID = -2027007556858126443L; /** * Compare two byte arrays, by the order of their tags, * as defined in ITU-T X.680, sec. 6.4. (First compare * tag classes, then tag numbers, ignoring the constructivity bit.) * * @param bytes1 first byte array to compare. * @param bytes2 second byte array to compare. * @return negative number if {@literal bytes1 < bytes2}, 0 if bytes1 == bytes2, * positive number if {@literal bytes1 > bytes2}. */ public final int compare(byte[] bytes1, byte[] bytes2) { // tag order is same as byte order ignoring any difference in // the constructivity bit (0x02) return (bytes1[0] | 0x20) - (bytes2[0] | 0x20); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/Cert.java000066400000000000000000000270441362106420000235470ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.io.IOException; import java.security.cert.CertificateException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.commons.lang.ArrayUtils; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.netscape.security.pkcs.PKCS7; import org.mozilla.jss.netscape.security.x509.X509CRLImpl; import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Cert { private static Logger logger = LoggerFactory.getLogger(Cert.class); public static final String HEADER = "-----BEGIN CERTIFICATE-----"; public static final String FOOTER = "-----END CERTIFICATE-----"; public static final String PKCS7_HEADER = "-----BEGIN PKCS7-----"; public static final String PKCS7_FOOTER = "-----END PKCS7-----"; // From https://www.rfc-editor.org/rfc/rfc7468.txt public static final String REQUEST_HEADER = "-----BEGIN CERTIFICATE REQUEST-----"; public static final String REQUEST_FOOTER = "-----END CERTIFICATE REQUEST-----"; public static SignatureAlgorithm mapAlgorithmToJss(String algname) { if (algname.equals("MD5withRSA")) return SignatureAlgorithm.RSASignatureWithMD5Digest; else if (algname.equals("MD2withRSA")) return SignatureAlgorithm.RSASignatureWithMD2Digest; else if (algname.equals("SHA1withRSA")) return SignatureAlgorithm.RSASignatureWithSHA1Digest; else if (algname.equals("SHA1withDSA")) return SignatureAlgorithm.DSASignatureWithSHA1Digest; else if (algname.equals("SHA256withRSA")) return SignatureAlgorithm.RSASignatureWithSHA256Digest; else if (algname.equals("SHA384withRSA")) return SignatureAlgorithm.RSASignatureWithSHA384Digest; else if (algname.equals("SHA512withRSA")) return SignatureAlgorithm.RSASignatureWithSHA512Digest; else if (algname.equals("SHA1withEC")) return SignatureAlgorithm.ECSignatureWithSHA1Digest; else if (algname.equals("SHA256withEC")) return SignatureAlgorithm.ECSignatureWithSHA256Digest; else if (algname.equals("SHA384withEC")) return SignatureAlgorithm.ECSignatureWithSHA384Digest; else if (algname.equals("SHA512withEC")) return SignatureAlgorithm.ECSignatureWithSHA512Digest; return null; } public static String stripBrackets(String s) { if (s == null) { return s; } if (s.startsWith(HEADER) && s.endsWith(FOOTER)) { return s.substring(HEADER.length(), s.length() - FOOTER.length()); } if (s.startsWith(PKCS7_HEADER) && s.endsWith(PKCS7_FOOTER)) { return s.substring(PKCS7_HEADER.length(), s.length() - PKCS7_FOOTER.length()); } // To support Thawte's header and footer if ((s.startsWith("-----BEGIN PKCS #7 SIGNED DATA-----")) && (s.endsWith("-----END PKCS #7 SIGNED DATA-----"))) { return (s.substring(35, (s.length() - 33))); } return s; } public static String stripCRLBrackets(String s) { if (s == null) { return s; } if ((s.startsWith("-----BEGIN CERTIFICATE REVOCATION LIST-----")) && (s.endsWith("-----END CERTIFICATE REVOCATION LIST-----"))) { return (s.substring(43, (s.length() - 41))); } return s; } public static String stripCertBrackets(String s) { return stripBrackets(s); } // private static BASE64Decoder mDecoder = new BASE64Decoder(); public static X509CertImpl mapCert(String mime64) throws IOException { mime64 = stripCertBrackets(mime64.trim()); String newval = normalizeCertStr(mime64); // byte rawPub[] = mDecoder.decodeBuffer(newval); byte rawPub[] = Utils.base64decode(newval); X509CertImpl cert = null; try { cert = new X509CertImpl(rawPub); } catch (CertificateException e) { } return cert; } public static X509Certificate[] mapCertFromPKCS7(String mime64) throws IOException { mime64 = stripCertBrackets(mime64.trim()); String newval = normalizeCertStr(mime64); // byte rawPub[] = mDecoder.decodeBuffer(newval); byte rawPub[] = Utils.base64decode(newval); PKCS7 p7 = null; try { p7 = new PKCS7(rawPub); } catch (Exception e) { throw new IOException("p7 is null"); } return p7.getCertificates(); } public static X509CRL mapCRL(String mime64) throws IOException { mime64 = stripCRLBrackets(mime64.trim()); String newval = normalizeCertStr(mime64); // byte rawPub[] = mDecoder.decodeBuffer(newval); byte rawPub[] = Utils.base64decode(newval); X509CRL crl = null; try { crl = new X509CRLImpl(rawPub); } catch (Exception e) { } return crl; } public static X509CRL mapCRL1(String mime64) throws IOException { mime64 = stripCRLBrackets(mime64.trim()); byte rawPub[] = Utils.base64decode(mime64); X509CRL crl = null; try { crl = new X509CRLImpl(rawPub); } catch (Exception e) { throw new IOException(e.toString()); } return crl; } public static String normalizeCertStr(String s) { StringBuffer val = new StringBuffer(); for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == '\n') { continue; } else if (s.charAt(i) == '\r') { continue; } else if (s.charAt(i) == '"') { continue; } else if (s.charAt(i) == ' ') { continue; } val.append(s.charAt(i)); } return val.toString(); } public static String normalizeCertStrAndReq(String s) { StringBuffer val = new StringBuffer(); for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == '\n') { continue; } else if (s.charAt(i) == '\r') { continue; } else if (s.charAt(i) == '"') { continue; } val.append(s.charAt(i)); } return val.toString(); } public static byte[] parseCertificate(String cert) { String encoded = normalizeCertStrAndReq(cert); String b64 = stripBrackets(encoded); return Utils.base64decode(b64); } /** * Sorts certificate chain from root to leaf. * * This method sorts an array of certificates (e.g. from a PKCS #7 * data) that represents a certificate chain from root to leaf * according to the subject DNs and issuer DNs. * * The input array is a set of certificates that are part of a * chain but not in specific order. * * The result is a new array that contains the certificate chain * sorted from root to leaf. The input array is unchanged. * * @param certs input array of certificates * @return new array containing sorted certificates */ public static java.security.cert.X509Certificate[] sortCertificateChain(java.security.cert.X509Certificate[] certs) throws Exception { if (certs == null) { return null; } if (certs.length == 0) { return certs; } // lookup map: subject DN -> cert Map certMap = new LinkedHashMap<>(); // hierarchy map: subject DN -> issuer DN Map parentMap = new HashMap<>(); // reverse hierarchy map: issuer DN -> subject DN Map childMap = new HashMap<>(); // build maps for (java.security.cert.X509Certificate cert : certs) { String subjectDN = cert.getSubjectDN().toString(); String issuerDN = cert.getIssuerDN().toString(); if (certMap.containsKey(subjectDN)) { throw new Exception("Duplicate certificate: " + subjectDN); } certMap.put(subjectDN, cert); // ignore self-signed certificate if (subjectDN.equals(issuerDN)) continue; if (childMap.containsKey(issuerDN)) { throw new Exception("Branched chain: " + issuerDN); } parentMap.put(subjectDN, issuerDN); childMap.put(issuerDN, subjectDN); } if (logger.isDebugEnabled()) { logger.debug("Certificates:"); for (String subjectDN : certMap.keySet()) { logger.debug(" - " + subjectDN); String parent = parentMap.get(subjectDN); if (parent != null) logger.debug(" parent: " + parent); String child = childMap.get(subjectDN); if (child != null) logger.debug(" child: " + child); } } // find leaf cert by removing certs that has a child List leafCerts = new ArrayList<>(); leafCerts.addAll(certMap.keySet()); leafCerts.removeAll(childMap.keySet()); if (leafCerts.isEmpty()) { throw new Exception("Unable to find leaf certificate"); } if (leafCerts.size() > 1) { StringBuilder sb = new StringBuilder(); for (String subjectDN : leafCerts) { if (sb.length() > 0) sb.append(", "); sb.append("[" + subjectDN + "]"); } throw new Exception("Multiple leaf certificates: " + sb); } // build sorted chain LinkedList chain = new LinkedList<>(); // start from leaf String current = leafCerts.get(0); while (current != null) { java.security.cert.X509Certificate cert = certMap.get(current); if (cert == null) { // incomplete chain break; } // add to the beginning of chain chain.addFirst(cert); // follow parent to root current = parentMap.get(current); } return chain.toArray(new java.security.cert.X509Certificate[chain.size()]); } public static java.security.cert.X509Certificate[] sortCertificateChain( java.security.cert.X509Certificate[] certs, boolean reverse) throws Exception { certs = sortCertificateChain(certs); if (reverse) { ArrayUtils.reverse(certs); } return certs; } } jss-4.6.3/org/mozilla/jss/netscape/security/util/CertPrettyPrint.java000066400000000000000000000314631362106420000257740ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.security.MessageDigest; import java.security.PublicKey; import java.security.cert.Certificate; import java.text.DateFormat; import java.util.Locale; import java.util.ResourceBundle; import java.util.TimeZone; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.pkcs7.ContentInfo; import org.mozilla.jss.pkcs7.SignedData; import org.mozilla.jss.netscape.security.x509.CertificateExtensions; import org.mozilla.jss.netscape.security.x509.CertificateX509Key; import org.mozilla.jss.netscape.security.x509.Extension; import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.mozilla.jss.netscape.security.x509.X509CertInfo; import org.mozilla.jss.netscape.security.x509.X509Key; /** * This class will display the certificate content in predefined * format. * * @author Jack Pan-Chen * @version $Revision$, $Date$ */ public class CertPrettyPrint { /*========================================================== * constants *==========================================================*/ private final static String CUSTOM_LOCALE = "Custom"; /*========================================================== * variables *==========================================================*/ private X509CertImpl mX509Cert = null; private PrettyPrintFormat pp = null; private byte[] mCert_b = null; /*========================================================== * constructors *==========================================================*/ public CertPrettyPrint(Certificate cert) { if (cert instanceof X509CertImpl) mX509Cert = (X509CertImpl) cert; pp = new PrettyPrintFormat(":"); } public CertPrettyPrint(byte[] certb) { mCert_b = certb; pp = new PrettyPrintFormat(":"); } /*========================================================== * public methods *==========================================================*/ /** * This method return string representation of the certificate * in predefined format using specified client local. I18N Support. * * @param clientLocale Locale to be used for localization * @return string representation of the certificate */ public String toString(Locale clientLocale) { if (mX509Cert != null) return X509toString(clientLocale); else if (mCert_b != null) return pkcs7toString(clientLocale); else return null; } public String pkcs7toString(Locale clientLocale) { StringBuffer content=new StringBuffer(); try { mX509Cert = new X509CertImpl(mCert_b); return toString(clientLocale); } catch (Exception e) { } ContentInfo ci = null; try { ci = (ContentInfo) ASN1Util.decode(ContentInfo.getTemplate(), mCert_b); } catch (Exception e) { return ""; } if (ci.getContentType().equals(ContentInfo.SIGNED_DATA)) { SignedData sd = null; try { sd = (SignedData) ci.getInterpretedContent(); } catch (Exception e) { return ""; } if (sd.hasCertificates()) { SET certs = sd.getCertificates(); for (int i = 0; i < certs.size(); i++) { org.mozilla.jss.pkix.cert.Certificate cert = (org.mozilla.jss.pkix.cert.Certificate) certs.elementAt(i); X509CertImpl certImpl = null; try { certImpl = new X509CertImpl( ASN1Util.encode(cert)); } catch (Exception e) { } CertPrettyPrint print = new CertPrettyPrint(certImpl); content.append(print.toString(Locale.getDefault())); content.append("\n"); } return content.toString(); } } return content.toString(); } public String stripCertBrackets(String s) { if (s == null) { return s; } if ((s.startsWith(Cert.HEADER)) && (s.endsWith(Cert.FOOTER))) { return (s.substring(27, (s.length() - 25))); } // To support Thawte's header and footer if ((s.startsWith("-----BEGIN PKCS #7 SIGNED DATA-----")) && (s.endsWith("-----END PKCS #7 SIGNED DATA-----"))) { return (s.substring(35, (s.length() - 33))); } return s; } public String normalizeCertStr(String s) { StringBuffer val = new StringBuffer(); for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == '\n') { continue; } else if (s.charAt(i) == '\r') { continue; } else if (s.charAt(i) == '"') { continue; } else if (s.charAt(i) == ' ') { continue; } val.append(s.charAt(i)); } return val.toString(); } public String X509toString(Locale clientLocale) { //get I18N resources ResourceBundle resource = ResourceBundle.getBundle( PrettyPrintResources.class.getName()); DateFormat dateFormater = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, clientLocale); //get timezone and timezone ID String tz = " "; String tzid = " "; StringBuffer sb = new StringBuffer(); try { X509CertInfo info = (X509CertInfo) mX509Cert.get( X509CertImpl.NAME + "." + X509CertImpl.INFO); String serial2 = mX509Cert.getSerialNumber().toString(16).toUpperCase(); //get correct instance of key PublicKey pKey = mX509Cert.getPublicKey(); X509Key key = null; if (pKey instanceof CertificateX509Key) { CertificateX509Key certKey = (CertificateX509Key) pKey; key = (X509Key) certKey.get(CertificateX509Key.KEY); } if (pKey instanceof X509Key) { key = (X509Key) pKey; } //take care of spki sb.append(pp.indent(4) + resource.getString( PrettyPrintResources.TOKEN_CERTIFICATE) + "\n"); sb.append(pp.indent(8) + resource.getString( PrettyPrintResources.TOKEN_DATA) + "\n"); sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_VERSION) + " v"); sb.append((mX509Cert.getVersion() + 1) + "\n"); sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_SERIAL) + "0x" + serial2 + "\n"); //XXX I18N Algorithm Name ? sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_SIGALG) + mX509Cert.getSigAlgName() + " - " + mX509Cert.getSigAlgOID() + "\n"); //XXX I18N IssuerDN ? sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_ISSUER) + mX509Cert.getIssuerDN().toString() + "\n"); sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_VALIDITY) + "\n"); String notBefore = dateFormater.format(mX509Cert.getNotBefore()); String notAfter = dateFormater.format(mX509Cert.getNotAfter()); //get timezone and timezone ID if (TimeZone.getDefault() != null) { tz = TimeZone.getDefault().getDisplayName( TimeZone.getDefault().inDaylightTime( mX509Cert.getNotBefore()), TimeZone.SHORT, clientLocale); tzid = TimeZone.getDefault().getID(); } // Specify notBefore if (tz.equals(tzid) || tzid.equals(CUSTOM_LOCALE)) { // Do NOT append timezone ID sb.append(pp.indent(16) + resource.getString( PrettyPrintResources.TOKEN_NOT_BEFORE) + notBefore + "\n"); } else { // Append timezone ID sb.append(pp.indent(16) + resource.getString( PrettyPrintResources.TOKEN_NOT_BEFORE) + notBefore + " " + tzid + "\n"); } // re-get timezone (just in case it is different . . .) if (TimeZone.getDefault() != null) { tz = TimeZone.getDefault().getDisplayName( TimeZone.getDefault().inDaylightTime( mX509Cert.getNotAfter()), TimeZone.SHORT, clientLocale); } // Specify notAfter if (tz.equals(tzid) || tzid.equals(CUSTOM_LOCALE)) { // Do NOT append timezone ID sb.append(pp.indent(16) + resource.getString( PrettyPrintResources.TOKEN_NOT_AFTER) + notAfter + "\n"); } else { // Append timezone ID sb.append(pp.indent(16) + resource.getString( PrettyPrintResources.TOKEN_NOT_AFTER) + notAfter + " " + tzid + "\n"); } //XXX I18N SubjectDN ? sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_SUBJECT) + mX509Cert.getSubjectDN().toString() + "\n"); sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_SPKI) + "\n"); PubKeyPrettyPrint pkpp = new PubKeyPrettyPrint(key); sb.append(pkpp.toString(clientLocale, 16, 16)); //take care of extensions CertificateExtensions extensions = (CertificateExtensions) info.get(X509CertInfo.EXTENSIONS); sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_EXTENSIONS) + "\n"); if (extensions != null) for (int i = 0; i < extensions.size(); i++) { Extension ext = extensions.elementAt(i); ExtPrettyPrint extpp = new ExtPrettyPrint(ext, 16); sb.append(extpp.toString()); } //take care of signature sb.append(pp.indent(8) + resource.getString( PrettyPrintResources.TOKEN_SIGNATURE) + "\n"); //XXX I18N Algorithm Name ? sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_ALGORITHM) + mX509Cert.getSigAlgName() + " - " + mX509Cert.getSigAlgOID() + "\n"); sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_SIGNATURE) + "\n"); sb.append(pp.toHexString(mX509Cert.getSignature(), 16, 16)); // fingerprints String[] hashes = new String[] { "MD2", "MD5", "SHA-1", "SHA-256", "SHA-512" }; StringBuffer certFingerprints = new StringBuffer(); sb.append(pp.indent(8) + "FingerPrint\n"); for (int i = 0; i < hashes.length; i++) { MessageDigest md = MessageDigest.getInstance(hashes[i]); md.update(mX509Cert.getEncoded()); certFingerprints.append(pp.indent(12) + hashes[i] + ":\n" + pp.toHexString(md.digest(), 16, 16)); } sb.append(certFingerprints.toString()); } catch (Exception e) { e.printStackTrace(); } return sb.toString(); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/CrlPrettyPrint.java000066400000000000000000000276661362106420000256310ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.text.DateFormat; import java.util.Iterator; import java.util.Locale; import java.util.ResourceBundle; import java.util.Set; import java.util.TimeZone; import org.mozilla.jss.netscape.security.x509.CRLExtensions; import org.mozilla.jss.netscape.security.x509.Extension; import org.mozilla.jss.netscape.security.x509.RevokedCertificate; import org.mozilla.jss.netscape.security.x509.X509CRLImpl; /** * This class will display the certificate content in predefined * format. * * @author Andrew Wnuk * @version $Revision$, $Date$ */ public class CrlPrettyPrint { /*========================================================== * constants *==========================================================*/ private final static String CUSTOM_LOCALE = "Custom"; /*========================================================== * variables *==========================================================*/ private X509CRLImpl mCRL = null; private PrettyPrintFormat pp = null; /*========================================================== * constructors *==========================================================*/ public CrlPrettyPrint(X509CRLImpl crl) { mCRL = crl; pp = new PrettyPrintFormat(":"); } /*========================================================== * public methods *==========================================================*/ /** * This method return string representation of the certificate * revocation list in predefined format using specified client * local. I18N Support. * * @param clientLocale Locale to be used for localization * @return string representation of the certificate */ public String toString(Locale clientLocale) { return toString(clientLocale, 0, 0, 0); } public String toString(Locale clientLocale, long crlSize, long pageStart, long pageSize) { //get I18N resources ResourceBundle resource = ResourceBundle.getBundle( PrettyPrintResources.class.getName()); DateFormat dateFormater = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, clientLocale); //get timezone and timezone ID String tz = " "; String tzid = " "; StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(4) + resource.getString( PrettyPrintResources.TOKEN_CRL) + "\n"); sb.append(pp.indent(8) + resource.getString( PrettyPrintResources.TOKEN_DATA) + "\n"); sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_VERSION) + " v"); sb.append((mCRL.getVersion() + 1) + "\n"); sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_SIGALG) + mCRL.getSigAlgName() + " - " + mCRL.getSigAlgOID() + "\n"); sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_ISSUER) + mCRL.getIssuerDN().toString() + "\n"); // Format thisUpdate String thisUpdate = dateFormater.format(mCRL.getThisUpdate()); // get timezone and timezone ID if (TimeZone.getDefault() != null) { tz = TimeZone.getDefault().getDisplayName( TimeZone.getDefault().inDaylightTime( mCRL.getThisUpdate()), TimeZone.SHORT, clientLocale); tzid = TimeZone.getDefault().getID(); } // Specify ThisUpdate if (tz.equals(tzid) || tzid.equals(CUSTOM_LOCALE)) { // Do NOT append timezone ID sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_THIS_UPDATE) + thisUpdate + "\n"); } else { // Append timezone ID sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_THIS_UPDATE) + thisUpdate + " " + tzid + "\n"); } // Check for presence of NextUpdate if (mCRL.getNextUpdate() != null) { // Format nextUpdate String nextUpdate = dateFormater.format(mCRL.getNextUpdate()); // re-get timezone (just in case it is different . . .) if (TimeZone.getDefault() != null) { tz = TimeZone.getDefault().getDisplayName( TimeZone.getDefault().inDaylightTime( mCRL.getNextUpdate()), TimeZone.SHORT, clientLocale); } // Specify NextUpdate if (tz.equals(tzid) || tzid.equals(CUSTOM_LOCALE)) { // Do NOT append timezone ID sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_NEXT_UPDATE) + nextUpdate + "\n"); } else { // Append timezone ID sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_NEXT_UPDATE) + nextUpdate + " " + tzid + "\n"); } } if (crlSize > 0 && pageStart == 0 && pageSize == 0) { sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_REVOKED_CERTIFICATES) + crlSize + "\n"); } else if ((crlSize == 0 && pageStart == 0 && pageSize == 0) || (crlSize > 0 && pageStart > 0 && pageSize > 0)) { sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_REVOKED_CERTIFICATES)); if (crlSize > 0 && pageStart > 0 && pageSize > 0) { long upperLimit = (pageStart + pageSize - 1 > crlSize) ? crlSize : pageStart + pageSize - 1; sb.append("" + pageStart + "-" + upperLimit + " of " + crlSize); } sb.append("\n"); Set revokedCerts = mCRL.getRevokedCertificates(); if (revokedCerts != null) { Iterator i = revokedCerts.iterator(); long l = 1; while ((i.hasNext()) && ((crlSize == 0) || (pageStart + pageSize > l))) { RevokedCertificate revokedCert = i.next(); if ((crlSize == 0) || ((pageStart <= l) && (pageStart + pageSize > l))) { sb.append(pp.indent(16) + resource.getString( PrettyPrintResources.TOKEN_SERIAL) + "0x" + revokedCert.getSerialNumber().toString(16).toUpperCase() + "\n"); String revocationDate = dateFormater.format(revokedCert.getRevocationDate()); // re-get timezone // (just in case it is different . . .) if (TimeZone.getDefault() != null) { tz = TimeZone.getDefault().getDisplayName( TimeZone.getDefault().inDaylightTime( revokedCert.getRevocationDate()), TimeZone.SHORT, clientLocale); } // Specify revocationDate if (tz.equals(tzid) || tzid.equals(CUSTOM_LOCALE)) { // Do NOT append timezone ID sb.append(pp.indent(16) + resource.getString( PrettyPrintResources.TOKEN_REVOCATION_DATE) + revocationDate + "\n"); } else { // Append timezone ID sb.append(pp.indent(16) + resource.getString( PrettyPrintResources.TOKEN_REVOCATION_DATE) + revocationDate + " " + tzid + "\n"); } if (revokedCert.hasExtensions()) { sb.append(pp.indent(16) + resource.getString( PrettyPrintResources.TOKEN_EXTENSIONS) + "\n"); CRLExtensions crlExtensions = revokedCert.getExtensions(); if (crlExtensions != null) { for (int k = 0; k < crlExtensions.size(); k++) { Extension ext = crlExtensions.elementAt(k); ExtPrettyPrint extpp = new ExtPrettyPrint(ext, 20); sb.append(extpp.toString()); } } } } l++; } } } CRLExtensions crlExtensions = mCRL.getExtensions(); if (crlExtensions != null) { sb.append(pp.indent(8) + resource.getString( PrettyPrintResources.TOKEN_EXTENSIONS) + "\n"); for (int k = 0; k < crlExtensions.size(); k++) { Extension ext = crlExtensions.elementAt(k); ExtPrettyPrint extpp = new ExtPrettyPrint(ext, 12); sb.append(extpp.toString()); } } //take care of signature sb.append(pp.indent(8) + resource.getString( PrettyPrintResources.TOKEN_SIGNATURE) + "\n"); //XXX I18N Algorithm Name ? sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_ALGORITHM) + mCRL.getSigAlgName() + " - " + mCRL.getSigAlgOID() + "\n"); sb.append(pp.indent(12) + resource.getString( PrettyPrintResources.TOKEN_SIGNATURE) + "\n"); sb.append(pp.toHexString(mCRL.getSignature(), 16, 16)); } catch (Exception e) { sb.append("\n\n" + pp.indent(4) + resource.getString( PrettyPrintResources.TOKEN_DECODING_ERROR) + "\n\n"); e.printStackTrace(); } return sb.toString(); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/DerEncoder.java000066400000000000000000000024401362106420000246550ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.io.IOException; import java.io.OutputStream; /** * Interface to an object that knows how to write its own DER * encoding to an output stream. * * @version 1.2 97/12/10 * @author D. N. Hoover */ public interface DerEncoder { /** * DER encode this object and write the results to a stream. * * @param out the stream on which the DER encoding is written. */ public void derEncode(OutputStream out) throws IOException; } jss-4.6.3/org/mozilla/jss/netscape/security/util/DerInputBuffer.java000066400000000000000000000127721362106420000255400ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; /** * DER input buffer ... this is the main abstraction in the DER library * which actively works with the "untyped byte stream" abstraction. It * does so with impunity, since it's not intended to be exposed to the * anyone who could violate the "typed value stream" DER model and hence * corrupt the input stream of DER values. * * @version 1.11 * @author David Brownell */ class DerInputBuffer extends ByteArrayInputStream implements Cloneable { DerInputBuffer(byte[] buf) { super(buf); } DerInputBuffer(byte[] buf, int offset, int len) { super(buf, offset, len); } DerInputBuffer dup() { try { DerInputBuffer retval = (DerInputBuffer) clone(); retval.mark(Integer.MAX_VALUE); return retval; } catch (CloneNotSupportedException e) { throw new IllegalArgumentException(e.toString()); } } byte[] toByteArray() throws IOException { int len = available(); if (len <= 0) throw new IOException("No Buffer Space Available."); byte[] retval = new byte[len]; System.arraycopy(buf, pos, retval, 0, len); return retval; } int peek() throws IOException { if (pos >= count) throw new IOException("out of data"); else return buf[pos]; } /** * Compares this DerInputBuffer for equality with the specified * object. */ public boolean equals(Object other) { if (other instanceof DerInputBuffer) return equals((DerInputBuffer) other); else return false; } boolean equals(DerInputBuffer other) { if (this == other) return true; int max = this.available(); if (other.available() != max) return false; for (int i = 0; i < max; i++) { if (this.buf[this.pos + i] != other.buf[other.pos + i]) { return false; } } return true; } void truncate(int len) throws IOException { if (len > available()) throw new IOException("insufficient data"); count = pos + len; } /** * Returns the unsigned integer which takes up the specified number * of bytes in this buffer. */ BigInt getUnsigned(int len) throws IOException { if (len > available()) throw new IOException("short read, getInteger"); /* * A prepended zero is used to ensure that the integer is * interpreted as unsigned even when the high order bit is * zero. We don't support signed BigInts. * * Fix this here ... BigInts aren't expected to have these, * and stuff like signing (sigsize = f(modulus)) misbehaves. */ if (len > 1 && buf[pos] == 0) { len--; skip(1); } /* * Consume the rest of the buffer, returning its value as * an unsigned integer. */ byte[] bytes = new byte[len]; System.arraycopy(buf, pos, bytes, 0, len); skip(len); return new BigInt(bytes); } /** * Returns the bit string which takes up the rest of this buffer. * This bit string must be byte-aligned. */ byte[] getBitString() { if (pos >= count || buf[pos] != 0) return null; /* * Just copy the data into an aligned, padded octet buffer, * and consume the rest of the buffer. */ int len = available(); byte[] retval = new byte[len - 1]; System.arraycopy(buf, pos + 1, retval, 0, len - 1); pos = count; return retval; } /** * Returns the bit string which takes up the rest of this buffer. * The bit string need not be byte-aligned. */ BitArray getUnalignedBitString() { if (pos >= count) return null; /* * Just copy the data into an aligned, padded octet buffer, * and consume the rest of the buffer. */ int len = available(); byte[] bits = new byte[len - 1]; int length = bits.length * 8 - buf[pos]; // number of valid bits System.arraycopy(buf, pos + 1, bits, 0, len - 1); BitArray bitArray = new BitArray(length, bits); pos = count; return bitArray; } /** * Package-access method to optimize output operations */ void dump(OutputStream out, int length) throws IOException { if (count < mark + length) throw new IOException("short DER value (encode)"); out.write(buf, mark, length); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/DerInputStream.java000066400000000000000000000544401362106420000255600ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.io.IOException; import java.io.InputStream; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; import java.util.Vector; /** * A DER input stream, used for parsing ASN.1 DER-encoded data such as * that found in X.509 certificates. DER is a subset of BER/1, which has * the advantage that it allows only a single encoding of primitive data. * (High level data such as dates still support many encodings.) That is, * it uses the "Definite" Encoding Rules (DER) not the "Basic" ones (BER). * *

* Note that, like BER/1, DER streams are streams of explicitly tagged data values. Accordingly, this programming * interface does not expose any variant of the java.io.InputStream interface, since that kind of input stream holds * untagged data values and using that I/O model could prevent correct parsing of the DER data. * *

* At this time, this class supports only a subset of the types of DER data encodings which are defined. That subset is * sufficient for parsing most X.509 certificates. * * @version 1.35 * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra */ public class DerInputStream { /* * This version only supports fully buffered DER. This is easy to * work with, though if large objects are manipulated DER becomes * awkward to deal with. That's where BER is useful, since BER * handles streaming data relatively well. */ DerInputBuffer buffer; /** * Create a DER input stream from a data buffer. The buffer is not * copied, it is shared. Accordingly, the buffer should be treated * as read-only. * * @param data the buffer from which to create the string (CONSUMED) */ public DerInputStream(byte[] data) { buffer = new DerInputBuffer(data); buffer.mark(Integer.MAX_VALUE); } /** * Create a DER input stream from part of a data buffer. * The buffer is not copied, it is shared. Accordingly, the * buffer should be treated as read-only. * * @param data the buffer from which to create the string (CONSUMED) * @param offset the first index of data which will * be read as DER input in the new stream * @param len how long a chunk of the buffer to use, * starting at "offset" */ public DerInputStream(byte[] data, int offset, int len) { buffer = new DerInputBuffer(data, offset, len); buffer.mark(Integer.MAX_VALUE); } DerInputStream(DerInputBuffer buf) { buffer = buf; buffer.mark(Integer.MAX_VALUE); } /** * Creates a new DER input stream from part of this input stream. * * @param len how long a chunk of the current input stream to use, * starting at the current position. * @param do_skip true if the existing data in the input stream should * be skipped. If this value is false, the next data read * on this stream and the newly created stream will be the * same. */ public DerInputStream subStream(int len, boolean do_skip) throws IOException { DerInputBuffer newbuf = buffer.dup(); newbuf.truncate(len); if (do_skip) buffer.skip(len); return new DerInputStream(newbuf); } /** * Return what has been written to this DerInputStream * as a byte array. Useful for debugging. * @throws IOException */ public byte[] toByteArray() throws IOException { return buffer.toByteArray(); } /* * PRIMITIVES -- these are "universal" ASN.1 simple types. * * INTEGER, BIT STRING, OCTET STRING, NULL * OBJECT IDENTIFIER, SEQUENCE (OF), SET (OF) * PrintableString, T61String, IA5String, UTCTime */ /** * Get an (unsigned) integer from the input stream. */ public BigInt getInteger() throws IOException { if (buffer.read() != DerValue.tag_Integer) throw new IOException("DER input, Integer tag error"); return buffer.getUnsigned(getLength(buffer)); } /** * Get a bit string from the input stream. Only octet-aligned * bitstrings (multiples of eight bits in length) are handled * by this method. */ public byte[] getBitString() throws IOException { if (buffer.read() != DerValue.tag_BitString) throw new IOException("DER input not an bit string"); int length = getLength(buffer); /* * This byte affects alignment and padding (for the last byte). * Use getUnalignedBitString() for none 8-bit aligned bit strings. */ if (buffer.read() != 0) return null; length--; /* * Just read the data into an aligned, padded octet buffer. */ byte[] retval = new byte[length]; if (buffer.read(retval) != length) throw new IOException("short read of DER bit string"); return retval; } /** * Get a bit string from the input stream. The bit string need * not be byte-aligned. */ public BitArray getUnalignedBitString() throws IOException { if (buffer.read() != DerValue.tag_BitString) throw new IOException("DER input not a bit string"); int length = getLength(buffer) - 1; /* * First byte = number of excess bits in the last octet of the * representation. */ int validBits = length * 8 - buffer.read(); byte[] repn = new byte[length]; if (buffer.read(repn) != length) throw new IOException("short read of DER bit string"); return new BitArray(validBits, repn); } /** * Returns an ASN.1 OCTET STRING from the input stream. */ public byte[] getOctetString() throws IOException { if (buffer.read() != DerValue.tag_OctetString) throw new IOException("DER input not an octet string"); int length = getLength(buffer); byte[] retval = new byte[length]; if (buffer.read(retval) != length) throw new IOException("short read of DER octet string"); return retval; } /** * Returns the asked number of bytes from the input stream. */ public void getBytes(byte[] val) throws IOException { if (val.length != 0) { if (buffer.read(val) != val.length) { throw new IOException("short read of DER octet string"); } } } /** * Reads an encoded null value from the input stream. */ public void getNull() throws IOException { if (buffer.read() != DerValue.tag_Null || buffer.read() != 0) throw new IOException("getNull, bad data"); } /** * Reads an X.200 style Object Identifier from the stream. */ public ObjectIdentifier getOID() throws IOException { return new ObjectIdentifier(this); } /** * Return a sequence of encoded entities. ASN.1 sequences are * ordered, and they are often used, like a "struct" in C or C++, * to group data values. They may have optional or context * specific values. * * @param startLen guess about how long the sequence will be * (used to initialize an auto-growing data structure) * @return array of the values in the sequence */ public DerValue[] getSequence(int startLen) throws IOException { int b = buffer.read(); if (b != DerValue.tag_Sequence) throw new IOException("Sequence tag error " + b); return readVector(startLen); } public void skipSequence(int startLen) throws IOException { int b = buffer.read(); if (b != DerValue.tag_Sequence) throw new IOException("Sequence tag error " + b); int len = getLength(buffer); buffer.skip(len); } /** * Return a set of encoded entities. ASN.1 sets are unordered, * though DER may specify an order for some kinds of sets (such * as the attributes in an X.500 relative distinguished name) * to facilitate binary comparisons of encoded values. * * @param startLen guess about how large the set will be * (used to initialize an auto-growing data structure) * @return array of the values in the sequence */ public DerValue[] getSet(int startLen) throws IOException { if (buffer.read() != DerValue.tag_Set) throw new IOException("Set tag error"); return readVector(startLen); } /** * Return a set of encoded entities. ASN.1 sets are unordered, * though DER may specify an order for some kinds of sets (such * as the attributes in an X.500 relative distinguished name) * to facilitate binary comparisons of encoded values. * * @param startLen guess about how large the set will be * (used to initialize an auto-growing data structure) * @param implicit if true tag is assumed implicit. * @return array of the values in the sequence */ public DerValue[] getSet(int startLen, boolean implicit) throws IOException { int tag = buffer.read(); if (!implicit) { if (tag != DerValue.tag_Set) { throw new IOException("Set tag error"); } } return (readVector(startLen)); } /* * Read a "vector" of values ... set or sequence have the * same encoding, except for the initial tag, so both use * this same helper routine. */ protected DerValue[] readVector(int startLen) throws IOException { int len = getLength(buffer); DerInputStream newstr; if (len == 0) // return empty array instead of null, which should be // used only for missing optionals return new DerValue[0]; /* * Create a temporary stream from which to read the data, * unless it's not really needed. */ if (buffer.available() == len) newstr = this; else newstr = subStream(len, true); /* * Pull values out of the stream. */ Vector vec = new Vector(startLen); DerValue value; do { value = new DerValue(newstr.buffer); vec.addElement(value); } while (newstr.available() > 0); if (newstr.available() != 0) throw new IOException("extra data at end of vector"); /* * Now stick them into the array we're returning. */ int i, max = vec.size(); DerValue[] retval = new DerValue[max]; for (i = 0; i < max; i++) retval[i] = vec.elementAt(i); return retval; } /** * Get a single DER-encoded value from the input stream. * It can often be useful to pull a value from the stream * and defer parsing it. For example, you can pull a nested * sequence out with one call, and only examine its elements * later when you really need to. */ public DerValue getDerValue() throws IOException { return new DerValue(buffer); } public String getPrintableString() throws IOException { return (new DerValue(buffer)).getPrintableString(); } public String getT61String() throws IOException { return (new DerValue(buffer)).getT61String(); } public String getIA5String() throws IOException { return (new DerValue(buffer)).getIA5String(); } public String getBMPString() throws IOException { return (new DerValue(buffer)).getBMPString(); } public String getUniversalString() throws IOException { return (new DerValue(buffer)).getUniversalString(); } public String getDirectoryString() throws IOException { return (new DerValue(buffer)).getDirectoryString(); } /** * Get a UTC encoded time value from the input stream. */ public Date getUTCTime() throws IOException { if (buffer.read() != DerValue.tag_UtcTime) throw new IOException("DER input, UTCtime tag invalid "); if (buffer.available() < 11) throw new IOException("DER input, UTCtime short input"); int len = getLength(buffer); if (len < 11 || len > 17) throw new IOException("DER getUTCTime length error"); /* * UTC time encoded as ASCII chars, YYMMDDhhmmss. * If YY <= 50, we assume 20YY; * if YY > 50, we assume 19YY, as per IETF-PKIX part I. */ int year, month, day, hour, minute, second; year = 10 * Character.digit((char) buffer.read(), 10); year += Character.digit((char) buffer.read(), 10); if (year <= 50) // origin 2000 year += 2000; else year += 1900; // origin 1900 month = 10 * Character.digit((char) buffer.read(), 10); month += Character.digit((char) buffer.read(), 10); month -= 1; // months are 0-11 day = 10 * Character.digit((char) buffer.read(), 10); day += Character.digit((char) buffer.read(), 10); hour = 10 * Character.digit((char) buffer.read(), 10); hour += Character.digit((char) buffer.read(), 10); minute = 10 * Character.digit((char) buffer.read(), 10); minute += Character.digit((char) buffer.read(), 10); len -= 10; /** * We allow for non-encoded seconds, even though the * IETF-PKIX specification says that the seconds should * always be encoded even if it is zero. */ if (len == 3 || len == 7) { second = 10 * Character.digit((char) buffer.read(), 10); second += Character.digit((char) buffer.read(), 10); len -= 2; } else second = 0; if (month < 0 || day <= 0 || month > 11 || day > 31 || hour >= 24 || minute >= 60 || second >= 60) throw new IOException("Parse UTC time, invalid format"); Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); cal.set(year, month, day, hour, minute, second); cal.set(Calendar.MILLISECOND, 0); /* To clear millisecond field */ cal.set(Calendar.ERA, GregorianCalendar.AD); Date readDate = cal.getTime(); long utcTime = readDate.getTime(); /* * Finally, "Z" or "+hhmm" or "-hhmm" ... offsets change hhmm */ if (!(len == 1 || len == 5)) throw new IOException("Parse UTC time, invalid offset"); switch (buffer.read()) { case '+': { int Htmp = 10 * Character.digit((char) buffer.read(), 10); Htmp += Character.digit((char) buffer.read(), 10); int Mtmp = 10 * Character.digit((char) buffer.read(), 10); Mtmp += Character.digit((char) buffer.read(), 10); if (Htmp >= 24 || Mtmp >= 60) throw new IOException("Parse UTCtime, +hhmm"); utcTime += ((Htmp * 60) + Mtmp) * 60 * 1000L; } break; case '-': { int Htmp = 10 * Character.digit((char) buffer.read(), 10); Htmp += Character.digit((char) buffer.read(), 10); int Mtmp = 10 * Character.digit((char) buffer.read(), 10); Mtmp += Character.digit((char) buffer.read(), 10); if (Htmp >= 24 || Mtmp >= 60) throw new IOException("Parse UTCtime, -hhmm"); utcTime -= ((Htmp * 60) + Mtmp) * 60 * 1000L; } break; case 'Z': break; default: throw new IOException("Parse UTCtime, garbage offset"); } readDate.setTime(utcTime); return readDate; } /** * Get a Generalized encoded time value from the input stream. */ public Date getGeneralizedTime() throws IOException { if (buffer.read() != DerValue.tag_GeneralizedTime) throw new IOException("DER input, GeneralizedTime tag invalid "); if (buffer.available() < 13) throw new IOException("DER input, GeneralizedTime short input"); int len = getLength(buffer); /* * Generalized time encoded as ASCII chars, YYYYMMDDhhmm[ss] */ int year, month, day, hour, minute, second; year = 1000 * Character.digit((char) buffer.read(), 10); year += 100 * Character.digit((char) buffer.read(), 10); year += 10 * Character.digit((char) buffer.read(), 10); year += Character.digit((char) buffer.read(), 10); month = 10 * Character.digit((char) buffer.read(), 10); month += Character.digit((char) buffer.read(), 10); month -= 1; // Calendar months are 0-11 day = 10 * Character.digit((char) buffer.read(), 10); day += Character.digit((char) buffer.read(), 10); hour = 10 * Character.digit((char) buffer.read(), 10); hour += Character.digit((char) buffer.read(), 10); minute = 10 * Character.digit((char) buffer.read(), 10); minute += Character.digit((char) buffer.read(), 10); len -= 12; /** * We allow for non-encoded seconds, even though the * IETF-PKIX specification says that the seconds should * always be encoded even if it is zero. */ if (len == 3 || len == 7) { second = 10 * Character.digit((char) buffer.read(), 10); second += Character.digit((char) buffer.read(), 10); len -= 2; } else second = 0; if (month < 0 || day <= 0 || month > 11 || day > 31 || hour >= 24 || minute >= 60 || second >= 60) throw new IOException("Parse Generalized time, invalid format"); /* Shouldn't this construct a Gregorian calendar directly??? * We don't really want locale dependant processing here */ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); cal.set(year, month, day, hour, minute, second); cal.set(Calendar.MILLISECOND, 0); /* To clear millisecond field */ cal.set(Calendar.ERA, GregorianCalendar.AD); Date readDate = cal.getTime(); long utcTime = readDate.getTime(); /* * Finally, "Z" or "+hhmm" or "-hhmm" ... offsets change hhmm */ if (!(len == 1 || len == 5)) throw new IOException("Parse Generalized time, invalid offset"); switch (buffer.read()) { case '+': { int Htmp = 10 * Character.digit((char) buffer.read(), 10); Htmp += Character.digit((char) buffer.read(), 10); int Mtmp = 10 * Character.digit((char) buffer.read(), 10); Mtmp += Character.digit((char) buffer.read(), 10); if (Htmp >= 24 || Mtmp >= 60) throw new IOException("Parse GeneralizedTime, +hhmm"); utcTime += ((Htmp * 60) + Mtmp) * 60 * 1000L; } break; case '-': { int Htmp = 10 * Character.digit((char) buffer.read(), 10); Htmp += Character.digit((char) buffer.read(), 10); int Mtmp = 10 * Character.digit((char) buffer.read(), 10); Mtmp += Character.digit((char) buffer.read(), 10); if (Htmp >= 24 || Mtmp >= 60) throw new IOException("Parse GeneralizedTime, -hhmm"); utcTime -= ((Htmp * 60) + Mtmp) * 60 * 1000L; } break; case 'Z': break; default: throw new IOException("Parse GeneralizedTime, garbage offset"); } readDate.setTime(utcTime); return readDate; } /* * Get a byte from the input stream. */ // package private int getByte() throws IOException { return (0x00ff & buffer.read()); } public int peekByte() throws IOException { return buffer.peek(); } // package private int getLength() throws IOException { return getLength(buffer); } /* * Get a length from the input stream, allowing for at most 32 bits of * encoding to be used. (Not the same as getting a tagged integer!) */ static int getLength(InputStream in) throws IOException { int value, tmp; tmp = in.read(); if ((tmp & 0x080) == 0x00) { // 1 byte datum? value = tmp; } else { // no, more ... tmp &= 0x07f; /* * NOTE: tmp == 0 indicates BER encoded data. * tmp > 4 indicates more than 4Gb of data. */ if (tmp <= 0 || tmp > 4) throw new IOException("DerInput.getLength(): lengthTag=" + tmp + ", " + ((tmp == 0) ? "Indefinite length encoding not supported" + " or incorrect DER encoding." : "too big.")); for (value = 0; tmp > 0; tmp--) { value <<= 8; value += 0x0ff & in.read(); } } return value; } /** * Mark the current position in the buffer, so that * a later call to reset will return here. */ public void mark(int value) { buffer.mark(value); } /** * Return to the position of the last mark call. A mark is implicitly set at the beginning of * the stream when it is created. */ public void reset() { buffer.reset(); } /** * Returns the number of bytes available for reading. * This is most useful for testing whether the stream is * empty. */ public int available() { return buffer.available(); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/DerOutputStream.java000066400000000000000000000543441362106420000257640ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetEncoder; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; import java.util.Comparator; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; /** * Output stream marshaling DER-encoded data. This is eventually provided * in the form of a byte array; there is no advance limit on the size of * that byte array. * *

* At this time, this class supports only a subset of the types of DER data encodings which are defined. That subset is * sufficient for generating most X.509 certificates. * * @version 1.32 * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra */ public class DerOutputStream extends ByteArrayOutputStream implements DerEncoder { /** * Construct an DER output stream. * * @param size how large a buffer to preallocate. */ public DerOutputStream(int size) { super(size); } /** * Construct an DER output stream. */ public DerOutputStream() { } /** * Writes tagged, pre-marshaled data. This calcuates and encodes * the length, so that the output data is the standard triple of * { tag, length, data } used by all DER values. * * @param tag the DER value tag for the data, such as DerValue.tag_Sequence * @param buf buffered data, which must be DER-encoded */ public void write(byte tag, byte[] buf) throws IOException { write(tag); putLength(buf.length); write(buf, 0, buf.length); } /** * Writes tagged data using buffer-to-buffer copy. As above, * this writes a standard DER record. This is often used when * efficiently encapsulating values in sequences. * * @param tag the DER value tag for the data, such as DerValue.tag_Sequence * @param out buffered data */ public void write(byte tag, DerOutputStream out) throws IOException { write(tag); putLength(out.count); write(out.buf, 0, out.count); } /** * Writes implicitly tagged data using buffer-to-buffer copy. As above, * this writes a standard DER record. This is often used when * efficiently encapsulating implicitly tagged values. * * @param tag the DER value of the context-specific tag that replaces * original tag of the value in the output , such as in *

     *  {@literal } [N] IMPLICIT {@literal }
     * 
* * For example, FooLength [1] IMPLICIT INTEGER, with value=4; * would be encoded as "81 01 04" whereas in explicit * tagging it would be encoded as "A1 03 02 01 04". * Notice that the tag is A1 and not 81, this is because with * explicit tagging the form is always constructed. * @param value original value being implicitly tagged */ public void writeImplicit(byte tag, DerOutputStream value) throws IOException { write(tag); write(value.buf, 1, value.count - 1); } /** * Marshals pre-encoded DER value onto the output stream. */ public void putDerValue(DerValue val) throws IOException { val.encode(this); } /* * PRIMITIVES -- these are "universal" ASN.1 simple types. * * BOOLEAN, INTEGER, BIT STRING, OCTET STRING, NULL * OBJECT IDENTIFIER, SEQUENCE(OF), SET(OF) * PrintableString, T61String, IA5String, UTCTime */ /** * Marshals a DER boolean on the output stream. */ public void putBoolean(boolean val) throws IOException { write(DerValue.tag_Boolean); putLength(1); if (val) { write(0xff); } else { write(0); } } /** * Marshals a DER unsigned integer on the output stream. */ public void putInteger(BigInt i) throws IOException { putUnsignedInteger(i.toByteArray()); } /** * Marshals a DER unsigned integer on the output stream. */ public void putUnsignedInteger(byte[] integerBytes) throws IOException { write(DerValue.tag_Integer); if ((integerBytes[0] & 0x080) != 0) { /* * prepend zero so it's not read as a negative number */ putLength(integerBytes.length + 1); write(0); } else putLength(integerBytes.length); write(integerBytes, 0, integerBytes.length); } /** * Marshals a DER enumerated value on the output stream. */ public void putEnumerated(int i) throws IOException { write(DerValue.tag_Enumerated); int bytemask = 0xff000000; int signmask = 0x80000000; int length; if ((i & 0x80000000) != 0) { // negative case for (length = 4; length > 1; --length) { if ((i & bytemask) != bytemask) break; bytemask = bytemask >>> 8; signmask = signmask >>> 8; } if ((i & signmask) == 0) { // ensure negative case putLength(length + 1); write(0xff); } else { putLength(length); } // unrolled loop switch (length) { case 4: write((byte) (i >>> 24)); case 3: write((byte) (i >>> 16)); case 2: write((byte) (i >>> 8)); case 1: write((byte) i); } } else { // positive case for (length = 4; length > 1; --length) { if ((i & bytemask) != 0) break; bytemask = bytemask >>> 8; signmask = signmask >>> 8; } if ((i & signmask) != 0) { // ensure posititive case putLength(length + 1); write(0x00); } else { putLength(length); } // unrolled loop switch (length) { case 4: write((byte) (i >>> 24)); case 3: write((byte) (i >>> 16)); case 2: write((byte) (i >>> 8)); case 1: write((byte) i); } } } /** * Marshals a DER bit string on the output stream. The bit * string must be byte-aligned. * * @param bits the bit string, MSB first */ public void putBitString(byte[] bits) throws IOException { write(DerValue.tag_BitString); putLength(bits.length + 1); write(0); // all of last octet is used write(bits); } /** * Converts a boolean array to a BitArray. Trims trailing 0 bits * in accordance with DER encoding standard. We assume the input is not * null. */ private static BitArray toBitArray(boolean[] bitString) { if (bitString.length == 0) { return new BitArray(bitString); } // find index of last 1 bit. -1 if there aren't any int i; for (i = bitString.length - 1; i >= 0; i--) { if (bitString[i]) { break; } } int length = i + 1; // if length changed, copy to new appropriately-sized array if (length != bitString.length) { boolean[] newBitString = new boolean[length]; System.arraycopy(bitString, 0, newBitString, 0, length); bitString = newBitString; } return new BitArray(bitString); } /** * Converts bit string to a BitArray, stripping off trailing 0 bits. * We assume that the bit string is not null. */ private static BitArray toBitArray(byte[] bitString) { // compute length in bits of bit string int length, i; int maxIndex = 0; if (bitString.length == 0) { return new BitArray(0, bitString); } // find the index of the last byte with a 1 bit for (i = 0; i < bitString.length; i++) { if (bitString[i] != 0) { maxIndex = i; } } byte lastByte = bitString[maxIndex]; length = (maxIndex + 1) * 8; // maximum, might reduce in next step // now find the last 1 bit in this last byte for (i = 1; i <= 0x80; i <<= 1) { if ((lastByte & i) == 0) { length--; } else { break; } } return new BitArray(length, bitString); } /** * Marshals a DER bit string on the output stream. * The bit strings need not be byte-aligned. * * @param ba the bit string, MSB first */ public void putUnalignedBitString(BitArray ba) throws IOException { byte[] bits = ba.toByteArray(); write(DerValue.tag_BitString); putLength(bits.length + 1); write(bits.length * 8 - ba.length()); // excess bits in last octet write(bits); } /** * Marshals a DER bit string on the output stream. * All trailing 0 bits will be stripped off in accordance with DER * encoding. * * @param bitString the bit string, MSB first */ public void putUnalignedBitString(byte[] bitString) throws IOException { putUnalignedBitString(toBitArray(bitString)); } /** * Marshals a DER bit string on the output stream. * All trailing 0 bits will be stripped off in accordance with DER * encoding. * * @param bitString the bit string as an array of booleans. */ public void putUnalignedBitString(boolean[] bitString) throws IOException { putUnalignedBitString(toBitArray(bitString)); } /** * DER-encodes an ASN.1 OCTET STRING value on the output stream. * * @param octets the octet string */ public void putOctetString(byte[] octets) throws IOException { write(DerValue.tag_OctetString, octets); } /** * Marshals a DER "null" value on the output stream. These are * often used to indicate optional values which have been omitted. */ public void putNull() throws IOException { write(DerValue.tag_Null); putLength(0); } /** * Marshals an object identifier (OID) on the output stream. * Corresponds to the ASN.1 "OBJECT IDENTIFIER" construct. */ public void putOID(ObjectIdentifier oid) throws IOException { oid.encode(this); } /** * Marshals a sequence on the output stream. This supports both * the ASN.1 "SEQUENCE" (zero to N values) and "SEQUENCE OF" * (one to N values) constructs. */ public void putSequence(DerValue[] seq) throws IOException { DerOutputStream bytes = new DerOutputStream(); int i; for (i = 0; i < seq.length; i++) seq[i].encode(bytes); write(DerValue.tag_Sequence, bytes); } /** * Marshals the contents of a set on the output stream without * ordering the elements. Ok for BER encoding, but not for DER * encoding. * * For DER encoding, use orderedPutSet() or orderedPutSetOf(). */ public void putSet(DerValue[] set) throws IOException { DerOutputStream bytes = new DerOutputStream(); int i; for (i = 0; i < set.length; i++) set[i].encode(bytes); write(DerValue.tag_Set, bytes); } /** * NSCP : * Like putOrderSetOf, except not sorted. * This may defy DER encoding but is needed for compatibility * with communicator. */ public void putSet(byte tag, DerEncoder[] set) throws IOException { putOrderedSet(tag, set, null); } /** * Marshals the contents of a set on the output stream. Sets * are semantically unordered, but DER requires that encodings of * set elements be sorted into ascending lexicographical order * before being output. Hence sets with the same tags and * elements have the same DER encoding. * * This method supports the ASN.1 "SET OF" construct, but not * "SET", which uses a different order. */ public void putOrderedSetOf(byte tag, DerEncoder[] set) throws IOException { putOrderedSet(tag, set, lexOrder); } /** * Marshals the contents of a set on the output stream. Sets * are semantically unordered, but DER requires that encodings of * set elements be sorted into ascending tag order * before being output. Hence sets with the same tags and * elements have the same DER encoding. * * This method supports the ASN.1 "SET" construct, but not * "SET OF", which uses a different order. */ public void putOrderedSet(byte tag, DerEncoder[] set) throws IOException { putOrderedSet(tag, set, tagOrder); } /** * Lexicographical order comparison on byte arrays, for ordering * elements of a SET OF objects in DER encoding. */ private static ByteArrayLexOrder lexOrder = new ByteArrayLexOrder(); /** * Tag order comparison on byte arrays, for ordering elements of * SET objects in DER encoding. */ private static ByteArrayTagOrder tagOrder = new ByteArrayTagOrder(); /** * Marshals a the contents of a set on the output stream with the * encodings of its sorted in increasing order. * * @param order the order to use when sorting encodings of components. */ private void putOrderedSet(byte tag, DerEncoder[] set, Comparator order) throws IOException { DerOutputStream[] streams = new DerOutputStream[set.length]; for (int i = 0; i < set.length; i++) { streams[i] = new DerOutputStream(); set[i].derEncode(streams[i]); } // order the element encodings byte[][] bufs = new byte[streams.length][]; for (int i = 0; i < streams.length; i++) { bufs[i] = streams[i].toByteArray(); } if (order != null) { Arrays.sort(bufs, order); } DerOutputStream bytes = new DerOutputStream(); for (int i = 0; i < streams.length; i++) { bytes.write(bufs[i]); } write(tag, bytes); } /** * Converts string to printable and writes to der output stream. */ public void putPrintableString(String s) throws IOException { putStringType(DerValue.tag_PrintableString, s); } public void putVisibleString(String s) throws IOException { putStringType(DerValue.tag_VisibleString, s); } /** * Marshals a string which is consists of BMP (unicode) characters */ public void putBMPString(String s) throws IOException { putStringType(DerValue.tag_BMPString, s); } public void putGeneralString(String s) throws IOException { putStringType(DerValue.tag_GeneralString, s); } // /* // * T61 is an 8 bit extension to ASCII, escapes e.g. to Japanese // */ // void putT61String(String s) throws IOException // { // // XXX IMPLEMENT ME // // throw new IOException("DerOutputStream.putT61String() NYI"); // } // /* // * Universal String. // */ // void putUniversalString(String s) throws IOException // { // // XXX IMPLEMENT ME // // throw new IOException("DerOutputStream.putUniversalString() NYI"); // } /** * Marshals a string which is consists of IA5(ASCII) characters */ public void putIA5String(String s) throws IOException { putStringType(DerValue.tag_IA5String, s); } public void putUTF8String(String s) throws IOException { putStringType(DerValue.tag_UTF8String, s); } public void putStringType(byte tag, String s) throws IOException { try { CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(tag); if (encoder == null) throw new IOException("No encoder for tag"); CharBuffer charBuffer = CharBuffer.wrap(s.toCharArray()); ByteBuffer byteBuffer = encoder.encode(charBuffer); write(tag); putLength(byteBuffer.limit()); write(byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit()); } catch (CharacterCodingException e) { throw new IOException("Not a valid string type " + tag, e); } } private void put2DateBytes(byte[] buffer, int value, int offset) { int upper = value / 10; int lower = value % 10; buffer[offset] = (byte) ((byte) upper + (byte) '0'); buffer[offset + 1] = (byte) ((byte) lower + (byte) '0'); } private static Calendar GMTGregorianCalendar = null; private Calendar getGMTGregorianCalendar() { if (GMTGregorianCalendar == null) { TimeZone tz = TimeZone.getTimeZone("GMT"); GMTGregorianCalendar = new GregorianCalendar(tz); } return (Calendar) GMTGregorianCalendar.clone(); } public byte[] getDateBytes(Date d, boolean UTC) { byte[] datebytes; if (UTC) { datebytes = new byte[13]; } else { // generalized time has 4 digits for yr datebytes = new byte[15]; } Calendar cal = getGMTGregorianCalendar(); cal.setTime(d); int i = 0; if (!UTC) { put2DateBytes(datebytes, cal.get(Calendar.YEAR) / 100, i); i += 2; } put2DateBytes(datebytes, cal.get(Calendar.YEAR) % 100, i); // Calendar's MONTH is zero-based i += 2; put2DateBytes(datebytes, cal.get(Calendar.MONTH) + 1, i); i += 2; put2DateBytes(datebytes, cal.get(Calendar.DAY_OF_MONTH), i); i += 2; put2DateBytes(datebytes, cal.get(Calendar.HOUR_OF_DAY), i); i += 2; put2DateBytes(datebytes, cal.get(Calendar.MINUTE), i); i += 2; put2DateBytes(datebytes, cal.get(Calendar.SECOND), i); i += 2; // datebytes[i] = 'Z'; datebytes[i] = (byte) 'Z'; return datebytes; } /** * Marshals a DER UTC time/date value. * *

* YYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time and with seconds (even if seconds=0) as per IETF-PKIX * partI. */ public void putUTCTime(Date d) throws IOException { /* * Format the date. */ // This was the old code. Way too slow to be usable (stevep) // String pattern = "yyMMddHHmmss'Z'"; // SimpleDateFormat sdf = new SimpleDateFormat(pattern); // TimeZone tz = TimeZone.getTimeZone("GMT"); // sdf.setTimeZone(tz); // byte[] utc = (sdf.format(d)).getBytes(); byte[] datebytes = getDateBytes(d, true); // UTC = true /* * Write the formatted date. */ write(DerValue.tag_UtcTime); putLength(datebytes.length); write(datebytes); } /** * Marshals a DER Generalized Time/date value. * *

* YYYYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time and with seconds (even if seconds=0) as per * IETF-PKIX partI. */ public void putGeneralizedTime(Date d) throws IOException { /* * Format the date. */ TimeZone tz = TimeZone.getTimeZone("GMT"); // This is way too slow to be usable (stevep) String pattern = "yyyyMMddHHmmss'Z'"; SimpleDateFormat sdf = new SimpleDateFormat(pattern); sdf.setTimeZone(tz); byte[] gt = (sdf.format(d)).getBytes(); /* * Write the formatted date. */ write(DerValue.tag_GeneralizedTime); putLength(gt.length); write(gt); } /** * Put the encoding of the length in the stream. * * @param len the length of the attribute. * @exception IOException on writing errors. */ public void putLength(int len) throws IOException { if (len < 128) { write((byte) len); } else if (len < (1 << 8)) { write((byte) 0x081); write((byte) len); } else if (len < (1 << 16)) { write((byte) 0x082); write((byte) (len >> 8)); write((byte) len); } else if (len < (1 << 24)) { write((byte) 0x083); write((byte) (len >> 16)); write((byte) (len >> 8)); write((byte) len); } else { write((byte) 0x084); write((byte) (len >> 24)); write((byte) (len >> 16)); write((byte) (len >> 8)); write((byte) len); } } /** * Put the tag of the attribute in the stream. * * @param tagClass the tag class type, one of UNIVERSAL, CONTEXT, * APPLICATION or PRIVATE * @param form if true, the value is constructed, otherwise it is * primitive. * @param val the tag value */ public void putTag(byte tagClass, boolean form, byte val) { byte tag = (byte) (tagClass | val); if (form) { tag |= (byte) 0x20; } write(tag); } /** * Write the current contents of this DerOutputStream to an OutputStream. * * @exception IOException on output error. */ public void derEncode(OutputStream out) throws IOException { out.write(toByteArray()); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/DerValue.java000066400000000000000000000567401362106420000243660ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetDecoder; import java.util.Arrays; import org.mozilla.jss.netscape.security.x509.AVAValueConverter; import org.mozilla.jss.netscape.security.x509.GenericValueConverter; /** * Represents a single DER-encoded value. DER encoding rules are a subset * of the "Basic" Encoding Rules (BER), but they only support a single way * ("Definite" encoding) to encode any given value. * *

* All DER-encoded data are triples {type, length, data}. This class represents such tagged values as they have * been read (or constructed), and provides structured access to the encoded data. * *

* At this time, this class supports only a subset of the types of DER data encodings which are defined. That subset is * sufficient for parsing most X.509 certificates, and working with selected additional formats (such as PKCS #10 * certificate requests, and some kinds of PKCS #7 data). * * @version 1.43 * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra */ public class DerValue { /** The tag class types */ public static final byte TAG_UNIVERSAL = (byte) 0x000; public static final byte TAG_APPLICATION = (byte) 0x040; public static final byte TAG_CONTEXT = (byte) 0x080; public static final byte TAG_PRIVATE = (byte) 0x0c0; /** The DER tag of the value; one of the tag_ constants. */ public byte tag; protected DerInputBuffer buffer; /** * The DER-encoded data of the value. */ public DerInputStream data; private int length; /* * The type starts at the first byte of the encoding, and * is one of these tag_* values. That may be all the type * data that is needed. */ /* * These tags are the "universal" tags ... they mean the same * in all contexts. (Mask with 0x1f -- five bits.) */ /** Tag value indicating an ASN.1 "BOOLEAN" value. */ public final static byte tag_Boolean = 0x01; /** Tag value indicating an ASN.1 "INTEGER" value. */ public final static byte tag_Integer = 0x02; /** Tag value indicating an ASN.1 "BIT STRING" value. */ public final static byte tag_BitString = 0x03; /** Tag value indicating an ASN.1 "OCTET STRING" value. */ public final static byte tag_OctetString = 0x04; /** Tag value indicating an ASN.1 "NULL" value. */ public final static byte tag_Null = 0x05; /** Tag value indicating an ASN.1 "OBJECT IDENTIFIER" value. */ public final static byte tag_ObjectId = 0x06; /** Tag value including an ASN.1 "ENUMERATED" value */ public final static byte tag_Enumerated = 0x0A; /** Tag value including a "printable" string */ public final static byte tag_PrintableString = 0x13; public final static byte tag_VisibleString = 0x1A; /** Tag value including a "teletype" string */ public final static byte tag_T61String = 0x14; /** Tag value including an ASCII string */ public final static byte tag_IA5String = 0x16; /** Tag value indicating an ASN.1 "UTCTime" value. */ public final static byte tag_UtcTime = 0x17; /** Tag value indicating an ASN.1 "GeneralizedTime" value. */ public final static byte tag_GeneralizedTime = 0x18; /** Tag value indicating an ASN.1 "GeneralString" value. */ public final static byte tag_GeneralString = 0x1B; /** Tag value indicating an ASN.1 "BMPString" value. */ public final static byte tag_BMPString = 0x1E; /** Tag value indicating an ASN.1 "UniversalString" value. */ public final static byte tag_UniversalString = 0x1C; /** Tag value indicating an ASN.1 "UTF8String" value. (since 1998) */ public final static byte tag_UTF8String = 0x0C; public final static byte[] tags_DirectoryString = { tag_T61String , tag_PrintableString , tag_UniversalString , tag_UTF8String , tag_BMPString }; // CONSTRUCTED seq/set /** * Tag value indicating an ASN.1 * "SEQUENCE" (zero to N elements, order is significant). */ public final static byte tag_Sequence = 0x30; /** * Tag value indicating an ASN.1 * "SEQUENCE OF" (one to N elements, order is significant). */ public final static byte tag_SequenceOf = 0x30; /** * Tag value indicating an ASN.1 * "SET" (zero to N members, order does not matter). */ public final static byte tag_Set = 0x31; /** * Tag value indicating an ASN.1 * "SET OF" (one to N members, order does not matter). */ public final static byte tag_SetOf = 0x31; /* * These values are the high order bits for the other kinds of tags. */ boolean isUniversal() { return ((tag & 0x0c0) == 0x000); } boolean isApplication() { return ((tag & 0x0c0) == 0x040); } /** * Returns true iff the CONTEXT SPECIFIC bit is set in the type tag. * This is associated with the ASN.1 "DEFINED BY" syntax. */ public boolean isContextSpecific() { return ((tag & 0x0c0) == 0x080); } /** * Returns true iff the CONTEXT SPECIFIC TAG matches the passed tag. */ public boolean isContextSpecific(byte cntxtTag) { if (!isContextSpecific()) { return false; } return ((tag & 0x01f) == cntxtTag); } boolean isPrivate() { return ((tag & 0x0c0) == 0x0c0); } /** Returns true iff the CONSTRUCTED bit is set in the type tag. */ public boolean isConstructed() { return ((tag & 0x020) == 0x020); } /** * Creates a DER value from a string * using a generic way of determining the proper tag for the string. * Assumes the string is a Generic attribute value and uses * the converter for generic string values to convert to the Der Value. */ public DerValue(String value) throws IOException { AVAValueConverter genericValue = new GenericValueConverter(); DerValue val; val = genericValue.getValue(value); tag = val.tag; buffer = val.buffer; length = val.length; data = val.data; data.mark(Integer.MAX_VALUE); } /** * Creates a DerValue from a tag and some DER-encoded data. * * @param tag the DER type tag * @param data the DER-encoded data */ public DerValue(byte tag, byte[] data) { this.tag = tag; buffer = new DerInputBuffer(data.clone()); length = data.length; this.data = new DerInputStream(buffer); this.data.mark(Integer.MAX_VALUE); } /** * Creates a DerValue from a tag and some DER-encoded data. * * @param tag the DER type tag * @param data the DER-encoded data * @param offset offset of the data * @param length length of the data */ public DerValue(byte tag, byte[] data, int offset, int length) { this(tag, Arrays.copyOfRange(data, offset, offset + length)); } /* * package private */ DerValue(DerInputBuffer in) throws IOException { // NOTE: This must handle the special value used // to terminate BER indefinite encodings (tag and // length are both zero) // XXX must also parse BER-encoded constructed // values such as sequences, sets... tag = (byte) in.read(); length = DerInputStream.getLength(in); buffer = in.dup(); buffer.truncate(length); data = new DerInputStream(buffer); in.skip(length); } /** * Get an ASN.1/DER encoded datum from a buffer. The * entire buffer must hold exactly one datum, including * its tag and length. * * @param buf buffer holding a single DER-encoded datum. */ public DerValue(byte[] buf) throws IOException { init(true, new ByteArrayInputStream(buf)); } /** * Get an ASN.1/DER encoded datum from part of a buffer. * That part of the buffer must hold exactly one datum, including * its tag and length. * * @param buf the buffer * @param offset start point of the single DER-encoded dataum * @param len how many bytes are in the encoded datum */ public DerValue(byte[] buf, int offset, int len) throws IOException { init(true, new ByteArrayInputStream(buf, offset, len)); } /** * Get an ASN1/DER encoded datum from an input stream. The * stream may have additional data following the encoded datum. * * @param in the input stream holding a single DER datum, * which may be followed by additional data */ public DerValue(InputStream in) throws IOException { init(false, in); } /* * helper routine */ private void init(boolean fullyBuffered, InputStream in) throws IOException { byte[] bytes; tag = (byte) in.read(); length = DerInputStream.getLength(in); if (fullyBuffered && in.available() != length) throw new IOException("extra DER value data (constructor)"); bytes = new byte[length]; // n.b. readFully not needed in normal fullyBuffered case DataInputStream dis = new DataInputStream(in); dis.readFully(bytes); buffer = new DerInputBuffer(bytes); data = new DerInputStream(buffer); } /** * Encode an ASN1/DER encoded datum onto a DER output stream. */ public void encode(DerOutputStream out) throws IOException { out.write(tag); out.putLength(length); buffer.dump(out, length); } /** * Returns an ASN.1 BOOLEAN * * @return the boolean held in this DER value */ public boolean getBoolean() throws IOException { if (tag != tag_Boolean) { throw new IOException("DerValue.getBoolean, not a BOOLEAN " + tag); } if (length != 1) { throw new IOException("DerValue.getBoolean, invalid length " + length); } if (buffer.read() != 0) { return true; } return false; } /** * Returns an ASN.1 OBJECT IDENTIFIER. * * @return the OID held in this DER value */ public ObjectIdentifier getOID() throws IOException { if (tag != tag_ObjectId) throw new IOException("DerValue.getOID, not an OID " + tag); return new ObjectIdentifier(buffer); } /** * Returns an ASN.1 OCTET STRING * * @return the octet string held in this DER value */ public byte[] getOctetString() throws IOException { if (tag != tag_OctetString) throw new IOException( "DerValue.getOctetString, not an Octet String: " + tag); byte[] bytes = new byte[length]; int n = buffer.read(bytes); if (n != length && !(n == -1 && length == 0)) { /* We read less (or more, somehow?) than expected. * * The second condition handles a corner case: when * ByteArrayInputStream has no more data, read returns -1, even if * are asking to read 0 bytes. This seems to violate the contract * of the superclass InputStream.read() which says that if the * requested read length is 0, the return value is 0. So we have * to treat a return value of (-1) as acceptable iff the length is * zero. */ throw new IOException( "getOctetString: short read on DerValue buffer: " + "expected to read " + length + " bytes; " + "actually read " + n + " bytes."); } return bytes; } /** * Returns an ASN.1 unsigned integer value of enumerated value. * * @return the (unsigned) integer held in this DER value */ public int getEnumerated() throws IOException { if (tag != tag_Enumerated) throw new IOException("DerValue.getEnumerated, not an ENUMERATED " + tag); if (length == 0) return 0; if (length > 4 || length < 1) throw new IOException("DerValue.getEnumerated, invalid length " + length + "(must be between 1 and 4)"); int value = 0; int nextbyte = buffer.read(); if (nextbyte == -1) throw new IOException("short read on DerValue buffer"); // perform sign extension value = (byte) nextbyte; for (int i = length - 1; i > 0; --i) { nextbyte = buffer.read(); if (nextbyte == -1) throw new IOException("short read on DerValue buffer"); value = 256 * value + nextbyte; } return value; } /** * Returns an ASN.1 unsigned INTEGER value. * * @return the (unsigned) integer held in this DER value */ public BigInt getInteger() throws IOException { if (tag != tag_Integer) throw new IOException("DerValue.getInteger, not an int " + tag); return buffer.getUnsigned(data.available()); } /** * Returns an ASN.1 unsigned INTEGER value, the parameter determining * if the tag is implicit. * * @param tagImplicit if true, ignores the tag value as it is * assumed implicit. * @return the (unsigned) integer held in this DER value */ public BigInt getInteger(boolean tagImplicit) throws IOException { if (!tagImplicit) { if (tag != tag_Integer) { throw new IOException("DerValue.getInteger, not an int " + tag); } } return buffer.getUnsigned(data.available()); } /** * Returns an ASN.1 BIT STRING value. The bit string must be byte-aligned. * * @return the bit string held in this value */ public byte[] getBitString() throws IOException { if (tag != tag_BitString) throw new IOException( "DerValue.getBitString, not a bit string " + tag); return buffer.getBitString(); } /** * Returns an ASN.1 BIT STRING value that need not be byte-aligned. * * @return a BitArray representing the bit string held in this value */ public BitArray getUnalignedBitString() throws IOException { if (tag != tag_BitString) throw new IOException( "DerValue.getBitString, not a bit string " + tag); return buffer.getUnalignedBitString(); } /** * Returns the name component as a Java string, regardless of its * encoding restrictions (ASCII, T61, Printable, etc). */ public String getAsString() throws IOException { AVAValueConverter genericValue = new GenericValueConverter(); return genericValue.getAsString(this); } /** * Returns an ASN.1 BIT STRING value, with the tag assumed implicit * based on the parameter. The bit string must be byte-aligned. * * @param tagImplicit if true, the tag is assumed implicit. * @return the bit string held in this value */ public byte[] getBitString(boolean tagImplicit) throws IOException { if (!tagImplicit) { if (tag != tag_BitString) throw new IOException("DerValue.getBitString, not a bit string " + tag); } return buffer.getBitString(); } /** * Returns an ASN.1 BIT STRING value, with the tag assumed implicit * based on the parameter. The bit string need not be byte-aligned. * * @param tagImplicit if true, the tag is assumed implicit. * @return the bit string held in this value */ public BitArray getUnalignedBitString(boolean tagImplicit) throws IOException { if (!tagImplicit) { if (tag != tag_BitString) throw new IOException("DerValue.getBitString, not a bit string " + tag); } return buffer.getUnalignedBitString(); } /** * Returns an ASN.1 STRING value * * @return the printable string held in this value */ public String getPrintableString() throws IOException { if (tag != tag_PrintableString) throw new IOException( "DerValue.getPrintableString, not a string " + tag); return getASN1CharString(); } public String getDirectoryString() throws IOException { boolean tagValid = false; for (int i = 0; i < tags_DirectoryString.length; i++) { if (tag == tags_DirectoryString[i]) { tagValid = true; break; } } if (!tagValid) throw new IOException( "DerValue.getDirectoryString: invalid tag: " + tag); return getASN1CharString(); } /* * @eturns a string if the DerValue is a ASN.1 character string type and * if there is a decoder for the type. Returns null otherwise. */ public String getASN1CharString() throws IOException { try { CharsetDecoder decoder = ASN1CharStrConvMap.getDefault().getDecoder(tag); if (decoder == null) return null; ByteBuffer byteBuffer = ByteBuffer.allocate(length); data.reset(); data.getBytes(byteBuffer.array()); CharBuffer charBuffer = decoder.decode(byteBuffer); return charBuffer.toString(); } catch (CharacterCodingException e) { throw new IOException("Misformed DER value", e); } } /** * Returns an ASN.1 T61 (Teletype) STRING value * * @return the teletype string held in this value */ public String getT61String() throws IOException { if (tag != tag_T61String) throw new IOException( "DerValue.getT61String, not T61 " + tag); return getASN1CharString(); } /** * Returns an ASN.1 IA5 (ASCII) STRING value * * @return the ASCII string held in this value */ public String getIA5String() throws IOException { if (tag != tag_IA5String) throw new IOException( "DerValue.getIA5String, not IA5 " + tag); return getASN1CharString(); } public String getBMPString() throws IOException { if (tag != tag_BMPString) throw new IOException( "DerValue.getBMPString, not BMP " + tag); return getASN1CharString(); } public String getUniversalString() throws IOException { if (tag != tag_UniversalString) throw new IOException( "DerValue.getUniversalString, not UniversalString " + tag); return getASN1CharString(); } public String getUTF8String() throws IOException { if (tag != tag_UTF8String) throw new IOException( "DerValue.getUTF8String, not UTF8String " + tag); return getASN1CharString(); } /** * Returns true iff the other object is a DER value which * is bitwise equal to this one. * * @param other the object being compared with this one */ public boolean equals(Object other) { if (other instanceof DerValue) return equals((DerValue) other); else return false; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((buffer == null) ? 0 : buffer.hashCode()); result = prime * result + ((data == null) ? 0 : data.hashCode()); result = prime * result + length; result = prime * result + tag; return result; } /** * Bitwise equality comparison. DER encoded values have a single * encoding, so that bitwise equality of the encoded values is an * efficient way to establish equivalence of the unencoded values. * * @param other the object being compared with this one */ public boolean equals(DerValue other) { data.reset(); other.data.reset(); if (this == other) return true; else if (tag != other.tag) { return false; } else { return buffer.equals(other.buffer); } } /** * Returns a printable representation of the value. * * @return printable representation of the value */ public String toString() { try { String s = getAsString(); if (s != null) return s; if (tag == tag_Null) return "[DerValue, null]"; if (tag == tag_ObjectId) return "OID." + getOID(); // integers else return "[DerValue, tag = " + tag + ", length = " + length + "]"; } catch (IOException e) { throw new IllegalArgumentException("misformatted DER value"); } } /** * Returns a DER-encoded value, such that if it's passed to the * DerValue constructor, a value equivalent to "this" is returned. * * @return DER-encoded value, including tag and length. */ public byte[] toByteArray() throws IOException { DerOutputStream out = new DerOutputStream(); encode(out); data.reset(); return out.toByteArray(); } /** * For "set" and "sequence" types, this function may be used * to return a DER stream of the members of the set or sequence. * This operation is not supported for primitive types such as * integers or bit strings. */ public DerInputStream toDerInputStream() throws IOException { if (tag == tag_Sequence || tag == tag_Set) return new DerInputStream(buffer); throw new IOException("toDerInputStream rejects tag type " + tag); } /** * Get the length of the encoded value. */ public int length() { return length; } /** * Create the tag of the attribute. * * @param tagClass the tag class type, one of UNIVERSAL, CONTEXT, * APPLICATION or PRIVATE * @param form if true, the value is constructed, otherwise it * is primitive. * @param val the tag value */ public static byte createTag(byte tagClass, boolean form, byte val) { byte tag = (byte) (tagClass | val); if (form) { tag |= (byte) 0x20; } return (tag); } /** * Set the tag of the attribute. Commonly used to reset the * tag value used for IMPLICIT encodings. * * @param tag the tag value */ public void resetTag(byte tag) { this.tag = tag; } } jss-4.6.3/org/mozilla/jss/netscape/security/util/ExtPrettyPrint.java000066400000000000000000002112711362106420000256340ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CertificateException; import java.text.DateFormat; import java.util.Enumeration; import java.util.ResourceBundle; import java.util.Vector; import org.mozilla.jss.netscape.security.extensions.AccessDescription; import org.mozilla.jss.netscape.security.extensions.AuthInfoAccessExtension; import org.mozilla.jss.netscape.security.extensions.CertificateScopeEntry; import org.mozilla.jss.netscape.security.extensions.CertificateScopeOfUseExtension; import org.mozilla.jss.netscape.security.extensions.ExtendedKeyUsageExtension; import org.mozilla.jss.netscape.security.extensions.InhibitAnyPolicyExtension; import org.mozilla.jss.netscape.security.extensions.NSCertTypeExtension; import org.mozilla.jss.netscape.security.extensions.OCSPNoCheckExtension; import org.mozilla.jss.netscape.security.extensions.PresenceServerExtension; import org.mozilla.jss.netscape.security.extensions.SubjectInfoAccessExtension; import org.mozilla.jss.netscape.security.x509.Attribute; import org.mozilla.jss.netscape.security.x509.AuthorityKeyIdentifierExtension; import org.mozilla.jss.netscape.security.x509.BasicConstraintsExtension; import org.mozilla.jss.netscape.security.x509.CPSuri; import org.mozilla.jss.netscape.security.x509.CRLDistributionPoint; import org.mozilla.jss.netscape.security.x509.CRLDistributionPointsExtension; import org.mozilla.jss.netscape.security.x509.CRLDistributionPointsExtension.Reason; import org.mozilla.jss.netscape.security.x509.CRLNumberExtension; import org.mozilla.jss.netscape.security.x509.CRLReasonExtension; import org.mozilla.jss.netscape.security.x509.CertificateIssuerExtension; import org.mozilla.jss.netscape.security.x509.CertificatePoliciesExtension; import org.mozilla.jss.netscape.security.x509.CertificatePolicyInfo; import org.mozilla.jss.netscape.security.x509.CertificatePolicyMap; import org.mozilla.jss.netscape.security.x509.DeltaCRLIndicatorExtension; import org.mozilla.jss.netscape.security.x509.DisplayText; import org.mozilla.jss.netscape.security.x509.Extension; import org.mozilla.jss.netscape.security.x509.FreshestCRLExtension; import org.mozilla.jss.netscape.security.x509.GeneralName; import org.mozilla.jss.netscape.security.x509.GeneralNameInterface; import org.mozilla.jss.netscape.security.x509.GeneralNames; import org.mozilla.jss.netscape.security.x509.HoldInstructionExtension; import org.mozilla.jss.netscape.security.x509.InvalidityDateExtension; import org.mozilla.jss.netscape.security.x509.IssuerAlternativeNameExtension; import org.mozilla.jss.netscape.security.x509.IssuingDistributionPoint; import org.mozilla.jss.netscape.security.x509.IssuingDistributionPointExtension; import org.mozilla.jss.netscape.security.x509.KeyIdentifier; import org.mozilla.jss.netscape.security.x509.KeyUsageExtension; import org.mozilla.jss.netscape.security.x509.NSCCommentExtension; import org.mozilla.jss.netscape.security.x509.NameConstraintsExtension; import org.mozilla.jss.netscape.security.x509.NoticeReference; import org.mozilla.jss.netscape.security.x509.OIDMap; import org.mozilla.jss.netscape.security.x509.PolicyConstraintsExtension; import org.mozilla.jss.netscape.security.x509.PolicyMappingsExtension; import org.mozilla.jss.netscape.security.x509.PolicyQualifierInfo; import org.mozilla.jss.netscape.security.x509.PolicyQualifiers; import org.mozilla.jss.netscape.security.x509.PrivateKeyUsageExtension; import org.mozilla.jss.netscape.security.x509.Qualifier; import org.mozilla.jss.netscape.security.x509.RDN; import org.mozilla.jss.netscape.security.x509.SerialNumber; import org.mozilla.jss.netscape.security.x509.SubjectAlternativeNameExtension; import org.mozilla.jss.netscape.security.x509.SubjectDirAttributesExtension; import org.mozilla.jss.netscape.security.x509.SubjectKeyIdentifierExtension; import org.mozilla.jss.netscape.security.x509.UserNotice; /** * This class will display the certificate content in predefined * format. * * @author Andrew Wnuk * @version $Revision$, $Date$ */ public class ExtPrettyPrint { /*========================================================== * variables *==========================================================*/ private Extension mExt = null; private ResourceBundle mResource = null; private PrettyPrintFormat pp = null; private int mIndentSize = 0; DateFormat dateFormater = null; /*========================================================== * constructors *==========================================================*/ public ExtPrettyPrint(Extension ext, int indentSize) { mExt = ext; mResource = ResourceBundle.getBundle(PrettyPrintResources.class.getName()); mIndentSize = indentSize; pp = new PrettyPrintFormat(":"); } /*========================================================== * public methods *==========================================================*/ /** * This method return string representation of the certificate * in predefined format using specified client local. I18N Support. * * @return string representation of the certificate */ public String toString() { StringBuffer sb = new StringBuffer(); //check if the extension is known if (mExt instanceof KeyUsageExtension) { return getKeyUsage(); } if (mExt instanceof NSCertTypeExtension) { return getCertType(); } if (mExt instanceof AuthorityKeyIdentifierExtension) { return getAuthorityKeyIdentifier(); } if (mExt instanceof SubjectKeyIdentifierExtension) { return getSubjectKeyIdentifier(); } if (mExt instanceof CRLReasonExtension) { return getCRLReasonExtension(); } if (mExt instanceof BasicConstraintsExtension) { return getBasicConstraintsExtension(); } if (mExt instanceof NSCCommentExtension) { return getNSCCommentExtension(); } if (mExt instanceof NameConstraintsExtension) { return getNameConstraintsExtension(); } if (mExt instanceof CRLNumberExtension) { return getCRLNumberExtension(); } if (mExt instanceof DeltaCRLIndicatorExtension) { return getDeltaCRLIndicatorExtension(); } if (mExt instanceof IssuerAlternativeNameExtension) { return getIssuerAlternativeNameExtension(); } if (mExt instanceof SubjectAlternativeNameExtension) { return getSubjectAlternativeNameExtension(); } if (mExt instanceof FreshestCRLExtension) { return getFreshestCRLExtension(); } if (mExt instanceof CRLDistributionPointsExtension) { return getCRLDistributionPointsExtension(); } if (mExt instanceof IssuingDistributionPointExtension) { return getIssuingDistributionPointExtension(); } if (mExt instanceof ExtendedKeyUsageExtension) { return getExtendedKeyUsageExtension(); } if (mExt instanceof AuthInfoAccessExtension) { return getAuthInfoAccessExtension(); } if (mExt instanceof SubjectInfoAccessExtension) { return getSubjectInfoAccessExtension(); } if (mExt instanceof OCSPNoCheckExtension) { return getOCSPNoCheckExtension(); } if (mExt instanceof PrivateKeyUsageExtension) { return getPrivateKeyUsageExtension(); } if (mExt instanceof InvalidityDateExtension) { return getInvalidityDateExtension(); } if (mExt instanceof CertificateIssuerExtension) { return getCertificateIssuerExtension(); } if (mExt instanceof HoldInstructionExtension) { return getHoldInstructionExtension(); } if (mExt instanceof PolicyConstraintsExtension) { return getPolicyConstraintsExtension(); } if (mExt instanceof PolicyMappingsExtension) { return getPolicyMappingsExtension(); } if (mExt instanceof SubjectDirAttributesExtension) { return getSubjectDirAttributesExtension(); } if (mExt instanceof CertificateScopeOfUseExtension) { return getCertificateScopeOfUseExtension(); } if (mExt instanceof PresenceServerExtension) { return getPresenceServerExtension(); } if (mExt instanceof InhibitAnyPolicyExtension) { return getInhibitAnyPolicyExtension(); } if (mExt instanceof CertificatePoliciesExtension) { return getCertificatePoliciesExtension(); } //unknown cert extension String extName = OIDMap.getName(mExt.getExtensionId()); if (extName == null) sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER) + mExt.getExtensionId().toString() + "\n"); else sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER) + " " + extName + " - " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_VALUE) + "\n"); sb.append(pp.toHexString(mExt.getExtensionValue(), mIndentSize + 8, 16)); return sb.toString(); } /*========================================================== * Private methods *==========================================================*/ private String getNSCCommentExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_NSC_COMMENT) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + ((NSCCommentExtension) mExt).toPrint(mIndentSize) + "\n"); return sb.toString(); } private String getNameConstraintsExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_NAME_CONSTRAINTS) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + ((NameConstraintsExtension) mExt).toPrint(mIndentSize + 4)); return sb.toString(); } private String getOCSPNoCheckExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_OCSP_NOCHECK) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } return sb.toString(); } private String getSubjectInfoAccessExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_SIA) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_ACCESS_DESC) + "\n"); SubjectInfoAccessExtension aia = (SubjectInfoAccessExtension) mExt; for (int i = 0; i < aia.numberOfAccessDescription(); i++) { AccessDescription ad = aia.getAccessDescription(i); ObjectIdentifier method = ad.getMethod(); if (method.equals(SubjectInfoAccessExtension.METHOD_OCSP)) { sb.append(pp.indent(mIndentSize + 8) + "Method #" + i + ": " + "ocsp" + "\n"); } else { sb.append(pp.indent(mIndentSize + 8) + "Method #" + i + ": " + method.toString() + "\n"); } sb.append(pp.indent(mIndentSize + 8) + "Location #" + i + ": " + ad.getLocation().toString() + "\n"); } return sb.toString(); } private String getAuthInfoAccessExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_AIA) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_ACCESS_DESC) + "\n"); AuthInfoAccessExtension aia = (AuthInfoAccessExtension) mExt; for (int i = 0; i < aia.numberOfAccessDescription(); i++) { AccessDescription ad = aia.getAccessDescription(i); ObjectIdentifier method = ad.getMethod(); if (method.equals(AuthInfoAccessExtension.METHOD_OCSP)) { sb.append(pp.indent(mIndentSize + 8) + "Method #" + i + ": " + "ocsp" + "\n"); } else { sb.append(pp.indent(mIndentSize + 8) + "Method #" + i + ": " + method.toString() + "\n"); } sb.append(pp.indent(mIndentSize + 8) + "Location #" + i + ": " + ad.getLocation().toString() + "\n"); } return sb.toString(); } private String getPresenceServerExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_PRESENCE_SERVER) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } PresenceServerExtension pse = (PresenceServerExtension) mExt; sb.append(pp.indent(mIndentSize + 4) + "Version : " + pse.getVersion() + "\n"); sb.append(pp.indent(mIndentSize + 4) + "Street Address : " + pse.getStreetAddress() + "\n"); sb.append(pp.indent(mIndentSize + 4) + "Telephone Number : " + pse.getTelephoneNumber() + "\n"); sb.append(pp.indent(mIndentSize + 4) + "RFC822 Name : " + pse.getRFC822() + "\n"); sb.append(pp.indent(mIndentSize + 4) + "ID : " + pse.getID() + "\n"); sb.append(pp.indent(mIndentSize + 4) + "Host Name : " + pse.getHostName() + "\n"); sb.append(pp.indent(mIndentSize + 4) + "Port Number : " + pse.getPortNumber() + "\n"); sb.append(pp.indent(mIndentSize + 4) + "Max Users : " + pse.getMaxUsers() + "\n"); sb.append(pp.indent(mIndentSize + 4) + "Service Level : " + pse.getServiceLevel() + "\n"); return sb.toString(); } private String getPrivateKeyUsageExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_PRIVATE_KEY_USAGE) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } PrivateKeyUsageExtension usage = (PrivateKeyUsageExtension) mExt; sb.append(pp.indent(mIndentSize + 4) + "Validity:\n"); if (dateFormater == null) { dateFormater = DateFormat.getDateInstance(DateFormat.FULL); } String notBefore = dateFormater.format(usage.getNotBefore()); String notAfter = dateFormater.format(usage.getNotAfter()); sb.append(pp.indent(mIndentSize + 8) + "Not Before: " + notBefore + "\n"); sb.append(pp.indent(mIndentSize + 8) + "Not After: " + notAfter + "\n"); return sb.toString(); } private String getExtendedKeyUsageExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_EXTENDED_KEY_USAGE) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_EXTENDED_KEY_USAGE) + "\n"); ExtendedKeyUsageExtension usage = (ExtendedKeyUsageExtension) mExt; Enumeration e = usage.getOIDs(); if (e != null) { while (e.hasMoreElements()) { ObjectIdentifier oid = e.nextElement(); if (oid.equals(ExtendedKeyUsageExtension.OID_OCSP_SIGNING)) { sb.append(pp.indent(mIndentSize + 8) + "OCSPSigning" + "\n"); } else { sb.append(pp.indent(mIndentSize + 8) + oid.toString() + "\n"); } } } return sb.toString(); } /** * String Representation of KeyUsageExtension */ private String getKeyUsage() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_KEY_USAGE) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_KEY_USAGE) + "\n"); KeyUsageExtension usage = (KeyUsageExtension) mExt; if (((Boolean) usage.get(KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.DIGITAL_SIGNATURE) + "\n"); } if (((Boolean) usage.get(KeyUsageExtension.NON_REPUDIATION)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.NON_REPUDIATION) + "\n"); } if (((Boolean) usage.get(KeyUsageExtension.KEY_ENCIPHERMENT)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.KEY_ENCIPHERMENT) + "\n"); } if (((Boolean) usage.get(KeyUsageExtension.DATA_ENCIPHERMENT)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.DATA_ENCIPHERMENT) + "\n"); } if (((Boolean) usage.get(KeyUsageExtension.KEY_AGREEMENT)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.KEY_AGREEMENT) + "\n"); } if (((Boolean) usage.get(KeyUsageExtension.KEY_CERTSIGN)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.KEY_CERTSIGN) + "\n"); } if (((Boolean) usage.get(KeyUsageExtension.CRL_SIGN)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.CRL_SIGN) + "\n"); } if (((Boolean) usage.get(KeyUsageExtension.ENCIPHER_ONLY)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.ENCIPHER_ONLY) + "\n"); } if (((Boolean) usage.get(KeyUsageExtension.DECIPHER_ONLY)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(KeyUsageExtension.DECIPHER_ONLY) + "\n"); } return sb.toString(); } catch (IOException e) { e.printStackTrace(); return sb.toString(); } } /** * String Representation of NSCertTypeExtension */ private String getCertType() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_CERT_TYPE) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CERT_USAGE) + "\n"); NSCertTypeExtension type = (NSCertTypeExtension) mExt; if (((Boolean) type.get(NSCertTypeExtension.SSL_CLIENT)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.SSL_CLIENT) + "\n"); } if (((Boolean) type.get(NSCertTypeExtension.SSL_SERVER)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.SSL_SERVER) + "\n"); } if (((Boolean) type.get(NSCertTypeExtension.EMAIL)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.EMAIL) + "\n"); } if (((Boolean) type.get(NSCertTypeExtension.OBJECT_SIGNING)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.OBJECT_SIGNING) + "\n"); } if (((Boolean) type.get(NSCertTypeExtension.SSL_CA)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.SSL_CA) + "\n"); } if (((Boolean) type.get(NSCertTypeExtension.EMAIL_CA)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.EMAIL_CA) + "\n"); } if (((Boolean) type.get(NSCertTypeExtension.OBJECT_SIGNING_CA)).booleanValue()) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(NSCertTypeExtension.OBJECT_SIGNING_CA) + "\n"); } return sb.toString(); } catch (CertificateException e) { e.printStackTrace(); return ""; } } /** * String Representation of SubjectKeyIdentifierExtension */ private String getSubjectKeyIdentifier() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_SKI) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } SubjectKeyIdentifierExtension id = (SubjectKeyIdentifierExtension) mExt; KeyIdentifier keyId = (KeyIdentifier) id.get(SubjectKeyIdentifierExtension.KEY_ID); if (keyId != null) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_KEY_ID) + "\n"); sb.append(pp.toHexString(keyId.getIdentifier(), 24, 16)); } return sb.toString(); } catch (IOException e) { e.printStackTrace(); return ""; } } /** * String Representation of AuthorityKeyIdentifierExtension */ private String getAuthorityKeyIdentifier() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_AKI) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } AuthorityKeyIdentifierExtension id = (AuthorityKeyIdentifierExtension) mExt; KeyIdentifier keyId = (KeyIdentifier) id.get(AuthorityKeyIdentifierExtension.KEY_ID); if (keyId != null) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_KEY_ID) + "\n"); sb.append(pp.toHexString(keyId.getIdentifier(), mIndentSize + 8, 16)); // sb.append(pp.toHexString(keyId.getIdentifier(),24,16)); } GeneralNames authNames = (GeneralNames) id.get(AuthorityKeyIdentifierExtension.AUTH_NAME); if (authNames != null) { for (int i = 0; i < authNames.size(); i++) { GeneralName authName = (GeneralName) authNames.elementAt(i); if (authName != null) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_AUTH_NAME) + authName.toString() + "\n"); } } } SerialNumber serial = (SerialNumber) id.get(AuthorityKeyIdentifierExtension.SERIAL_NUMBER); if (serial != null) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_SERIAL) + "0x" + serial.getNumber().toBigInteger().toString(16).toUpperCase() + "\n"); } return sb.toString(); } catch (IOException e) { e.printStackTrace(); return ""; } } /** * String Representation of CRLReasonExtension */ private String getCRLReasonExtension() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_REVOCATION_REASON) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); CRLReasonExtension ext = (CRLReasonExtension) mExt; if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_REASON) + ext.getReason().toString() + "\n"); return sb.toString(); } catch (Exception e) { return ""; } } /** * String Representation of InhibitAnyPolicyExtension */ private String getInhibitAnyPolicyExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString( PrettyPrintResources.TOKEN_INHIBIT_ANY_POLICY_EXT) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); InhibitAnyPolicyExtension ext = (InhibitAnyPolicyExtension) mExt; if (mExt.isCritical()) sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); else sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_SKIP_CERTS)); BigInt num = ext.getSkipCerts(); sb.append("" + num.toInt() + "\n"); return sb.toString(); } /** * String Representation of BasicConstraintsExtension */ private String getBasicConstraintsExtension() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_BASIC_CONSTRAINTS) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); BasicConstraintsExtension ext = (BasicConstraintsExtension) mExt; if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_IS_CA)); boolean isCA = ((Boolean) ext.get(BasicConstraintsExtension.IS_CA)).booleanValue(); if (isCA) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } Integer pathLength = (Integer) ext.get(BasicConstraintsExtension.PATH_LEN); if (pathLength != null) { if (pathLength.longValue() >= 0) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_PATH_LEN) + pathLength.toString() + "\n"); } else if (pathLength.longValue() == -1 || pathLength.longValue() == -2) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_PATH_LEN) + mResource.getString(PrettyPrintResources.TOKEN_PATH_LEN_UNLIMITED) + "\n"); } else { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_PATH_LEN) + mResource.getString(PrettyPrintResources.TOKEN_PATH_LEN_INVALID) + " (" + pathLength.toString() + ")\n"); } } return sb.toString(); } catch (IOException e) { e.printStackTrace(); return ""; } } /** * String Representation of CRLNumberExtension */ private String getCRLNumberExtension() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_CRL_NUMBER) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); CRLNumberExtension ext = (CRLNumberExtension) mExt; if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } BigInteger crlNumber = (BigInteger) ext.get(CRLNumberExtension.NUMBER); if (crlNumber != null) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_NUMBER) + crlNumber.toString() + "\n"); } return sb.toString(); } catch (IOException e) { e.printStackTrace(); return ""; } } /** * String Representation of DeltaCRLIndicatorExtension */ private String getDeltaCRLIndicatorExtension() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_DELTA_CRL_INDICATOR) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); DeltaCRLIndicatorExtension ext = (DeltaCRLIndicatorExtension) mExt; if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } BigInteger crlNumber = (BigInteger) ext.get(DeltaCRLIndicatorExtension.NUMBER); if (crlNumber != null) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_BASE_CRL_NUMBER) + crlNumber.toString() + "\n"); } return sb.toString(); } catch (IOException e) { e.printStackTrace(); return ""; } } /** * String Representation of IssuerAlternativeName Extension */ private String getIssuerAlternativeNameExtension() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_ISSUER_ALT_NAME) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); IssuerAlternativeNameExtension ext = (IssuerAlternativeNameExtension) mExt; if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } GeneralNames issuerNames = (GeneralNames) ext.get(IssuerAlternativeNameExtension.ISSUER_NAME); if (issuerNames != null) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_ISSUER_NAMES) + "\n"); for (int i = 0; i < issuerNames.size(); i++) { GeneralName issuerName = (GeneralName) issuerNames.elementAt(i); if (issuerName != null) { String nameType = ""; if (issuerName.getType() == GeneralNameInterface.NAME_DIRECTORY) nameType = "DirectoryName: "; sb.append(pp.indent(mIndentSize + 8) + nameType + issuerName.toString() + "\n"); } } } return sb.toString(); } catch (IOException e) { return ""; } } /** * String Representation of SubjectAlternativeName Extension */ private String getSubjectAlternativeNameExtension() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_SUBJECT_ALT_NAME) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); SubjectAlternativeNameExtension ext = (SubjectAlternativeNameExtension) mExt; if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } GeneralNames subjectNames = (GeneralNames) ext.get(SubjectAlternativeNameExtension.SUBJECT_NAME); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_VALUE) + "\n"); for (int i = 0; i < subjectNames.size(); i++) { GeneralName subjectName = (GeneralName) subjectNames.elementAt(i); if (subjectName != null) { String nameType = ""; if (subjectName.getType() == GeneralNameInterface.NAME_DIRECTORY) nameType = "DirectoryName: "; sb.append(pp.indent(mIndentSize + 8) + nameType + subjectName.toString() + "\n"); } } return sb.toString(); } catch (IOException e) { e.printStackTrace(); return ""; } } /** * String Representation of CertificateScopeOfUse Extension */ private String getCertificateScopeOfUseExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_CERT_SCOPE_OF_USE) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); CertificateScopeOfUseExtension ext = (CertificateScopeOfUseExtension) mExt; if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } Vector entries = ext.getCertificateScopeEntries(); if (entries != null) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_SCOPE_OF_USE) + "\n"); for (int i = 0; i < entries.size(); i++) { CertificateScopeEntry se = entries.elementAt(i); GeneralName gn = se.getGeneralName(); if (gn != null) { String nameType = ""; if (gn.getType() == GeneralNameInterface.NAME_DIRECTORY) nameType = "DirectoryName: "; sb.append(pp.indent(mIndentSize + 8) + nameType + gn.toString() + "\n"); } BigInt port = se.getPort(); if (port != null) { sb.append(pp.indent(mIndentSize + 8) + PrettyPrintResources.TOKEN_PORT + port.toBigInteger().toString() + "\n"); } } } return sb.toString(); } /** * String Representation of FreshestCRLExtension */ private String getFreshestCRLExtension() { StringBuffer sb = new StringBuffer(); // // Generic stuff: name, OID, criticality // sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString( PrettyPrintResources.TOKEN_FRESHEST_CRL_EXT) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } // // Now the CRLDP-specific stuff // FreshestCRLExtension ext = (FreshestCRLExtension) mExt; int numPoints = ext.getNumPoints(); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRLDP_NUMPOINTS) + numPoints + "\n"); for (int i = 0; i < numPoints; i++) { // // print one individual CRL distribution point // int idt; idt = mIndentSize + 4; // reset each time through loop boolean isEmpty = true; sb.append(pp.indent(idt) + mResource.getString(PrettyPrintResources.TOKEN_CRLDP_POINTN) + i + "\n"); CRLDistributionPoint pt = ext.getPointAt(i); idt += 4; // further indent rest of information if (pt.getFullName() != null) { isEmpty = false; sb.append(pp.indent(idt) + mResource.getString(PrettyPrintResources.TOKEN_CRLDP_DISTPOINT) + pt.getFullName() + "\n"); } if (pt.getRelativeName() != null) { isEmpty = false; sb.append(pp.indent(idt) + mResource.getString(PrettyPrintResources.TOKEN_CRLDP_DISTPOINT) + pt.getRelativeName() + "\n"); } if (pt.getReasons() != null) { isEmpty = false; byte[] reasonBits = pt.getReasons().toByteArray(); String reasonList = reasonBitsToReasonList(reasonBits); sb.append(pp.indent(idt) + mResource.getString(PrettyPrintResources.TOKEN_CRLDP_REASONS) + reasonList + "\n"); } if (pt.getCRLIssuer() != null) { isEmpty = false; sb.append(pp.indent(idt) + mResource.getString(PrettyPrintResources.TOKEN_CRLDP_CRLISSUER) + pt.getCRLIssuer() + "\n"); } if (isEmpty) { sb.append(pp.indent(idt) + "empty\n"); } } return sb.toString(); } /** * String Representation of CRLDistributionPointsExtension */ private String getCRLDistributionPointsExtension() { StringBuffer sb = new StringBuffer(); // // Generic stuff: name, OID, criticality // sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString( PrettyPrintResources.TOKEN_CRL_DP_EXT) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } // // Now the CRLDP-specific stuff // CRLDistributionPointsExtension ext = (CRLDistributionPointsExtension) mExt; int numPoints = ext.getNumPoints(); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRLDP_NUMPOINTS) + numPoints + "\n"); for (int i = 0; i < numPoints; i++) { // // print one individual CRL distribution point // int idt; idt = mIndentSize + 4; // reset each time through loop boolean isEmpty = true; sb.append(pp.indent(idt) + mResource.getString(PrettyPrintResources.TOKEN_CRLDP_POINTN) + i + "\n"); CRLDistributionPoint pt = ext.getPointAt(i); idt += 4; // further indent rest of information if (pt.getFullName() != null) { isEmpty = false; sb.append(pp.indent(idt) + mResource.getString(PrettyPrintResources.TOKEN_CRLDP_DISTPOINT) + pt.getFullName() + "\n"); } if (pt.getRelativeName() != null) { isEmpty = false; sb.append(pp.indent(idt) + mResource.getString(PrettyPrintResources.TOKEN_CRLDP_DISTPOINT) + pt.getRelativeName() + "\n"); } if (pt.getReasons() != null) { isEmpty = false; byte[] reasonBits = pt.getReasons().toByteArray(); String reasonList = reasonBitsToReasonList(reasonBits); sb.append(pp.indent(idt) + mResource.getString(PrettyPrintResources.TOKEN_CRLDP_REASONS) + reasonList + "\n"); } if (pt.getCRLIssuer() != null) { isEmpty = false; sb.append(pp.indent(idt) + mResource.getString(PrettyPrintResources.TOKEN_CRLDP_CRLISSUER) + pt.getCRLIssuer() + "\n"); } if (isEmpty) { sb.append(pp.indent(idt) + "empty\n"); } } return sb.toString(); } private static String reasonBitsToReasonList(byte[] reasonBits) { Reason[] reasons = Reason.bitArrayToReasonArray(reasonBits); if (reasons.length == 0) { return ""; } else { StringBuffer buf = new StringBuffer(); buf.append(reasons[0].getName()); for (int i = 1; i < reasons.length; i++) { buf.append(", "); buf.append(reasons[i].getName()); } return buf.toString(); } } /** * String Representation of IssuerAlternativeName Extension */ private String getIssuingDistributionPointExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString(PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_ISSUING_DIST_POINT) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } IssuingDistributionPointExtension ext = (IssuingDistributionPointExtension) mExt; IssuingDistributionPoint issuingDistributionPoint = ext.getIssuingDistributionPoint(); if (issuingDistributionPoint != null) { GeneralNames fullNames = issuingDistributionPoint.getFullName(); RDN relativeName = issuingDistributionPoint.getRelativeName(); if (fullNames != null || relativeName != null) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_DIST_POINT_NAME) + "\n"); if (fullNames != null) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(PrettyPrintResources.TOKEN_FULL_NAME) + "\n"); for (int i = 0; i < fullNames.size(); i++) { GeneralName fullName = (GeneralName) fullNames.elementAt(i); if (fullName != null) { sb.append(pp.indent(mIndentSize + 12) + fullName.toString() + "\n"); } } } if (relativeName != null) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString(PrettyPrintResources.TOKEN_RELATIVE_NAME) + relativeName.toString() + "\n"); } } sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_ONLY_USER_CERTS)); if (issuingDistributionPoint.getOnlyContainsUserCerts()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_ONLY_CA_CERTS)); if (issuingDistributionPoint.getOnlyContainsCACerts()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } BitArray onlySomeReasons = issuingDistributionPoint.getOnlySomeReasons(); if (onlySomeReasons != null) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_ONLY_SOME_REASONS)); sb.append("0x" + pp.toHexString(onlySomeReasons.toByteArray())); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_INDIRECT_CRL)); if (issuingDistributionPoint.getIndirectCRL()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } } return sb.toString(); } /** * String Representation of InvalidityDateExtension */ private String getInvalidityDateExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_INVALIDITY_DATE) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); InvalidityDateExtension ext = (InvalidityDateExtension) mExt; if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_DATE_OF_INVALIDITY) + ext.getInvalidityDate().toString() + "\n"); return sb.toString(); } /** * String Representation of CertificateIssuerExtension */ private String getCertificateIssuerExtension() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_CERTIFICATE_ISSUER) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); CertificateIssuerExtension ext = (CertificateIssuerExtension) mExt; if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } GeneralNames issuerNames = (GeneralNames) ext.get( CertificateIssuerExtension.CERTIFICATE_ISSUER); if (issuerNames != null) { sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_ISSUER_NAMES) + "\n"); for (int i = 0; i < issuerNames.size(); i++) { GeneralName issuerName = (GeneralName) issuerNames.elementAt(i); if (issuerName != null) { String nameType = ""; if (issuerName.getType() == GeneralNameInterface.NAME_DIRECTORY) nameType = "DirectoryName: "; sb.append(pp.indent(mIndentSize + 8) + nameType + issuerName.toString() + "\n"); } } } return sb.toString(); } catch (IOException e) { e.printStackTrace(); return ""; } } /** * String Representation of HoldInstructionExtension */ private String getHoldInstructionExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_HOLD_INSTRUCTION) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); HoldInstructionExtension ext = (HoldInstructionExtension) mExt; if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_HOLD_INSTRUCTION_CODE) + ext.getHoldInstructionCodeDescription() + "\n"); return sb.toString(); } /** * String Representation of PolicyConstraintsExtension */ private String getPolicyConstraintsExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append( mResource.getString( PrettyPrintResources.TOKEN_POLICY_CONSTRAINTS) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } PolicyConstraintsExtension ext = (PolicyConstraintsExtension) mExt; int require = ext.getRequireExplicitMapping(); int inhibit = ext.getInhibitPolicyMapping(); sb.append( pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_REQUIRE_EXPLICIT_POLICY) + ((require == -1) ? mResource.getString(PrettyPrintResources.TOKEN_NOT_SET) : String.valueOf(require)) + "\n"); sb.append( pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_INHIBIT_POLICY_MAPPING) + ((inhibit == -1) ? mResource.getString(PrettyPrintResources.TOKEN_NOT_SET) : String.valueOf(inhibit)) + "\n"); return sb.toString(); } /** * String Representation of PolicyMappingsExtension */ private String getPolicyMappingsExtension() { StringBuffer sb = new StringBuffer(); sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_POLICY_MAPPINGS) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } PolicyMappingsExtension ext = (PolicyMappingsExtension) mExt; Enumeration maps = ext.getMappings(); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_MAPPINGS)); if (maps == null || !maps.hasMoreElements()) { sb.append( mResource.getString(PrettyPrintResources.TOKEN_NONE) + "\n"); } else { sb.append("\n"); for (int i = 0; maps.hasMoreElements(); i++) { sb.append(pp.indent(mIndentSize + 8) + mResource.getString( PrettyPrintResources.TOKEN_MAP) + i + ":" + "\n"); CertificatePolicyMap m = maps.nextElement(); sb.append(pp.indent(mIndentSize + 12) + mResource.getString( PrettyPrintResources.TOKEN_ISSUER_DOMAIN_POLICY) + m.getIssuerIdentifier().getIdentifier().toString() + "\n"); sb.append(pp.indent(mIndentSize + 12) + mResource.getString( PrettyPrintResources.TOKEN_SUBJECT_DOMAIN_POLICY) + m.getSubjectIdentifier().getIdentifier().toString() + "\n"); } } return sb.toString(); } /** * String Representation of SubjectDirAttributesExtension */ private String getSubjectDirAttributesExtension() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_SUBJECT_DIR_ATTR) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString(PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString(PrettyPrintResources.TOKEN_NO) + "\n"); } SubjectDirAttributesExtension ext = (SubjectDirAttributesExtension) mExt; sb.append(pp.indent(mIndentSize + 4) + mResource.getString(PrettyPrintResources.TOKEN_ATTRIBUTES)); Enumeration attrs = ext.getAttributesList(); if (attrs == null || !attrs.hasMoreElements()) { sb.append( mResource.getString(PrettyPrintResources.TOKEN_NONE) + "\n"); } else { sb.append("\n"); for (int j = 0; attrs.hasMoreElements(); j++) { Attribute attr = attrs.nextElement(); sb.append(pp.indent(mIndentSize + 8) + mResource.getString( PrettyPrintResources.TOKEN_ATTRIBUTE) + j + ":" + "\n"); sb.append(pp.indent(mIndentSize + 12) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER) + attr.getOid().toString() + "\n"); sb.append(pp.indent(mIndentSize + 12) + mResource.getString( PrettyPrintResources.TOKEN_VALUES)); Enumeration values = attr.getValues(); if (values == null || !values.hasMoreElements()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NONE) + "\n"); } else { for (int k = 0; values.hasMoreElements(); k++) { String v = values.nextElement(); if (k != 0) sb.append(","); sb.append(v); } } sb.append("\n"); } } return sb.toString(); } catch (Throwable e) { return ""; } } private String getCertificatePoliciesExtension() { StringBuffer sb = new StringBuffer(); try { sb.append(pp.indent(mIndentSize) + mResource.getString( PrettyPrintResources.TOKEN_IDENTIFIER)); sb.append(mResource.getString(PrettyPrintResources.TOKEN_CERT_POLICIES) + "- " + mExt.getExtensionId().toString() + "\n"); sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CRITICAL)); if (mExt.isCritical()) { sb.append(mResource.getString( PrettyPrintResources.TOKEN_YES) + "\n"); } else { sb.append(mResource.getString( PrettyPrintResources.TOKEN_NO) + "\n"); } sb.append(pp.indent(mIndentSize + 4) + mResource.getString( PrettyPrintResources.TOKEN_CERT_POLICIES) + "\n"); CertificatePoliciesExtension cp = (CertificatePoliciesExtension) mExt; @SuppressWarnings("unchecked") Vector cpv = (Vector) cp.get("infos"); Enumeration e = cpv.elements(); if (e != null) { while (e.hasMoreElements()) { CertificatePolicyInfo cpi = e.nextElement(); sb.append(pp.indent(mIndentSize + 8) + "Policy Identifier: " + cpi.getPolicyIdentifier().getIdentifier().toString() + "\n"); PolicyQualifiers cpq = cpi.getPolicyQualifiers(); if (cpq != null) { for (int i = 0; i < cpq.size(); i++) { PolicyQualifierInfo pq = cpq.getInfoAt(i); Qualifier q = pq.getQualifier(); if (q instanceof CPSuri) { sb.append(pp.indent(mIndentSize + 12) + "Policy Qualifier Identifier: CPS Pointer Qualifier - " + pq.getId() + "\n"); sb.append(pp.indent(mIndentSize + 12) + "Policy Qualifier Data: " + ((CPSuri) q).getURI() + "\n"); } else if (q instanceof UserNotice) { sb.append(pp.indent(mIndentSize + 12) + "Policy Qualifier Identifier: CPS User Notice Qualifier - " + pq.getId() + "\n"); NoticeReference nref = ((UserNotice) q).getNoticeReference(); DisplayText dt = ((UserNotice) q).getDisplayText(); sb.append(pp.indent(mIndentSize + 12) + "Policy Qualifier Data: \n"); if (nref != null) { sb.append(pp.indent(mIndentSize + 16) + "Organization: " + nref.getOrganization().toString() + "\n"); sb.append(pp.indent(mIndentSize + 16) + "Notice Numbers: "); int[] nums = nref.getNumbers(); for (int k = 0; k < nums.length; k++) { if (k != 0) { sb.append(","); sb.append(nums[k]); } else { sb.append(nums[k]); } } sb.append("\n"); } if (dt != null) { sb.append(pp.indent(mIndentSize + 16) + "Explicit Text: " + dt.toString() + "\n"); } } } } } } return sb.toString(); } catch (IOException e) { return sb.toString(); } } } jss-4.6.3/org/mozilla/jss/netscape/security/util/IA5Charset.java000066400000000000000000000010211362106420000245250ustar00rootroot00000000000000package org.mozilla.jss.netscape.security.util; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; public class IA5Charset extends Charset { public IA5Charset() { super("ASN.1-IA5", null); } public boolean contains(Charset cs) { return false; } public CharsetDecoder newDecoder() { return new IA5CharsetDecoder(this); } public CharsetEncoder newEncoder() { return new IA5CharsetEncoder(this); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/IA5CharsetDecoder.java000066400000000000000000000035521362106420000260260ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; /** * Converts bytes in ASN.1 IA5String character set to IA5String characters. * * @author Lily Hsiao * @author Slava Galperin */ public class IA5CharsetDecoder extends CharsetDecoder { public IA5CharsetDecoder(Charset cs) { super(cs, 1, 1); } protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) { while (true) { if (in.remaining() < 1) return CoderResult.UNDERFLOW; in.mark(); byte b = in.get(); if (CodingErrorAction.REPORT == unmappableCharacterAction() && (b & 0x80) != 0) { return CoderResult.unmappableForLength(1); } if (out.remaining() < 1) { in.reset(); return CoderResult.OVERFLOW; } out.put((char) (b & 0x7f)); } } } jss-4.6.3/org/mozilla/jss/netscape/security/util/IA5CharsetEncoder.java000066400000000000000000000041701362106420000260350ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; /** * Converts characters in ASN.1 IA5String character set to IA5String bytes. * * @author Lily Hsiao * @author Slava Galperin */ public class IA5CharsetEncoder extends CharsetEncoder { public IA5CharsetEncoder(Charset cs) { super(cs, 1, 1); } /* * Converts an array of Unicode characters into an array of IA5String * bytes and returns the conversion result. * @param in input character buffer to convert. * @param out byte buffer to store output. * @return encoding result. */ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) { while (true) { if (in.remaining() < 1) return CoderResult.UNDERFLOW; in.mark(); char c = in.get(); if (CodingErrorAction.REPORT == unmappableCharacterAction() && (c & 0xFF80) != 0) { return CoderResult.unmappableForLength(1); } if (out.remaining() < 1) { in.reset(); return CoderResult.OVERFLOW; } out.put((byte) (c & 0x7f)); } } } jss-4.6.3/org/mozilla/jss/netscape/security/util/ObjectIdentifier.java000066400000000000000000000370451362106420000260650ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.io.IOException; import java.io.Serializable; import java.math.BigInteger; import java.util.Hashtable; import java.util.StringTokenizer; /** * Represent an ISO Object Identifier. * *

* Object Identifiers are arbitrary length hierarchical identifiers. The individual components are numbers, and they * define paths from the root of an ISO-managed identifier space. You will sometimes see a string name used instead of * (or in addition to) the numerical id. These are synonyms for the numerical IDs, but are not widely used since most * sites do not know all the requisite strings, while all sites can parse the numeric forms. * *

* So for example, JavaSoft has the sole authority to assign the meaning to identifiers below the 1.3.6.1.4.42.2.17 node * in the hierarchy, and other organizations can easily acquire the ability to assign such unique identifiers. * * @version 1.23 * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra */ final public class ObjectIdentifier implements Serializable { /** use serialVersionUID from JDK 1.1. for interoperability */ private static final long serialVersionUID = 8697030238860181294L; /** * Constructs an object identifier from a string. This string * should be of the form 1.23.34.45.56 etc. */ public ObjectIdentifier(String oid) { if (oid == null) return; int ch = '.'; int start = 0; int end = 0; // Calculate length of oid componentLen = 0; while ((end = oid.indexOf(ch, start)) != -1) { start = end + 1; componentLen += 1; } componentLen += 1; components = new BigInteger[componentLen]; start = 0; int i = 0; String comp = null; while ((end = oid.indexOf(ch, start)) != -1) { comp = oid.substring(start, end); components[i++] = new BigInteger(comp); start = end + 1; } comp = oid.substring(start); components[i] = new BigInteger(comp); } /** * Constructs an object ID from an array of integers. This * is used to construct constant object IDs. */ public ObjectIdentifier(int values[]) { try { componentLen = values.length; BigInteger[] tmp = new BigInteger[componentLen]; for (int i = 0; i < componentLen; i++) { tmp[i] = BigInteger.valueOf(values[i]); } components = tmp.clone(); } catch (Throwable t) { System.out.println("X509.ObjectIdentifier(), no cloning!"); } } public ObjectIdentifier(BigInteger values[]) { try { componentLen = values.length; componentLen = values.length; BigInteger[] tmp = new BigInteger[componentLen]; for (int i = 0; i < componentLen; i++) { tmp[i] = new BigInteger(values[i].toString()); } components = tmp.clone(); } catch(Throwable t) { System.out.println("X509.ObjectIdentifier(), no cloning!"); } } /** * Constructs an object ID from an array of longs This * is used to construct constant object IDs. */ public ObjectIdentifier(long values[]) { try { componentLen = values.length; BigInteger[] tmp = new BigInteger[componentLen]; for (int i = 0; i < componentLen; i++) { tmp[i] = BigInteger.valueOf(values[i]); } components = tmp.clone(); } catch (Throwable t) { System.out.println("X509.ObjectIdentifier(), no cloning!"); } } /** * Constructs an object ID from an ASN.1 encoded input stream. * The encoding of the ID in the stream uses "DER", a BER/1 subset. * In this case, that means a triple { typeId, length, data }. * *

* NOTE: When an exception is thrown, the input stream has not been returned to its "initial" * state. * * @param in DER-encoded data holding an object ID * @exception IOException indicates a decoding error */ public ObjectIdentifier(DerInputStream in) throws IOException { byte type_id; int bufferEnd; /* * Object IDs are a "universal" type, and their tag needs only * one byte of encoding. Verify that the tag of this datum * is that of an object ID. * * Then get and check the length of the ID's encoding. We set * up so that we can use in.available() to check for the end of * this value in the data stream. */ type_id = (byte) in.getByte(); if (type_id != DerValue.tag_ObjectId) throw new IOException( "X509.ObjectIdentifier() -- data isn't an object ID" + " (tag = " + type_id + ")"); bufferEnd = in.available() - in.getLength() - 1; if (bufferEnd < 0) throw new IOException( "X509.ObjectIdentifier() -- not enough data"); initFromEncoding(in, bufferEnd); } /* * Build the OID from the rest of a DER input buffer; the tag * and length have been removed/verified */ ObjectIdentifier(DerInputBuffer buf) throws IOException { initFromEncoding(new DerInputStream(buf), 0); } /* * Helper function -- get the OID from a stream, after tag and * length are verified. */ private void initFromEncoding(DerInputStream in, int bufferEnd) throws IOException { /* * Now get the components ("sub IDs") one at a time. We fill a * temporary buffer, resizing it as needed. */ BigInteger component; boolean first_subid = true; for (components = new BigInteger[allocationQuantum], componentLen = 0; in.available() > bufferEnd;) { component = getComponentBigInt(in); if (first_subid) { long X, Y; /* * The ISO root has three children (0, 1, 2) and those nodes * aren't allowed to assign IDs larger than 39. These rules * are memorialized by some special casing in the BER encoding * of object IDs ... or maybe it's vice versa. * * NOTE: the allocation quantum is large enough that we know * we don't have to reallocate here! */ if (component.intValue() < 40) X = 0; else if (component.intValue() < 80) X = 1; else X = 2; Y = component.intValue() - (X * 40); components[0] = BigInteger.valueOf(X); components[1] = BigInteger.valueOf(Y); componentLen = 2; first_subid = false; } else { /* * Other components are encoded less exotically. The only * potential trouble is the need to grow the array. */ if (componentLen >= components.length) { BigInteger tmp_components[]; tmp_components = new BigInteger[components.length + allocationQuantum]; System.arraycopy(components, 0, tmp_components, 0, components.length); components = tmp_components; } components[componentLen++] = component; } } /* * Final sanity check -- if we didn't use exactly the number of bytes * specified, something's quite wrong. */ if (in.available() != bufferEnd) { throw new IOException( "X509.ObjectIdentifier() -- malformed input data"); } } /* * n.b. the only public interface is DerOutputStream.putOID() */ public void encode(DerOutputStream out) throws IOException { DerOutputStream bytes = new DerOutputStream(); int i; /* We can use the int here because we know we are dealing with small numbers for the first byte */ bytes.write((components[0].intValue() * 40) + components[1].intValue()); for (i = 2; i < componentLen; i++) putComponentBigInt(bytes, components[i]); /* * Now that we've constructed the component, encode * it in the stream we were given. */ out.write(DerValue.tag_ObjectId, bytes); } /* * Tricky OID component parsing technique ... note that one bit * per octet is lost, this returns at most 28 bits of component. * Also, notice this parses in big-endian format. */ private static BigInteger getComponentBigInt(DerInputStream in) throws IOException { BigInteger retval = BigInteger.valueOf(0); int tmp; while (true) { retval = retval.shiftLeft(7); tmp = in.getByte(); retval = retval.or(BigInteger.valueOf(tmp & 0x07f)); if ((tmp & 0x080) == 0) return retval; } } /* * Reverse of the above routine. Notice it needs to emit in * big-endian form, so it buffers the output until it's ready. * (Minimum length encoding is a DER requirement.) */ private static void putComponentBigInt(DerOutputStream out, BigInteger val) throws IOException { int i; int blockSize = 100; byte buf[] = new byte[blockSize]; BigInteger bigInt7f = BigInteger.valueOf(0x7f); BigInteger cur = new BigInteger(val.toString()); for (i = 0;; i++) { buf[i] = (cur.and(bigInt7f).byteValue()); cur = cur.shiftRight(7); if (cur.compareTo(BigInteger.ZERO) == 0 ) break; } for (; i > 0; --i) out.write(buf[i] | 0x080); out.write(buf[0]); } // XXX this API should probably facilitate the JDK sort utility /** * Compares this identifier with another, for sorting purposes. * An identifier does not precede itself. * * @param other identifer that may precede this one. * @return true iff other precedes this one * in a particular sorting order. */ public boolean precedes(ObjectIdentifier other) { int i; // shorter IDs go first if (other == this || componentLen < other.componentLen) return false; if (other.componentLen < componentLen) return true; // for each component, the lesser component goes first for (i = 0; i < componentLen; i++) { if (other.components[i].compareTo(components[i]) > 0) return true; } // identical IDs don't precede each other return false; } public boolean equals(Object other) { if (other instanceof ObjectIdentifier) return equals((ObjectIdentifier) other); else return false; } /** * Compares this identifier with another, for equality. * * @return true iff the names are identical. */ public boolean equals(ObjectIdentifier other) { int i; if (other == this) return true; if (componentLen != other.componentLen) return false; for (i = 0; i < componentLen; i++) { if (components[i].compareTo(other.components[i]) != 0 ) return false; } return true; } public int hashCode() { int h = 0; int oflow = 0; for (int i = 0; i < componentLen; i++) { oflow = (h & 0xff800000) >> 23; h <<= 9; h += components[i].intValue(); h ^= oflow; } return h; } /** * Returns a string form of the object ID. The format is the * conventional "dot" notation for such IDs, without any * user-friendly descriptive strings, since those strings * will not be understood everywhere. */ public String toString() { StringBuffer retval = new StringBuffer(); int i; for (i = 0; i < componentLen; i++) { if (i != 0) retval.append("."); retval.append(components[i]); } return retval.toString(); } /* * To simplify, we assume no individual component of an object ID is * larger than 64 bits. Then we represent the path from the root as * an array that's (usually) only filled at the beginning. */ private BigInteger components[]; // path from root private int componentLen; // how much is used. private static final int allocationQuantum = 5; // >= 2 /** * Netscape Enhancement: * This function implements a object identifier factory. It * should help reduces in-memory Object Identifier object. * This function also provide additional checking on the OID. * A valid OID should start with 0, 1, or 2. * * Notes: * This function never returns null. IOException is raised * in error conditions. */ public static Hashtable mOIDs = new Hashtable(); public static ObjectIdentifier getObjectIdentifier(String oid) throws IOException { int value; if (oid == null) throw new IOException("empty object identifier"); oid = oid.trim(); ObjectIdentifier thisOID = mOIDs.get(oid); if (thisOID != null) return thisOID; StringTokenizer token = new StringTokenizer(oid, "."); value = Integer.valueOf(token.nextToken()); /* First token should be 0, 1, 2 */ if (value >= 0 && value <= 2) { value = Integer.valueOf(token.nextToken()); /* Second token should be 0 <= && >= 39 */ if (value >= 0 && value <= 39) { thisOID = new ObjectIdentifier(oid); if (thisOID.toString().equals(oid)) { mOIDs.put(oid, thisOID); return thisOID; } throw new IOException("invalid oid " + oid); } else throw new IOException("invalid oid " + oid); } else throw new IOException("invalid oid " + oid); } public static ObjectIdentifier getObjectIdentifier(int values[]) throws IOException { StringBuffer retval = new StringBuffer(); int i; for (i = 0; i < values.length; i++) { if (i != 0) retval.append("."); retval.append(values[i]); } return getObjectIdentifier(retval.toString()); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/PrettyPrintFormat.java000066400000000000000000000122311362106420000263170ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; /** * This class will display the certificate content in predefined * format. * * @author Andrew Wnuk * @version $Revision$, $Date$ */ public class PrettyPrintFormat { /*========================================================== * variables *==========================================================*/ private String mSeparator = ""; private int mIndentSize = 0; private int mLineLen = 0; /*========================================================== * constants * *==========================================================*/ private final static String spaces = " " + " " + " " + " " + " "; /*========================================================== * constructors *==========================================================*/ public PrettyPrintFormat(String separator) { mSeparator = separator; } public PrettyPrintFormat(String separator, int lineLen) { mSeparator = separator; mLineLen = lineLen; } public PrettyPrintFormat(String separator, int lineLen, int indentSize) { mSeparator = separator; mLineLen = lineLen; mIndentSize = indentSize; } /*========================================================== * Private methods *==========================================================*/ /*========================================================== * public methods *==========================================================*/ /** * Provide white space indention * stevep - speed improvements. Factor of 10 improvement * * @param size number of white space to be returned * @return white spaces */ public String indent(int size) { return spaces.substring(0, size); } private static final char[] hexdigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** * Convert Byte Array to Hex String Format * stevep - speedup by factor of 8 * * @param in byte array of data to hexify * @param indentSize number of spaces to prepend before each line * @param lineLen number of bytes to output on each line (0 * means: put everything on one line * @param separator the first character of this string will be used as * the separator between bytes. * @return string representation */ public String toHexString(byte[] in, int indentSize, int lineLen, String separator) { if (in == null) { return ""; } StringBuffer sb = new StringBuffer(); int hexCount = 0; char c[]; int j = 0; if (lineLen == 0) { c = new char[in.length * 3 + 1]; } else { c = new char[lineLen * 3 + 1]; } char sep = separator.charAt(0); sb.append(indent(indentSize)); for (int i = 0; i < in.length; i++) { if (lineLen > 0 && hexCount == lineLen) { c[j++] = '\n'; sb.append(c, 0, j); sb.append(indent(indentSize)); hexCount = 0; j = 0; } byte x = in[i]; // output hex digits to buffer c[j++] = hexdigits[(char) ((x >> 4) & 0xf)]; c[j++] = hexdigits[(char) (x & 0xf)]; // if not last char, output separator if (i != in.length - 1) { c[j++] = sep; } hexCount++; } if (j > 0) { c[j++] = '\n'; sb.append(c, 0, j); } // sb.append("\n"); return sb.toString(); } public String toHexString(byte[] in, int indentSize, int lineLen) { return toHexString(in, indentSize, lineLen, mSeparator); } public String toHexString(byte[] in, int indentSize) { return toHexString(in, indentSize, mLineLen); } public String toHexString(byte[] in) { return toHexString(in, mIndentSize); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/PrettyPrintResources.java000066400000000000000000000365201362106420000270500ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.util.ListResourceBundle; import org.mozilla.jss.netscape.security.extensions.NSCertTypeExtension; import org.mozilla.jss.netscape.security.x509.KeyUsageExtension; /** * Resource Boundle for the Pretty Print * * @author Jack Pan-Chen * @version $Revision$, $Date$ */ public class PrettyPrintResources extends ListResourceBundle { /** * Returns content */ public Object[][] getContents() { return contents; } /** * Constants. The suffix represents the number of * possible parameters. */ //certificate pretty print public final static String TOKEN_CERTIFICATE = "tokenCertificate"; public final static String TOKEN_DATA = "tokenData"; public final static String TOKEN_VERSION = "tokenVersion"; public final static String TOKEN_SERIAL = "tokenSerial"; public final static String TOKEN_SIGALG = "tokenSignatureAlgorithm"; public final static String TOKEN_ISSUER = "tokenIssuer"; public final static String TOKEN_VALIDITY = "tokenValidity"; public final static String TOKEN_NOT_BEFORE = "tokenNotBefore"; public final static String TOKEN_NOT_AFTER = "tokenNotAfter"; public final static String TOKEN_SUBJECT = "tokenSubject"; public final static String TOKEN_SPKI = "tokenSPKI"; public final static String TOKEN_ALGORITHM = "tokenAlgorithm"; public final static String TOKEN_PUBLIC_KEY = "tokenPublicKey"; public final static String TOKEN_PUBLIC_KEY_MODULUS = "tokenPublicKeyModulus"; public final static String TOKEN_PUBLIC_KEY_EXPONENT = "tokenPublicKeyExponent"; public final static String TOKEN_EXTENSIONS = "tokenExtensions"; public final static String TOKEN_SIGNATURE = "tokenSignature"; //extension pretty print public final static String TOKEN_YES = "tokenYes"; public final static String TOKEN_NO = "tokenNo"; public final static String TOKEN_IDENTIFIER = "tokenIdentifier"; public final static String TOKEN_CRITICAL = "tokenCritical"; public final static String TOKEN_VALUE = "tokenValue"; //specific extension token public final static String TOKEN_KEY_TYPE = "tokenKeyType"; public final static String TOKEN_CERT_TYPE = "tokenCertType"; public final static String TOKEN_SKI = "tokenSKI"; public final static String TOKEN_AKI = "tokenAKI"; public final static String TOKEN_ACCESS_DESC = "tokenAccessDesc"; public final static String TOKEN_OCSP_NOCHECK = "tokenOcspNoCheck"; public final static String TOKEN_EXTENDED_KEY_USAGE = "tokenExtendedKeyUsage"; public final static String TOKEN_PRIVATE_KEY_USAGE = "tokenPrivateKeyUsage"; public final static String TOKEN_PRESENCE_SERVER = "tokenPresenceServer"; public final static String TOKEN_AIA = "tokenAIA"; public final static String TOKEN_CERT_POLICIES = "tokenCertPolicies"; public final static String TOKEN_SIA = "tokenSIA"; public final static String TOKEN_KEY_USAGE = "tokenKeyUsage"; public final static String TOKEN_CERT_USAGE = "tokenCertUsage"; public final static String TOKEN_KEY_ID = "tokenKeyId"; public final static String TOKEN_AUTH_NAME = "tokenAuthName"; public final static String TOKEN_CRL = "tokenCRL"; public final static String TOKEN_THIS_UPDATE = "tokenThisUpdate"; public final static String TOKEN_NEXT_UPDATE = "tokenNextUpdate"; public final static String TOKEN_REVOKED_CERTIFICATES = "revokedCerts"; public final static String TOKEN_REVOCATION_DATE = "revocationDate"; public final static String TOKEN_REVOCATION_REASON = "revocationReason"; public final static String TOKEN_REASON = "reason"; public final static String TOKEN_BASIC_CONSTRAINTS = "basicConstraints"; public final static String TOKEN_NAME_CONSTRAINTS = "tokenNameConstraints"; public final static String TOKEN_NSC_COMMENT = "tokenNSCComment"; public final static String TOKEN_IS_CA = "isCA"; public final static String TOKEN_PATH_LEN = "pathLen"; public final static String TOKEN_PATH_LEN_UNLIMITED = "pathLenUnlimited"; public final static String TOKEN_PATH_LEN_UNDEFINED = "pathLenUndefined"; public final static String TOKEN_PATH_LEN_INVALID = "pathLenInvalid"; public final static String TOKEN_CRL_NUMBER = "CRLNumber"; public final static String TOKEN_NUMBER = "Number"; public final static String TOKEN_DELTA_CRL_INDICATOR = "DeltaCRLIndicator"; public final static String TOKEN_BASE_CRL_NUMBER = "BaseCRLNumber"; public final static String TOKEN_CERT_SCOPE_OF_USE = "CertificateScopeOfUse"; public final static String TOKEN_SCOPE_OF_USE = "ScopeOfUse"; public final static String TOKEN_PORT = "Port"; public final static String TOKEN_ISSUER_ALT_NAME = "IssuerAlternativeName"; public final static String TOKEN_ISSUER_NAMES = "IssuerNames"; public final static String TOKEN_SUBJECT_ALT_NAME = "SubjectAlternativeName"; public final static String TOKEN_SUBJECT_NAME = "SubjectName"; public final static String TOKEN_DECODING_ERROR = "decodingError"; public final static String TOKEN_FRESHEST_CRL_EXT = "FreshestCRL"; public final static String TOKEN_INHIBIT_ANY_POLICY_EXT = "InhibitAnyPolicy"; public final static String TOKEN_SKIP_CERTS = "SkipCerts"; public final static String TOKEN_CRL_DP_EXT = "CRLDistributionPoints"; public final static String TOKEN_CRLDP_NUMPOINTS = "CRLDP_NUMPOINTS"; public final static String TOKEN_CRLDP_POINTN = "CRLDP_POINTN"; public final static String TOKEN_CRLDP_DISTPOINT = "CRLDP_DISTPOINT"; public final static String TOKEN_CRLDP_REASONS = "CRLDP_REASONS"; public final static String TOKEN_CRLDP_CRLISSUER = "CRLDP_CRLISSUER"; public final static String TOKEN_ISSUING_DIST_POINT = "IssuingDistributionPoint"; public final static String TOKEN_DIST_POINT_NAME = "DistributionPointName"; public final static String TOKEN_FULL_NAME = "FullName"; public final static String TOKEN_RELATIVE_NAME = "NameRelativeToCRLIssuer"; public final static String TOKEN_ONLY_USER_CERTS = "OnlyContainsUserCerts"; public final static String TOKEN_ONLY_CA_CERTS = "OnlyContainsCACerts"; public final static String TOKEN_ONLY_SOME_REASONS = "OnlySomeReasons"; public final static String TOKEN_INDIRECT_CRL = "IndirectCRL"; public final static String TOKEN_INVALIDITY_DATE = "invalidityDate"; public final static String TOKEN_DATE_OF_INVALIDITY = "dateOfInvalidity"; public final static String TOKEN_CERTIFICATE_ISSUER = "CertificateIssuer"; public final static String TOKEN_HOLD_INSTRUCTION = "HoldInstruction"; public final static String TOKEN_HOLD_INSTRUCTION_CODE = "HoldInstructionCode"; public final static String TOKEN_POLICY_CONSTRAINTS = "PolicyConstraints"; public final static String TOKEN_POLICY_MAPPINGS = "PolicyMappings"; public final static String TOKEN_SUBJECT_DIR_ATTR = "SubjectDirectoryAttributes"; // policy constriants extension fields public final static String TOKEN_INHIBIT_POLICY_MAPPING = "inhibitPolicyMapping"; public final static String TOKEN_REQUIRE_EXPLICIT_POLICY = "requireExplicitPolicy"; // policy mappings extension fields public final static String TOKEN_MAPPINGS = "mappings"; public final static String TOKEN_MAP = "map"; public final static String TOKEN_ISSUER_DOMAIN_POLICY = "issuerDomainPolicy"; public final static String TOKEN_SUBJECT_DOMAIN_POLICY = "subjectDomainPolicy"; // subject directory attribute fields public final static String TOKEN_ATTRIBUTES = "Attributes"; public final static String TOKEN_ATTRIBUTE = "Attribute"; public final static String TOKEN_VALUES = "Values"; // field values public final static String TOKEN_NOT_SET = "notSet"; public final static String TOKEN_NONE = "none"; public final static String TOKEN_CACHE_NOT_AVAILABLE = "cacheNotAvailable"; public final static String TOKEN_CACHE_IS_EMPTY = "cacheIsEmpty"; //Tokens should have blank_space as trailer static final Object[][] contents = { { TOKEN_CERTIFICATE, "Certificate: " }, { TOKEN_DATA, "Data: " }, { TOKEN_VERSION, "Version: " }, { TOKEN_SERIAL, "Serial Number: " }, { TOKEN_SIGALG, "Signature Algorithm: " }, { TOKEN_ISSUER, "Issuer: " }, { TOKEN_VALIDITY, "Validity: " }, { TOKEN_NOT_BEFORE, "Not Before: " }, { TOKEN_NOT_AFTER, "Not After: " }, { TOKEN_SUBJECT, "Subject: " }, { TOKEN_SPKI, "Subject Public Key Info: " }, { TOKEN_ALGORITHM, "Algorithm: " }, { TOKEN_PUBLIC_KEY, "Public Key: " }, { TOKEN_PUBLIC_KEY_MODULUS, "Public Key Modulus: " }, { TOKEN_PUBLIC_KEY_EXPONENT, "Exponent: " }, { TOKEN_EXTENSIONS, "Extensions: " }, { TOKEN_SIGNATURE, "Signature: " }, { TOKEN_YES, "yes " }, { TOKEN_NO, "no " }, { TOKEN_IDENTIFIER, "Identifier: " }, { TOKEN_CRITICAL, "Critical: " }, { TOKEN_VALUE, "Value: " }, { TOKEN_KEY_TYPE, "Key Type " }, { TOKEN_CERT_TYPE, "Netscape Certificate Type " }, { TOKEN_SKI, "Subject Key Identifier " }, { TOKEN_AKI, "Authority Key Identifier " }, { TOKEN_ACCESS_DESC, "Access Description: " }, { TOKEN_OCSP_NOCHECK, "OCSP NoCheck: " }, { TOKEN_EXTENDED_KEY_USAGE, "Extended Key Usage: " }, { TOKEN_PRIVATE_KEY_USAGE, "Private Key Usage: " }, { TOKEN_PRESENCE_SERVER, "Presence Server: " }, { TOKEN_AIA, "Authority Info Access: " }, { TOKEN_CERT_POLICIES, "Certificate Policies: " }, { TOKEN_SIA, "Subject Info Access: " }, { TOKEN_KEY_USAGE, "Key Usage: " }, { KeyUsageExtension.DIGITAL_SIGNATURE, "Digital Signature " }, { KeyUsageExtension.NON_REPUDIATION, "Non Repudiation " }, { KeyUsageExtension.KEY_ENCIPHERMENT, "Key Encipherment " }, { KeyUsageExtension.DATA_ENCIPHERMENT, "Data Encipherment " }, { KeyUsageExtension.KEY_AGREEMENT, "Key Agreement " }, { KeyUsageExtension.KEY_CERTSIGN, "Key CertSign " }, { KeyUsageExtension.CRL_SIGN, "Crl Sign " }, { KeyUsageExtension.ENCIPHER_ONLY, "Encipher Only " }, { KeyUsageExtension.DECIPHER_ONLY, "Decipher Only " }, { TOKEN_CERT_USAGE, "Certificate Usage: " }, { NSCertTypeExtension.SSL_CLIENT, "SSL Client " }, { NSCertTypeExtension.SSL_SERVER, "SSL Server " }, { NSCertTypeExtension.EMAIL, "Secure Email " }, { NSCertTypeExtension.OBJECT_SIGNING, "Object Signing " }, { NSCertTypeExtension.SSL_CA, "SSL CA " }, { NSCertTypeExtension.EMAIL_CA, "Secure Email CA " }, { NSCertTypeExtension.OBJECT_SIGNING_CA, "ObjectSigning CA " }, { TOKEN_KEY_ID, "Key Identifier: " }, { TOKEN_AUTH_NAME, "Authority Name: " }, { TOKEN_CRL, "Certificate Revocation List: " }, { TOKEN_THIS_UPDATE, "This Update: " }, { TOKEN_NEXT_UPDATE, "Next Update: " }, { TOKEN_REVOKED_CERTIFICATES, "Revoked Certificates: " }, { TOKEN_REVOCATION_DATE, "Revocation Date: " }, { TOKEN_REVOCATION_REASON, "Revocation Reason " }, { TOKEN_REASON, "Reason: " }, { TOKEN_BASIC_CONSTRAINTS, "Basic Constraints " }, { TOKEN_NAME_CONSTRAINTS, "Name Constraints " }, { TOKEN_NSC_COMMENT, "Netscape Comment " }, { TOKEN_IS_CA, "Is CA: " }, { TOKEN_PATH_LEN, "Path Length Constraint: " }, { TOKEN_PATH_LEN_UNLIMITED, "UNLIMITED" }, { TOKEN_PATH_LEN_UNDEFINED, "UNDEFINED" }, { TOKEN_PATH_LEN_INVALID, "INVALID" }, { TOKEN_CRL_NUMBER, "CRL Number " }, { TOKEN_NUMBER, "Number: " }, { TOKEN_DELTA_CRL_INDICATOR, "Delta CRL Indicator " }, { TOKEN_BASE_CRL_NUMBER, "Base CRL Number: " }, { TOKEN_CERT_SCOPE_OF_USE, "Certificate Scope of Use " }, { TOKEN_SCOPE_OF_USE, "Scope of Use: " }, { TOKEN_PORT, "Port: " }, { TOKEN_ISSUER_ALT_NAME, "Issuer Alternative Name " }, { TOKEN_ISSUER_NAMES, "Issuer Names: " }, { TOKEN_SUBJECT_ALT_NAME, "Subject Alternative Name " }, { TOKEN_DECODING_ERROR, "Decoding Error" }, { TOKEN_FRESHEST_CRL_EXT, "Freshest CRL " }, { TOKEN_INHIBIT_ANY_POLICY_EXT, "Inhibit Any-Policy " }, { TOKEN_SKIP_CERTS, "Skip Certs: " }, { TOKEN_CRL_DP_EXT, "CRL Distribution Points " }, { TOKEN_CRLDP_NUMPOINTS, "Number of Points: " }, { TOKEN_CRLDP_POINTN, "Point " }, { TOKEN_CRLDP_DISTPOINT, "Distribution Point: " }, { TOKEN_CRLDP_REASONS, "Reason Flags: " }, { TOKEN_CRLDP_CRLISSUER, "CRL Issuer: " }, { TOKEN_ISSUING_DIST_POINT, "Issuing Distribution Point " }, { TOKEN_DIST_POINT_NAME, "Distribution Point: " }, { TOKEN_FULL_NAME, "Full Name: " }, { TOKEN_RELATIVE_NAME, "Name Relative To CRL Issuer: " }, { TOKEN_ONLY_USER_CERTS, "Only Contains User Certificates: " }, { TOKEN_ONLY_CA_CERTS, "Only Contains CA Certificates: " }, { TOKEN_ONLY_SOME_REASONS, "Only Some Reasons: " }, { TOKEN_INDIRECT_CRL, "Indirect CRL: " }, { TOKEN_INVALIDITY_DATE, "Invalidity Date " }, { TOKEN_DATE_OF_INVALIDITY, "Invalidity Date: " }, { TOKEN_CERTIFICATE_ISSUER, "Certificate Issuer " }, { TOKEN_HOLD_INSTRUCTION, "Hold Instruction Code " }, { TOKEN_HOLD_INSTRUCTION_CODE, "Hold Instruction Code: " }, { TOKEN_POLICY_CONSTRAINTS, "Policy Constraints " }, { TOKEN_INHIBIT_POLICY_MAPPING, "Inhibit Policy Mapping: " }, { TOKEN_REQUIRE_EXPLICIT_POLICY, "Require Explicit Policy: " }, { TOKEN_POLICY_MAPPINGS, "Policy Mappings " }, { TOKEN_MAPPINGS, "Mappings: " }, { TOKEN_MAP, "Map " }, { TOKEN_ISSUER_DOMAIN_POLICY, "Issuer Domain Policy: " }, { TOKEN_SUBJECT_DOMAIN_POLICY, "Subject Domain Policy: " }, { TOKEN_SUBJECT_DIR_ATTR, "Subject Directory Attributes " }, { TOKEN_ATTRIBUTES, "Attributes:" }, { TOKEN_ATTRIBUTE, "Attribute " }, { TOKEN_VALUES, "Values: " }, { TOKEN_NOT_SET, "not set" }, { TOKEN_NONE, "none" }, { TOKEN_CACHE_NOT_AVAILABLE, "CRL cache is not available. " }, { TOKEN_CACHE_IS_EMPTY, "CRL cache is empty. " }, }; } jss-4.6.3/org/mozilla/jss/netscape/security/util/PrintableCharset.java000066400000000000000000000022251362106420000260760ustar00rootroot00000000000000package org.mozilla.jss.netscape.security.util; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; public class PrintableCharset extends Charset { public PrintableCharset() { super("ASN.1-Printable", null); } public static boolean isPrintableChar(char c) { if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && (c < '0' || c > '9') && (c != ' ') && (c != '\'') && (c != '(') && (c != ')') && (c != '+') && (c != ',') && (c != '-') && (c != '.') && (c != '/') && (c != ':') && (c != '=') && (c != '?')) { return false; } else { return true; } } public boolean contains(Charset cs) { return false; } public CharsetDecoder newDecoder() { return new PrintableCharsetDecoder(this); } public CharsetEncoder newEncoder() { return new PrintableCharsetEncoder(this); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/PrintableCharsetDecoder.java000066400000000000000000000040531362106420000273650ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; /** * Converts bytes in ASN.1 PrintableString character set to PrintableString * characters. * * @author Lily Hsiao * @author Slava Galperin */ public class PrintableCharsetDecoder extends CharsetDecoder { public PrintableCharsetDecoder(Charset cs) { super(cs, 1, 1); } protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) { while (true) { if (in.remaining() < 1) return CoderResult.UNDERFLOW; in.mark(); byte b = in.get(); char c = (char) (b & 0x7f); if (CodingErrorAction.REPORT == unmappableCharacterAction() && !PrintableCharset.isPrintableChar(c)) { /* "bug" fix for 359010 return CoderResult.unmappableForLength(1); */ continue; } if (out.remaining() < 1) { in.reset(); return CoderResult.OVERFLOW; } out.put(c); } } } jss-4.6.3/org/mozilla/jss/netscape/security/util/PrintableCharsetEncoder.java000066400000000000000000000043001362106420000273720ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; /** * Converts characters in ASN.1 PrintableString character set to PrintableString * bytes. * * @author Lily Hsiao * @author Slava Galperin */ public class PrintableCharsetEncoder extends CharsetEncoder { public PrintableCharsetEncoder(Charset cs) { super(cs, 1, 1); } /* * Converts an array of Unicode characters into an array of PrintableString * bytes and returns the conversion result. * @param in input character buffer to convert. * @param out byte buffer to store output. * @return encoding result. */ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) { while (true) { if (in.remaining() < 1) return CoderResult.UNDERFLOW; in.mark(); char c = in.get(); if (CodingErrorAction.REPORT == unmappableCharacterAction() && !PrintableCharset.isPrintableChar(c)) { return CoderResult.unmappableForLength(1); } if (out.remaining() < 1) { in.reset(); return CoderResult.OVERFLOW; } out.put((byte) (c & 0x7f)); } } } jss-4.6.3/org/mozilla/jss/netscape/security/util/PubKeyPrettyPrint.java000066400000000000000000000106711362106420000262740ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.security.InvalidKeyException; import java.security.PublicKey; import java.util.Locale; import java.util.ResourceBundle; import org.mozilla.jss.netscape.security.provider.RSAPublicKey; import org.mozilla.jss.netscape.security.x509.X509Key; /** * This class will display the certificate content in predefined * format. * * @author Jack Pan-Chen * @author Andrew Wnuk * @version $Revision$, $Date$ */ public class PubKeyPrettyPrint { /*========================================================== * variables *==========================================================*/ private X509Key mX509Key = null; private PrettyPrintFormat pp = null; /*========================================================== * constructors *==========================================================*/ public PubKeyPrettyPrint(PublicKey key) { if (key instanceof X509Key) mX509Key = (X509Key) key; pp = new PrettyPrintFormat(":"); } /*========================================================== * public methods *==========================================================*/ /** * This method return string representation of the certificate * in predefined format using specified client local. I18N Support. * * @param clientLocale Locale to be used for localization * @return string representation of the certificate */ public String toString(Locale clientLocale, int indentSize, int lineLen) { if (mX509Key != null) return X509toString(clientLocale, indentSize, lineLen); else return null; } public String X509toString(Locale clientLocale, int indentSize, int lineLen) { //get I18N resources ResourceBundle resource = ResourceBundle.getBundle( PrettyPrintResources.class.getName()); StringBuffer sb = new StringBuffer(); try { String alg = mX509Key.getAlgorithm(); //XXX I18N Algorithm Name ? sb.append(pp.indent(indentSize) + resource.getString( PrettyPrintResources.TOKEN_ALGORITHM) + alg + " - " + mX509Key.getAlgorithmId().getOID().toString() + "\n"); if (alg.equals("RSA")) { RSAPublicKey rsakey = new RSAPublicKey(mX509Key.getEncoded()); sb.append(pp.indent(indentSize) + resource.getString( PrettyPrintResources.TOKEN_PUBLIC_KEY) + "\n"); sb.append(pp.indent(indentSize + 4) + resource.getString( PrettyPrintResources.TOKEN_PUBLIC_KEY_EXPONENT) + rsakey.getPublicExponent().toInt() + "\n"); sb.append(pp.indent(indentSize + 4) + resource.getString( PrettyPrintResources.TOKEN_PUBLIC_KEY_MODULUS) + "(" + rsakey.getKeySize() + " bits) :\n"); sb.append(pp.toHexString( rsakey.getModulus().toByteArray(), indentSize + 8, lineLen)); } else { // DSAPublicKey is more complicated to decode, since // the DSAParams (PQG) is not fully decoded. // So, we just print the entire public key blob sb.append(pp.indent(indentSize) + resource.getString( PrettyPrintResources.TOKEN_PUBLIC_KEY) + "\n"); sb.append(pp.toHexString(mX509Key.getKey(), indentSize + 4, lineLen)); } } catch(InvalidKeyException e){ e.printStackTrace(); } return sb.toString(); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/UniversalCharset.java000066400000000000000000000010571362106420000261300ustar00rootroot00000000000000package org.mozilla.jss.netscape.security.util; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; public class UniversalCharset extends Charset { public UniversalCharset() { super("ASN.1-Universal", null); } public boolean contains(Charset cs) { return false; } public CharsetDecoder newDecoder() { return new UniversalCharsetDecoder(this); } public CharsetEncoder newEncoder() { return new UniversalCharsetEncoder(this); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/UniversalCharsetDecoder.java000066400000000000000000000067001362106420000274160ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; /** * Converts bytes in ASN.1 UniversalString character set to UniversalString * characters. * * @author Lily Hsiao * @author Slava Galperin */ public class UniversalCharsetDecoder extends CharsetDecoder { public UniversalCharsetDecoder(Charset cs) { super(cs, 0.25f, 1); } protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) { while (true) { // XXX we do not know what to do with truly UCS-4 characters here // we also assumed network byte order if (in.remaining() < 4) return CoderResult.UNDERFLOW; in.mark(); byte b0 = in.get(); byte b1 = in.get(); byte b2 = in.get(); byte b3 = in.get(); if (CodingErrorAction.REPORT == unmappableCharacterAction() && !((b0 == 0 && b1 == 0) || (b2 == 0 && b3 == 0))) { return CoderResult.unmappableForLength(4); } char c; if (b2 == 0 && b3 == 0) { // Try to be a bit forgiving. If the byte order is // reversed, we still try handle it. // Sample Date Set (1): // 0000000 f 0 \0 \0 213 0 \0 \0 S 0 \0 \0 // 0000014 // Sample Date Set (2): // 0000000 w \0 \0 \0 w \0 \0 \0 w \0 \0 \0 . \0 \0 \0 // 0000020 ( \0 \0 \0 t \0 \0 \0 o \0 \0 \0 b \0 \0 \0 // 0000040 e \0 \0 \0 | \0 \0 \0 n \0 \0 \0 o \0 \0 \0 // 0000060 t \0 \0 \0 t \0 \0 \0 o \0 \0 \0 b \0 \0 \0 // 0000100 e \0 \0 \0 ) \0 \0 \0 . \0 \0 \0 c \0 \0 \0 // 0000120 o \0 \0 \0 m \0 \0 \0 // 0000130 c = (char) (((b1 << 8) & 0xff00) + (b0 & 0x00ff)); } else { // (b0 == 0 && b1 == 0) // This should be the right order. // // 0000000 0000 00c4 0000 0064 0000 006d 0000 0069 // 0000020 0000 006e 0000 0020 0000 0051 0000 0041 // 0000040 c = (char) (((b2 << 8) & 0xff00) + (b3 & 0x00ff)); } if (out.remaining() < 1) { in.reset(); return CoderResult.OVERFLOW; } out.put(c); } } } jss-4.6.3/org/mozilla/jss/netscape/security/util/UniversalCharsetEncoder.java000066400000000000000000000041141362106420000274250ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; /** * Converts characters in ASN.1 UniversalString character set to UniversalString * bytes. * * @author Lily Hsiao * @author Slava Galperin */ public class UniversalCharsetEncoder extends CharsetEncoder { public UniversalCharsetEncoder(Charset cs) { super(cs, 4, 4, new byte[] { 0, 0, 0, 0 }); } /* * Converts an array of Unicode characters into an array of UniversalString * bytes and returns the conversion result. * @param in input character buffer to convert. * @param out byte buffer to store output. * @return encoding result. */ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) { while (true) { if (in.remaining() < 1) return CoderResult.UNDERFLOW; in.mark(); char c = in.get(); if (out.remaining() < 4) { in.reset(); return CoderResult.OVERFLOW; } out.put((byte) 0); out.put((byte) 0); out.put((byte) ((c >> 8) & 0xff)); out.put((byte) (c & 0xff)); } } } jss-4.6.3/org/mozilla/jss/netscape/security/util/Utils.java000066400000000000000000000324371362106420000237540ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.util; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.UnknownHostException; import java.text.SimpleDateFormat; import java.util.Base64; import java.util.Date; import java.util.StringTokenizer; import java.util.Vector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Utils { public static Logger logger = LoggerFactory.getLogger(Utils.class); /** * Checks if this is NT. */ public static boolean isNT() { return File.separator.equals("\\"); } public static boolean isUnix() { return File.separator.equals("/"); } public static boolean exec(String cmd) { try { String cmds[] = null; if (isNT()) { // NT cmds = new String[3]; cmds[0] = "cmd"; cmds[1] = "/c"; cmds[2] = cmd; } else { // UNIX cmds = new String[3]; cmds[0] = "/bin/sh"; cmds[1] = "-c"; cmds[2] = cmd; } Process process = Runtime.getRuntime().exec(cmds); process.waitFor(); if (process.exitValue() == 0) { /** * pOut = new BufferedReader( * new InputStreamReader(process.getInputStream())); * while ((l = pOut.readLine()) != null) { * System.out.println(l); * } **/ return true; } else { /** * pOut = new BufferedReader( * new InputStreamReader(process.getErrorStream())); * l = null; * while ((l = pOut.readLine()) != null) { * System.out.println(l); * } **/ return false; } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return false; } public static String readFromStream(InputStream inputStream) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(inputStream)); String line = null; while ((line = br.readLine()) != null) { sb.append(line + System.getProperty("line.separator")); } } finally { br.close(); } return sb.toString().trim(); } public static void writeToStream(OutputStream outputStream, String input) throws IOException { BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream)); writer.write(input); writer.flush(); writer.close(); } /** * Utility method to execute system commands * * @param cmd The command to be executed and its arguments * @param input The stdin input to be passed to the cmd * @return stdout or stderr of the command executed * @throws IOException * @throws InterruptedException */ public static String exec(String[] cmd, String input) throws IOException, InterruptedException { ProcessBuilder pb = new ProcessBuilder(cmd); Process p = pb.start(); if (input != null) { writeToStream(p.getOutputStream(), input); } p.waitFor(); String output; if (p.exitValue() == 0) { output = readFromStream(p.getInputStream()); } else { output = readFromStream(p.getErrorStream()); } p.destroy(); return output; } public static String SpecialURLDecode(String s) { if (s == null) return null; ByteArrayOutputStream out = new ByteArrayOutputStream(s.length()); for (int i = 0; i < s.length(); i++) { int c = s.charAt(i); if (c == '+') { out.write(' '); } else if (c == '#') { int c1 = Character.digit(s.charAt(++i), 16); int c2 = Character.digit(s.charAt(++i), 16); out.write((char) (c1 * 16 + c2)); } else { out.write(c); } } // end for return out.toString(); } public static byte[] SpecialDecode(String s) { if (s == null) return null; ByteArrayOutputStream out = new ByteArrayOutputStream(s.length()); for (int i = 0; i < s.length(); i++) { int c = s.charAt(i); if (c == '+') { out.write(' '); } else if (c == '#') { int c1 = Character.digit(s.charAt(++i), 16); int c2 = Character.digit(s.charAt(++i), 16); out.write((char) (c1 * 16 + c2)); } else { out.write(c); } } // end for return out.toByteArray(); } public static String SpecialEncode(byte data[]) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < data.length; i++) { sb.append("%"); if ((data[i] & 0xff) < 16) { sb.append("0"); } sb.append(Integer.toHexString((data[i] & 0xff))); } return sb.toString().toUpperCase(); } public static String HexEncode(byte data[]) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < data.length; i++) { if ((data[i] & 0xff) < 16) { sb.append("0"); } sb.append(Integer.toHexString((data[i] & 0xff))); } return sb.toString(); } public static void checkHost(String hostname) throws UnknownHostException { InetAddress.getByName(hostname); } public static void copy(String orig, String dest) throws Exception { BufferedReader in = null; PrintWriter out = null; try { in = new BufferedReader(new FileReader(orig)); out = new PrintWriter( new BufferedWriter(new FileWriter(dest))); String line = ""; while (in.ready()) { line = in.readLine(); if (line != null) out.println(line); } } catch (Exception ee) { ee.printStackTrace(); throw ee; } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out != null) { out.close(); } } } public static void copyStream(InputStream in, OutputStream out) throws IOException { byte[] buf = new byte[4096]; int len; while ((len = in.read(buf)) != -1) { out.write(buf, 0, len); } } public static void copyStream(BufferedReader in, OutputStreamWriter out) throws IOException { char[] buf = new char[4096]; int len; while ((len = in.read(buf)) != -1) { out.write(buf, 0, len); } } /// Sorts an array of Strings. // Java currently has no general sort function. Sorting Strings is // common enough that it's worth making a special case. public static void sortStrings(String[] strings) { // Just does a bubblesort. for (int i = 0; i < strings.length - 1; ++i) { for (int j = i + 1; j < strings.length; ++j) { if (strings[i].compareTo(strings[j]) > 0) { String t = strings[i]; strings[i] = strings[j]; strings[j] = t; } } } } /// Returns a date string formatted in Unix ls style - if it's within // six months of now, Mmm dd hh:ss, else Mmm dd yyyy. public static String lsDateStr(Date date) { long dateTime = date.getTime(); if (dateTime == -1L) return "------------"; long nowTime = System.currentTimeMillis(); SimpleDateFormat formatter = new SimpleDateFormat(); if (Math.abs(nowTime - dateTime) < 183L * 24L * 60L * 60L * 1000L) formatter.applyPattern("MMM dd hh:ss"); else formatter.applyPattern("MMM dd yyyy"); return formatter.format(date); } /** * compares contents two byte arrays returning true if exactly same. */ static public boolean byteArraysAreEqual(byte[] a, byte[] b) { if (a.length != b.length) return false; for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) return false; } return true; } /** * strips out double quotes around String parameter * * @param s the string potentially bracketed with double quotes * @return string stripped of surrounding double quotes */ public static String stripQuotes(String s) { if (s == null) { return s; } if ((s.startsWith("\"")) && (s.endsWith("\""))) { return (s.substring(1, (s.length() - 1))); } return s; } /** * returns an array of strings from a vector of Strings * there'll be trouble if the Vector contains something other * than just Strings */ public static String[] getStringArrayFromVector(Vector v) { String s[] = new String[v.size()]; v.copyInto(s); return s; } /** * Converts a byte array into a Base-64 encoded string. * If the chunked option is true, the output will be split into * multiple lines. Otherwise, the output will be a single line. * * @param bytes byte array * @param chunked generate chunked output * @return base-64 encoded data */ public static String base64encode(byte[] bytes, boolean chunked) { if (chunked) { return base64encodeMultiLine(bytes); } else { return base64encodeSingleLine(bytes); } } /** * Converts a byte array into a multi-line Base-64 encoded string. * Each line is at most 64-character long and terminated with CRLF. * * @param bytes byte array * @return base-64 encoded data */ public static String base64encodeMultiLine(byte[] bytes) { return Base64.getMimeEncoder().encodeToString(bytes); } /** * Converts a byte array into a single-line Base-64 encoded string. * The line is not terminated with CRLF. * * @param bytes byte array * @return base-64 encoded data */ public static String base64encodeSingleLine(byte[] bytes) { return Base64.getEncoder().encodeToString(bytes); } /** * Converts a Base-64 encoded string into a byte array. * * @param string base-64 encoded data * @return byte array */ public static byte[] base64decode(String string) { try { return Base64.getMimeDecoder().decode(string); } catch (IllegalArgumentException iae) { logger.warn("Invalid base64: [" + string + "]: " + iae); return new byte[0]; } } /** * Normalize B64 input String * * @param string base-64 string * @return normalized string */ public static String normalizeString(String string) { return normalizeString(string, false); } /** * Normalize B64 input String * * @param string base-64 string * @param keepSpace a boolean variable to control whether to keep spaces or not * @return normalized string */ public static String normalizeString(String string, Boolean keepSpace) { if (string == null) { return string; } StringBuffer sb = new StringBuffer(); StringTokenizer st = null; if (keepSpace) st = new StringTokenizer(string, "\r\n"); else st = new StringTokenizer(string, "\r\n "); while (st.hasMoreTokens()) { String nextLine = st.nextToken(); nextLine = nextLine.trim(); sb.append(nextLine); } return sb.toString(); } } jss-4.6.3/org/mozilla/jss/netscape/security/util/WrappingParams.java000066400000000000000000000262011362106420000255770ustar00rootroot00000000000000package org.mozilla.jss.netscape.security.util; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.IVParameterSpec; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.SymmetricKey.Type; public class WrappingParams { // session key attributes SymmetricKey.Type skType; KeyGenAlgorithm skKeyGenAlgorithm; int skLength; // wrapping algorithm for session key KeyWrapAlgorithm skWrapAlgorithm; // Encryption algorithm for payload EncryptionAlgorithm payloadEncryptionAlgorithm; //wrapping algorithm for payload KeyWrapAlgorithm payloadWrapAlgorithm; // payload encryption IV IVParameterSpec payloadEncryptionIV; // payload wrapping IV IVParameterSpec payloadWrappingIV; public WrappingParams(Type skType, KeyGenAlgorithm skKeyGenAlgorithm, int skLength, KeyWrapAlgorithm skWrapAlgorithm, EncryptionAlgorithm payloadEncryptionAlgorithm, KeyWrapAlgorithm payloadWrapAlgorithm, IVParameterSpec payloadEncryptIV, IVParameterSpec payloadWrapIV) { super(); this.skType = skType; this.skKeyGenAlgorithm = skKeyGenAlgorithm; this.skLength = skLength; this.skWrapAlgorithm = skWrapAlgorithm; this.payloadEncryptionAlgorithm = payloadEncryptionAlgorithm; this.payloadWrapAlgorithm = payloadWrapAlgorithm; this.payloadEncryptionIV = payloadEncryptIV; this.payloadWrappingIV = payloadWrapIV; } public static EncryptionAlgorithm getEncryptionAlgorithmFromName(String name) throws Exception { String fields[] = name.split("//"); String alg = fields[0]; String mode = fields[1]; String padding = fields[2]; int strength = Integer.parseInt(fields[3]); return EncryptionAlgorithm.lookup(alg, mode, padding, strength); } public WrappingParams() {} public WrappingParams(String encryptOID, String wrapName, String priKeyAlgo, IVParameterSpec encryptIV, IVParameterSpec wrapIV) throws NumberFormatException, NoSuchAlgorithmException { EncryptionAlgorithm encrypt = null; OBJECT_IDENTIFIER eccOID = new OBJECT_IDENTIFIER("1.2.840.10045.2.1"); if (encryptOID.equals(eccOID.toString())) { // old CRMFPopClients send this OID for ECC Keys for no apparent reason. // New clients set this correctly. // We'll assume the old DES3 wrapping here. encrypt = EncryptionAlgorithm.DES_CBC_PAD; } else if (encryptOID.equals(KeyWrapAlgorithm.DES3_CBC_PAD_OID.toString())) { encrypt = EncryptionAlgorithm.DES3_CBC_PAD; } else if (encryptOID.equals(KeyWrapAlgorithm.AES_CBC_PAD_OID.toString())) { encrypt = EncryptionAlgorithm.AES_128_CBC_PAD; } else { encrypt = EncryptionAlgorithm.fromOID(new OBJECT_IDENTIFIER(encryptOID)); } KeyWrapAlgorithm wrap = null; if (wrapName != null) { wrap = KeyWrapAlgorithm.fromString(wrapName); payloadWrapAlgorithm = wrap; } switch (encrypt.getAlg().toString()) { case "AES": // TODO(alee) - Terrible hack till we figure out why GCM is not working // or a way to detect the padding. // We are going to assume AES-128-PAD encrypt = EncryptionAlgorithm.AES_128_CBC_PAD; skType = SymmetricKey.AES; skKeyGenAlgorithm = KeyGenAlgorithm.AES; if (wrap == null) payloadWrapAlgorithm = KeyWrapAlgorithm.AES_KEY_WRAP_PAD; break; case "DESede": skType = SymmetricKey.DES3; skKeyGenAlgorithm = KeyGenAlgorithm.DES3; skWrapAlgorithm = KeyWrapAlgorithm.DES3_CBC_PAD; if (wrap == null) payloadWrapAlgorithm = KeyWrapAlgorithm.DES3_CBC_PAD; break; case "DES": skType = SymmetricKey.DES; skKeyGenAlgorithm = KeyGenAlgorithm.DES; skWrapAlgorithm = KeyWrapAlgorithm.DES3_CBC_PAD; if (wrap == null) payloadWrapAlgorithm = KeyWrapAlgorithm.DES_CBC_PAD; break; default: throw new NoSuchAlgorithmException("Invalid algorithm"); } this.skLength = encrypt.getKeyStrength(); if (priKeyAlgo.equals("EC")) { skWrapAlgorithm = KeyWrapAlgorithm.AES_ECB; } else { skWrapAlgorithm = KeyWrapAlgorithm.RSA; } payloadEncryptionAlgorithm = encrypt; payloadEncryptionIV = encryptIV; if (payloadWrapAlgorithm == KeyWrapAlgorithm.AES_KEY_WRAP_PAD) { // TODO(alee) Hack -- if we pass in null for the iv in the // PKIArchiveOptions, we fail to decode correctly when parsing a // CRMFPopClient request. payloadWrappingIV = null; } else { payloadWrappingIV = wrapIV; } } private WrappingParams(String wrapOID, String priKeyAlgo, IVParameterSpec wrapIV) throws NumberFormatException, NoSuchAlgorithmException { KeyWrapAlgorithm kwAlg = KeyWrapAlgorithm.fromOID(wrapOID); if (kwAlg == KeyWrapAlgorithm.AES_KEY_WRAP_PAD) { skType = SymmetricKey.AES; skKeyGenAlgorithm = KeyGenAlgorithm.AES; payloadWrapAlgorithm = KeyWrapAlgorithm.AES_KEY_WRAP_PAD; payloadEncryptionAlgorithm = EncryptionAlgorithm.AES_128_CBC_PAD; skLength = 128; } else if (kwAlg == KeyWrapAlgorithm.AES_CBC_PAD) { skType = SymmetricKey.AES; skKeyGenAlgorithm = KeyGenAlgorithm.AES; payloadWrapAlgorithm = KeyWrapAlgorithm.AES_CBC_PAD; payloadEncryptionAlgorithm = EncryptionAlgorithm.AES_128_CBC_PAD; skLength = 128; } else if (kwAlg == KeyWrapAlgorithm.DES3_CBC_PAD) { skType = SymmetricKey.DES3; skKeyGenAlgorithm = KeyGenAlgorithm.DES3; skWrapAlgorithm = KeyWrapAlgorithm.DES3_CBC_PAD; payloadWrapAlgorithm = KeyWrapAlgorithm.DES3_CBC_PAD; payloadEncryptionAlgorithm = EncryptionAlgorithm.DES3_CBC_PAD; skLength = payloadEncryptionAlgorithm.getKeyStrength(); } else if (kwAlg == KeyWrapAlgorithm.DES_CBC_PAD) { skType = SymmetricKey.DES; skKeyGenAlgorithm = KeyGenAlgorithm.DES; skWrapAlgorithm = KeyWrapAlgorithm.DES3_CBC_PAD; payloadWrapAlgorithm = KeyWrapAlgorithm.DES3_CBC_PAD; payloadEncryptionAlgorithm = EncryptionAlgorithm.DES_CBC_PAD; skLength = payloadEncryptionAlgorithm.getKeyStrength(); } if (priKeyAlgo.equals("EC")) { skWrapAlgorithm = KeyWrapAlgorithm.AES_ECB; } else { skWrapAlgorithm = KeyWrapAlgorithm.RSA; } // set the IVs payloadEncryptionIV = wrapIV; if (payloadWrapAlgorithm == KeyWrapAlgorithm.AES_KEY_WRAP_PAD) { // TODO(alee) Hack -- if we pass in null for the iv in the // PKIArchiveOptions, we fail to decode correctly when parsing a // CRMFPopClient request. payloadWrappingIV = null; } else { payloadWrappingIV = wrapIV; } } public static WrappingParams getWrappingParamsFromArchiveOptions(String wrapOID, String priKeyAlgo, IVParameterSpec wrapIV) throws NumberFormatException, NoSuchAlgorithmException { return new WrappingParams(wrapOID, priKeyAlgo, wrapIV); } public SymmetricKey.Type getSkType() { return skType; } public void setSkType(SymmetricKey.Type skType) { this.skType = skType; } public void setSkType(String skTypeName) throws NoSuchAlgorithmException { this.skType = SymmetricKey.Type.fromName(skTypeName); } public KeyGenAlgorithm getSkKeyGenAlgorithm() { return skKeyGenAlgorithm; } public void setSkKeyGenAlgorithm(KeyGenAlgorithm skKeyGenAlgorithm) { this.skKeyGenAlgorithm = skKeyGenAlgorithm; } public void setSkKeyGenAlgorithm(String algName) throws NoSuchAlgorithmException { // JSS mapping is not working. Lets just do something brain-dead to // handle the cases we expect. if (algName.equalsIgnoreCase("AES")) { skKeyGenAlgorithm = KeyGenAlgorithm.AES; } else if (algName.equalsIgnoreCase("DES")) { skKeyGenAlgorithm = KeyGenAlgorithm.DES; } else if (algName.equalsIgnoreCase("DESede")) { skKeyGenAlgorithm = KeyGenAlgorithm.DES3; } else if (algName.equalsIgnoreCase("DES3")) { skKeyGenAlgorithm = KeyGenAlgorithm.DES3; } } public int getSkLength() { return skLength; } public void setSkLength(int skLength) { this.skLength = skLength; } public KeyWrapAlgorithm getSkWrapAlgorithm() { return skWrapAlgorithm; } public void setSkWrapAlgorithm(KeyWrapAlgorithm skWrapAlgorithm) { this.skWrapAlgorithm = skWrapAlgorithm; } public void setSkWrapAlgorithm(String name) throws NoSuchAlgorithmException { this.skWrapAlgorithm = KeyWrapAlgorithm.fromString(name); } public EncryptionAlgorithm getPayloadEncryptionAlgorithm() { return payloadEncryptionAlgorithm; } public void setPayloadEncryptionAlgorithm(EncryptionAlgorithm payloadEncryptionAlgorithm) { this.payloadEncryptionAlgorithm = payloadEncryptionAlgorithm; } public void setPayloadEncryptionAlgorithm(String algName, String modeName, String paddingName, int keyStrength) throws NoSuchAlgorithmException { this.payloadEncryptionAlgorithm = EncryptionAlgorithm.lookup(algName, modeName, paddingName, keyStrength); } public String getPayloadEncryptionAlgorithmName() { // work around some of the issues with OIDs in JSS int strength = payloadEncryptionAlgorithm.getKeyStrength(); String mode = payloadEncryptionAlgorithm.getMode().toString(); String padding = payloadEncryptionAlgorithm.getPadding().toString(); String alg = payloadEncryptionAlgorithm.getAlg().toString(); return alg + "/" + mode + "/" + padding + "/" + Integer.toString(strength); } public KeyWrapAlgorithm getPayloadWrapAlgorithm() { return payloadWrapAlgorithm; } public void setPayloadWrapAlgorithm(KeyWrapAlgorithm payloadWrapAlgorithm) { this.payloadWrapAlgorithm = payloadWrapAlgorithm; } public void setPayloadWrapAlgorithm(String name) throws NoSuchAlgorithmException { this.payloadWrapAlgorithm = KeyWrapAlgorithm.fromString(name); } public IVParameterSpec getPayloadEncryptionIV() { return payloadEncryptionIV; } public void setPayloadEncryptionIV(IVParameterSpec payloadEncryptionIV) { this.payloadEncryptionIV = payloadEncryptionIV; } public IVParameterSpec getPayloadWrappingIV() { return payloadWrappingIV; } public void setPayloadWrappingIV(IVParameterSpec payloadWrappingIV) { this.payloadWrappingIV = payloadWrappingIV; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/000077500000000000000000000000001362106420000215305ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/netscape/security/x509/ACertAttrSet.java000066400000000000000000000104741362106420000247060ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * A plain certattr set used by pkcs10 to parse an unknown attribute. * * @author Lily Hsiao */ public class ACertAttrSet implements CertAttrSet { protected DerValue mDerValue = null; public ACertAttrSet(DerValue derValue) throws IOException { mDerValue = derValue; } public DerValue getDerValue() { return mDerValue; } /** * Returns a short string describing this certificate attribute. * * @return value of this certificate attribute in * printable form. */ public String toString() { return "ACertAttrSet value " + (mDerValue == null ? "null" : "not null"); } /** * Encodes the attribute to the output stream in a format * that can be parsed by the decode method. * * @param out the OutputStream to encode the attribute to. * * @exception CertificateException on encoding or validity errors. * @exception IOException on other errors. */ public void encode(OutputStream out) throws CertificateException, IOException { mDerValue.encode((DerOutputStream) out); } /** * Decodes the attribute in the input stream. * * @param in the InputStream to read the encoded attribute from. * * @exception CertificateException on decoding or validity errors. * @exception IOException on other errors. */ public void decode(InputStream in) throws CertificateException, IOException { throw new IOException("not supported"); } /** * Sets an attribute value within this CertAttrSet. * * @param name the name of the attribute (e.g. "x509.info.key") * @param obj the attribute object. * * @exception CertificateException on attribute handling errors. * @exception IOException on other errors. */ public void set(String name, Object obj) throws CertificateException, IOException { throw new IOException("not supported"); } /** * Gets an attribute value for this CertAttrSet. * * @param name the name of the attribute to return. * * @exception CertificateException on attribute handling errors. * @exception IOException on other errors. */ public Object get(String name) throws CertificateException, IOException { throw new IOException("not supported"); } /** * Deletes an attribute value from this CertAttrSet. * * @param name the name of the attribute to delete. * * @exception CertificateException on attribute handling errors. * @exception IOException on other errors. */ public void delete(String name) throws CertificateException, IOException { throw new IOException("not supported"); } /** * Returns an enumeration of the names of the attributes existing within * this attribute. * * @return an enumeration of the attribute names. */ public Enumeration getAttributeNames() { return null; } /** * Returns the name (identifier) of this CertAttrSet. * * @return the name of this CertAttrSet. */ public String getName() { return "Generic Extension"; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/AVA.java000066400000000000000000000235661362106420000230160ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.UnsupportedCharsetException; import org.mozilla.jss.netscape.security.util.DerEncoder; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * X.500 Attribute-Value-Assertion (AVA): an attribute, as identified by * some attribute ID, has some particular value. Values are as a rule ASN.1 * printable strings. A conventional set of type IDs is recognized when * parsing (and generating) RFC 1779 syntax strings. * *

* AVAs are components of X.500 relative names. Think of them as being individual fields of a database record. The * attribute ID is how you identify the field, and the value is part of a particular record. * * @see X500Name * @see RDN * @see LdapDNStrConverter * * @version 1.14 * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra */ // public ... when RDN is public and X.500Names can be // constructed using RDNs, and all three classes are cleaner public final class AVA implements DerEncoder { ObjectIdentifier oid; DerValue value; /** * Constructs an AVA from a Ldap DN string with one AVA component * using the global default LdapDNStrConverter. * * @see LdapDNStrConverter * @param avaString a Ldap DN string with one AVA component. */ public AVA(String avaString) throws IOException { AVA ava; ava = LdapDNStrConverter.getDefault().parseAVA(avaString); oid = ava.getOid(); value = ava.getValue(); } /** * Like AVA(String) with a DER encoding order given for Directory Strings. */ public AVA(String avaString, byte[] tags) throws IOException { AVA ava; ava = LdapDNStrConverter.getDefault().parseAVA(avaString, tags); oid = ava.getOid(); value = ava.getValue(); } /** * Constructs an AVA from a Ldap DN string containing one AVA * component using the specified LdapDNStrConverter. * * @see LdapDNStrConverter * @param avaString a Ldap DN string containing one AVA. * @param ldapDNStrConverter a LdapDNStrConverter */ public AVA(String avaString, LdapDNStrConverter ldapDNStrConverter) throws IOException { AVA ava; ava = ldapDNStrConverter.parseAVA(avaString); oid = ava.getOid(); value = ava.getValue(); } /** * Constructs an AVA from an OID and DerValue. * * @param type an ObjectIdentifier * @param val a DerValue */ public AVA(ObjectIdentifier type, DerValue val) throws IOException { oid = type; value = val; } /** * Constructs an AVA from an input stream of UTF8 bytes that form * a Ldap DN string. Then parse the Ldap DN string using the global * default LdapDNStrConverter.
* Parses an RFC 1779 style AVA string: CN=fee fie foe fum * or perhaps with quotes. Not all defined AVA tags are supported; * of current note are X.400 related ones (PRMD, ADMD, etc). * * This terminates at unescaped AVA separators ("+") or RDN * separators (",", ";"), or DN terminators {@literal (">")}, and removes * cosmetic whitespace at the end of values. * * @see LdapDNStrConverter * @param in the input stream. */ public AVA(InputStream in) throws IOException { try { // convert from UTF8 bytes to java string then parse it. byte[] buffer = new byte[in.available()]; in.read(buffer); Charset charset = Charset.forName("UTF-8"); CharsetDecoder decoder = charset.newDecoder(); CharBuffer charBuffer = decoder.decode(ByteBuffer.wrap(buffer)); AVA a = LdapDNStrConverter.getDefault().parseAVA(charBuffer.toString()); oid = a.getOid(); value = a.getValue(); } catch (UnsupportedCharsetException e) { throw new IOException("UTF8 encoding not supported", e); } } /** * Constructs an AVA from a Der Input Stream. * * @param in the Der Input Stream. */ public AVA(DerInputStream in) throws IOException { DerValue assertion = in.getDerValue(); /* * Individual attribute value assertions are SEQUENCE of two values. * That'd be a "struct" outside of ASN.1. */ if (assertion.tag != DerValue.tag_Sequence) throw new CertParseError("X500 AVA, not a sequence"); ObjectIdentifier o = assertion.data.getOID(); oid = X500NameAttrMap.getDefault().getOid(o); if (oid == null) { // NSCP #329837 // if this OID is not recongized in our map (table), // it is fine. we just store it as regular OID. oid = o; } value = assertion.data.getDerValue(); if (assertion.data.available() != 0) throw new CertParseError("AVA, extra bytes = " + assertion.data.available()); } // other public methods. /** * Returns true if another AVA has the same OID and DerValue. * * @param other the other AVA. * @return ture iff other AVA has same oid and value. */ public boolean equals(AVA other) { return oid.equals(other.oid) && value.equals(other.value); } /** * Compares the AVA with an Object, returns true if the object is * an AVA and has the same OID and value. * * @param other the other object. * @return true iff other object is an AVA and has same oid and value. */ public boolean equals(Object other) { if (other instanceof AVA) return equals((AVA) other); else return false; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((oid == null) ? 0 : oid.hashCode()); result = prime * result + ((value == null) ? 0 : value.hashCode()); return result; } /** * Encodes the AVA to a Der output stream. * AVAs are encoded as a SEQUENCE of two elements. * * @param out The Der output stream. */ public void encode(DerOutputStream out) throws IOException { derEncode(out); } /** * DER encode this object onto an output stream. * Implements the DerEncoder interface. * * @param out * the output stream on which to write the DER encoding. * * @exception IOException on encoding error. */ public void derEncode(OutputStream out) throws IOException { try (DerOutputStream tmp2 = new DerOutputStream()) { DerOutputStream tmp = new DerOutputStream(); tmp.putOID(oid); value.encode(tmp); tmp2.write(DerValue.tag_Sequence, tmp); out.write(tmp2.toByteArray()); } } /** * Returns a Ldap DN string with one AVA component using * the global default LdapDNStrConverter. * * @return a Ldap DN string * @exception IOException if an error occurs during conversion. * @see LdapDNStrConverter */ public String toLdapDNString() throws IOException { LdapDNStrConverter v = LdapDNStrConverter.getDefault(); return v.encodeAVA(this); } /** * Returns a Ldap DN string with one AVA component using the specified * LdapDNStrConverter. * * @return a Ldap DN string * @param ldapDNStrConverter a Ldap DN String Converter * @exception IOException if an error occurs during the conversion. * @see LdapDNStrConverter */ public String toLdapDNString(LdapDNStrConverter ldapDNStrConverter) throws IOException { return ldapDNStrConverter.encodeAVA(this); } /** * Returns a Ldap DN string with the AVA component using the global * default LdapDNStrConverter, or null if an error occurs in conversion. * * @return a Ldap DN string containing the AVA, or null if an * error occurs in the conversion. */ public String toString() { String s; try { // NOTE that a LdapDNString is returned here to match the // original source from sun. Could also return the raw value // (before Ldap escaping) here. s = toLdapDNString(); } catch (IOException e) { return null; } return s; } /** * Returns the OID in the AVA. * * @return the ObjectIdentifier in this AVA. */ public ObjectIdentifier getOid() { return oid; } /** * Returns the value in this AVA as a DerValue * * @return attribute value in this AVA. */ public DerValue getValue() { return value; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/AVAValueConverter.java000066400000000000000000000061751362106420000257000ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerValue; /** * Interface for classes that convert a attribute value string to a * DER encoded ASN.1 value and vice versa. * The converters are associated with attribute types, such as * directory string, ia5string, etc. * *

* For example, to convert a string, such as an organization name for the "O" attribute to a DerValue, the "O" attribute * is mapped to the DirStrConverter which is used to convert the organization name to a DER encoded Directory String * which is a DerValue of a ASN.1 PrintableString, T.61String or UniversalString for the organization name. * * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc. */ public interface AVAValueConverter { /** * Converts a string to a DER encoded attribute value. * * @param valueString An AVA value string not encoded in any form. * * @return A DerValue object. * * @exception IOException if an error occurs during the conversion. */ public DerValue getValue(String valueString) throws IOException; /** * Converts a string to a DER encoded attribute value. * Specify the order of DER tags to use if more than one encoding is * possible. Currently Directory Strings can have different order * for backwards compatibility. By 2003 all should be UTF8String. * * @param valueString An AVA value string not encoded in any form. * * @return A DerValue object. * * @exception IOException if an error occurs during the conversion. */ public DerValue getValue(String valueString, byte[] tags) throws IOException; /** * Converts a BER encoded value to a DER encoded attribute value. * * @param berStream A byte array of the BER encoded AVA value. * @return A DerValue object. */ public DerValue getValue(byte[] berStream) throws IOException; /** * Converts a DER encoded value to a string, not encoded in any form. * * @param avaValue A DerValue object. * * @return A string for the value or null if it can't be converted. * * @exception IOException if an error occurs during the conversion. */ public String getAsString(DerValue avaValue) throws IOException; } jss-4.6.3/org/mozilla/jss/netscape/security/x509/AlgIdDSA.java000066400000000000000000000151201362106420000237020ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.math.BigInteger; import java.security.ProviderException; import java.security.interfaces.DSAParams; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class identifies DSS/DSA Algorithm variants, which are distinguished * by using different algorithm parameters P, Q, G. It uses the * NIST/IETF standard DER encoding. These are used to implement the Digital * Signature Standard (DSS), FIPS 186. * *

* NOTE: At this time, DSS/DSA Algorithm IDs must always * include these parameters. Use of DSS/DSA in modes where parameters are * either implicit (e.g. a default applicable to a site or a larger scope), * or are derived from some Certificate Authority's DSS certificate, is * not currently supported. * * @version 1.31 * @author David Brownell */ public final class AlgIdDSA extends AlgorithmId implements DSAParams { /** * */ private static final long serialVersionUID = 5978220691806461631L; /* * The three unsigned integer parameters. */ private BigInteger p, q, g; /** Returns the DSS/DSA parameter "P" */ public BigInteger getP() { return p; } /** Returns the DSS/DSA parameter "Q" */ public BigInteger getQ() { return q; } /** Returns the DSS/DSA parameter "G" */ public BigInteger getG() { return g; } AlgIdDSA(DerValue val) throws IOException { super(val.getOID()); } /** * Construct an AlgIdDSA from an X.509 encoded byte array. */ public AlgIdDSA(byte[] encodedAlg) throws IOException { super(new DerValue(encodedAlg).getOID()); } /** * Constructs a DSS/DSA Algorithm ID from unsigned integers that * define the algorithm parameters. Those integers are encoded * as big-endian byte arrays. * * @param p the DSS/DSA paramter "P" * @param q the DSS/DSA paramter "Q" * @param g the DSS/DSA paramter "G" */ public AlgIdDSA(byte p[], byte q[], byte g[]) throws IOException { this(new BigInteger(1, p), new BigInteger(1, q), new BigInteger(1, g)); } /** * Constructs a DSS/DSA Algorithm ID from numeric parameters. * * @param p the DSS/DSA paramter "P" * @param q the DSS/DSA paramter "Q" * @param g the DSS/DSA paramter "G" */ public AlgIdDSA(BigInteger p, BigInteger q, BigInteger g) { super(DSA_oid); try { this.p = p; this.q = q; this.g = g; initializeParams(); } catch (IOException e) { /* this should not happen */ throw new ProviderException("Construct DSS/DSA Algorithm ID"); } } /** * Returns "DSA", indicating the Digital Signature Algorithm (DSA) as * defined by the Digital Signature Standard (DSS), FIPS 186. */ public String getName() { return "DSA"; } /* * For algorithm IDs which haven't been created from a DER encoded * value, "params" must be created. */ private void initializeParams() throws IOException { try (DerOutputStream out = new DerOutputStream()) { out.putInteger(new BigInt(p.toByteArray())); out.putInteger(new BigInt(q.toByteArray())); out.putInteger(new BigInt(g.toByteArray())); params = new DerValue(DerValue.tag_Sequence, out.toByteArray()); } } /** * Parses algorithm parameters P, Q, and G. They're found * in the "params" member, which never needs to be changed. */ protected void decodeParams() throws IOException { if (params == null || params.tag != DerValue.tag_Sequence) throw new IOException("DSA alg parsing error"); params.data.reset(); this.p = params.data.getInteger().toBigInteger(); this.q = params.data.getInteger().toBigInteger(); this.g = params.data.getInteger().toBigInteger(); if (params.data.available() != 0) throw new IOException("AlgIdDSA params, extra=" + params.data.available()); } /* * Returns a formatted string describing the parameters. */ public String toString() { return paramsToString(); } /* * Returns a string describing the parameters. */ protected String paramsToString() { return "\n p:\n" + (new BigInt(p)).toString() + "\n q:\n" + (new BigInt(q)).toString() + "\n g:\n" + (new BigInt(g)).toString() + "\n"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((g == null) ? 0 : g.hashCode()); result = prime * result + ((p == null) ? 0 : p.hashCode()); result = prime * result + ((q == null) ? 0 : q.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; AlgIdDSA other = (AlgIdDSA) obj; if (g == null) { if (other.g != null) return false; } else if (!g.equals(other.g)) return false; if (p == null) { if (other.p != null) return false; } else if (!p.equals(other.p)) return false; if (q == null) { if (other.q != null) return false; } else if (!q.equals(other.q)) return false; return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/AlgorithmId.java000066400000000000000000000742271362106420000246120ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; import java.security.AlgorithmParameters; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.netscape.security.util.DerEncoder; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * This class identifies algorithms, such as cryptographic transforms, each * of which may be associated with parameters. Instances of this base class * are used when this runtime environment has no special knowledge of the * algorithm type, and may also be used in other cases. Equivalence is * defined according to OID and (where relevant) parameters. * *

* Subclasses may be used, for example when when the algorithm ID has associated parameters which some code (e.g. code * using public keys) needs to have parsed. Two examples of such algorithms are Diffie-Hellman key exchange, and the * Digital Signature Standard Algorithm (DSS/DSA). * *

* The OID constants defined in this class correspond to some widely used algorithms, for which conventional string * names have been defined. This class is not a general repository for OIDs, or for such string names. Note that the * mappings between algorithm IDs and algorithm names is not one-to-one. * * @version 1.70 * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra */ public class AlgorithmId implements Serializable, DerEncoder { /** use serialVersionUID from JDK 1.1. for interoperability */ private static final long serialVersionUID = 7205873507486557157L; /** * The object identitifer being used for this algorithm. */ private ObjectIdentifier algid = null; // The (parsed) parameters private AlgorithmParameters algParams; /** * Parameters for this algorithm. These are stored in unparsed * DER-encoded form; subclasses can be made to automaticaly parse * them so there is fast access to these parameters. */ protected DerValue params = null; protected String paramsString = null; public AlgorithmParameters getParameters() { return this.algParams; } public String getParametersString() { return this.paramsString; } public void setParametersString(String paramStr) { this.paramsString = paramStr; } /** * Returns one of the algorithm IDs most commonly associated * with this algorithm name. * * @param algname the name being used * @exception NoSuchAlgorithmException on error. */ public static AlgorithmId get(String algname) throws NoSuchAlgorithmException { ObjectIdentifier oid = algOID(algname); if (oid == null) throw new NoSuchAlgorithmException("unrecognized algorithm name: " + algname); return new AlgorithmId(oid); } /** * Parse (unmarshal) an ID from a DER sequence input value. This form * parsing might be used when expanding a value which has already been * partially unmarshaled as a set or sequence member. * * @exception IOException on error. * @param val the input value, which contains the algid and, if * there are any parameters, those parameters. * @return an ID for the algorithm. If the system is configured * appropriately, this may be an instance of a class * with some kind of special support for this algorithm. * In that case, you may "narrow" the type of the ID. */ public static AlgorithmId parse(DerValue val) throws IOException { if (val.tag != DerValue.tag_Sequence) throw new IOException("algid parse error, not a sequence"); /* * Get the algorithm ID and any parameters. */ ObjectIdentifier algid; DerValue params; DerInputStream in = val.toDerInputStream(); algid = in.getOID(); if (in.available() == 0) params = null; else { params = in.getDerValue(); if (params.tag == DerValue.tag_Null) params = null; } /* * Figure out what class (if any) knows about this oid's * parameters. Make one, and give it the data to decode. */ AlgorithmId alg = null; // omit parameter field for ECDSA if (!algid.equals(sha224WithEC_oid) && !algid.equals(sha256WithEC_oid) && !algid.equals(sha384WithEC_oid) && !algid.equals(sha512WithEC_oid)) { alg = new AlgorithmId(algid, params); } else { alg = new AlgorithmId(algid); } if (params != null) alg.decodeParams(); /* * Set the raw params string in case * higher level code might want the info */ String paramStr = null; if (params != null) { paramStr = params.toString(); } alg.setParametersString(paramStr); return alg; } public static AlgorithmId parse(byte[] val) throws IOException { return null; } /** * Constructs a parameterless algorithm ID. * * @param oid the identifier for the algorithm */ public AlgorithmId(ObjectIdentifier oid) { algid = oid; } private AlgorithmId(ObjectIdentifier oid, DerValue params) throws IOException { this.algid = oid; this.params = params; if (this.params != null) decodeParams(); } /** * Constructs an algorithm ID which will be initialized * separately, for example by deserialization. * * @deprecated use one of the other constructors. */ @Deprecated public AlgorithmId() { } protected void decodeParams() throws IOException { try { this.algParams = AlgorithmParameters.getInstance (this.algid.toString()); } catch (NoSuchAlgorithmException e) { /* * This algorithm parameter type is not supported, so we cannot * parse the parameters. */ this.algParams = null; return; } // Decode (parse) the parameters this.algParams.init(this.params.toByteArray()); } /** * Marshal a DER-encoded "AlgorithmID" sequence on the DER stream. */ public final void encode(DerOutputStream out) throws IOException { derEncode(out); } /** * DER encode this object onto an output stream. * Implements the DerEncoder interface. * * @param out * the output stream on which to write the DER encoding. * * @exception IOException on encoding error. */ public void derEncode(OutputStream out) throws IOException { try (DerOutputStream tmp = new DerOutputStream()) { DerOutputStream bytes = new DerOutputStream(); bytes.putOID(algid); // omit parameter field for ECDSA if (!algid.equals(sha224WithEC_oid) && !algid.equals(sha256WithEC_oid) && !algid.equals(sha384WithEC_oid) && !algid.equals(sha512WithEC_oid)) { if (params == null) { bytes.putNull(); } else bytes.putDerValue(params); } tmp.write(DerValue.tag_Sequence, bytes); out.write(tmp.toByteArray()); } } // XXXX cleaning required /** * Returns the DER-encoded X.509 AlgorithmId as a byte array. */ public final byte[] encode() throws IOException { try (DerOutputStream out = new DerOutputStream()) { DerOutputStream bytes = new DerOutputStream(); bytes.putOID(algid); // omit parameter field for ECDSA if (!algid.equals(sha224WithEC_oid) && !algid.equals(sha256WithEC_oid) && !algid.equals(sha384WithEC_oid) && !algid.equals(sha512WithEC_oid)) { if (params == null) { bytes.putNull(); } else bytes.putDerValue(params); } out.write(DerValue.tag_Sequence, bytes); return out.toByteArray(); } } /** * Returns list of signing algorithms for a key algorithm such as * RSA or DSA. */ public static String[] getSigningAlgorithms(AlgorithmId alg) { ObjectIdentifier algOid = alg.getOID(); //System.out.println("Key Alg oid "+algOid.toString()); if (algOid.equals(DSA_oid) || algOid.equals(DSA_OIW_oid)) { return DSA_SIGNING_ALGORITHMS; } else if (algOid.equals(RSA_oid) || algOid.equals(RSAEncryption_oid)) { return RSA_SIGNING_ALGORITHMS; } else if (algOid.equals(ANSIX962_EC_Public_Key_oid) || algOid.equals(ANSIX962_SHA1_With_EC_oid)) { return EC_SIGNING_ALGORITHMS; } else { return null; } } /* * Translates from some common algorithm names to the * OID with which they're usually associated ... this mapping * is the reverse of the one below, except in those cases * where synonyms are supported or where a given algorithm * is commonly associated with multiple OIDs. */ private static ObjectIdentifier algOID(String name) { // Digesting algorithms if (name.equals("MD5")) return AlgorithmId.MD5_oid; if (name.equals("MD2")) return AlgorithmId.MD2_oid; if (name.equals("SHA") || name.equals("SHA1") || name.equals("SHA-1")) return AlgorithmId.SHA_oid; if (name.equals("SHA256") || name.equals("SHA-256")) return AlgorithmId.SHA256_oid; if (name.equals("SHA512") || name.equals("SHA-512")) return AlgorithmId.SHA512_oid; // Various public key algorithms if (name.equals("RSA")) return AlgorithmId.RSA_oid; if (name.equals("RSAEncryption")) return AlgorithmId.RSAEncryption_oid; if (name.equals("Diffie-Hellman") || name.equals("DH")) return AlgorithmId.DH_oid; if (name.equals("DSA")) return AlgorithmId.DSA_oid; // Common signature types if (name.equals("SHA1withEC") || name.equals("SHA1/EC") || name.equals("1.2.840.10045.4.1")) return AlgorithmId.sha1WithEC_oid; if (name.equals("SHA224withEC") || name.equals("SHA224/EC") || name.equals("1.2.840.10045.4.3.1")) return AlgorithmId.sha224WithEC_oid; if (name.equals("SHA256withEC") || name.equals("SHA256/EC") || name.equals("1.2.840.10045.4.3.2")) return AlgorithmId.sha256WithEC_oid; if (name.equals("SHA384withEC") || name.equals("SHA384/EC") || name.equals("1.2.840.10045.4.3.3")) return AlgorithmId.sha384WithEC_oid; if (name.equals("SHA512withEC") || name.equals("SHA512/EC") || name.equals("1.2.840.10045.4.3.4")) return AlgorithmId.sha512WithEC_oid; if (name.equals("SHA1withRSA") || name.equals("SHA1/RSA") || name.equals("1.2.840.113549.1.1.5")) return AlgorithmId.sha1WithRSAEncryption_oid; if (name.equals("SHA256withRSA") || name.equals("SHA256/RSA") || name.equals("1.2.840.113549.1.1.11")) return AlgorithmId.sha256WithRSAEncryption_oid; if (name.equals("SHA384withRSA") || name.equals("SHA384/RSA") || name.equals("1.2.840.113549.1.1.12")) return AlgorithmId.sha384WithRSAEncryption_oid; if (name.equals("SHA512withRSA") || name.equals("SHA512/RSA") || name.equals("1.2.840.113549.1.1.13")) return AlgorithmId.sha512WithRSAEncryption_oid; if (name.equals("MD5withRSA") || name.equals("MD5/RSA")) return AlgorithmId.md5WithRSAEncryption_oid; if (name.equals("MD2withRSA") || name.equals("MD2/RSA")) return AlgorithmId.md2WithRSAEncryption_oid; if (name.equals("SHAwithDSA") || name.equals("SHA1withDSA") || name.equals("SHA/DSA") || name.equals("SHA1/DSA")) return AlgorithmId.sha1WithDSA_oid; return null; } /* * For the inevitable cases where key or signature types are not * configured in an environment which encounters such keys or * signatures, we still attempt to provide user-friendly names * for some of the most common algorithms. Subclasses can of * course override getName(). * * Wherever possible, the names are those defined by the IETF. * Such names are noted below. */ private String algName() { // Common message digest algorithms if (algid.equals(AlgorithmId.MD5_oid)) return "MD5"; // RFC 1423 if (algid.equals(AlgorithmId.MD2_oid)) return "MD2"; // RFC 1423 if (algid.equals(AlgorithmId.SHA_oid)) return "SHA"; if (algid.equals(AlgorithmId.SHA256_oid)) return "SHA256"; if (algid.equals(AlgorithmId.SHA384_oid)) return "SHA384"; if (algid.equals(AlgorithmId.SHA512_oid)) return "SHA512"; // Common key types if (algid.equals(AlgorithmId.ANSIX962_EC_Public_Key_oid)) return "EC"; if (algid.equals(AlgorithmId.RSAEncryption_oid) || algid.equals(AlgorithmId.RSA_oid)) return "RSA"; if (algid.equals(AlgorithmId.DH_oid) || algid.equals(AlgorithmId.DH_PKIX_oid)) return "Diffie-Hellman"; if (algid.equals(AlgorithmId.DSA_oid) || algid.equals(AlgorithmId.DSA_OIW_oid)) return "DSA"; // Common signature types if (algid.equals(AlgorithmId.sha1WithEC_oid)) return "SHA1withEC"; if (algid.equals(AlgorithmId.sha256WithEC_oid)) return "SHA256withEC"; if (algid.equals(AlgorithmId.sha384WithEC_oid)) return "SHA384withEC"; if (algid.equals(AlgorithmId.sha512WithEC_oid)) return "SHA512withEC"; if (algid.equals(AlgorithmId.md5WithRSAEncryption_oid)) return "MD5withRSA"; if (algid.equals(AlgorithmId.md2WithRSAEncryption_oid)) return "MD2withRSA"; if (algid.equals(AlgorithmId.sha1WithRSAEncryption_oid)) return "SHA1withRSA"; if (algid.equals(AlgorithmId.sha256WithRSAEncryption_oid)) return "SHA256withRSA"; if (algid.equals(AlgorithmId.sha384WithRSAEncryption_oid)) return "SHA384withRSA"; if (algid.equals(AlgorithmId.sha512WithRSAEncryption_oid)) return "SHA512withRSA"; if (algid.equals(AlgorithmId.sha1WithDSA_oid) || algid.equals(AlgorithmId.sha1WithDSA_OIW_oid) || algid.equals(AlgorithmId.shaWithDSA_OIW_oid)) return "SHA1withDSA"; // default returns a dot-notation ID return "OID." + algid.toString(); } /** * Returns the ISO OID for this algorithm. This is usually converted * to a string and used as part of an algorithm name, for example * "OID.1.3.14.3.2.13" style notation. Use the getName call when you do not need to ensure cross-system * portability * of algorithm names, or need a user friendly name. */ final public ObjectIdentifier getOID() { return algid; } /** * Returns a name for the algorithm which may be more intelligible * to humans than the algorithm's OID, but which won't necessarily * be comprehensible on other systems. For example, this might * return a name such as "MD5withRSA" for a signature algorithm on * some systems. It also returns names like "OID.1.2.3.4", when * no particular name for the algorithm is known. */ public String getName() { return algName(); } /** * Returns a string describing the algorithm and its parameters. */ public String toString() { return (algName() + paramsToString()); } /** * Returns the DER encoded parameter, which can then be * used to initialize java.security.AlgorithmParamters. * * @return DER encoded parameters, or null not present. */ public byte[] getEncodedParams() throws IOException { if (params == null) return null; else return params.toByteArray(); } /** * Provides a human-readable description of the algorithm parameters. * This may be redefined by subclasses which parse those parameters. */ protected String paramsToString() { if (params == null) { return ""; } else if (algParams != null) { return algParams.toString(); } else { return ", params unparsed"; } } /** * Returns true iff the argument indicates the same algorithm * with the same parameters. */ public boolean equals(AlgorithmId other) { if (!algid.equals(other.algid)) return false; else if (params == null && other.params == null) return true; else if (params == null) return false; else return params.equals(other.params); } /** * Compares this AlgorithmID to another. If algorithm parameters are * available, they are compared. Otherwise, just the object IDs * for the algorithm are compared. * * @param other preferably an AlgorithmId, else an ObjectIdentifier */ public boolean equals(Object other) { if (other instanceof AlgorithmId) return equals((AlgorithmId) other); else if (other instanceof ObjectIdentifier) return equals((ObjectIdentifier) other); else return false; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((algParams == null) ? 0 : algParams.hashCode()); result = prime * result + ((algid == null) ? 0 : algid.hashCode()); result = prime * result + ((params == null) ? 0 : params.hashCode()); result = prime * result + ((paramsString == null) ? 0 : paramsString.hashCode()); return result; } /** * Compares two algorithm IDs for equality. Returns true iff * they are the same algorithm, ignoring algorithm parameters. */ public final boolean equals(ObjectIdentifier id) { return algid.equals(id); } /*****************************************************************/ /* * HASHING ALGORITHMS */ private static final int MD2_data[] = { 1, 2, 840, 113549, 2, 2 }; private static final int MD5_data[] = { 1, 2, 840, 113549, 2, 5 }; // sha = { 1, 3, 14, 3, 2, 18 }; private static final int SHA1_OIW_data[] = { 1, 3, 14, 3, 2, 26 }; private static final int SHA256_data[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 }; private static final int SHA384_data[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 }; private static final int SHA512_data[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 }; /** * Algorithm ID for the MD2 Message Digest Algorthm, from RFC 1319. * OID = 1.2.840.113549.2.2 */ public static final ObjectIdentifier MD2_oid = new ObjectIdentifier(MD2_data); /** * Algorithm ID for the MD5 Message Digest Algorthm, from RFC 1321. * OID = 1.2.840.113549.2.5 */ public static final ObjectIdentifier MD5_oid = new ObjectIdentifier(MD5_data); /** * Algorithm ID for the SHA1 Message Digest Algorithm, from FIPS 180-1. * This is sometimes called "SHA", though that is often confusing since * many people refer to FIPS 180 (which has an error) as defining SHA. * OID = 1.3.14.3.2.26 */ public static final ObjectIdentifier SHA_oid = new ObjectIdentifier(SHA1_OIW_data); public static final ObjectIdentifier SHA256_oid = new ObjectIdentifier(SHA256_data); public static final ObjectIdentifier SHA384_oid = new ObjectIdentifier(SHA384_data); public static final ObjectIdentifier SHA512_oid = new ObjectIdentifier(SHA512_data); /* * COMMON PUBLIC KEY TYPES */ private static final int DH_data[] = { 1, 2, 840, 113549, 1, 3, 1 }; private static final int DH_PKIX_data[] = { 1, 2, 840, 10046, 2, 1 }; private static final int DSA_OIW_data[] = { 1, 3, 14, 3, 2, 12 }; private static final int DSA_PKIX_data[] = { 1, 2, 840, 10040, 4, 1 }; private static final int RSA_data[] = { 1, 2, 5, 8, 1, 1 }; private static final int RSAEncryption_data[] = { 1, 2, 840, 113549, 1, 1, 1 }; private static final int ANSI_X962_public_key_data[] = { 1, 2, 840, 10045, 2, 1 }; private static final int ANSI_X962_sha1_with_ec_data[] = { 1, 2, 840, 10045, 4, 1 }; public static final ObjectIdentifier ANSIX962_EC_Public_Key_oid = new ObjectIdentifier(ANSI_X962_public_key_data); public static final ObjectIdentifier ANSIX962_SHA1_With_EC_oid = new ObjectIdentifier(ANSI_X962_sha1_with_ec_data); /* * Note the preferred OIDs are named simply with no "OIW" or * "PKIX" in them, even though they may point to data from these * specs; e.g. SHA_oid, DH_oid, DSA_oid, SHA1WithDSA_oid... */ /** * Algorithm ID for Diffie Hellman Key agreement, from PKCS #3. * Parameters include public values P and G, and may optionally specify * the length of the private key X. Alternatively, algorithm parameters * may be derived from another source such as a Certificate Authority's * certificate. * OID = 1.2.840.113549.1.3.1 */ public static final ObjectIdentifier DH_oid = new ObjectIdentifier(DH_data); /** * Algorithm ID for the Diffie Hellman Key Agreement (DH), from the * IETF PKIX IPKI Part I. * Parameters may include public values P and G. * OID = 1.2.840.10046.2.1 */ public static final ObjectIdentifier DH_PKIX_oid = new ObjectIdentifier(DH_PKIX_data); /** * Algorithm ID for the Digital Signing Algorithm (DSA), from the * NIST OIW Stable Agreements part 12. * Parameters may include public values P, Q, and G; or these may be * derived from * another source such as a Certificate Authority's certificate. * OID = 1.3.14.3.2.12 */ public static final ObjectIdentifier DSA_OIW_oid = new ObjectIdentifier(DSA_OIW_data); /** * Algorithm ID for the Digital Signing Algorithm (DSA), from the * IETF PKIX IPKI Part I. * Parameters may include public values P, Q, and G; or these may be * derived from * another source such as a Certificate Authority's certificate. * OID = 1.2.840.10040.4.1 */ public static final ObjectIdentifier DSA_oid = new ObjectIdentifier(DSA_PKIX_data); /** * Algorithm ID for RSA keys used for any purpose, as defined in X.509. * The algorithm parameter is a single value, the number of bits in the * public modulus. * OID = 1.2.5.8.1.1 */ public static final ObjectIdentifier RSA_oid = new ObjectIdentifier(RSA_data); /** * Algorithm ID for RSA keys used with RSA encryption, as defined * in PKCS #1. There are no parameters associated with this algorithm. * OID = 1.2.840.113549.1.1.1 */ public static final ObjectIdentifier RSAEncryption_oid = new ObjectIdentifier(RSAEncryption_data); /* * COMMON SIGNATURE ALGORITHMS */ private static final int sha1WithEC_data[] = { 1, 2, 840, 10045, 4, 1 }; private static final int sha224WithEC_data[] = { 1, 2, 840, 10045, 4, 3, 1 }; private static final int sha256WithEC_data[] = { 1, 2, 840, 10045, 4, 3, 2 }; private static final int sha384WithEC_data[] = { 1, 2, 840, 10045, 4, 3, 3 }; private static final int sha512WithEC_data[] = { 1, 2, 840, 10045, 4, 3, 4 }; private static final int md2WithRSAEncryption_data[] = { 1, 2, 840, 113549, 1, 1, 2 }; private static final int md5WithRSAEncryption_data[] = { 1, 2, 840, 113549, 1, 1, 4 }; private static final int sha1WithRSAEncryption_data[] = { 1, 2, 840, 113549, 1, 1, 5 }; private static final int sha256WithRSAEncryption_data[] = { 1, 2, 840, 113549, 1, 1, 11 }; private static final int sha384WithRSAEncryption_data[] = { 1, 2, 840, 113549, 1, 1, 12 }; private static final int sha512WithRSAEncryption_data[] = { 1, 2, 840, 113549, 1, 1, 13 }; private static final int sha1WithRSAEncryption_OIW_data[] = { 1, 3, 14, 3, 2, 29 }; private static final int shaWithDSA_OIW_data[] = { 1, 3, 14, 3, 2, 13 }; private static final int sha1WithDSA_OIW_data[] = { 1, 3, 14, 3, 2, 27 }; private static final int dsaWithSHA1_PKIX_data[] = { 1, 2, 840, 10040, 4, 3 }; public static final ObjectIdentifier sha1WithEC_oid = new ObjectIdentifier(sha1WithEC_data); public static final ObjectIdentifier sha224WithEC_oid = new ObjectIdentifier(sha224WithEC_data); public static final ObjectIdentifier sha256WithEC_oid = new ObjectIdentifier(sha256WithEC_data); public static final ObjectIdentifier sha384WithEC_oid = new ObjectIdentifier(sha384WithEC_data); public static final ObjectIdentifier sha512WithEC_oid = new ObjectIdentifier(sha512WithEC_data); /** * Identifies a signing algorithm where an MD2 digest is encrypted * using an RSA private key; defined in PKCS #1. Use of this * signing algorithm is discouraged due to MD2 vulnerabilities. * OID = 1.2.840.113549.1.1.2 */ public static final ObjectIdentifier md2WithRSAEncryption_oid = new ObjectIdentifier(md2WithRSAEncryption_data); /** * Identifies a signing algorithm where an MD5 digest is * encrypted using an RSA private key; defined in PKCS #1. * OID = 1.2.840.113549.1.1.4 */ public static final ObjectIdentifier md5WithRSAEncryption_oid = new ObjectIdentifier(md5WithRSAEncryption_data); /** * The proper one for sha1/rsa */ public static final ObjectIdentifier sha1WithRSAEncryption_oid = new ObjectIdentifier(sha1WithRSAEncryption_data); /** * The proper one for sha256/rsa */ public static final ObjectIdentifier sha256WithRSAEncryption_oid = new ObjectIdentifier(sha256WithRSAEncryption_data); /** * The proper one for sha384/rsa */ public static final ObjectIdentifier sha384WithRSAEncryption_oid = new ObjectIdentifier(sha384WithRSAEncryption_data); /** * The proper one for sha512/rsa */ public static final ObjectIdentifier sha512WithRSAEncryption_oid = new ObjectIdentifier(sha512WithRSAEncryption_data); /** * Identifies a signing algorithm where an SHA1 digest is * encrypted using an RSA private key; defined in NIST OIW. * OID = 1.3.14.3.2.29 */ public static final ObjectIdentifier sha1WithRSAEncryption_OIW_oid = new ObjectIdentifier(sha1WithRSAEncryption_OIW_data); /** * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a * SHA digest is signed using the Digital Signing Algorithm (DSA). * This should not be used. * OID = 1.3.14.3.2.13 */ public static final ObjectIdentifier shaWithDSA_OIW_oid = new ObjectIdentifier(shaWithDSA_OIW_data); /** * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a * SHA1 digest is signed using the Digital Signing Algorithm (DSA). * OID = 1.3.14.3.2.27 */ public static final ObjectIdentifier sha1WithDSA_OIW_oid = new ObjectIdentifier(sha1WithDSA_OIW_data); /** * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a * SHA1 digest is signed using the Digital Signing Algorithm (DSA). * OID = 1.2.840.10040.4.3 */ public static final ObjectIdentifier sha1WithDSA_oid = new ObjectIdentifier(dsaWithSHA1_PKIX_data); /** * Supported signing algorithms for a DSA key. */ public static final String[] DSA_SIGNING_ALGORITHMS = new String[] { "SHA1withDSA" }; /** * Supported signing algorithms for a RSA key. */ public static final String[] RSA_SIGNING_ALGORITHMS = new String[] { "SHA256withRSA", "SHA384withRSA", "SHA512withRSA", "SHA1withRSA" }; public static final String[] EC_SIGNING_ALGORITHMS = new String[] { "SHA256withEC", "SHA384withEC", "SHA512withEC", "SHA1withEC" }; /** * All supported signing algorithms. */ public static final String[] ALL_SIGNING_ALGORITHMS = new String[] { "SHA256withRSA", "SHA384withRSA", "SHA512withRSA", "SHA1withRSA", "SHA256withEC", "SHA384withEC", "SHA512withEC", "SHA1withEC" }; } jss-4.6.3/org/mozilla/jss/netscape/security/x509/Attribute.java000066400000000000000000000245521362106420000243460ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerEncoder; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * An attribute, as identified by some attribute ID, has some particular values. * Values are as a rule ASN.1 printable strings. A conventional set of type IDs * is recognized when parsing. The following shows the syntax: * *

 *
 *    Attribute	::= SEQUENCE {
 * type		AttributeType,
 * 	value		SET OF AttributeValue
 *              	-- at least one value is required --}
 *
 *    AttributeType	::= OBJECT IDENTIFIER
 *
 *    AttributeValue	::= ANY
 *
 * 
* * Refer to draft-ietf-pkix-ipki-part1-11 for the support attributes listed on * page 96 of the internet draft. The are listed here for easy reference: name, * common name, surname, given name, initials, generation qualifier, dn qualifier, * country name, locality name, state or province name, organization name, organization * unit name, title, pkcs9 email. Not all the attributes are supported. Please check * the X500NameAttrMap for defined attributes. * * @author Christine Ho */ public final class Attribute implements Serializable, DerEncoder { /** * */ private static final long serialVersionUID = -931486084625476764L; //private variables ObjectIdentifier oid; Vector valueSet = new Vector(); transient protected X500NameAttrMap attrMap; //========== CONSTRUCTOR ================================== /** * Construct an attribute from attribute type and attribute value * * @param oid the object identifier of the attribute type * @param value the value string */ public Attribute(ObjectIdentifier oid, String value) throws IOException { //pre-condition verification if ((oid == null) || (value == null)) throw new IOException("Invalid Input - null passed"); attrMap = X500NameAttrMap.getDefault(); this.oid = oid; valueSet.addElement(value); } /** * Construct an attribute from attribute type and attribute values * * @param oid the object identifier of the attribute type * @param values String value vector */ public Attribute(ObjectIdentifier oid, Vector values) throws IOException { //pre-condition verification if ((oid == null) || (values == null)) throw new IOException("Invalid Input - null passed"); attrMap = X500NameAttrMap.getDefault(); this.oid = oid; //copy the value into the valueSet list Enumeration vals = values.elements(); while (vals.hasMoreElements()) { valueSet.addElement(vals.nextElement()); } } /** * Construct an attribute from attribute type and attribute values * * @param attr oid attribute type string CN,OU,O,C,L,TITLE,ST,STREET,UID,MAIL,E,DC * @param values String value vector */ public Attribute(String attr, Vector values) throws IOException { //pre-condition verification if ((attr == null) || (values == null)) throw new IOException("Invalid Input - null passed"); ObjectIdentifier identifier = null; try { identifier = new ObjectIdentifier(attr); } catch (Exception e) { } ObjectIdentifier id = identifier; if (identifier == null) { attrMap = X500NameAttrMap.getDefault(); id = attrMap.getOid(attr); if (id == null) throw new IOException("Attr is not supported - does not contain in attr map"); } this.oid = id; //copy the value into the valueSet list Enumeration vals = values.elements(); while (vals.hasMoreElements()) { valueSet.addElement(vals.nextElement()); } } /** * Construct an attribute from a der encoded object. This der * der encoded value should represent the attribute object. * * @param val the attribute object in der encode form. */ public Attribute(DerValue val) throws IOException { //pre-condition verification if (val == null) throw new IOException("Invalid Input - null passed"); attrMap = X500NameAttrMap.getDefault(); decodeThis(val); } //========== PUBLIC METHODS ================================== /** * Returns the OID in the Attribute. * * @return the ObjectIdentifier in this Attribute. */ public ObjectIdentifier getOid() { return oid; } /** * Returns enumeration of values in this attribute. * * @return Enumeration of values of this Attribute. */ public Enumeration getValues() { if (valueSet == null) return null; return valueSet.elements(); } /** * Encodes the Attribute to a Der output stream. * Attribute are encoded as a SEQUENCE of two elements. * * @param out The Der output stream. */ public void encode(DerOutputStream out) throws IOException { encodeThis(out); } /** * DER encode this object onto an output stream. * Implements the DerEncoder interface. * * @param out * the output stream on which to write the DER encoding. * * @exception IOException on encoding error. */ public void derEncode(OutputStream out) throws IOException { encodeThis(out); } /** * Prints a string version of this extension. */ public String toString() { String theoid = "Attribute: " + oid + "\n"; StringBuffer values = new StringBuffer("Values: "); Enumeration n = valueSet.elements(); if (n.hasMoreElements()) { values.append(n.nextElement()); while (n.hasMoreElements()) values.append("," + n.nextElement()); } return theoid + values.toString() + "\n"; } //========== PRIVATE METHODS ================================== //encode the attribute object private void encodeThis(OutputStream out) throws IOException { try (DerOutputStream tmp2 = new DerOutputStream()) { DerOutputStream tmp = new DerOutputStream(); tmp.putOID(oid); encodeValueSet(tmp); tmp2.write(DerValue.tag_Sequence, tmp); out.write(tmp2.toByteArray()); } } //encode the attribute object private void encodeValueSet(OutputStream out) throws IOException { try (DerOutputStream tmp2 = new DerOutputStream()) { DerOutputStream tmp = new DerOutputStream(); //get the attribute converter AVAValueConverter converter = attrMap.getValueConverter(oid); if (converter == null) { converter = new GenericValueConverter(); //throw new IOException("Converter not found: unsupported attribute type"); } //loop through all the values and encode Enumeration vals = valueSet.elements(); while (vals.hasMoreElements()) { String val = vals.nextElement(); DerValue derobj = converter.getValue(val); derobj.encode(tmp); } tmp2.write(DerValue.tag_SetOf, tmp); out.write(tmp2.toByteArray()); } } //decode the attribute object private void decodeThis(DerValue val) throws IOException { //pre-condition verification if (val == null) { throw new IOException("Invalid Input - null passed."); } if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for Attribute."); } if (val.data.available() == 0) { throw new IOException("No data available in " + "passed DER encoded value."); } this.oid = val.data.getDerValue().getOID(); if (val.data.available() == 0) { throw new IOException("Invalid encoding for Attribute - value missing"); } decodeValueSet(val.data.getDerValue()); if (this.oid == null) throw new IOException("Invalid encoding for Attribute - OID missing"); } //decode the attribute value set private void decodeValueSet(DerValue val) throws IOException { //pre-condition verification if (val == null) { throw new IOException("Invalid Input - null passed."); } AVAValueConverter converter = attrMap.getValueConverter(this.oid); if (converter == null) { converter = new GenericValueConverter(); //throw new IOException("Attribute is not supported - not in attr map"); } if (val.tag != DerValue.tag_SetOf) { throw new IOException("Invalid encoding for Attribute Value Set."); } if (val.data.available() == 0) { throw new IOException("No data available in " + "passed DER encoded attribute value set."); } //get the value set while (val.data.available() != 0) { DerValue value = val.data.getDerValue(); valueSet.addElement(converter.getAsString(value)); } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/AuthorityKeyIdentifierExtension.java000066400000000000000000000276551362106420000307530ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class represents the Authority Key Identifier Extension. * *

* The authority key identifier extension provides a means of identifying the particular public key used to sign a * certificate. This extension would be used where an issuer has multiple signing keys (either due to multiple * concurrent key pairs or due to changeover). *

* The ASN.1 syntax for this is: * *

 * AuthorityKeyIdentifier ::= SEQUENCE {
 *    keyIdentifier             [0] KeyIdentifier           OPTIONAL,
 *    authorityCertIssuer       [1] GeneralNames            OPTIONAL,
 *    authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL
 * }
 * KeyIdentifier ::= OCTET STRING
 * 
* * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.9 * @see Extension * @see CertAttrSet */ public class AuthorityKeyIdentifierExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -157913621972354170L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.AuthorityKeyIdentifier"; /** * Attribute names. */ public static final String NAME = "AuthorityKeyIdentifier"; public static final String KEY_ID = "key_id"; public static final String AUTH_NAME = "auth_name"; public static final String SERIAL_NUMBER = "serial_number"; // Private data members private static final byte TAG_ID = 0; private static final byte TAG_NAMES = 1; private static final byte TAG_SERIAL_NUM = 2; private KeyIdentifier id = null; private GeneralNames names = null; private SerialNumber serialNum = null; // Encode only the extension value private void encodeThis() throws IOException { try (DerOutputStream tmp = new DerOutputStream(); DerOutputStream seq = new DerOutputStream()) { if (id != null) { DerOutputStream tmp1 = new DerOutputStream(); id.encode(tmp1); tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false, TAG_ID), tmp1); } try { if (names != null) { DerOutputStream tmp1 = new DerOutputStream(); names.encode(tmp1); tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_NAMES), tmp1); } } catch (Exception e) { throw new IOException(e); } if (serialNum != null) { DerOutputStream tmp1 = new DerOutputStream(); serialNum.encode(tmp1); tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false, TAG_SERIAL_NUM), tmp1); } seq.write(DerValue.tag_Sequence, tmp); this.extensionValue = seq.toByteArray(); } } /** * Exposed critical parameter. 99/11/03 */ public AuthorityKeyIdentifierExtension(boolean critical, KeyIdentifier kid, GeneralNames name, SerialNumber sn) throws IOException { this.id = kid; this.names = name; this.serialNum = sn; this.extensionId = PKIXExtensions.AuthorityKey_Id; this.critical = critical; encodeThis(); } /** * The default constructor for this extension. Null parameters make * the element optional (not present). * * @param kid the KeyIdentifier associated with this extension. * @param name the GeneralNames associated with this extension * @param sn the CertificateSerialNumber associated with * this extension. * @exception IOException on error. */ public AuthorityKeyIdentifierExtension(KeyIdentifier kid, GeneralNames name, SerialNumber sn) throws IOException { this.id = kid; this.names = name; this.serialNum = sn; this.extensionId = PKIXExtensions.AuthorityKey_Id; this.critical = false; encodeThis(); } /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public AuthorityKeyIdentifierExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.AuthorityKey_Id; this.critical = critical.booleanValue(); if (!(value instanceof byte[])) throw new IOException("Illegal argument type"); int len = Array.getLength(value); byte[] extValue = new byte[len]; System.arraycopy(value, 0, extValue, 0, len); this.extensionValue = extValue; DerValue val = new DerValue(extValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for " + "AuthorityKeyIdentifierExtension."); } // NB. this is always encoded with the IMPLICIT tag // The checks only make sense if we assume implicit tagging, // with explicit tagging the form is always constructed. while (val.data.available() != 0) { DerValue opt = val.data.getDerValue(); if (opt.isContextSpecific(TAG_ID) && !opt.isConstructed()) { if (id != null) throw new IOException("Duplicate KeyIdentifier in " + "AuthorityKeyIdentifier."); opt.resetTag(DerValue.tag_OctetString); id = new KeyIdentifier(opt); } else if (opt.isContextSpecific(TAG_NAMES) && opt.isConstructed()) { if (names != null) throw new IOException("Duplicate GeneralNames in " + "AuthorityKeyIdentifier."); try { opt.resetTag(DerValue.tag_Sequence); names = new GeneralNames(opt); } catch (GeneralNamesException e) { throw new IOException(e); } } else if (opt.isContextSpecific(TAG_SERIAL_NUM) && !opt.isConstructed()) { if (serialNum != null) throw new IOException("Duplicate SerialNumber in " + "AuthorityKeyIdentifier."); opt.resetTag(DerValue.tag_Integer); serialNum = new SerialNumber(opt); } else throw new IOException("Invalid encoding of " + "AuthorityKeyIdentifierExtension."); } } /** * Return the object as a string. */ public String toString() { String s = super.toString() + "AuthorityKeyIdentifier [\n"; if (id != null) { s += id.toString(); } if (names != null) { s += names.toString() + "\n"; } if (serialNum != null) { s += serialNum.toString() + "\n"; } return (s + "]\n"); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the OutputStream. * * @param out the OutputStream to write the extension to. * @exception IOException on error. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { extensionId = PKIXExtensions.AuthorityKey_Id; critical = false; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { clearValue(); if (name.equalsIgnoreCase(KEY_ID)) { if (!(obj instanceof KeyIdentifier)) { throw new IOException("Attribute value should be of " + "type KeyIdentifier."); } id = (KeyIdentifier) obj; } else if (name.equalsIgnoreCase(AUTH_NAME)) { if (!(obj instanceof GeneralNames)) { throw new IOException("Attribute value should be of " + "type GeneralNames."); } names = (GeneralNames) obj; } else if (name.equalsIgnoreCase(SERIAL_NUMBER)) { if (!(obj instanceof SerialNumber)) { throw new IOException("Attribute value should be of " + "type SerialNumber."); } serialNum = (SerialNumber) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:AuthorityKeyIdentifier."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(KEY_ID)) { return (id); } else if (name.equalsIgnoreCase(AUTH_NAME)) { return (names); } else if (name.equalsIgnoreCase(SERIAL_NUMBER)) { return (serialNum); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:AuthorityKeyIdentifier."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(KEY_ID)) { id = null; } else if (name.equalsIgnoreCase(AUTH_NAME)) { names = null; } else if (name.equalsIgnoreCase(SERIAL_NUMBER)) { serialNum = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:AuthorityKeyIdentifier."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(KEY_ID); elements.addElement(AUTH_NAME); elements.addElement(SERIAL_NUMBER); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/BasicConstraintsExtension.java000066400000000000000000000226471362106420000275540ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class represents the Basic Constraints Extension. * *

* The basic constraints extension identifies whether the subject of the certificate is a CA and how deep a * certification path may exist through that CA. * *

 * The ASN.1 syntax for this extension is:
 * BasicConstraints ::= SEQUENCE {
 *     cA                BOOLEAN DEFAULT FALSE,
 *     pathLenConstraint INTEGER (0..MAX) OPTIONAL
 * }
 * 
* * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.7 * @see CertAttrSet * @see Extension */ public class BasicConstraintsExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 6213957094939885889L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.BasicConstraints"; /** * Attribute names. */ public static final String NAME = "BasicConstraints"; public static final String IS_CA = "is_ca"; public static final String PATH_LEN = "path_len"; // Private data members private boolean ca = false; private int pathLen = -1; // Encode this extension value private void encodeThis() throws IOException { try (DerOutputStream out = new DerOutputStream()) { DerOutputStream tmp = new DerOutputStream(); if (ca) { tmp.putBoolean(ca); } if (pathLen >= 0) { tmp.putInteger(new BigInt(pathLen)); } out.write(DerValue.tag_Sequence, tmp); this.extensionValue = out.toByteArray(); } } /** * Default constructor for this object. * * @param ca true, if the subject of the Certificate is a CA. * @param len specifies the depth of the certification path. */ public BasicConstraintsExtension(boolean ca, int len) throws IOException { this.ca = ca; this.pathLen = len; this.extensionId = PKIXExtensions.BasicConstraints_Id; if (ca) { critical = true; } else { critical = false; } encodeThis(); } /** * Default constructor for this object. * * @param ca true, if the subject of the Certificate is a CA. * @param len specifies the depth of the certification path. */ public BasicConstraintsExtension(boolean ca, boolean critical, int len) throws IOException { this.ca = ca; this.pathLen = len; this.extensionId = PKIXExtensions.BasicConstraints_Id; this.critical = critical; encodeThis(); } /** * Create the extension from the passed DER encoded value of the same. * * @param value the DER encoded value of the extension. * @exception IOException on error. */ public BasicConstraintsExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.BasicConstraints_Id; this.critical = critical.booleanValue(); if (value instanceof byte[]) { int len = Array.getLength(value); byte[] extValue = new byte[len]; System.arraycopy(value, 0, extValue, 0, len); this.extensionValue = extValue; DerValue val = new DerValue(extValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding of BasicConstraints"); } // non-CA cert with no limit to certification path length if (val.data == null || val.data.available() < 1) { this.ca = false; this.pathLen = -1; return; } DerValue opt = val.data.getDerValue(); if (opt.tag != DerValue.tag_Boolean) { this.ca = false; } else { this.ca = true; if (val.data.available() != 0) { opt = val.data.getDerValue(); } else { this.pathLen = -1; return; } } if (opt.tag != DerValue.tag_Integer) { throw new IOException("Invalid encoding of BasicConstraints"); } this.pathLen = (opt.getInteger()).toInt(); /* * Activate this check once again after PKIX profiling * is a standard and this check no longer imposes an * interoperability barrier. * if (ca) { * if (!this.critical) { * throw new IOException("Criticality cannot be false for CA."); * } * } */ } else throw new IOException("Invalid argument type"); } /** * Return user readable form of extension. */ public String toString() { String s = super.toString() + "BasicConstraints:[\n"; s += ((ca) ? ("CA:true") : ("CA:false")) + "\n"; if (pathLen >= 0) { s += "PathLen:" + pathLen + "\n"; } else { s += "PathLen: undefined\n"; } return (s + "]\n"); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Encode this extension value to the output stream. * * @param out the DerOutputStream to encode the extension to. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { this.extensionId = PKIXExtensions.BasicConstraints_Id; /* #57286 - so that profile can set critiality */ /* if (ca) { critical = true; } else { critical = false; } */ encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { clearValue(); if (name.equalsIgnoreCase(IS_CA)) { if (!(obj instanceof Boolean)) { throw new IOException("Attribute value should be of type Boolean."); } ca = ((Boolean) obj).booleanValue(); } else if (name.equalsIgnoreCase(PATH_LEN)) { if (!(obj instanceof Integer)) { throw new IOException("Attribute value should be of type Integer."); } pathLen = ((Integer) obj).intValue(); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:BasicConstraints."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(IS_CA)) { return (Boolean.valueOf(ca)); } else if (name.equalsIgnoreCase(PATH_LEN)) { return (Integer.valueOf(pathLen)); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:BasicConstraints."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(IS_CA)) { ca = false; } else if (name.equalsIgnoreCase(PATH_LEN)) { pathLen = -1; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:BasicConstraints."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(IS_CA); elements.addElement(PATH_LEN); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CIDRNetmask.java000066400000000000000000000045451362106420000244470ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2018 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.nio.ByteBuffer; /** * Netmask that is the number of significant bits. */ public class CIDRNetmask { private int n; public CIDRNetmask(String s) { this(Integer.parseInt(s)); } public CIDRNetmask(int n) { if (n < 0) throw new InvalidNetmaskException("cannot be negative"); this.n = n; } /** * Write the netmask into a byte buffer. * * Throw InvalidNetmaskException if negative or if the * size exceeds the size of the address type inferred * from the remaining buffer space (which must be 4 * bytes for IPv4 and 16 bytes for IPv6). * * exceeds the size of the buffer */ protected void write(ByteBuffer buf) { // determine type of addr based on bytes left in buffer int remaining = buf.remaining(); int bits = 0; if (remaining == 4) bits = 32; else if (remaining == 16) bits = 128; else throw new InvalidNetmaskException( "cannot determine type of address for netmask"); if (n > bits) throw new InvalidNetmaskException("netmask exceed address size"); int maskSigBits = n; for (; remaining > 0; remaining--) { int maskByteSigBits = Math.min(8, maskSigBits); byte maskByte = (byte) (0xff - (0xff >> maskByteSigBits)); buf.put(maskByte); maskSigBits = Math.max(maskSigBits - 8, 0); } } public String toString() { return "/" + n; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CPSuri.java000066400000000000000000000033241362106420000235420ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the CPSuri Qualifier. * * CPSuri ::= IA5String; * * @author Thomas Kwan */ public class CPSuri extends Qualifier { /** * */ private static final long serialVersionUID = -2814961293159006960L; private String mURI = null; public CPSuri(String uri) { mURI = uri; } public CPSuri(DerValue val) throws IOException { mURI = val.getIA5String(); } /** * Write the PolicyQualifier to the DerOutputStream. * * @param out the DerOutputStream to write the object to. * @exception IOException on errors. */ public void encode(DerOutputStream out) throws IOException { out.putIA5String(mURI); } public String getURI() { return mURI; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CRLDistributionPoint.java000066400000000000000000000423451362106420000264350ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.netscape.security.util.BitArray; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** *
 * DistributionPoint ::= SEQUENCE {
 *      distributionPoint       [0]     DistributionPointName OPTIONAL,
 *      reasons                 [1]     ReasonFlags OPTIONAL,
 *      cRLIssuer               [2]     GeneralNames OPTIONAL }
 *
 * DistributionPointName ::= CHOICE {
 *      fullName                [0]     GeneralNames,
 *      nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
 *
 * ReasonFlags ::= BIT STRING {
 *      unused                  (0),
 *      keyCompromise           (1),
 *      cACompromise            (2),
 *      affiliationChanged      (3),
 *      superseded              (4),
 *      cessationOfOperation    (5),
 *      certificateHold         (6) }
 * 
*/ public class CRLDistributionPoint implements ASN1Value { // at most one of the two following may be specified: private GeneralNames fullName; private RDN relativeName; // cache encoding of fullName private ANY fullNameEncoding; private BitArray reasons; // optional, may be null private GeneralNames CRLIssuer; // optional, may be null private ANY CRLIssuerEncoding; // default constructor does nothing. /** * Returns the fullName of the DistributionPointName, which may be null. */ public GeneralNames getFullName() { return fullName; } /** * Returns the relativeName of the DistributionPointName, which may be null. */ public RDN getRelativeName() { return relativeName; } /** * Sets the fullName of the DistributionPointName. It may be set to null. * If it is set to a non-null value, relativeName will be * set to null, because at most one of these two attributes * can be specified at a time. * * @exception GeneralNamesException If an error occurs encoding the * name. */ public void setFullName(GeneralNames fullName) throws GeneralNamesException, IOException { this.fullName = fullName; if (fullName != null) { // encode the name to catch any problems with it DerOutputStream derOut = new DerOutputStream(); fullName.encode(derOut); try { ANY raw = new ANY(derOut.toByteArray()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); raw.encodeWithAlternateTag(Tag.get(0), bos); fullNameEncoding = new ANY(bos.toByteArray()); } catch (InvalidBERException e) { // assume this won't happen, since it would imply a bug // in DerOutputStream throw new GeneralNamesException(e.toString()); } this.relativeName = null; } } /** * Sets the relativeName of the DistributionPointName. It may be set to null. * If it is set to a non-null value, fullName will be * set to null, because at most one of these two attributes * can be specified at a time. */ public void setRelativeName(RDN relativeName) { this.relativeName = relativeName; if (relativeName != null) { this.fullName = null; } } /** * Returns the reason flags for this distribution point. May be null. */ public BitArray getReasons() { return reasons; } /** * Sets the reason flags for this distribution point. May be set to null. */ public void setReasons(BitArray reasons) { this.reasons = reasons; } /** * Returns the CRLIssuer for the CRL at this distribution point. * May be null. */ public GeneralNames getCRLIssuer() { return CRLIssuer; } /** * Sets the CRLIssuer for the CRL at this distribution point. * May be set to null. * * @exception GeneralNamesException If an error occurs encoding the name. */ public void setCRLIssuer(GeneralNames CRLIssuer) throws GeneralNamesException, IOException { this.CRLIssuer = CRLIssuer; if (CRLIssuer != null) { // encode the name to catch any problems with it DerOutputStream derOut = new DerOutputStream(); CRLIssuer.encode(derOut); try { ANY raw = new ANY(derOut.toByteArray()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); raw.encodeWithAlternateTag(Tag.get(2), bos); CRLIssuerEncoding = new ANY(bos.toByteArray()); } catch (InvalidBERException e) { throw new GeneralNamesException(e.toString()); } } } ///////////////////////////////////////////////////////////// // DER encoding ///////////////////////////////////////////////////////////// private 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(); DerOutputStream derOut; try { // Encodes the DistributionPointName. Because DistributionPointName // is a CHOICE, the [0] tag is forced to be EXPLICIT. if (fullName != null) { EXPLICIT distPoint = new EXPLICIT(Tag.get(0), fullNameEncoding); seq.addElement(distPoint); } else if (relativeName != null) { derOut = new DerOutputStream(); relativeName.encode(derOut); ANY rn = new ANY(derOut.toByteArray()); EXPLICIT raw = new EXPLICIT(Tag.get(1), rn); ByteArrayOutputStream bos = new ByteArrayOutputStream(); raw.encode(bos); ANY distPointName = new ANY(bos.toByteArray()); EXPLICIT distPoint = new EXPLICIT(Tag.get(0), distPointName); seq.addElement(distPoint); } // Encodes the ReasonFlags. if (reasons != null) { derOut = new DerOutputStream(); derOut.putUnalignedBitString(reasons); ANY raw = new ANY(derOut.toByteArray()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); raw.encodeWithAlternateTag(Tag.get(1), bos); ANY reasonEncoding = new ANY(bos.toByteArray()); seq.addElement(Tag.get(1), reasonEncoding); } // Encodes the CRLIssuer if (CRLIssuer != null) { seq.addElement(Tag.get(2), CRLIssuerEncoding); } seq.encode(implicitTag, ostream); } catch (InvalidBERException e) { // this shouldn't happen unless there is a bug in one of // the Sun encoding classes throw new IOException(e.toString()); } } // Template singleton private static Template templateInstance = new Template(); /** * Returns an instance of a template for decoding a CRLDistributionPoint. */ public static Template getTemplate() { return templateInstance; } public static void main(String args[]) throws GeneralNamesException, IOException, InvalidBERException { ByteArrayOutputStream bos = null; FileOutputStream fos = null; try { if (args.length != 1) { System.out.println("Usage: CRLDistributionPoint "); System.exit(-1); } bos = new ByteArrayOutputStream(); SEQUENCE cdps = new SEQUENCE(); // URI only CRLDistributionPoint cdp = new CRLDistributionPoint(); URIName uri = new URIName("http://www.mycrl.com/go/here"); GeneralNames generalNames = new GeneralNames(); generalNames.addElement(uri); cdp.setFullName(generalNames); cdps.addElement(cdp); // DN only cdp = new CRLDistributionPoint(); X500Name dn = new X500Name("CN=Otis Smith,E=otis@fedoraproject.org" + ",OU=Certificate Server,O=Fedora,C=US"); generalNames = new GeneralNames(); generalNames.addElement(dn); cdp.setFullName(generalNames); cdps.addElement(cdp); // DN + reason BitArray ba = new BitArray(5, new byte[] { (byte) 0x28 }); cdp = new CRLDistributionPoint(); cdp.setFullName(generalNames); cdp.setReasons(ba); cdps.addElement(cdp); // relative DN + reason + crlIssuer cdp = new CRLDistributionPoint(); RDN rdn = new RDN("OU=foobar dept"); cdp.setRelativeName(rdn); cdp.setReasons(ba); cdp.setCRLIssuer(generalNames); cdps.addElement(cdp); cdps.encode(bos); byte[] encoded = bos.toByteArray(); fos = new FileOutputStream(args[0]); fos.write(encoded); SEQUENCE.OF_Template seqt = new SEQUENCE.OF_Template(getTemplate()); cdps = (SEQUENCE) ASN1Util.decode(seqt, encoded); int size = cdps.size(); System.out.println("Total number of CDPs: " + size); for (int i = 0; i < size; i++) { System.out.println("\nCDP " + i); cdp = (CRLDistributionPoint) cdps.elementAt(i); GeneralNames gn = cdp.getFullName(); if (gn == null) { System.out.println("No full name"); } else { System.out.println(gn); } rdn = cdp.getRelativeName(); if (rdn == null) { System.out.println("No relative name"); } else { System.out.println(rdn); } if (cdp.getReasons() == null) { System.out.println("No reasons"); } else { System.out.println(cdp.getReasons()); } gn = cdp.getCRLIssuer(); if (gn == null) { System.out.println("No cRLIssuer"); } else { System.out.println(gn); } } System.out.println("Done"); } finally { if (bos != null) { bos.close(); } if (fos != null) { fos.close(); } if (fos != null) { fos.close(); } } } /** * Template for decoding CRLDistributionPoint. */ 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 implicitTag, InputStream istream) throws IOException, InvalidBERException { CRLDistributionPoint cdp = new CRLDistributionPoint(); // // construct the top-level sequence // SEQUENCE.Template seqt = SEQUENCE.getTemplate(); // distributionPoint seqt.addOptionalElement( new EXPLICIT.Template(Tag.get(0), ANY.getTemplate())); // reasons seqt.addOptionalElement(Tag.get(1), BIT_STRING.getTemplate()); // cRLIssuer // This will have a tag of 2, but we can't say that here // because ANYs can't have implicit tags. We don't need to say // it, because we do check the tags on the other two elements // in the sequence, so we'll know if we get this one. seqt.addOptionalElement(ANY.getTemplate()); // // decode the top-level sequence // SEQUENCE top = (SEQUENCE) seqt.decode(implicitTag, istream); // decode the distribution point name if (top.elementAt(0) != null) { EXPLICIT exp = (EXPLICIT) top.elementAt(0); ANY distPoint = (ANY) exp.getContent(); if (distPoint.getTag().equals(Tag.get(0))) { // fullName try { DerValue dv = new DerValue(distPoint.getEncoded()); //toFile("encodedFullName", distPoint.getEncoded()); dv.resetTag(DerValue.tag_Sequence); cdp.setFullName(new GeneralNames(dv)); } catch (GeneralNamesException e) { throw new InvalidBERException("fullName: " + e.toString()); } catch (IOException e) { throw new InvalidBERException("fullName: " + e.toString()); } } else if (distPoint.getTag().equals(Tag.get(1))) { // relative name try { DerValue dv = new DerValue(distPoint.getEncoded()); /* dv is as follows: 0 12: [1] { 2 10: SET { 4 8: SEQUENCE { 6 3: OBJECT IDENTIFIER commonName (2 5 4 3) 11 1: PrintableString 'x' : } : } : } */ dv = dv.data.getDerValue(); // skipping the tag /* after the skipping, we have: 0 10: SET { 2 8: SEQUENCE { 4 3: OBJECT IDENTIFIER commonName (2 5 4 3) 9 1: PrintableString 'x' : } : } */ dv.resetTag(DerValue.tag_Set); cdp.setRelativeName(new RDN(dv)); } catch (IOException e) { throw new InvalidBERException("relativeName " + e.toString()); } } else { throw new InvalidBERException( "Unknown tag " + distPoint.getTag() + " in distributionPoint"); } } // decode the reasons if (top.elementAt(1) != null) { BIT_STRING bs = (BIT_STRING) top.elementAt(1); byte[] bits = bs.getBits(); cdp.setReasons( new BitArray((bits.length * 8) - bs.getPadCount(), bits)); } // decode the cRLIssuer if (top.elementAt(2) != null) { ANY issuer = (ANY) top.elementAt(2); if (!issuer.getTag().equals(Tag.get(2))) { throw new InvalidBERException("Invalid tag " + issuer.getTag()); } try { DerValue dv = new DerValue(issuer.getEncoded()); dv.resetTag(DerValue.tag_Sequence); cdp.setCRLIssuer(new GeneralNames(dv)); } catch (GeneralNamesException e) { throw new InvalidBERException("cRLIssuer " + e.toString()); } catch (IOException e) { throw new InvalidBERException("cRLIssuer " + e.toString()); } } return cdp; } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CRLDistributionPointsExtension.java000066400000000000000000000316201362106420000305070ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.netscape.security.util.BitArray; import org.mozilla.jss.netscape.security.util.DerOutputStream; /** * An extension that tells applications where to find the CRL for * this certificate. * *
 * cRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
 *
 * DistributionPoint ::= SEQUENCE {
 *      distributionPoint       [0]     DistributionPointName OPTIONAL,
 *      reasons                 [1]     ReasonFlags OPTIONAL,
 *      cRLIssuer               [2]     GeneralNames OPTIONAL }
 *
 * DistributionPointName ::= CHOICE {
 *      fullName                [0]     GeneralNames,
 *      nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
 *
 * ReasonFlags ::= BIT STRING {
 *      unused                  (0),
 *      keyCompromise           (1),
 *      cACompromise            (2),
 *      affiliationChanged      (3),
 *      superseded              (4),
 *      cessationOfOperation    (5),
 *      certificateHold         (6) }
 * 
*/ public class CRLDistributionPointsExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 8551761833349709229L; // vector of CRLDistributionPoint private SEQUENCE distributionPoints = new SEQUENCE(); // Cached DER-encoding to improve performance. private byte[] cachedEncoding = null; /** * This constructor is called by the CertificateExtensions class to decode * an extension whose OID indicates it is a CRLDistributionsPoints * extension. */ public CRLDistributionPointsExtension(Boolean critical, Object value) //throws IOException { try { this.extensionId = PKIXExtensions.CRLDistributionPoints_Id; this.critical = critical.booleanValue(); this.extensionValue = ((byte[]) value).clone(); // decode the value try { SEQUENCE.OF_Template seqOfCRLDP = new SEQUENCE.OF_Template(CRLDistributionPoint.getTemplate()); distributionPoints = (SEQUENCE) ASN1Util.decode(seqOfCRLDP, extensionValue); } catch (InvalidBERException e) { throw new IOException("Invalid BER-encoding: " + e, e); } } catch (IOException e) { System.out.println("Big error"); System.out.println(e); e.printStackTrace(); //throw e; } } /** * The Object Identifier for this extension. */ public static final String OID = "2.5.29.31"; /** * Creates a new CRLDistributionPoints extension, with the given * distribution point as the first element. */ public CRLDistributionPointsExtension(CRLDistributionPoint dp) { this.extensionId = PKIXExtensions.CRLDistributionPoints_Id; this.critical = false; distributionPoints.addElement(dp); } /** * Adds an additional distribution point to the end of the sequence. */ public void addPoint(CRLDistributionPoint dp) { distributionPoints.addElement(dp); cachedEncoding = null; } /** * Returns the number of distribution points in the sequence. */ public int getNumPoints() { return distributionPoints.size(); } /** * Returns the DistributionPoint at the given index in the sequence. */ public CRLDistributionPoint getPointAt(int index) { return (CRLDistributionPoint) distributionPoints.elementAt(index); } /** * Sets the criticality of this extension. PKIX dictates that this * extension SHOULD NOT be critical, so applications can make it critical * if they have a very good reason. By default, the extension is not * critical. */ public void setCritical(boolean critical) { this.critical = critical; } /** * Encodes this extension to the given DerOutputStream. * This method re-encodes each time it is called, so it is not very * efficient. */ public void encode(DerOutputStream out) throws IOException { extensionValue = ASN1Util.encode(distributionPoints); super.encode(out); } /** * Should be called if any change is made to this data structure * so that the cached DER encoding can be discarded. */ public void flushCachedEncoding() { cachedEncoding = null; } ///////////////////////////////////////////////////////////// // CertAttrSet interface // This interface is not really appropriate for this extension // because it is so complicated. Therefore, we only provide a // minimal implementation. ///////////////////////////////////////////////////////////// public static final String NAME = "CRLDistributionPoints"; @Override public String toString() { return NAME; } /** * DER-encodes this extension to the given OutputStream. */ public void encode(OutputStream ostream) throws CertificateException, IOException { if (cachedEncoding == null) { // only re-encode if necessary DerOutputStream tmp = new DerOutputStream(); encode(tmp); cachedEncoding = tmp.toByteArray(); } ostream.write(cachedEncoding); } public void decode(InputStream in) throws CertificateException, IOException { throw new IOException("Not supported"); } public void set(String name, Object obj) throws CertificateException, IOException { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CRLDistributionPointsExtension"); } public Object get(String name) throws CertificateException, IOException { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CRLDistributionPointsExtension"); } public void delete(String name) throws CertificateException, IOException { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CRLDistributionPointsExtension"); } /* * TODO use an empty collection to generate these */ public Enumeration getAttributeNames() { return (new Vector()).elements(); } public String getName() { return NAME; } /** * Test driver. */ public static void main(String args[]) { BufferedOutputStream bos = null; try { if (args.length != 1) { System.out.println("Usage: CRLDistributionPointsExtentions " + ""); System.exit(-1); } bos = new BufferedOutputStream( new FileOutputStream(args[0])); // URI only CRLDistributionPoint cdp = new CRLDistributionPoint(); URIName uri = new URIName("http://www.mycrl.com/go/here"); GeneralNames generalNames = new GeneralNames(); generalNames.addElement(uri); cdp.setFullName(generalNames); CRLDistributionPointsExtension crldpExt = new CRLDistributionPointsExtension(cdp); // DN only cdp = new CRLDistributionPoint(); X500Name dn = new X500Name("CN=Otis Smith,E=otis@fedoraproject.org" + ",OU=Certificate Server,O=Fedora,C=US"); generalNames = new GeneralNames(); generalNames.addElement(dn); cdp.setFullName(generalNames); crldpExt.addPoint(cdp); // DN + reason BitArray ba = new BitArray(5, new byte[] { (byte) 0x28 }); cdp = new CRLDistributionPoint(); cdp.setFullName(generalNames); cdp.setReasons(ba); crldpExt.addPoint(cdp); // relative DN + reason + crlIssuer cdp = new CRLDistributionPoint(); RDN rdn = new RDN("OU=foobar dept"); cdp.setRelativeName(rdn); cdp.setReasons(ba); cdp.setCRLIssuer(generalNames); crldpExt.addPoint(cdp); crldpExt.setCritical(true); crldpExt.encode(bos); } catch (Exception e) { e.printStackTrace(); } finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Represents a reason that a cert may be revoked. These reasons are * expressed in a ReasonFlags bit string. */ public static class Reason { private String name; private byte bitMask; private Reason() { } private Reason(String name, byte bitMask) { this.name = name; this.bitMask = bitMask; map.put(name, this); list.addElement(this); } private static Hashtable map = new Hashtable(); private static Vector list = new Vector(); public static Reason fromString(String name) { return map.get(name); } public String getName() { return name; } public byte getBitMask() { return bitMask; } /** * Given a bit array representing reason flags, extracts the reasons * and returns them as an array. * * @param bitFlags A bit vector containing reason flags. * @return An array of reasons contained in the bit vector. * May be zero-length but will not be null. */ public static Reason[] bitArrayToReasonArray(byte bitFlags) { return bitArrayToReasonArray(new byte[] { bitFlags }); } /** * Given a bit array representing reason flags, extracts the reasons * and returns them as an array. Currently, only the first byte * of the bitflags are examined. * * @param bitFlags A bit vector containing reason flags. The format * is big-endian (MSB first). Only the first byte is examined. * @return An array of reasons contained in the bit vector. * May be zero-length but will not be null. */ public static Reason[] bitArrayToReasonArray(byte[] bitFlags) { byte first = bitFlags[0]; int size = list.size(); Vector result = new Vector(); for (int i = 0; i < size; i++) { Reason r = list.elementAt(i); byte b = r.getBitMask(); if ((first & b) != 0) { result.addElement(r); } } size = result.size(); Reason[] retval = new Reason[size]; for (int i = 0; i < size; i++) { retval[i] = result.elementAt(i); } return retval; } public static final Reason UNUSED = new Reason("unused", (byte) 0x80); public static final Reason KEY_COMPROMISE = new Reason("keyCompromise", (byte) 0x40); public static final Reason CA_COMPROMISE = new Reason("cACompromise", (byte) 0x20); public static final Reason AFFILIATION_CHANGED = new Reason("affiliationChanged", (byte) 0x10); public static final Reason SUPERSEDED = new Reason("superseded", (byte) 0x08); public static final Reason CESSATION_OF_OPERATION = new Reason("cessationOfOperation", (byte) 0x04); public static final Reason CERTIFICATE_HOLD = new Reason("certificateHold", (byte) 0x02); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CRLExtensions.java000066400000000000000000000213751362106420000251030ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.security.cert.CRLException; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the CRL Extensions. * * @author Hemma Prafullchandra * @version 1.4 */ public class CRLExtensions extends Vector { /** * */ private static final long serialVersionUID = 365767738692986418L; private Hashtable map; // Parse the encoded extension private void parseExtension(Extension ext) throws X509ExtensionException { try { Class extClass = OIDMap.getClass(ext.getExtensionId()); if (extClass == null) { // Unsupported extension if (ext.isCritical()) { throw new IOException("Unsupported CRITICAL extension: " + ext.getExtensionId()); } else { map.put(ext.getExtensionId().toString(), ext); addElement(ext); return; } } Class[] params = { Boolean.class, Object.class }; Constructor cons = extClass.getConstructor(params); byte[] extData = ext.getExtensionValue(); int extLen = extData.length; Object value = Array.newInstance(byte.class, extLen); for (int i = 0; i < extLen; i++) { Array.setByte(value, i, extData[i]); } Object[] passed = new Object[] { Boolean.valueOf(ext.isCritical()), value }; CertAttrSet crlExt = (CertAttrSet) cons.newInstance(passed); map.put(crlExt.getName(), (Extension) crlExt); addElement((Extension) crlExt); } catch (InvocationTargetException invk) { throw new X509ExtensionException( invk.getTargetException().getMessage()); } catch (Exception e) { throw new X509ExtensionException(e.toString()); } } /** * Default constructor. */ public CRLExtensions() { map = new Hashtable(); } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the Extension from. * @exception CRLException on decoding errors. * @exception X509ExtensionException on extension handling errors. */ public CRLExtensions(DerInputStream in) throws CRLException, X509ExtensionException { map = new Hashtable(); try { DerValue[] exts = in.getSequence(5); for (int i = 0; i < exts.length; i++) { Extension ext = new Extension(exts[i]); parseExtension(ext); } } catch (IOException e) { throw new CRLException("Parsing error: " + e.toString()); } } /** * Decode the extensions from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception CRLException on decoding or validity errors. * @exception X509ExtensionException on extension handling errors. */ public void decode(InputStream in) throws CRLException, X509ExtensionException { try { DerValue val = new DerValue(in); DerInputStream str = val.toDerInputStream(); map = new Hashtable(); DerValue[] exts = str.getSequence(5); for (int i = 0; i < exts.length; i++) { Extension ext = new Extension(exts[i]); parseExtension(ext); } } catch (IOException e) { throw new CRLException("Parsing error: " + e.toString()); } } /** * Encode the extensions in DER form to the stream. * * @param out the DerOutputStream to marshal the contents to. * @param isExplicit the tag indicating whether this is an entry * extension or a CRL extension. * @exception CRLException on encoding errors. */ public void encode(OutputStream out, boolean isExplicit) throws CRLException { try (DerOutputStream tmp = new DerOutputStream()) { // #381559 if (size() == 0) return; DerOutputStream extOut = new DerOutputStream(); for (int i = 0; i < size(); i++) { Object thisOne = elementAt(i); if (thisOne instanceof CertAttrSet) ((CertAttrSet) thisOne).encode(extOut); else if (thisOne instanceof Extension) ((Extension) thisOne).encode(extOut); else throw new CRLException("Illegal extension object"); } DerOutputStream seq = new DerOutputStream(); seq.write(DerValue.tag_Sequence, extOut); if (isExplicit) { tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), seq); out.write(tmp.toByteArray()); } else { out.write(seq.toByteArray()); } } catch (IOException e) { throw new CRLException("Encoding error: " + e.toString()); } catch (CertificateException e) { throw new CRLException("Encoding error: " + e.toString()); } } /** * Get the extension with this alias. * * @param alias the identifier string for the extension to retrieve. * @exception X509ExtensionException on extension handling errors. */ public Extension get(String alias) throws X509ExtensionException { X509AttributeName attr = new X509AttributeName(alias); String name; String id = attr.getPrefix(); if (id.equalsIgnoreCase(X509CertImpl.NAME)) { // fully qualified int index = alias.lastIndexOf("."); name = alias.substring(index + 1); } else name = alias; Extension ext = map.get(name); if (ext == null) throw new X509ExtensionException("No extension found with name: " + alias); return ext; } /** * Set the extension value with this alias. * * @param alias the identifier string for the extension to set. * @param obj the Object to set the extension identified by the * alias. * @exception IOException on errors. */ public void set(String alias, Extension obj) throws IOException { map.put(alias, obj); addElement(obj); } /** * Return an enumeration of names of the extensions. * * @return an enumeration of the names of the extensions in this CRL. */ public Enumeration getElements() { return (map.elements()); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((map == null) ? 0 : map.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; CRLExtensions other = (CRLExtensions) obj; if (map == null) { if (other.map != null) return false; } else if (!map.equals(other.map)) return false; return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CRLNumberExtension.java000066400000000000000000000163271362106420000260720ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.math.BigInteger; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the CRL Number Extension. * *

* This extension, if present, conveys a monotonically increasing sequence number for each CRL issued by a given CA * through a specific CA X.500 Directory entry or CRL distribution point. This extension allows users to easily * determine when a particular CRL supersedes another CRL. * * @author Hemma Prafullchandra * @version 1.2 * @see Extension * @see CertAttrSet */ public class CRLNumberExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 2992307666566322402L; /** * Attribute name. */ public static final String NAME = "CRLNumber"; public static final String NUMBER = "value"; private BigInt crlNumber = null; // Encode this extension value private void encodeThis() throws IOException { if (crlNumber == null) throw new IOException("Unintialized CRL number extension"); try (DerOutputStream os = new DerOutputStream()) { os.putInteger(this.crlNumber); this.extensionValue = os.toByteArray(); } } /** * Create a CRLNumberExtension with the integer value . * The criticality is set to false. * * @param crlNum the value to be set for the extension. */ public CRLNumberExtension(int crlNum) throws IOException { this.crlNumber = new BigInt(crlNum); this.extensionId = PKIXExtensions.CRLNumber_Id; this.critical = false; encodeThis(); } /** * Create a CRLNumberExtension with the BigInteger value . * The criticality is set to false. * * @param crlNum the value to be set for the extension. */ public CRLNumberExtension(BigInteger crlNum) throws IOException { this.crlNumber = new BigInt(crlNum); this.extensionId = PKIXExtensions.CRLNumber_Id; this.critical = false; encodeThis(); } /** * Create a CRLNumberExtension with the BigInteger value . * * @param critical true if the extension is to be treated as critical. * @param crlNum the value to be set for the extension. */ public CRLNumberExtension(Boolean critical, BigInteger crlNum) throws IOException { this.crlNumber = new BigInt(crlNum); this.extensionId = PKIXExtensions.CRLNumber_Id; this.critical = critical.booleanValue(); encodeThis(); } /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public CRLNumberExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.CRLNumber_Id; this.critical = critical.booleanValue(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; DerValue val = new DerValue(extValue); this.crlNumber = val.getInteger(); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (name.equalsIgnoreCase(NUMBER)) { if (!(obj instanceof BigInteger)) { throw new IOException("Attribute must be of type BigInteger."); } crlNumber = new BigInt((BigInteger) obj); } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:CRLNumber."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(NUMBER)) { if (crlNumber == null) return null; else return crlNumber.toBigInteger(); } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:CRLNumber."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(NUMBER)) { crlNumber = null; } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:CRLNumber."); } } /** * Returns a printable representation of the CRLNumberExtension. */ public String toString() { String s = super.toString() + "CRL Number: " + ((crlNumber == null) ? "" : crlNumber.toString()) + "\n"; return (s); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { this.extensionId = PKIXExtensions.CRLNumber_Id; this.critical = false; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(NUMBER); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CRLReasonExtension.java000066400000000000000000000173341362106420000260700ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the CRLReason Extension of CRL entry. * *

* This extension, if present, defines the identifies the reason for the certificate revocation. * * @author galperin * @version $Revision$, $Date$ * @see Extension * @see CertAttrSet */ public final class CRLReasonExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 4544973296866779535L; /** * Canned instances for all revocation reasons */ public static final CRLReasonExtension UNSPECIFIED = new CRLReasonExtension(RevocationReason.UNSPECIFIED); public static final CRLReasonExtension KEY_COMPROMISE = new CRLReasonExtension(RevocationReason.KEY_COMPROMISE); public static final CRLReasonExtension CA_COMPROMISE = new CRLReasonExtension(RevocationReason.CA_COMPROMISE); public static final CRLReasonExtension AFFILIATION_CHANGED = new CRLReasonExtension( RevocationReason.AFFILIATION_CHANGED); public static final CRLReasonExtension SUPERSEDED = new CRLReasonExtension(RevocationReason.SUPERSEDED); public static final CRLReasonExtension CESSATION_OF_OPERATION = new CRLReasonExtension( RevocationReason.CESSATION_OF_OPERATION); public static final CRLReasonExtension CERTIFICATE_HOLD = new CRLReasonExtension(RevocationReason.CERTIFICATE_HOLD); public static final CRLReasonExtension REMOVE_FROM_CRL = new CRLReasonExtension(RevocationReason.REMOVE_FROM_CRL); public static final CRLReasonExtension PRIVILEGE_WITHDRAWN = new CRLReasonExtension( RevocationReason.PRIVILEGE_WITHDRAWN); public static final CRLReasonExtension AA_COMPROMISE = new CRLReasonExtension(RevocationReason.AA_COMPROMISE); /** * Attribute names. */ public static final String NAME = "CRLReason"; public static final String REASON = "value"; private RevocationReason mReason = null; public RevocationReason getReason() { return mReason; } /** * Default constructor * */ public CRLReasonExtension() { this.extensionId = PKIXExtensions.ReasonCode_Id; this.critical = false; mReason = null; } /** * Create extension value for specific revocation reason * */ public CRLReasonExtension(RevocationReason reason) { this.extensionId = PKIXExtensions.ReasonCode_Id; this.critical = false; mReason = reason; } public CRLReasonExtension(Boolean critical, RevocationReason reason) throws IOException { this.extensionId = PKIXExtensions.ReasonCode_Id; this.critical = critical.booleanValue(); mReason = reason; } /** * Create the object from the passed DER encoded value. * * @param value the DerValue decoded from the stream. * @exception IOException on decoding errors. */ public CRLReasonExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.ReasonCode_Id; this.critical = critical.booleanValue(); byte[] extValue = ((byte[]) value).clone(); this.extensionValue = extValue; DerValue val = new DerValue(extValue); int reasonCode = val.getEnumerated(); mReason = RevocationReason.fromInt(reasonCode); if (mReason == null) throw new IOException("Unknown revocation reason value " + reasonCode); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (!(obj instanceof RevocationReason)) { throw new IOException("Attribute must be of type RevocationReason."); } if (name.equalsIgnoreCase(REASON)) { mReason = (RevocationReason) obj; } else { throw new IOException("Name not recognized by CRLReason"); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(REASON)) { return mReason; } else { throw new IOException("Name not recognized by CRLReason"); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(REASON)) { mReason = null; } else { throw new IOException("Name not recognized by CRLReason"); } } /** * Returns a printable representation of the ReasonFlags. */ public String toString() { String s = super.toString() + "CRL Reason [" + mReason + "]\n"; return (s); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } // Encode this extension value private void encodeThis() throws IOException { if (mReason == null) throw new IOException("Unintialized CRLReason extension"); try (DerOutputStream os = new DerOutputStream()) { os.putEnumerated(mReason.toInt()); this.extensionValue = os.toByteArray(); } } /** * Write the extension to the DerOutputStream. * * @param out the OutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(REASON); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } public boolean equals(Object other) { if (this == other) return true; else if (other instanceof CRLReasonExtension) return ((CRLReasonExtension) other).mReason == mReason && ((CRLReasonExtension) other).critical == critical; else return false; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((mReason == null) ? 0 : mReason.hashCode()); return result; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertAndKeyGen.java000066400000000000000000000263301362106420000250220ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Date; import org.mozilla.jss.netscape.security.pkcs.PKCS10; /** * Generate a pair of keys, and provide access to them. This class is * provided primarily for ease of use. * *

* This provides some simple certificate management functionality. Specifically, it allows you to create self-signed * X.509 certificates as well as PKCS 10 based certificate signing requests. * *

* Keys for some public key signature algorithms have algorithm parameters, such as DSS/DSA. Some sites' Certificate * Authorities adopt fixed algorithm parameters, which speeds up some operations including key generation and signing. * At this time, this interface * does not provide a way to provide such algorithm parameters, e.g. * by providing the CA certificate which includes those parameters. * *

* Also, note that at this time only signature-capable keys may be acquired through this interface. Diffie-Hellman keys, * used for secure key exchange, may be supported later. * * @author David Brownell * @author Hemma Prafullchandra * @version 1.44 * @see PKCS10 * @see X509CertImpl */ public final class CertAndKeyGen { /** * Creates a CertAndKeyGen object for a particular key type * and signature algorithm. * * @param keyType type of key, e.g. "RSA", "DSA" * @param sigAlg name of the signature algorithm, e.g. "MD5WithRSA", * "MD2WithRSA", "SHAwithDSA". * @exception NoSuchAlgorithmException on unrecognized algorithms. */ public CertAndKeyGen(String keyType, String sigAlg) throws NoSuchAlgorithmException { keyGen = KeyPairGenerator.getInstance(keyType); this.sigAlg = sigAlg; } /** * Sets the source of random numbers used when generating keys. * If you do not provide one, a system default facility is used. * You may wish to provide your own source of random numbers * to get a reproducible sequence of keys and signatures, or * because you may be able to take advantage of strong sources * of randomness/entropy in your environment. * * @deprecated All random numbers come from PKCS #11 now. */ @Deprecated public void setRandom(SecureRandom generator) { } // want "public void generate (X509Certificate)" ... inherit DSA/D-H param /** * Generates a random public/private key pair, with a given key * size. Different algorithms provide different degrees of security * for the same key size, because of the "work factor" involved in * brute force attacks. As computers become faster, it becomes * easier to perform such attacks. Small keys are to be avoided. * *

* Note that not all values of "keyBits" are valid for all algorithms, and not all public key algorithms are * currently supported for use in X.509 certificates. If the algorithm you specified does not produce X.509 * compatible keys, an invalid key exception is thrown. * * @param keyBits the number of bits in the keys. * @exception InvalidKeyException if the environment does not * provide X.509 public keys for this signature algorithm. */ public void generate(int keyBits) throws InvalidKeyException { KeyPair pair; try { keyGen.initialize(keyBits); pair = keyGen.generateKeyPair(); } catch (Exception e) { throw new IllegalArgumentException(e.getMessage()); } PublicKey publicKey = pair.getPublic(); if (publicKey instanceof X509Key) { this.publicKey = (X509Key) publicKey; } else { throw new InvalidKeyException("public key " + publicKey + " not an X509Key."); } privateKey = pair.getPrivate(); } /** * Returns the public key of the generated key pair. */ public X509Key getPublicKey() { return publicKey; } /** * Returns the private key of the generated key pair. * *

* Be extremely careful when handling private keys. * When private keys are not kept secret, they lose their ability * to securely authenticate specific entities ... that is a huge * security risk! */ public PrivateKey getPrivateKey() { return privateKey; } /** * Returns a self-signed X.509v1 certificate for the public key. * The certificate is immediately valid. * *

* Such certificates normally are used to identify a "Certificate Authority" (CA). Accordingly, they will not always * be accepted by other parties. However, such certificates are also useful when you are bootstrapping your security * infrastructure, or deploying system prototypes. * * @deprecated Use the new {@link #getSelfCertificate(X500Name, long)} * * @param myname X.500 name of the subject (who is also the issuer) * @param validity how long the certificate should be valid, in seconds */ @Deprecated public X509Cert getSelfCert(X500Name myname, long validity) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException { X509Certificate cert; try { cert = getSelfCertificate(myname, validity); return new X509Cert(cert.getEncoded()); } catch (CertificateException e) { throw new SignatureException(e.getMessage()); } catch (NoSuchProviderException e) { throw new NoSuchAlgorithmException(e.getMessage()); } catch (IOException e) { throw new SignatureException(e.getMessage()); } } /** * Returns a self-signed X.509v3 certificate for the public key. * The certificate is immediately valid. No extensions. * *

* Such certificates normally are used to identify a "Certificate Authority" (CA). Accordingly, they will not always * be accepted by other parties. However, such certificates are also useful when you are bootstrapping your security * infrastructure, or deploying system prototypes. * * @param myname X.500 name of the subject (who is also the issuer) * @param validity how long the certificate should be valid, in seconds * @exception CertificateException on certificate handling errors. * @exception InvalidKeyException on key handling errors. * @exception SignatureException on signature handling errors. * @exception NoSuchAlgorithmException on unrecognized algorithms. * @exception NoSuchProviderException on unrecognized providers. */ public X509Certificate getSelfCertificate(X500Name myname, long validity) throws CertificateException, InvalidKeyException, SignatureException, NoSuchAlgorithmException, NoSuchProviderException { X500Signer issuer; X509CertImpl cert; Date firstDate, lastDate; try { issuer = getSigner(myname); firstDate = new Date(); lastDate = new Date(); lastDate.setTime(lastDate.getTime() + validity * 1000); CertificateValidity interval = new CertificateValidity(firstDate, lastDate); X509CertInfo info = new X509CertInfo(); // Add all mandatory attributes info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V1)); info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber((int) (firstDate.getTime() / 1000))); AlgorithmId algID = issuer.getAlgorithmId(); info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algID)); info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(myname)); info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey)); info.set(X509CertInfo.VALIDITY, interval); info.set(X509CertInfo.ISSUER, new CertificateIssuerName(issuer.getSigner())); cert = new X509CertImpl(info); cert.sign(privateKey, algID.getName()); return cert; } catch (IOException e) { throw new CertificateEncodingException("getSelfCert: " + e.getMessage()); } } /** * Returns a PKCS #10 certificate request. The caller uses either PKCS10.print or * PKCS10.toByteArray operations on the result, to get the request in an appropriate * transmission format. * *

* PKCS #10 certificate requests are sent, along with some proof of identity, to Certificate Authorities (CAs) which * then issue X.509 public key certificates. * * @param myname X.500 name of the subject * @exception InvalidKeyException on key handling errors. * @exception SignatureException on signature handling errors. */ public PKCS10 getCertRequest(X500Name myname) throws InvalidKeyException, SignatureException { PKCS10 req = new PKCS10(publicKey); try { req.encodeAndSign(getSigner(myname)); } catch (CertificateException e) { throw new SignatureException(sigAlg + " CertificateException"); } catch (IOException e) { throw new SignatureException(sigAlg + " IOException"); } catch (NoSuchAlgorithmException e) { // "can't happen" throw new SignatureException(sigAlg + " unavailable?"); } return req; } private X500Signer getSigner(X500Name me) throws InvalidKeyException, NoSuchAlgorithmException { Signature signature = Signature.getInstance(sigAlg); signature.initSign(privateKey); return new X500Signer(signature, me); } private String sigAlg; private KeyPairGenerator keyGen; private X509Key publicKey; private PrivateKey privateKey; } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertAttrSet.java000066400000000000000000000077031362106420000246060ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; /** * This interface defines the methods required of a certificate attribute. * Examples of X.509 certificate attributes are Validity, Issuer_Name, and * Subject Name. A CertAttrSet may compromise one attribute or many * attributes. *

* A CertAttrSet itself can also be comprised of other sub-sets. In the case of X.509 V3 certificates, for example, the * "extensions" attribute has subattributes, such as those for KeyUsage and AuthorityKeyIdentifier. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.9 * @see CertificateException */ public interface CertAttrSet { /** * Returns a short string describing this certificate attribute. * * @return value of this certificate attribute in * printable form. */ String toString(); /** * Encodes the attribute to the output stream in a format * that can be parsed by the decode method. * * @param out the OutputStream to encode the attribute to. * * @exception CertificateException on encoding or validity errors. * @exception IOException on other errors. */ void encode(OutputStream out) throws CertificateException, IOException; /** * Decodes the attribute in the input stream. * * @param in the InputStream to read the encoded attribute from. * * @exception CertificateException on decoding or validity errors. * @exception IOException on other errors. */ void decode(InputStream in) throws CertificateException, IOException; /** * Sets an attribute value within this CertAttrSet. * * @param name the name of the attribute (e.g. "x509.info.key") * @param obj the attribute object. * * @exception CertificateException on attribute handling errors. * @exception IOException on other errors. */ void set(String name, Object obj) throws CertificateException, IOException; /** * Gets an attribute value for this CertAttrSet. * * @param name the name of the attribute to return. * * @exception CertificateException on attribute handling errors. * @exception IOException on other errors. */ Object get(String name) throws CertificateException, IOException; /** * Deletes an attribute value from this CertAttrSet. * * @param name the name of the attribute to delete. * * @exception CertificateException on attribute handling errors. * @exception IOException on other errors. */ void delete(String name) throws CertificateException, IOException; /** * Returns an enumeration of the names of the attributes existing within * this attribute. * * @return an enumeration of the attribute names. */ Enumeration getAttributeNames(); /** * Returns the name (identifier) of this CertAttrSet. * * @return the name of this CertAttrSet. */ String getName(); } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertException.java000066400000000000000000000125051362106420000251520ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; /** * CertException indicates one of a variety of certificate problems. * * @version 1.18 * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra */ public class CertException extends SecurityException { // Zero is reserved. /** * */ private static final long serialVersionUID = -4046189948107720588L; /** Indicates that the signature in the certificate is not valid. */ public static final int verf_INVALID_SIG = 1; /** Indicates that the certificate was revoked, and so is invalid. */ public static final int verf_INVALID_REVOKED = 2; /** Indicates that the certificate is not yet valid. */ public static final int verf_INVALID_NOTBEFORE = 3; /** Indicates that the certificate has expired and so is not valid. */ public static final int verf_INVALID_EXPIRED = 4; /** * Indicates that a certificate authority in the certification * chain is not trusted. */ public static final int verf_CA_UNTRUSTED = 5; /** Indicates that the certification chain is too long. */ public static final int verf_CHAIN_LENGTH = 6; /** Indicates an error parsing the ASN.1/DER encoding of the certificate. */ public static final int verf_PARSE_ERROR = 7; /** Indicates an error constructing a certificate or certificate chain. */ public static final int err_CONSTRUCTION = 8; /** Indicates a problem with the public key */ public static final int err_INVALID_PUBLIC_KEY = 9; /** Indicates a problem with the certificate version */ public static final int err_INVALID_VERSION = 10; /** Indicates a problem with the certificate format */ public static final int err_INVALID_FORMAT = 11; /** Indicates a problem with the certificate encoding */ public static final int err_ENCODING = 12; // Private data members private int verfCode; private String moreData; /** * Constructs a certificate exception using an error code * (verf_*) and a string describing the context * of the error. */ public CertException(int code, String moredata) { verfCode = code; moreData = moredata; } /** * Constructs a certificate exception using just an error code, * without a string describing the context. */ public CertException(int code) { verfCode = code; } /** * Returns the error code with which the exception was created. */ public int getVerfCode() { return verfCode; } /** * Returns a string describing the context in which the exception * was reported. */ public String getMoreData() { return moreData; } /** * Return a string corresponding to the error code used to create * this exception. */ public String getVerfDescription() { switch (verfCode) { case verf_INVALID_SIG: return "The signature in the certificate is not valid."; case verf_INVALID_REVOKED: return "The certificate has been revoked."; case verf_INVALID_NOTBEFORE: return "The certificate is not yet valid."; case verf_INVALID_EXPIRED: return "The certificate has expired."; case verf_CA_UNTRUSTED: return "The Authority which issued the certificate is not trusted."; case verf_CHAIN_LENGTH: return "The certificate path to a trusted authority is too long."; case verf_PARSE_ERROR: return "The certificate could not be parsed."; case err_CONSTRUCTION: return "There was an error when constructing the certificate."; case err_INVALID_PUBLIC_KEY: return "The public key was not in the correct format."; case err_INVALID_VERSION: return "The certificate has an invalid version number."; case err_INVALID_FORMAT: return "The certificate has an invalid format."; case err_ENCODING: return "Problem encountered while encoding the data."; default: return "Unknown code: " + verfCode; } } /** * Returns a string describing the certificate exception. */ public String toString() { return "[Certificate Exception: " + getMessage() + "]"; } /** * Returns a string describing the certificate exception. */ public String getMessage() { return getVerfDescription() + ((moreData != null) ? ("\n (" + moreData + ")") : ""); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertParseError.java000066400000000000000000000024661362106420000253050ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; //back out these changes until backwards compatibility with //CertException is not an issue. //import java.security.CertificateException; /** * CertException indicates one of a variety of certificate problems. * * @version 1.7 * @author David Brownell */ class CertParseError extends CertException { /** * */ private static final long serialVersionUID = -7623327377774730807L; CertParseError(String where) { super(CertException.verf_PARSE_ERROR, where); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateAlgorithmId.java000066400000000000000000000132341362106420000267440ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the AlgorithmId for the Certificate. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.7 */ public class CertificateAlgorithmId implements CertAttrSet, Serializable { /** * */ private static final long serialVersionUID = 6084780721443376563L; private AlgorithmId algId; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.algorithmID"; /** * Sub attributes name for this CertAttrSet. */ public static final String NAME = "algorithmID"; public static final String ALGORITHM = "algorithm"; /** * Default constructor for the certificate attribute. * * @param algId the Algorithm identifier */ public CertificateAlgorithmId(AlgorithmId algId) { this.algId = algId; } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the serial number from. * @exception IOException on decoding errors. */ public CertificateAlgorithmId(DerInputStream in) throws IOException { DerValue val = in.getDerValue(); algId = AlgorithmId.parse(val); } /** * Create the object, decoding the values from the passed stream. * * @param in the InputStream to read the serial number from. * @exception IOException on decoding errors. */ public CertificateAlgorithmId(InputStream in) throws IOException { DerValue val = new DerValue(in); algId = AlgorithmId.parse(val); } /** * Return the algorithm identifier as user readable string. */ public String toString() { if (algId == null) return ""; return (algId.toString() + ", OID = " + (algId.getOID()).toString() + "\n"); } private void writeObject(ObjectOutputStream stream) throws IOException { encode(stream); } private void readObject(ObjectInputStream stream) throws IOException { decode(stream); } /** * Encode the algorithm identifier in DER form to the stream. * * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); algId.encode(tmp); out.write(tmp.toByteArray()); } /** * Decode the algorithm identifier from the passed stream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on errors. */ public void decode(InputStream in) throws IOException { DerValue derVal = new DerValue(in); algId = AlgorithmId.parse(derVal); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (!(obj instanceof AlgorithmId)) { throw new IOException("Attribute must be of type AlgorithmId."); } if (name.equalsIgnoreCase(ALGORITHM)) { algId = (AlgorithmId) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateAlgorithmId."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(ALGORITHM)) { return (algId); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateAlgorithmId."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(ALGORITHM)) { algId = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateAlgorithmId."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(ALGORITHM); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateChain.java000066400000000000000000000074321362106420000255660ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; import java.security.cert.X509Certificate; import org.mozilla.jss.netscape.security.pkcs.ContentInfo; import org.mozilla.jss.netscape.security.pkcs.PKCS7; import org.mozilla.jss.netscape.security.pkcs.SignerInfo; public class CertificateChain implements Serializable { public CertificateChain() { } /** * constructs a certificate chain from a certificate. * * @param cert a certificate */ public CertificateChain(X509Certificate cert) { mChain = new X509Certificate[1]; mChain[0] = cert; } /** * constructs a certificate chain from a X509 certificate array. * * @param chain a certificate array. */ public CertificateChain(X509Certificate[] chain) { mChain = chain.clone(); } /** * returns the certificate at specified index in chain. * * @param index the index. * @return the X509 certificate at the given index. */ public X509Certificate getCertificate(int index) { return mChain[index]; } /** * returns the first certificate in chain. * * @return the X509 certificate at the given index. */ public X509Certificate getFirstCertificate() { return mChain[0]; } /** * returns the certificate chain as an array of X509 certificates. * * @return an array of X509 Certificates. */ public X509Certificate[] getChain() { return mChain.clone(); } public void encode(OutputStream out) throws IOException { encode(out, true); } /** * encode in PKCS7 blob. */ public void encode(OutputStream out, boolean sort) throws IOException { PKCS7 p7 = new PKCS7(new AlgorithmId[0], new ContentInfo(new byte[0]), mChain, new SignerInfo[0]); p7.encodeSignedData(out, sort); } /** * decode from PKCS7 blob. */ public void decode(InputStream in) throws IOException { PKCS7 p7 = new PKCS7(in); mChain = p7.getCertificates(); } /** * for serialization */ private void writeObject(java.io.ObjectOutputStream out) throws IOException { encode(out); } /** * for serialization */ private void readObject(java.io.ObjectInputStream in) throws IOException { decode(in); } /** * Converts the certificate chain to a readable string. */ public String toString() { String s = "[\n"; if (mChain == null) return "[empty]"; StringBuffer tempBuffer = new StringBuffer(); for (int i = 0; i < mChain.length; i++) { tempBuffer.append(mChain[i].toString()); } s += tempBuffer.toString() + "]\n"; return s; } private X509Certificate[] mChain = null; } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateExtensions.java000066400000000000000000000227401362106420000267020ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the Extensions attribute for the Certificate. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.11 * @see CertAttrSet */ public class CertificateExtensions extends Vector implements CertAttrSet, Serializable { /** * */ private static final long serialVersionUID = -7172635300185788849L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions"; /** * name */ public static final String NAME = "extensions"; private Hashtable map; // Parse the encoded extension public void parseExtension(Extension ext) throws IOException { try { @SuppressWarnings("unchecked") Class extClass = (Class) OIDMap.getClass(ext.getExtensionId()); if (extClass == null) { // Unsupported extension map.put(ext.getExtensionId().toString(), ext); addElement(ext); return; } Class[] params = { Boolean.class, Object.class }; Constructor cons = extClass.getConstructor(params); byte[] extData = ext.getExtensionValue(); int extLen = extData.length; Object value = Array.newInstance(byte.class, extLen); for (int i = 0; i < extLen; i++) { Array.setByte(value, i, extData[i]); } Object[] passed = new Object[] { Boolean.valueOf(ext.isCritical()), value }; CertAttrSet certExt = cons.newInstance(passed); if (certExt != null && certExt.getName() != null) { map.put(certExt.getName(), (Extension) certExt); addElement((Extension) certExt); } } catch (NoSuchMethodException e) { throw new IOException(e); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t instanceof IOException) { throw (IOException)t; } throw new IOException(t); } catch (Exception e) { throw new IOException(e); } } /** * Default constructor for the certificate attribute. */ public CertificateExtensions() { map = new Hashtable(); } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the Extension from. * @exception IOException on decoding errors. */ public CertificateExtensions(DerInputStream in) throws IOException { map = new Hashtable(); DerValue[] exts = in.getSequence(5); for (int i = 0; i < exts.length; i++) { Extension ext = new Extension(exts[i]); parseExtension(ext); } } /** * Decode the extensions from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { DerValue val = new DerValue(in); DerInputStream str = val.toDerInputStream(); map = new Hashtable(); DerValue[] exts = str.getSequence(5); for (int i = 0; i < exts.length; i++) { Extension ext = new Extension(exts[i]); parseExtension(ext); } } /** * Decode the extensions from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decodeEx(InputStream in) throws IOException { DerValue val = new DerValue(in); DerInputStream str = null; if (val.isConstructed() && val.isContextSpecific((byte) 3)) { str = val.data; } else { str = val.toDerInputStream(); } map = new Hashtable(); DerValue[] exts = str.getSequence(5); for (int i = 0; i < exts.length; i++) { Extension ext = new Extension(exts[i]); parseExtension(ext); } } private void writeObject(ObjectOutputStream stream) throws CertificateException, IOException { encode(stream); } private void readObject(ObjectInputStream stream) throws CertificateException, IOException { decodeEx(stream); } /** * Encode the extensions in DER form to the stream. * * @param out the DerOutputStream to marshal the contents to. * @exception CertificateException on encoding errors. * @exception IOException on errors. */ public void encode(OutputStream out) throws CertificateException, IOException { try (DerOutputStream tmp = new DerOutputStream()) { DerOutputStream extOut = new DerOutputStream(); for (int i = 0; i < size(); i++) { Object thisOne = elementAt(i); if (thisOne instanceof CertAttrSet) ((CertAttrSet) thisOne).encode(extOut); else if (thisOne instanceof Extension) ((Extension) thisOne).encode(extOut); else throw new CertificateException("Invalid extension object"); } DerOutputStream seq = new DerOutputStream(); seq.write(DerValue.tag_Sequence, extOut); tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 3), seq); out.write(tmp.toByteArray()); } } /** * Set the attribute value. * * @param name the extension name used in the cache. * @param obj the object to set. * @exception IOException if the object could not be cached. */ public void set(String name, Object obj) throws IOException { map.put(name, (Extension) obj); addElement((Extension) obj); } /** * Get the attribute value. * * @param name the extension name used in the lookup. * @exception IOException if named extension is not found. */ public Object get(String name) throws IOException { Object obj = map.get(name); if (obj == null) { throw new IOException("No extension found with name " + name); } return (obj); } /** * Delete the attribute value. * * @param name the extension name used in the lookup. * @exception IOException if named extension is not found. */ public void delete(String name) throws IOException { Object obj = map.get(name); if (obj == null) { throw new IOException("No extension found with name " + name); } map.remove(name); removeElement(obj); } public Enumeration getNames() { return map.keys(); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributes() { return (map.elements()); } public Enumeration getAttributeNames() { return (map.keys()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((map == null) ? 0 : map.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; CertificateExtensions other = (CertificateExtensions) obj; if (map == null) { if (other.map != null) return false; } else if (!map.equals(other.map)) return false; return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateIssuerExtension.java000066400000000000000000000170141362106420000277100ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the CRL Certificate Issuer Extension. * *

* This CRL entry extension identifies the certificate issuer associated with an entry in an indirect CRL, i.e. a CRL * that has the indirectCRL indicator set in its issuing distribution point extension. * * @see Extension * @see CertAttrSet */ public class CertificateIssuerExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 8643788952936025986L; /** * Attribute name. */ public static final String NAME = "CertificateIssuer"; public static final String CERTIFICATE_ISSUER = "value"; /** * The Object Identifier for this extension. */ public static final String OID = "2.5.29.29"; // private data members GeneralNames names = null; static { try { OIDMap.addAttribute(CertificateIssuerExtension.class.getName(), OID, NAME); } catch (CertificateException e) { } } // Encode this extension private void encodeThis() throws IOException { DerOutputStream os = new DerOutputStream(); try { names.encode(os); } catch (GeneralNamesException e) { throw new IOException(e); } this.extensionValue = os.toByteArray(); } /** * Create a CertificateIssuerExtension with the passed GeneralNames * and criticality. * * @param critical true if the extension is to be treated as critical. * @param names the GeneralNames for the issuer. * @exception IOException on error. */ public CertificateIssuerExtension(Boolean critical, GeneralNames names) throws IOException { this.names = names; this.extensionId = PKIXExtensions.CertificateIssuer_Id; this.critical = critical.booleanValue(); encodeThis(); } /** * Create a CertificateIssuerExtension with the passed GeneralNames. * * @param names the GeneralNames for the issuer. * @exception IOException on error. */ public CertificateIssuerExtension(GeneralNames names) throws IOException { this.names = names; this.extensionId = PKIXExtensions.CertificateIssuer_Id; this.critical = true; encodeThis(); } /** * Create a default CertificateIssuerExtension. */ public CertificateIssuerExtension() { extensionId = PKIXExtensions.CertificateIssuer_Id; critical = false; names = new GeneralNames(); } /** * Create the extension from the passed DER encoded value. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public CertificateIssuerExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.CertificateIssuer_Id; this.critical = critical.booleanValue(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; DerValue val = new DerValue(extValue); try { names = new GeneralNames(val); } catch (GeneralNamesException e) { throw new IOException("CertificateIssuerExtension: " + e, e); } } /** * Returns a printable representation of the CertificateIssuerName. */ public String toString() { if (names == null) return ""; String s = super.toString() + "CertificateIssuerName [\n" + names.toString() + "]\n"; return (s); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the OutputStream. * * @param out the OutputStream to write the extension to. * @exception IOException on encoding error. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.CertificateIssuer_Id; critical = false; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (name.equalsIgnoreCase(CERTIFICATE_ISSUER)) { if (!(obj instanceof GeneralNames)) { throw new IOException("Attribute value should be of" + " type GeneralNames."); } names = (GeneralNames) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateIssuerName."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(CERTIFICATE_ISSUER)) { return (names); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateIssuerName."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(CERTIFICATE_ISSUER)) { names = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateIssuerName."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(CERTIFICATE_ISSUER); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateIssuerName.java000066400000000000000000000121371362106420000266150ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the X500Name attribute for the Certificate. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.6 * @see CertAttrSet */ public class CertificateIssuerName implements CertAttrSet { /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.issuer"; /** * Sub attributes name for this CertAttrSet. */ public static final String NAME = "issuer"; public static final String DN_NAME = "dname"; // Private data member private X500Name dnName; /** * Default constructor for the certificate attribute. * * @param name the X500Name */ public CertificateIssuerName(X500Name name) { this.dnName = name; } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the X500Name from. * @exception IOException on decoding errors. */ public CertificateIssuerName(DerInputStream in) throws IOException { dnName = new X500Name(in); } /** * Create the object, decoding the values from the passed stream. * * @param in the InputStream to read the X500Name from. * @exception IOException on decoding errors. */ public CertificateIssuerName(InputStream in) throws IOException { DerValue derVal = new DerValue(in); dnName = new X500Name(derVal); } /** * Return the name as user readable string. */ public String toString() { if (dnName == null) return ""; return (dnName.toString()); } /** * Encode the name in DER form to the stream. * * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); dnName.encode(tmp); out.write(tmp.toByteArray()); } /** * Decode the name in DER form from the stream. * * @param in the InputStream to marshal the contents from. * @exception IOException on errors. */ public void decode(InputStream in) throws IOException { DerValue derVal = new DerValue(in); dnName = new X500Name(derVal); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (!(obj instanceof X500Name)) { throw new IOException("Attribute must be of type X500Name."); } if (name.equalsIgnoreCase(DN_NAME)) { this.dnName = (X500Name) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateIssuerName."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(DN_NAME)) { return (dnName); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateIssuerName."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(DN_NAME)) { dnName = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateIssuerName."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(DN_NAME); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateIssuerUniqueIdentity.java000066400000000000000000000130431362106420000307120ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the subject/issuer unique identity attribute * for the Certificate. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.6 * @see CertAttrSet */ public class CertificateIssuerUniqueIdentity implements CertAttrSet { private UniqueIdentity id; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.issuerID"; /** * Sub attributes name for this CertAttrSet. */ public static final String NAME = "issuerID"; public static final String ID = "id"; /** * Default constructor for the certificate attribute. * * @param id the UniqueIdentity */ public CertificateIssuerUniqueIdentity(UniqueIdentity id) { this.id = id; } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the UniqueIdentity from. * @exception IOException on decoding errors. */ public CertificateIssuerUniqueIdentity(DerInputStream in) throws IOException { id = new UniqueIdentity(in); } /** * Create the object, decoding the values from the passed stream. * * @param in the InputStream to read the UniqueIdentity from. * @exception IOException on decoding errors. */ public CertificateIssuerUniqueIdentity(InputStream in) throws IOException { DerValue val = new DerValue(in); id = new UniqueIdentity(val); } /** * Create the object, decoding the values from the passed DER value. * * @param val the DerValue to read the UniqueIdentity from. * @exception IOException on decoding errors. */ public CertificateIssuerUniqueIdentity(DerValue val) throws IOException { id = new UniqueIdentity(val); } /** * Return the identity as user readable string. */ public String toString() { if (id == null) return ""; return (id.toString()); } /** * Decode the identity in DER form from the stream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on errors. */ public void decode(InputStream in) throws IOException { DerValue val = new DerValue(in); id = new UniqueIdentity(val); } /** * Encode the identity in DER form to the stream. * * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); id.encode(tmp, DerValue.createTag(DerValue.TAG_CONTEXT, false, (byte) 1)); out.write(tmp.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (!(obj instanceof UniqueIdentity)) { throw new IOException("Attribute must be of type UniqueIdentity."); } if (name.equalsIgnoreCase(ID)) { id = (UniqueIdentity) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateIssuerUniqueIdentity."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(ID)) { return (id); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateIssuerUniqueIdentity."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(ID)) { id = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateIssuerUniqueIdentity."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(ID); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificatePoliciesExtension.java000066400000000000000000000275101362106420000302070ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.util.Utils; /** * This class defines the Certificate Policies Extension. * *

* The certificate policies extension conatins a sequence of policy information terms, each of which consists of an * object identifier (OID) and optional qualifiers. These policy information terms indicate the policy under which the * certificate has been issued and the purposes for which the certificate may be used. Aplications with specific policy * requirements are expected to have a list of those policies which they will accept and to compare the policy OIDs in * the certificate to that list. If this extension is critical, the path validation software must be able to interpret * this extension, or must reject the certificate. * *

 * CertificatePolicies ::= SEQUENECE OF PolicyInformation
 * 
* * @author Christine Ho * @see Extension * @see CertAttrSet */ public class CertificatePoliciesExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -3729294064061837367L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.CertificatePolicies"; /** * Attribute names. */ public static final String NAME = "CertificatePolicies"; public static final String INFOS = "infos"; // Private data members private Vector mInfos; // Encode this extension value private void encodeThis() throws IOException { try (DerOutputStream os = new DerOutputStream();) { DerOutputStream tmp = new DerOutputStream(); for (int i = 0; i < mInfos.size(); i++) { mInfos.elementAt(i).encode(tmp); } os.write(DerValue.tag_Sequence, tmp); extensionValue = os.toByteArray(); } } public CertificatePoliciesExtension(boolean critical, Vector infos) throws IOException { this.mInfos = infos; this.extensionId = PKIXExtensions.CertificatePolicies_Id; this.critical = critical; encodeThis(); } /** * Create a CertificatePolicies with the Vector of CertificatePolicyInfo. * * @param infos the Vector of CertificatePolicyInfo. */ public CertificatePoliciesExtension(Vector infos) throws IOException { this.mInfos = infos; this.extensionId = PKIXExtensions.CertificatePolicies_Id; this.critical = false; encodeThis(); } /** * Create a default CertificatePoliciesExtension. */ public CertificatePoliciesExtension() { this.extensionId = PKIXExtensions.CertificatePolicies_Id; critical = false; mInfos = new Vector(1, 1); } /** * Create the extension from the passed DER encoded value. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public CertificatePoliciesExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.CertificatePolicies_Id; this.critical = critical.booleanValue(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; DerValue val = new DerValue(extValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for " + "CertificatePoliciesExtension."); } mInfos = new Vector(1, 1); while (val.data.available() != 0) { DerValue seq = val.data.getDerValue(); CertificatePolicyInfo info = new CertificatePolicyInfo(seq); mInfos.addElement(info); } } /** * Returns a printable representation of the policy extension. */ public String toString() { if (mInfos == null) return ""; String s = super.toString() + "Certificate Policies [\n" + mInfos.toString() + "]\n"; return (s); } /** * Write the extension to the OutputStream. * * @param out the OutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.CertificatePolicies_Id; critical = false; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Set the attribute value. */ @SuppressWarnings("unchecked") public void set(String name, Object obj) throws IOException { clearValue(); if (name.equalsIgnoreCase(INFOS)) { if (!(obj instanceof Vector)) { throw new IOException("Attribute value should be of" + " type Vector."); } mInfos = (Vector) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificatePoliciesExtension."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(INFOS)) { return (mInfos); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificatePoliciesExtension."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(INFOS)) { mInfos = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificatePoliciesExtension."); } } /** * Return an enumeration of attributes existing within this * attribute. */ public Enumeration> getAttributes() { Vector> elements = new Vector>(); elements.addElement(mInfos); return (elements.elements()); } private static final String[] NAMES = { INFOS }; @Override public Enumeration getAttributeNames() { // TODO Auto-generated method stub return Collections.enumeration(Arrays.asList(NAMES)); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } public static void main(String args[]) { /** * From ASN.1 dump * * 0 30 133: SEQUENCE { * 3 30 45: . SEQUENCE { * 5 06 3: . . OBJECT IDENTIFIER '1 2 3 5' * 10 30 38: . . SEQUENCE { * 12 30 36: . . . SEQUENCE { * 14 06 8: . . . . OBJECT IDENTIFIER cps (1 3 6 1 5 5 7 2 1) * : . . . . . (PKIX policy qualifier) * 24 16 24: . . . . IA5String 'http://home.netscape.com' * : . . . . } * : . . . } * : . . } * 50 30 84: . SEQUENCE { * 52 06 2: . . OBJECT IDENTIFIER '2 3 5' * 56 30 78: . . SEQUENCE { * 58 30 36: . . . SEQUENCE { * 60 06 8: . . . . OBJECT IDENTIFIER cps (1 3 6 1 5 5 7 2 1) * : . . . . . (PKIX policy qualifier) * 70 16 24: . . . . IA5String 'http://home.netscape.com' * : . . . . } * 96 30 38: . . . SEQUENCE { * 98 06 8: . . . . OBJECT IDENTIFIER unotice (1 3 6 1 5 5 7 2 2) * : . . . . . (PKIX policy qualifier) * 108 30 26: . . . . SEQUENCE { * 110 30 16: . . . . . SEQUENCE { * 112 1E 8: . . . . . . BMPString (1993) '_..o.r.g' * 122 02 1: . . . . . . INTEGER 1 * 125 02 1: . . . . . . INTEGER 2 * : . . . . . . } * 128 1E 6: . . . . . BMPString (1993) '_..d.t' * : . . . . . } * : . . . . } * : . . . } * : . . } * : . } **/ CertificatePolicyId plcyId0 = new CertificatePolicyId( new ObjectIdentifier("1.2.3.5") ); PolicyQualifiers qualifiers0 = new PolicyQualifiers(); CPSuri cpsQualifier0 = new CPSuri("http://home.netscape.com"); PolicyQualifierInfo qualifierInfo0 = new PolicyQualifierInfo( PolicyQualifierInfo.QT_CPS, cpsQualifier0 ); qualifiers0.add(qualifierInfo0); CertificatePolicyInfo info0 = new CertificatePolicyInfo( plcyId0, qualifiers0); CertificatePolicyId plcyId1 = new CertificatePolicyId( new ObjectIdentifier("2.3.5") ); PolicyQualifiers qualifiers1 = new PolicyQualifiers(); DisplayText org1 = new DisplayText(DisplayText.tag_BMPString, "org"); int nums[] = { 1, 2 }; NoticeReference nr1 = new NoticeReference(org1, nums); DisplayText dt1 = new DisplayText(DisplayText.tag_BMPString, "dt"); UserNotice userNotice1 = new UserNotice(nr1, dt1); PolicyQualifierInfo qualifierInfo1 = new PolicyQualifierInfo( PolicyQualifierInfo.QT_UNOTICE, userNotice1 ); qualifiers1.add(qualifierInfo0); qualifiers1.add(qualifierInfo1); CertificatePolicyInfo info1 = new CertificatePolicyInfo( plcyId1, qualifiers1); Vector infos = new Vector(); infos.addElement(info0); infos.addElement(info1); try { CertificatePoliciesExtension ext = new CertificatePoliciesExtension(infos); // BASE64 encode the whole thing and write it to stdout System.out.println(Utils.base64encode(ext.getExtensionValue(), true)); } catch (IOException e) { System.out.println(e.toString()); } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificatePolicyId.java000066400000000000000000000047461362106420000262650ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * Represent the CertificatePolicyId ASN.1 object. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.5 */ public class CertificatePolicyId implements java.io.Serializable { /** * */ private static final long serialVersionUID = -2376810529862707757L; private ObjectIdentifier id; /** * Create a CertificatePolicyId with the ObjectIdentifier. * * @param id the ObjectIdentifier for the policy id. */ public CertificatePolicyId(ObjectIdentifier id) { this.id = id; } /** * Create the object from its Der encoded value. * * @param val the DER encoded value for the same. */ public CertificatePolicyId(DerValue val) throws IOException { this.id = val.getOID(); } /** * Return the value of the CertificatePolicyId as an ObjectIdentifier. */ public ObjectIdentifier getIdentifier() { return (id); } /** * Returns a printable representation of the CertificatePolicyId. */ public String toString() { String s = "CertificatePolicyId: [" + id.toString() + "]\n"; return (s); } /** * Write the CertificatePolicyId to the DerOutputStream. * * @param out the DerOutputStream to write the object to. * @exception IOException on errors. */ public void encode(DerOutputStream out) throws IOException { out.putOID(id); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificatePolicyInfo.java000066400000000000000000000070501362106420000266130ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the CertificatePolicyInformation ASN.1 object. * * @author Christine Ho */ public class CertificatePolicyInfo implements java.io.Serializable { /** * */ private static final long serialVersionUID = -8516006396099280477L; private CertificatePolicyId mPolicyIdentifier; private PolicyQualifiers mPolicyQualifiers; /** * Create a CertificatePolicyInfo with the passed CertificatePolicyId's. * * @param id the CertificatePolicyId. */ public CertificatePolicyInfo(CertificatePolicyId id) { this.mPolicyIdentifier = id; this.mPolicyQualifiers = null; } public CertificatePolicyInfo(CertificatePolicyId id, PolicyQualifiers qualifiers) { this.mPolicyIdentifier = id; this.mPolicyQualifiers = qualifiers; } /** * Create the CertificatePolicyInfo from the DER encoded value. * * @param val the DER encoded value of the same. */ public CertificatePolicyInfo(DerValue val) throws IOException { if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for CertificatePolicyInfo"); } mPolicyIdentifier = new CertificatePolicyId(val.data.getDerValue()); // The specification is not clear on whether qualifier is // optional or not. GTE CyberTrust Root certificate has // no qualifier. if (val.data.available() == 0) { mPolicyQualifiers = null; } else { mPolicyQualifiers = new PolicyQualifiers(val.data.getDerValue()); } } /** * return the policy identifier of the policy info */ public CertificatePolicyId getPolicyIdentifier() { return (mPolicyIdentifier); } public PolicyQualifiers getPolicyQualifiers() { return mPolicyQualifiers; } /** * Returns a printable representation of the CertificatePolicyId. */ public String toString() { String s = "CertificatePolicyInfo: [\n" + "PolicyIdentifier:" + mPolicyIdentifier.toString() + "]\n"; return (s); } /** * Write the CertificatePolicyInfo to the DerOutputStream. * * @param out the DerOutputStream to write the object to. * @exception IOException on errors. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); mPolicyIdentifier.encode(tmp); if (mPolicyQualifiers != null) { mPolicyQualifiers.encode(tmp); } out.write(DerValue.tag_Sequence, tmp); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificatePolicyMap.java000066400000000000000000000063161362106420000264410ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the CertificatePolicyMap ASN.1 object. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.5 */ public class CertificatePolicyMap { private CertificatePolicyId issuerDomain; private CertificatePolicyId subjectDomain; /** * Create a CertificatePolicyMap with the passed CertificatePolicyId's. * * @param issuer the CertificatePolicyId for the issuer CA. * @param subject the CertificatePolicyId for the subject CA. */ public CertificatePolicyMap(CertificatePolicyId issuer, CertificatePolicyId subject) { this.issuerDomain = issuer; this.subjectDomain = subject; } /** * Create the CertificatePolicyMap from the DER encoded value. * * @param val the DER encoded value of the same. */ public CertificatePolicyMap(DerValue val) throws IOException { if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for CertificatePolicyMap"); } issuerDomain = new CertificatePolicyId(val.data.getDerValue()); subjectDomain = new CertificatePolicyId(val.data.getDerValue()); } /** * Return the issuer CA part of the policy map. */ public CertificatePolicyId getIssuerIdentifier() { return (issuerDomain); } /** * Return the subject CA part of the policy map. */ public CertificatePolicyId getSubjectIdentifier() { return (subjectDomain); } /** * Returns a printable representation of the CertificatePolicyId. */ public String toString() { String s = "CertificatePolicyMap: [\n" + "IssuerDomain:" + issuerDomain.toString() + "SubjectDomain:" + subjectDomain.toString() + "]\n"; return (s); } /** * Write the CertificatePolicyMap to the DerOutputStream. * * @param out the DerOutputStream to write the object to. * @exception IOException on errors. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); issuerDomain.encode(tmp); subjectDomain.encode(tmp); out.write(DerValue.tag_Sequence, tmp); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificatePolicySet.java000066400000000000000000000051341362106420000264540ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the certificate policy set ASN.1 object. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.4 */ public class CertificatePolicySet { private Vector ids; /** * The default constructor for this class. * * @param ids the sequence of CertificatePolicyId's. */ public CertificatePolicySet(Vector ids) { this.ids = ids; } /** * Create the object from the DerValue. * * @param in the passed DerInputStream. * @exception IOException on decoding errors. */ public CertificatePolicySet(DerInputStream in) throws IOException { ids = new Vector(1, 1); DerValue[] seq = in.getSequence(5); for (int i = 0; i < seq.length; i++) { CertificatePolicyId id = new CertificatePolicyId(seq[i]); ids.addElement(id); } } /** * Return printable form of the object. */ public String toString() { String s = "CertificatePolicySet:[\n" + ids.toString() + "]\n"; return (s); } /** * Encode the policy set to the output stream. * * @param out the DerOutputStream to encode the data to. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); for (int i = 0; i < ids.size(); i++) { ids.elementAt(i).encode(tmp); } out.write(DerValue.tag_Sequence, tmp); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateSerialNumber.java000066400000000000000000000133101362106420000271240ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the SerialNumber attribute for the Certificate. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.6 * @see CertAttrSet */ public class CertificateSerialNumber implements CertAttrSet { /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.serialNumber"; /** * Sub attributes name for this CertAttrSet. */ public static final String NAME = "serialNumber"; public static final String NUMBER = "number"; private SerialNumber serial; /** * Default constructor for the certificate attribute. * * @param num the serial number for the certificate. */ public CertificateSerialNumber(BigInteger num) { this.serial = new SerialNumber(num); } /** * Default constructor for the certificate attribute. * * @param num the serial number for the certificate. */ public CertificateSerialNumber(int num) { this.serial = new SerialNumber(num); } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the serial number from. * @exception IOException on decoding errors. */ public CertificateSerialNumber(DerInputStream in) throws IOException { serial = new SerialNumber(in); } /** * Create the object, decoding the values from the passed stream. * * @param in the InputStream to read the serial number from. * @exception IOException on decoding errors. */ public CertificateSerialNumber(InputStream in) throws IOException { serial = new SerialNumber(in); } /** * Create the object, decoding the values from the passed DerValue. * * @param val the DER encoded value. * @exception IOException on decoding errors. */ public CertificateSerialNumber(DerValue val) throws IOException { serial = new SerialNumber(val); } /** * Return the serial number as user readable string. */ public String toString() { if (serial == null) return ""; return (serial.toString()); } /** * Encode the serial number in DER form to the stream. * * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); serial.encode(tmp); out.write(tmp.toByteArray()); } /** * Decode the serial number in DER form from the stream. * * @param in the InputStream to marshal the contents from. * @exception IOException on errors. */ public void decode(InputStream in) throws IOException { DerValue derVal = new DerValue(in); serial = new SerialNumber(derVal); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (!(obj instanceof SerialNumber)) { throw new IOException("Attribute must be of type SerialNumber."); } if (name.equalsIgnoreCase(NUMBER)) { serial = (SerialNumber) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateSerialNumber."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(NUMBER)) { return (serial); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateSerialNumber."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(NUMBER)) { serial = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateSerialNumber."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(NUMBER); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateSubjectName.java000066400000000000000000000142251362106420000267420ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the X500Name attribute for the Certificate. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.6 * @see CertAttrSet */ public class CertificateSubjectName implements CertAttrSet, Serializable { /** * */ private static final long serialVersionUID = 503643453152834350L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.subject"; /** * Sub attributes name for this CertAttrSet. */ public static final String NAME = "subject"; public static final String DN_NAME = "dname"; // Private data member private X500Name dnName; /** * Default constructor for the certificate attribute. * * @param name the X500Name */ public CertificateSubjectName(X500Name name) { this.dnName = name; } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the X500Name from. * @exception IOException on decoding errors. */ public CertificateSubjectName(DerInputStream in) throws IOException { dnName = new X500Name(in); } /** * Create the object, decoding the values from the passed stream. * * @param in the InputStream to read the X500Name from. * @exception IOException on decoding errors. */ public CertificateSubjectName(InputStream in) throws IOException { DerValue derVal = new DerValue(in); dnName = new X500Name(derVal); } /** * Return the name as user readable string. */ public String toString() { if (dnName == null) return ""; return (dnName.toString()); } private void writeObject(ObjectOutputStream stream) throws IOException { encode(stream); } private void readObject(ObjectInputStream stream) throws IOException { decodeEx(stream); } /** * Encode the name in DER form to the stream. * * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); dnName.encode(tmp); out.write(tmp.toByteArray()); } /** * Decode the name in DER form from the stream. * * @param in the InputStream to marshal the contents from. * @exception IOException on errors. */ public void decodeEx(InputStream in) throws IOException { DerValue derVal = new DerValue(in); // dnName = new X500Name(derVal); dnName = new X500Name(derVal.toByteArray()); } /** * Decode the name in DER form from the stream. * * @param in the InputStream to marshal the contents from. * @exception IOException on errors. */ public void decode(InputStream in) throws IOException { DerValue derVal = new DerValue(in); dnName = new X500Name(derVal); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (!(obj instanceof X500Name)) { throw new IOException("Attribute must be of type X500Name."); } if (name.equalsIgnoreCase(DN_NAME)) { this.dnName = (X500Name) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateSubjectName."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(DN_NAME)) { return (dnName); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateSubjectName."); } } /** * Get underlying X500Name value. * * Where the type is known to be CertificateSubjectName, use * this method instead of 'get' to avoid casts and exceptions. */ public X500Name getX500Name() { return dnName; } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(DN_NAME)) { dnName = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:CertificateSubjectName."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(DN_NAME); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateSubjectUniqueIdentity.java000066400000000000000000000130551362106420000310420ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the subject/issuer unique identity attribute * for the Certificate. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.6 * @see CertAttrSet */ public class CertificateSubjectUniqueIdentity implements CertAttrSet { /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.subjectID"; /** * Sub attributes name for this CertAttrSet. */ public static final String NAME = "subjectID"; public static final String ID = "id"; private UniqueIdentity id; /** * Default constructor for the certificate attribute. * * @param id the UniqueIdentity */ public CertificateSubjectUniqueIdentity(UniqueIdentity id) { this.id = id; } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the UniqueIdentity from. * @exception IOException on decoding errors. */ public CertificateSubjectUniqueIdentity(DerInputStream in) throws IOException { id = new UniqueIdentity(in); } /** * Create the object, decoding the values from the passed stream. * * @param in the InputStream to read the UniqueIdentity from. * @exception IOException on decoding errors. */ public CertificateSubjectUniqueIdentity(InputStream in) throws IOException { DerValue val = new DerValue(in); id = new UniqueIdentity(val); } /** * Create the object, decoding the values from the passed DER value. * * @param val the DerValue to read the UniqueIdentity from. * @exception IOException on decoding errors. */ public CertificateSubjectUniqueIdentity(DerValue val) throws IOException { id = new UniqueIdentity(val); } /** * Return the identity as user readable string. */ public String toString() { if (id == null) return ""; return (id.toString()); } /** * Decode the identity in DER form from the stream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on errors. */ public void decode(InputStream in) throws IOException { DerValue val = new DerValue(in); id = new UniqueIdentity(val); } /** * Encode the identity in DER form to the stream. * * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); id.encode(tmp, DerValue.createTag(DerValue.TAG_CONTEXT, false, (byte) 2)); out.write(tmp.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (!(obj instanceof UniqueIdentity)) { throw new IOException("Attribute must be of type UniqueIdentity."); } if (name.equalsIgnoreCase(ID)) { id = (UniqueIdentity) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateSubjectUniqueIdentity."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(ID)) { return (id); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateSubjectUniqueIdentity."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(ID)) { id = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateSubjectUniqueIdentity."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(ID); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateValidity.java000066400000000000000000000242621362106420000263310ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.util.Date; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the interval for which the certificate is valid. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.12 * @see CertAttrSet */ public class CertificateValidity implements CertAttrSet, Serializable { private static final long serialVersionUID = 8277703278213804194L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.validity"; /** * Sub attributes name for this CertAttrSet. */ public static final String NAME = "validity"; public static final String NOT_BEFORE = "notBefore"; public static final String NOT_AFTER = "notAfter"; private static final long YR_2050 = 2524636800000L; // Private data members private Date notBefore; private Date notAfter; // Returns the first time the certificate is valid. private Date getNotBefore() { return (new Date(notBefore.getTime())); } // Returns the last time the certificate is valid. private Date getNotAfter() { return (new Date(notAfter.getTime())); } // Construct the class from the DerValue private void construct(DerValue derVal) throws IOException { if (derVal.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoded CertificateValidity, " + "starting sequence tag missing."); } // check if UTCTime encoded or GeneralizedTime if (derVal.data.available() == 0) throw new IOException("No data encoded for CertificateValidity"); DerInputStream derIn = new DerInputStream(derVal.toByteArray()); DerValue[] seq = derIn.getSequence(2); if (seq.length != 2) throw new IOException("Invalid encoding for CertificateValidity"); if (seq[0].tag == DerValue.tag_UtcTime) { notBefore = derVal.data.getUTCTime(); } else if (seq[0].tag == DerValue.tag_GeneralizedTime) { notBefore = derVal.data.getGeneralizedTime(); } else { throw new IOException("Invalid encoding for CertificateValidity"); } if (seq[1].tag == DerValue.tag_UtcTime) { notAfter = derVal.data.getUTCTime(); } else if (seq[1].tag == DerValue.tag_GeneralizedTime) { notAfter = derVal.data.getGeneralizedTime(); } else { throw new IOException("Invalid encoding for CertificateValidity"); } } /** * Default constructor for the class. */ public CertificateValidity() { } /** * The default constructor for this class for the specified interval. * * @param notBefore the date and time before which the certificate * is not valid. * @param notAfter the date and time after which the certificate is * not valid. */ public CertificateValidity(Date notBefore, Date notAfter) { this.notBefore = notBefore; this.notAfter = notAfter; } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the CertificateValidity from. * @exception IOException on decoding errors. */ public CertificateValidity(DerInputStream in) throws IOException { DerValue derVal = in.getDerValue(); construct(derVal); } /** * Return the validity period as user readable string. */ public String toString() { if (notBefore == null || notAfter == null) return ""; return ("Validity: [From: " + notBefore.toString() + ",\n To: " + notAfter.toString() + "]"); } /** * Decode the CertificateValidity period from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on errors. */ public void decode(InputStream in) throws IOException { DerValue derVal = new DerValue(in); construct(derVal); } private void writeObject(ObjectOutputStream stream) throws IOException { encode(stream); } private void readObject(ObjectInputStream stream) throws IOException { decode(stream); } /** * Encode the CertificateValidity period in DER form to the stream. * * @param out the OutputStream to marshal the contents to. * @exception IOException on errors. */ public void encode(OutputStream out) throws IOException { // in cases where default constructor is used check for // null values if (notBefore == null || notAfter == null) { throw new IOException("CertAttrSet:CertificateValidity:" + " null values to encode.\n"); } try (DerOutputStream pair = new DerOutputStream(); DerOutputStream seq = new DerOutputStream()) { if (notBefore.getTime() < YR_2050) { pair.putUTCTime(notBefore); } else pair.putGeneralizedTime(notBefore); if (notAfter.getTime() < YR_2050) { pair.putUTCTime(notAfter); } else { pair.putGeneralizedTime(notAfter); } seq.write(DerValue.tag_Sequence, pair); out.write(seq.toByteArray()); } } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (!(obj instanceof Date)) { throw new IOException("Attribute must be of type Date."); } if (name.equalsIgnoreCase(NOT_BEFORE)) { notBefore = (Date) obj; } else if (name.equalsIgnoreCase(NOT_AFTER)) { notAfter = (Date) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateValidity."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(NOT_BEFORE)) { return (getNotBefore()); } else if (name.equalsIgnoreCase(NOT_AFTER)) { return (getNotAfter()); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateValidity."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(NOT_BEFORE)) { notBefore = null; } else if (name.equalsIgnoreCase(NOT_AFTER)) { notAfter = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateValidity."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(NOT_BEFORE); elements.addElement(NOT_AFTER); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } /** * Verify that the current time is within the validity period. * * @exception CertificateExpiredException if the certificate has expired. * @exception CertificateNotYetValidException if the certificate is not * yet valid. */ public void valid() throws CertificateNotYetValidException, CertificateExpiredException { Date now = new Date(); valid(now); } /** * Verify that the passed time is within the validity period. * * @param now the Date against which to compare the validity * period. * * @exception CertificateExpiredException if the certificate has expired * with respect to the Date supplied. * @exception CertificateNotYetValidException if the certificate is not * yet valid with respect to the Date supplied. * */ public void valid(Date now) throws CertificateNotYetValidException, CertificateExpiredException { /* * we use the internal Dates rather than the passed in Date * because someone could override the Date methods after() * and before() to do something entirely different. */ if (notBefore.after(now)) { throw new CertificateNotYetValidException("NotBefore: " + notBefore.toString()); } if (notAfter.before(now)) { throw new CertificateExpiredException("NotAfter: " + notAfter.toString()); } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateVersion.java000066400000000000000000000163661362106420000261770ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the version of the X509 Certificate. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.8 * @see CertAttrSet */ public class CertificateVersion implements CertAttrSet { /** * X509Certificate Version 1 */ public static final int V1 = 0; /** * X509Certificate Version 2 */ public static final int V2 = 1; /** * X509Certificate Version 3 */ public static final int V3 = 2; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.version"; /** * Sub attributes name for this CertAttrSet. */ public static final String NAME = "version"; public static final String VERSION = "number"; // Private data members int version = V1; // Returns the version number. private int getVersion() { return (version); } // Construct the class from the passed DerValue private void construct(DerValue derVal) throws IOException { if (derVal.isConstructed() && derVal.isContextSpecific()) { derVal = derVal.data.getDerValue(); version = derVal.getInteger().toInt(); if (derVal.data.available() != 0) { throw new IOException("X.509 version, bad format"); } } } /** * The default constructor for this class, * sets the version to 0 (i.e. X.509 version 1). */ public CertificateVersion() { version = V1; } /** * The constructor for this class for the required version. * * @param version the version for the certificate. * @exception IOException if the version is not valid. */ public CertificateVersion(int version) throws IOException { // check that it is a valid version if (version == V1 || version == V2 || version == V3) this.version = version; else { throw new IOException("X.509 Certificate version " + version + " not supported.\n"); } } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the CertificateVersion from. * @exception IOException on decoding errors. */ public CertificateVersion(DerInputStream in) throws IOException { version = V1; DerValue derVal = in.getDerValue(); construct(derVal); } /** * Create the object, decoding the values from the passed stream. * * @param in the InputStream to read the CertificateVersion from. * @exception IOException on decoding errors. */ public CertificateVersion(InputStream in) throws IOException { version = V1; DerValue derVal = new DerValue(in); construct(derVal); } /** * Create the object, decoding the values from the passed DerValue. * * @param val the Der encoded value. * @exception IOException on decoding errors. */ public CertificateVersion(DerValue val) throws IOException { version = V1; construct(val); } /** * Return the version number of the certificate. */ public String toString() { return ("Version: V" + (version + 1)); } /** * Encode the CertificateVersion period in DER form to the stream. * * @param out the OutputStream to marshal the contents to. * @exception IOException on errors. */ public void encode(OutputStream out) throws IOException { // Nothing for default if (version == V1) { return; } try (DerOutputStream tmp = new DerOutputStream(); DerOutputStream seq = new DerOutputStream()) { tmp.putInteger(new BigInt(version)); seq.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), tmp); out.write(seq.toByteArray()); } } /** * Decode the CertificateVersion period in DER form from the stream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on errors. */ public void decode(InputStream in) throws IOException { DerValue derVal = new DerValue(in); construct(derVal); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (!(obj instanceof Integer)) { throw new IOException("Attribute must be of type Integer."); } if (name.equalsIgnoreCase(VERSION)) { version = ((Integer) obj).intValue(); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateVersion."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(VERSION)) { return (Integer.valueOf(getVersion())); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateVersion."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(VERSION)) { version = V1; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateVersion."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(VERSION); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } /** * Compare versions. */ public int compare(int vers) { return (version - vers); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/CertificateX509Key.java000066400000000000000000000126551362106420000256650ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the X509Key attribute for the Certificate. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.5 * @see CertAttrSet */ public class CertificateX509Key implements CertAttrSet, Serializable { /** * */ private static final long serialVersionUID = 6718749024328681131L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.key"; /** * Sub attributes name for this CertAttrSet. */ public static final String NAME = "key"; public static final String KEY = "value"; // Private data member private X509Key key; /** * Default constructor for the certificate attribute. * * @param key the X509Key */ public CertificateX509Key(X509Key key) { this.key = key; } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the X509Key from. * @exception IOException on decoding errors. */ public CertificateX509Key(DerInputStream in) throws IOException { DerValue val = in.getDerValue(); key = X509Key.parse(val); } /** * Create the object, decoding the values from the passed stream. * * @param in the InputStream to read the X509Key from. * @exception IOException on decoding errors. */ public CertificateX509Key(InputStream in) throws IOException { DerValue val = new DerValue(in); key = X509Key.parse(val); } /** * Return the key as printable string. */ public String toString() { if (key == null) return ""; return (key.toString()); } /** * Decode the key in DER form from the stream. * * @param in the InputStream to unmarshal the contents from * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { DerValue val = new DerValue(in); key = X509Key.parse(val); } private void writeObject(ObjectOutputStream stream) throws IOException { encode(stream); } private void readObject(ObjectInputStream stream) throws IOException { decode(stream); } /** * Encode the key in DER form to the stream. * * @param out the OutputStream to marshal the contents to. * @exception IOException on errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); key.encode(tmp); out.write(tmp.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (!(obj instanceof X509Key)) { throw new IOException("Attribute must be of type X509Key."); } if (name.equalsIgnoreCase(KEY)) { this.key = (X509Key) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateX509Key."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(KEY)) { return (key); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateX509Key."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(KEY)) { key = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet: CertificateX509Key."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(KEY); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/DNSName.java000066400000000000000000000046531362106420000236300ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class implements the DNSName as required by the GeneralNames * ASN.1 object. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.4 */ public class DNSName implements GeneralNameInterface { /** * */ private static final long serialVersionUID = -2907649488092607056L; private String name; /** * Create the DNSName object from the passed encoded Der value. * * @param derValue the encoded DER DNSName. * @exception IOException on error. */ public DNSName(DerValue derValue) throws IOException { name = derValue.getIA5String(); } /** * Create the DNSName object with the specified name. * * @param name the DNSName. */ public DNSName(String name) { this.name = name; } /** * Return the type of the GeneralName. */ public int getType() { return (GeneralNameInterface.NAME_DNS); } /** * Encode the DNS name into the DerOutputStream. * * @param out the DER stream to encode the DNSName to. * @exception IOException on encoding errors. */ public void encode(DerOutputStream out) throws IOException { out.putIA5String(name); } /** * Convert the name into user readable string. */ public String toString() { return ("DNSName: " + name); } /** * Get the raw DNSName value. */ public String getValue() { return name; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/DeltaCRLIndicatorExtension.java000066400000000000000000000175361362106420000275330ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.math.BigInteger; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the Delta CRL Indicator Extension. * *

* The delta CRL indicator is a critical CRL extension that identifies a delta-CRL. The value of BaseCRLNumber * identifies the CRL number of the base CRL that was used as the starting point in the generation of this delta- CRL. * The delta-CRL contains the changes between the base CRL and the current CRL issued along with the delta-CRL. * * @see Extension * @see CertAttrSet */ public class DeltaCRLIndicatorExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 7182919216525364676L; /** * Attribute name. */ public static final String NAME = "DeltaCRLIndicator"; public static final String NUMBER = "value"; /** * The Object Identifier for this extension. */ public static final String OID = "2.5.29.27"; private BigInt baseCRLNumber = null; static { try { OIDMap.addAttribute(DeltaCRLIndicatorExtension.class.getName(), OID, NAME); } catch (CertificateException e) { } } // Encode this extension value private void encodeThis() throws IOException { if (baseCRLNumber == null) throw new IOException("Unintialized delta CRL indicator extension"); try (DerOutputStream os = new DerOutputStream()) { os.putInteger(this.baseCRLNumber); this.extensionValue = os.toByteArray(); } } /** * Create a DeltaCRLIndicatorExtension with the integer value. * The criticality is set to true. * * @param baseCRLNum the value to be set for the extension. */ public DeltaCRLIndicatorExtension(int baseCRLNum) throws IOException { this.baseCRLNumber = new BigInt(baseCRLNum); this.extensionId = PKIXExtensions.DeltaCRLIndicator_Id; this.critical = true; encodeThis(); } /** * Create a DeltaCRLIndicatorExtension with the BigInteger value. * The criticality is set to true. * * @param baseCRLNum the value to be set for the extension. */ public DeltaCRLIndicatorExtension(BigInteger baseCRLNum) throws IOException { this.baseCRLNumber = new BigInt(baseCRLNum); this.extensionId = PKIXExtensions.DeltaCRLIndicator_Id; this.critical = true; encodeThis(); } /** * Create a DeltaCRLIndicatorExtension with the BigInteger value. * * @param critical true if the extension is to be treated as critical. * @param baseCRLNum the value to be set for the extension. */ public DeltaCRLIndicatorExtension(Boolean critical, BigInteger baseCRLNum) throws IOException { this.baseCRLNumber = new BigInt(baseCRLNum); this.extensionId = PKIXExtensions.DeltaCRLIndicator_Id; this.critical = critical.booleanValue(); encodeThis(); } /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public DeltaCRLIndicatorExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.DeltaCRLIndicator_Id; this.critical = critical.booleanValue(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; DerValue val = new DerValue(extValue); this.baseCRLNumber = val.getInteger(); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (name.equalsIgnoreCase(NUMBER)) { if (!(obj instanceof BigInteger)) { throw new IOException("Attribute must be of type BigInteger."); } baseCRLNumber = new BigInt((BigInteger) obj); } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:DeltaCRLIndicator."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(NUMBER)) { if (baseCRLNumber == null) return null; else return baseCRLNumber.toBigInteger(); } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:DeltaCRLIndicator."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(NUMBER)) { baseCRLNumber = null; } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:DeltaCRLIndicator."); } } /** * Returns a printable representation of the DeltaCRLIndicatorExtension. */ public String toString() { String s = super.toString() + "Delta CRL Indicator: " + ((baseCRLNumber == null) ? "" : baseCRLNumber.toString()) + "\n"; return (s); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { this.extensionId = PKIXExtensions.DeltaCRLIndicator_Id; this.critical = true; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(NUMBER); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/DirStrConverter.java000066400000000000000000000142721362106420000255000ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetEncoder; import org.mozilla.jss.netscape.security.util.ASN1CharStrConvMap; import org.mozilla.jss.netscape.security.util.DerValue; /** * A DirStrConverter converts a string to a DerValue of ASN.1 Directory String, * which is a CHOICE of Printable (subset of ASCII), T.61 (Teletex) or * Universal String (UCS-4), and vice versa. * *

* The string to DerValue conversion is done as follows. If the string has only PrintableString characters it is * converted to a ASN.1 Printable String using the PrintableString encoder from the global default ASN1CharStrConvMap. * If it has only characters covered in the PrintableString or T.61 character set it is converted to a ASN.1 T.61 string * using the T.61 encoder from the ASN1CharStrCovnMap. Otherwise it is converted to a ASN.1 UniversalString (UCS-4 * character set) which covers all characters. * * @see AVAValueConverter * @see ASN1CharStrConvMap * * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc. */ public class DirStrConverter implements AVAValueConverter { // public constructors /** * Constructs a DirStrConverter. */ public DirStrConverter() { } // public functions /** * Converts a string to a DER encoded ASN1 Directory String, which is a * CHOICE of PrintableString, T.61String or UniversalString. * The string is taken as is i.e. should not be in Ldap DN string syntax. * * @param ds a string representing a directory string value. * * @return a DerValue * * @exception IOException if the string cannot be converted, such as * when a UniversalString encoder * isn't available and the string contains * characters covered only in the universal * string (or UCS-4) character set. */ private static byte[] DefEncodingOrder = new byte[] { DerValue.tag_UTF8String, DerValue.tag_PrintableString, DerValue.tag_T61String, DerValue.tag_UniversalString }; public static synchronized void setDefEncodingOrder(byte[] defEncodingOrder) { DefEncodingOrder = defEncodingOrder; } public DerValue getValue(String ds) throws IOException { return getValue(ds, DefEncodingOrder); } /** * Like getValue(String) with specified DER tags as encoding order. */ public DerValue getValue(String valueString, byte[] tags) throws IOException { // try to convert to printable, then t61 the universal - // i.e. from minimal to the most liberal. if (tags == null || tags.length == 0) tags = DefEncodingOrder; for (int i = 0; i < tags.length; i++) { try { CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(tags[i]); if (encoder == null) continue; CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray()); ByteBuffer byteBuffer = encoder.encode(charBuffer); return new DerValue(tags[i], byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit()); } catch (CharacterCodingException e) { continue; } } throw new IOException( "Cannot convert the directory string value to a ASN.1 type"); } /** * Creates a DerValue from a BER encoded value, obtained from for example * a attribute value in octothorpe form of a Ldap DN string. * Checks if the BER encoded value is legal for a DirectoryString. * * NOTE: currently only supports DER encoding for the BER encoded value. * * @param berByteStream Byte array of a BER encoded value. * * @return DerValue object. * * @exception IOException If the BER value cannot be converted to a * valid Directory String DER value. */ public DerValue getValue(byte[] berByteStream) throws IOException { DerValue value = new DerValue(berByteStream); /* if (value.tag != DerValue.tag_PrintableString && value.tag != DerValue.tag_T61String && value.tag != DerValue.tag_UniversalString) throw new IOException("Invalid Directory String AVA Value"); */ return value; } /** * Converts a DerValue to a string. * The string is not in any syntax, such as RFC1779 string syntax. * * @param avaValue a DerValue * @return a string if the value can be converted. * @exception IOException if a decoder needed for the * conversion is not available. */ public String getAsString(DerValue avaValue) throws IOException { /* if (avaValue.tag != DerValue.tag_PrintableString && avaValue.tag != DerValue.tag_BMPString && avaValue.tag != DerValue.tag_UniversalString && avaValue.tag != DerValue.tag_T61String) throw new IllegalArgumentException( "Invalid Directory String value"); // NOTE will return null if a decoder is not available. */ return avaValue.getASN1CharString(); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/DisplayText.java000066400000000000000000000050501362106420000246450ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.Serializable; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the DisplayText. * * DisplayText ::= CHOICE { * visibleString VisibleString (SIZE (1..200)), * bmpString BMPString (SIZE (1..200)), * utf8String UTF8String (SIZE (1..200)), * } * * @author Thomas Kwan */ public class DisplayText implements Serializable { private static final long serialVersionUID = -6521458152495173328L; /** Tag value indicating an ASN.1 "BMPString" value. */ public final static byte tag_IA5String = 0x16; public final static byte tag_BMPString = 0x1E; public final static byte tag_VisibleString = 0x1A; public final static byte tag_UTF8String = 0x0C; private byte mTag; private String mS = null; public DisplayText(byte tag, String s) { mTag = tag; mS = s; } public DisplayText(DerValue val) throws IOException { mTag = val.tag; mS = val.getAsString(); } /** * Write the DisplayText to the DerOutputStream. * * @param out the DerOutputStream to write the object to. * @exception IOException on errors. */ public void encode(DerOutputStream out) throws IOException { out.putStringType(mTag, mS); } public String getText() { return mS; } public String toString() { if (mTag == tag_IA5String) { return "IA5String: " + mS; } else if (mTag == tag_BMPString) { return "BMPString: " + mS; } else if (mTag == tag_VisibleString) { return "VisibleString: " + mS; } else { return "UTF8String: " + mS; } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/EDIPartyName.java000066400000000000000000000122011362106420000246110ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the EDIPartyName of the GeneralName choice. * The ASN.1 syntax for this is: * *

 * EDIPartyName ::= SEQUENCE {
 *     nameAssigner  [0]  DirectoryString OPTIONAL,
 *     partyName     [1]  DirectoryString }
 * 
* * @author Hemma Prafullchandra * @version 1.2 * @see GeneralName * @see GeneralNames * @see GeneralNameInterface */ public class EDIPartyName implements GeneralNameInterface { /** * */ private static final long serialVersionUID = -8669257424766789063L; // Private data members private static final byte TAG_ASSIGNER = 0; private static final byte TAG_PARTYNAME = 1; private String assigner = null; private String party = null; /** * Create the EDIPartyName object from the specified names. * * @param assignerName the name of the assigner * @param partyName the name of the EDI party. */ public EDIPartyName(String assignerName, String partyName) { this.assigner = assignerName; this.party = partyName; } /** * Create the EDIPartyName object from the specified name. * * @param partyName the name of the EDI party. */ public EDIPartyName(String partyName) { this.party = partyName; } /** * Create the EDIPartyName object from the passed encoded Der value. * * @param derValue the encoded DER EDIPartyName. * @exception IOException on error. */ public EDIPartyName(DerValue derValue) throws IOException { DerInputStream in = new DerInputStream(derValue.toByteArray()); DerValue[] seq = in.getSequence(2); int len = seq.length; if (len < 1 || len > 2) throw new IOException("Invalid encoding of EDIPartyName"); for (int i = 0; i < len; i++) { DerValue opt = seq[i]; if (opt.isContextSpecific(TAG_ASSIGNER) && !opt.isConstructed()) { if (assigner != null) throw new IOException("Duplicate nameAssigner found in" + " EDIPartyName"); opt = opt.data.getDerValue(); assigner = opt.getAsString(); } if (opt.isContextSpecific(TAG_PARTYNAME) && !opt.isConstructed()) { if (party != null) throw new IOException("Duplicate partyName found in" + " EDIPartyName"); opt = opt.data.getDerValue(); party = opt.getAsString(); } } } /** * Return the type of the GeneralName. */ public int getType() { return (GeneralNameInterface.NAME_EDI); } /** * Encode the EDI party name into the DerOutputStream. * * @param out the DER stream to encode the EDIPartyName to. * @exception IOException on encoding errors. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tagged = new DerOutputStream(); DerOutputStream tmp = new DerOutputStream(); if (assigner != null) { DerOutputStream tmp2 = new DerOutputStream(); // XXX - shd check is chars fit into PrintableString tmp2.putPrintableString(assigner); tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT, false, TAG_ASSIGNER), tmp2); } if (party == null) { tagged.close(); tmp.close(); throw new IOException("Cannot have null partyName"); } // XXX - shd check is chars fit into PrintableString tmp.putPrintableString(party); tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT, false, TAG_PARTYNAME), tmp); out.write(DerValue.tag_Sequence, tagged); } /** * Return the printable string. */ public String toString() { return ("EDIPartyName: " + ((assigner == null) ? "" : (" nameAssigner = " + assigner + ",")) + " partyName = " + party); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/Extension.java000066400000000000000000000140431362106420000243510ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.Serializable; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * Represent a X509 Extension Attribute. * *

* Extensions are addiitonal attributes which can be inserted in a X509 v3 certificate. For example a * "Driving License Certificate" could have the driving license number as a extension. * *

* Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding * of the extension value). * *

 * ASN.1 definition of Extension:
 * Extension ::= SEQUENCE {
 * ExtensionId	OBJECT IDENTIFIER,
 * critical	BOOLEAN DEFAULT FALSE,
 * extensionValue	OCTET STRING
 * }
 * 
* * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.9 */ public class Extension implements Serializable { private static final long serialVersionUID = -643549610716024753L; protected ObjectIdentifier extensionId = null; protected boolean critical = false; protected byte[] extensionValue = null; /** * Default constructor. Used only by sub-classes. */ public Extension() { } /** * Constructs an extension from a DER encoded array of bytes. */ public Extension(DerValue derVal) throws IOException { DerInputStream in = derVal.toDerInputStream(); // Object identifier extensionId = in.getOID(); // If the criticality flag was false, it will not have been encoded. DerValue val = in.getDerValue(); if (val.tag == DerValue.tag_Boolean) { critical = val.getBoolean(); // Extension value (DER encoded) val = in.getDerValue(); extensionValue = val.getOctetString(); } else { critical = false; extensionValue = val.getOctetString(); } } /** * Constructs an Extension from individual components of ObjectIdentifier, * criticality and the DER encoded OctetString. * * @param extensionId the ObjectIdentifier of the extension * @param critical the boolean indicating if the extension is critical * @param extensionValue the DER encoded octet string of the value. */ public Extension(ObjectIdentifier extensionId, boolean critical, byte[] extensionValue) throws IOException { this.extensionId = extensionId; this.critical = critical; // passed in a DER encoded octet string, strip off the tag // and length DerValue inDerVal = new DerValue(extensionValue); this.extensionValue = inDerVal.getOctetString(); } /** * Constructs an Extension from another extension. To be used for * creating decoded subclasses. * * @param ext the extension to create from. */ public Extension(Extension ext) { this.extensionId = ext.extensionId; this.critical = ext.critical; this.extensionValue = ext.extensionValue; } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors */ public void encode(DerOutputStream out) throws IOException { if (extensionId == null) throw new IOException("Null OID to encode for the extension!"); DerOutputStream bytes = new DerOutputStream(); bytes.putOID(extensionId); if (critical) bytes.putBoolean(critical); if (extensionValue != null) bytes.putOctetString(extensionValue); out.write(DerValue.tag_Sequence, bytes); } /** * Returns true if extension is critical. */ public boolean isCritical() { return (critical); } public void setCritical(boolean c) { critical = c; } public void clearValue() { extensionValue = null; } /** * Returns the ObjectIdentifier of the extension. */ public ObjectIdentifier getExtensionId() { return (extensionId); } public void setExtensionId(ObjectIdentifier oid) { extensionId = oid; } /** * Returns the extension value as an byte array for further processing. * Note, this is the raw DER value of the extension, not the DER * encoded octet string which is in the certificate. */ public byte[] getExtensionValue() { if (extensionValue == null) return null; byte[] dup = new byte[extensionValue.length]; System.arraycopy(extensionValue, 0, dup, 0, dup.length); return dup; } public void setExtensionValue(byte value[]) { extensionValue = value; } /** * Returns the Extension in user readable form. */ public String toString() { String s = "ObjectId: " + extensionId.toString(); if (critical) { s += " Criticality=true\n"; } else { s += " Criticality=false\n"; } return (s); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/Extensions.java000066400000000000000000000200701362106420000245310ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the Extensions attribute for the Certificate. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.11 * @see CertAttrSet */ public class Extensions extends Vector implements CertAttrSet { /** * */ private static final long serialVersionUID = 4597917347772057433L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions"; /** * name */ public static final String NAME = "extensions"; private Hashtable map; // Parse the encoded extension public void parseExtension(Extension ext) throws IOException { try { @SuppressWarnings("unchecked") Class extClass = (Class) OIDMap.getClass(ext.getExtensionId()); if (extClass == null) { // Unsupported extension if (ext.isCritical()) { throw new IOException("Unsupported CRITICAL extension: " + ext.getExtensionId()); } else { map.put(ext.getExtensionId().toString(), ext); addElement(ext); return; } } Class[] params = { Boolean.class, Object.class }; Constructor cons = extClass.getConstructor(params); byte[] extData = ext.getExtensionValue(); int extLen = extData.length; Object value = Array.newInstance(byte.class, extLen); for (int i = 0; i < extLen; i++) { Array.setByte(value, i, extData[i]); } Object[] passed = new Object[] { Boolean.valueOf(ext.isCritical()), value }; CertAttrSet certExt = cons.newInstance(passed); map.put(certExt.getName(), (Extension) certExt); addElement((Extension) certExt); } catch (NoSuchMethodException nosuch) { throw new IOException(nosuch.toString()); } catch (InvocationTargetException invk) { throw new IOException(invk.getTargetException().toString()); } catch (Exception e) { throw new IOException(e.toString()); } } /** * Default constructor for the certificate attribute. */ public Extensions() { map = new Hashtable(); } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the Extension from. * @exception IOException on decoding errors. */ public Extensions(DerInputStream in) throws IOException { map = new Hashtable(); DerValue[] exts = in.getSequence(5); for (int i = 0; i < exts.length; i++) { Extension ext = new Extension(exts[i]); parseExtension(ext); } } /** * Decode the extensions from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { DerValue val = new DerValue(in); DerInputStream str = val.toDerInputStream(); map = new Hashtable(); DerValue[] exts = str.getSequence(5); for (int i = 0; i < exts.length; i++) { Extension ext = new Extension(exts[i]); parseExtension(ext); } } /** * Encode the extensions in DER form to the stream. * * @param out the DerOutputStream to marshal the contents to. * @exception CertificateException on encoding errors. * @exception IOException on errors. */ public void encode(OutputStream out) throws CertificateException, IOException { DerOutputStream extOut = new DerOutputStream(); for (int i = 0; i < size(); i++) { Object thisOne = elementAt(i); if (thisOne instanceof CertAttrSet) ((CertAttrSet) thisOne).encode(extOut); else if (thisOne instanceof Extension) ((Extension) thisOne).encode(extOut); else throw new CertificateException("Invalid extension object"); } try (DerOutputStream seq = new DerOutputStream()) { seq.write(DerValue.tag_Sequence, extOut); out.write(seq.toByteArray()); } } /** * Set the attribute value. * * @param name the extension name used in the cache. * @param obj the object to set. * @exception IOException if the object could not be cached. */ public void set(String name, Object obj) throws IOException { map.put(name, (Extension) obj); addElement((Extension) obj); } /** * Get the attribute value. * * @param name the extension name used in the lookup. * @exception IOException if named extension is not found. */ public Object get(String name) throws IOException { Object obj = map.get(name); if (obj == null) { throw new IOException("No extension found with name " + name); } return (obj); } /** * Delete the attribute value. * * @param name the extension name used in the lookup. * @exception IOException if named extension is not found. */ public void delete(String name) throws IOException { Object obj = map.get(name); if (obj == null) { throw new IOException("No extension found with name " + name); } map.remove(name); removeElement(obj); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { return map.keys(); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((map == null) ? 0 : map.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; Extensions other = (Extensions) obj; if (map == null) { if (other.map != null) return false; } else if (!map.equals(other.map)) return false; return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/FreshestCRLExtension.java000066400000000000000000000321741362106420000264230ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.netscape.security.util.BitArray; import org.mozilla.jss.netscape.security.util.DerOutputStream; /** * An extension that tells applications where to find * the latest (freshest) delta CRL for this certificate * or full CRL. * *
 * cRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
 *
 * DistributionPoint ::= SEQUENCE {
 *      distributionPoint       [0]     DistributionPointName OPTIONAL,
 *      reasons                 [1]     ReasonFlags OPTIONAL,
 *      cRLIssuer               [2]     GeneralNames OPTIONAL }
 *
 * DistributionPointName ::= CHOICE {
 *      fullName                [0]     GeneralNames,
 *      nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
 *
 * ReasonFlags ::= BIT STRING {
 *      unused                  (0),
 *      keyCompromise           (1),
 *      cACompromise            (2),
 *      affiliationChanged      (3),
 *      superseded              (4),
 *      cessationOfOperation    (5),
 *      certificateHold         (6) }
 * 
*/ public class FreshestCRLExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -8040203589629281781L; // vector of CRLDistributionPoint private SEQUENCE distributionPoints = new SEQUENCE(); public FreshestCRLExtension() { this.extensionId = PKIXExtensions.FreshestCRL_Id; this.critical = false; } // Cached DER-encoding to improve performance. private byte[] cachedEncoding = null; // Attribute name public static final String NAME = "FreshestCRL"; // The Object Identifier for this extension. public static final String OID = "2.5.29.46"; static { try { OIDMap.addAttribute(FreshestCRLExtension.class.getName(), OID, NAME); } catch (CertificateException e) { } } /** * This constructor is called by the CertificateExtensions class to decode * an extension whose OID indicates it is a CRLDistributionsPoints * extension. */ public FreshestCRLExtension(Boolean critical, Object value) //throws IOException { try { this.extensionId = PKIXExtensions.FreshestCRL_Id; this.critical = critical.booleanValue(); this.extensionValue = ((byte[]) value).clone(); // decode the value try { SEQUENCE.OF_Template seqOfCRLDP = new SEQUENCE.OF_Template(CRLDistributionPoint.getTemplate()); distributionPoints = (SEQUENCE) ASN1Util.decode(seqOfCRLDP, extensionValue); } catch (InvalidBERException e) { throw new IOException("Invalid BER-encoding: " + e, e); } } catch (IOException e) { System.out.println("Big error"); System.out.println(e); e.printStackTrace(); //throw e; } } /** * Creates a new FreshestCRL extension, with the given * distribution point as the first element. */ public FreshestCRLExtension(CRLDistributionPoint dp) { this.extensionId = PKIXExtensions.FreshestCRL_Id; this.critical = false; distributionPoints.addElement(dp); } /** * Adds an additional distribution point to the end of the sequence. */ public void addPoint(CRLDistributionPoint dp) { distributionPoints.addElement(dp); cachedEncoding = null; } /** * Returns the number of distribution points in the sequence. */ public int getNumPoints() { return distributionPoints.size(); } /** * Returns the DistributionPoint at the given index in the sequence. */ public CRLDistributionPoint getPointAt(int index) { return (CRLDistributionPoint) distributionPoints.elementAt(index); } /** * Sets the criticality of this extension. PKIX dictates that this * extension SHOULD NOT be critical, so applications can make it critical * if they have a very good reason. By default, the extension is not * critical. */ public void setCritical(boolean critical) { this.critical = critical; } /** * Encodes this extension to the given DerOutputStream. * This method re-encodes each time it is called, so it is not very * efficient. */ public void encode(DerOutputStream out) throws IOException { extensionValue = ASN1Util.encode(distributionPoints); super.encode(out); } /** * Should be called if any change is made to this data structure * so that the cached DER encoding can be discarded. */ public void flushCachedEncoding() { cachedEncoding = null; } ///////////////////////////////////////////////////////////// // CertAttrSet interface // This interface is not really appropriate for this extension // because it is so complicated. Therefore, we only provide a // minimal implementation. ///////////////////////////////////////////////////////////// @Override public String toString() { return NAME; } /** * DER-encodes this extension to the given OutputStream. */ public void encode(OutputStream ostream) throws CertificateException, IOException { if (cachedEncoding == null) { // only re-encode if necessary DerOutputStream tmp = new DerOutputStream(); encode(tmp); cachedEncoding = tmp.toByteArray(); } ostream.write(cachedEncoding); } public void decode(InputStream in) throws CertificateException, IOException { throw new IOException("Not supported"); } public void set(String name, Object obj) throws CertificateException, IOException { throw new IOException("Attribute name not recognized by " + "CertAttrSet:FreshestCRLExtension"); } public Object get(String name) throws CertificateException, IOException { throw new IOException("Attribute name not recognized by " + "CertAttrSet:FreshestCRLExtension"); } public void delete(String name) throws CertificateException, IOException { throw new IOException("Attribute name not recognized by " + "CertAttrSet:FreshestCRLExtension"); } /* * TODO replacewith empty collection */ public Enumeration getAttributeNames() { return (new Vector()).elements(); } public String getName() { return NAME; } /** * Test driver. */ public static void main(String args[]) { BufferedOutputStream bos = null; try { if (args.length != 1) { System.out.println("Usage: FreshestCRLExtentions " + ""); System.exit(-1); } bos = new BufferedOutputStream( new FileOutputStream(args[0])); // URI only CRLDistributionPoint cdp = new CRLDistributionPoint(); URIName uri = new URIName("http://www.mycrl.com/go/here"); GeneralNames generalNames = new GeneralNames(); generalNames.addElement(uri); cdp.setFullName(generalNames); FreshestCRLExtension crldpExt = new FreshestCRLExtension(cdp); // DN only cdp = new CRLDistributionPoint(); X500Name dn = new X500Name("CN=Otis Smith,E=otis@fedoraproject.org" + ",OU=Certificate Server,O=Fedora,C=US"); generalNames = new GeneralNames(); generalNames.addElement(dn); cdp.setFullName(generalNames); crldpExt.addPoint(cdp); // DN + reason BitArray ba = new BitArray(5, new byte[] { (byte) 0x28 }); cdp = new CRLDistributionPoint(); cdp.setFullName(generalNames); cdp.setReasons(ba); crldpExt.addPoint(cdp); // relative DN + reason + crlIssuer cdp = new CRLDistributionPoint(); RDN rdn = new RDN("OU=foobar dept"); cdp.setRelativeName(rdn); cdp.setReasons(ba); cdp.setCRLIssuer(generalNames); crldpExt.addPoint(cdp); crldpExt.setCritical(true); crldpExt.encode(bos); } catch (Exception e) { e.printStackTrace(); } finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Represents a reason that a cert may be revoked. These reasons are * expressed in a ReasonFlags bit string. */ public static class Reason { private String name; private byte bitMask; private Reason() { } private Reason(String name, byte bitMask) { this.name = name; this.bitMask = bitMask; map.put(name, this); list.addElement(this); } private static Hashtable map = new Hashtable(); private static Vector list = new Vector(); public static Reason fromString(String name) { return map.get(name); } public String getName() { return name; } public byte getBitMask() { return bitMask; } /** * Given a bit array representing reason flags, extracts the reasons * and returns them as an array. * * @param bitFlags A bit vector containing reason flags. * @return An array of reasons contained in the bit vector. * May be zero-length but will not be null. */ public static Reason[] bitArrayToReasonArray(byte bitFlags) { return bitArrayToReasonArray(new byte[] { bitFlags }); } /** * Given a bit array representing reason flags, extracts the reasons * and returns them as an array. Currently, only the first byte * of the bitflags are examined. * * @param bitFlags A bit vector containing reason flags. The format * is big-endian (MSB first). Only the first byte is examined. * @return An array of reasons contained in the bit vector. * May be zero-length but will not be null. */ public static Reason[] bitArrayToReasonArray(byte[] bitFlags) { byte first = bitFlags[0]; int size = list.size(); Vector result = new Vector(); for (int i = 0; i < size; i++) { Reason r = list.elementAt(i); byte b = r.getBitMask(); if ((first & b) != 0) { result.addElement(r); } } size = result.size(); Reason[] retval = new Reason[size]; for (int i = 0; i < size; i++) { retval[i] = result.elementAt(i); } return retval; } public static final Reason UNUSED = new Reason("unused", (byte) 0x80); public static final Reason KEY_COMPROMISE = new Reason("keyCompromise", (byte) 0x40); public static final Reason CA_COMPROMISE = new Reason("cACompromise", (byte) 0x20); public static final Reason AFFILIATION_CHANGED = new Reason("affiliationChanged", (byte) 0x10); public static final Reason SUPERSEDED = new Reason("superseded", (byte) 0x08); public static final Reason CESSATION_OF_OPERATION = new Reason("cessationOfOperation", (byte) 0x04); public static final Reason CERTIFICATE_HOLD = new Reason("certificateHold", (byte) 0x02); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/GeneralName.java000066400000000000000000000176301362106420000245600ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class implements the ASN.1 GeneralName object class. *

* The ASN.1 syntax for this is: * *

 * GeneralName ::= CHOICE {
 *    otherName                       [0]     OtherName,
 *    rfc822Name                      [1]     IA5String,
 *    dNSName                         [2]     IA5String,
 *    x400Address                     [3]     ORAddress,
 *    directoryName                   [4]     Name,
 *    ediPartyName                    [5]     EDIPartyName,
 *    uniformResourceIdentifier       [6]     IA5String,
 *    iPAddress                       [7]     OCTET STRING,
 *    registeredID                    [8]     OBJECT IDENTIFIER
 * }
 * 
* * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.7 */ public class GeneralName implements GeneralNameInterface { /** * */ private static final long serialVersionUID = 2244101501095555042L; // Private data members private GeneralNameInterface name = null; /** * Default constructor for the class. * * @param name the selected CHOICE from the list. */ public GeneralName(GeneralNameInterface name) { this.name = name; } /** * Create the object from its DER encoded value. * * @param encName the DER encoded GeneralName. */ public GeneralName(DerValue encName) throws IOException { short tag = (byte) (encName.tag & 0x1f); // NB. this is always encoded with the IMPLICIT tag // The checks only make sense if we assume implicit tagging, // with explicit tagging the form is always constructed. switch (tag) { case GeneralNameInterface.NAME_RFC822: if (encName.isContextSpecific() && !encName.isConstructed()) { encName.resetTag(DerValue.tag_IA5String); name = new RFC822Name(encName); } else throw new IOException("Invalid encoding of RFC822 name"); break; case GeneralNameInterface.NAME_DNS: if (encName.isContextSpecific() && !encName.isConstructed()) { encName.resetTag(DerValue.tag_IA5String); name = new DNSName(encName); } else throw new IOException("Invalid encoding of DNS name"); break; case GeneralNameInterface.NAME_URI: if (encName.isContextSpecific() && !encName.isConstructed()) { encName.resetTag(DerValue.tag_IA5String); name = new URIName(encName); } else throw new IOException("Invalid encoding of URI"); break; case GeneralNameInterface.NAME_IP: if (encName.isContextSpecific() && !encName.isConstructed()) { encName.resetTag(DerValue.tag_OctetString); name = new IPAddressName(encName); } else throw new IOException("Invalid encoding of IP address"); break; case GeneralNameInterface.NAME_ANY: if (encName.isContextSpecific() && encName.isConstructed()) { encName.resetTag(DerValue.tag_OctetString); name = new OtherName(encName); } else throw new IOException("Invalid encoding of other name"); break; case GeneralNameInterface.NAME_OID: if (encName.isContextSpecific() && !encName.isConstructed()) { encName.resetTag(DerValue.tag_ObjectId); name = new OIDName(encName); } else throw new IOException("Invalid encoding of OID name"); break; case GeneralNameInterface.NAME_DIRECTORY: if (encName.isContextSpecific() && encName.isConstructed()) { // Unlike the other cases, DirectoryName is EXPLICITly // tagged, because the X.500 Name type is a CHOICE. // Therefore, the sequence is actually nested in the // content of this value. We'll pretend it's an octet // string so we can get at the content bytes. encName.resetTag(DerValue.tag_OctetString); byte[] content = encName.getOctetString(); name = new X500Name(content); } else throw new IOException("Invalid encoding of Directory name"); break; case GeneralNameInterface.NAME_EDI: if (encName.isContextSpecific() && encName.isConstructed()) { encName.resetTag(DerValue.tag_Sequence); name = new EDIPartyName(encName); } else throw new IOException("Invalid encoding of EDI name"); break; default: throw new IOException("Unrecognized GeneralName tag, (" + tag + ")"); } } /** * Return the type of the general name. */ public int getType() { return (name.getType()); } /** * Return the name as user readable string */ public String toString() { return (name.toString()); } /** * Encode the name to the specified DerOutputStream. * * @param out the DerOutputStream to encode the the GeneralName to. * @exception IOException on encoding errors. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); name.encode(tmp); int nameType = name.getType(); boolean constructedForm; if (nameType == GeneralNameInterface.NAME_ANY || nameType == GeneralNameInterface.NAME_X400 || nameType == GeneralNameInterface.NAME_DIRECTORY || nameType == GeneralNameInterface.NAME_EDI) { constructedForm = true; } else { constructedForm = false; } if (nameType == GeneralNameInterface.NAME_DIRECTORY) { // EXPLICIT tag, because Name is a CHOICE type out.write(DerValue.createTag(DerValue.TAG_CONTEXT, constructedForm, (byte) nameType), tmp); } else { // IMPLICIT tag, the default out.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, constructedForm, (byte) nameType), tmp); } } @Override public boolean validSingle() { if (this == name) return false; // can't happen, but just in case... return name.validSingle(); } @Override public boolean validSubtree() { if (this == name) return false; // can't happen, but just in case... return name.validSubtree(); } /** * Unwrap this GeneralName until we reach something that is not * a GeneralName. */ public GeneralNameInterface unwrap() { if (this == name) return null; // can't happen, but just in case... if (name instanceof GeneralName) return ((GeneralName) name).unwrap(); else return name; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/GeneralNameInterface.java000066400000000000000000000046071362106420000264010ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; /** * This interface specifies the abstract methods which have to be * implemented by all the members of the GeneralNames ASN.1 object. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.6 */ public interface GeneralNameInterface extends java.io.Serializable { /** * The list of names supported. */ public static final int NAME_ANY = 0; public static final int NAME_RFC822 = 1; public static final int NAME_DNS = 2; public static final int NAME_X400 = 3; public static final int NAME_DIRECTORY = 4; public static final int NAME_EDI = 5; public static final int NAME_URI = 6; public static final int NAME_IP = 7; public static final int NAME_OID = 8; /** * Return the type of the general name, as * defined above. */ int getType(); /** * Encode the name to the specified DerOutputStream. * * @param out the DerOutputStream to encode the GeneralName to. * @exception IOException thrown if the GeneralName could not be * encoded. */ void encode(DerOutputStream out) throws IOException; /** * Whether the name is valid as a single name (e.g. for use in * Subject Alternative Name extension). */ default boolean validSingle() { return true; } /** * Whether the name is valid as a subtree name (e.g. for use in * Name Constraints extension) */ default boolean validSubtree() { return true; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/GeneralNames.java000066400000000000000000000122311362106420000247330ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This object class represents the GeneralNames type required in * X509 certificates. *

* The ASN.1 syntax for this is: * *

 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
 * 
* * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.7 */ public class GeneralNames extends Vector { /** * */ private static final long serialVersionUID = 3204492869396713312L; /** * Create the GeneralNames, decoding from the passed DerValue. * * Caution when using this constructor. It may be broken! * Better to call addElement(gni) directly where gni is * a GeneralNameInterface object * * @param derVal the DerValue to construct the GeneralNames from. * @exception GeneralNamesException on decoding error. * @exception IOException on error. */ public GeneralNames(DerValue derVal) throws IOException, GeneralNamesException { if (derVal.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for GeneralNames."); } if (derVal.data.available() == 0) { throw new GeneralNamesException("No data available in " + "passed DER encoded value."); } // Decode all the GeneralName's while (derVal.data.available() != 0) { DerValue encName = derVal.data.getDerValue(); GeneralName name = new GeneralName(encName); addElement(name); } } /** * Create the GeneralNames * * @param names a non-empty array of names to put into the * generalNames */ public GeneralNames(GeneralNameInterface[] names) throws GeneralNamesException { if (names == null || names.length == 0) throw new GeneralNamesException("Cannot create empty GeneralNames"); for (int i = 0; i < names.length; i++) { addElement(names[i]); } } /** * The default constructor for this class. */ public GeneralNames() { super(1, 1); } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception GeneralNamesException on encoding error. * @exception IOException on error. */ public void encode(DerOutputStream out) throws IOException, GeneralNamesException { if (size() == 0) { return; } Enumeration names = elements(); DerOutputStream temp = new DerOutputStream(); while (names.hasMoreElements()) { Object obj = names.nextElement(); if (!(obj instanceof GeneralNameInterface)) { throw new GeneralNamesException("Element in GeneralNames " + "not of type GeneralName."); } GeneralNameInterface intf = (GeneralNameInterface) obj; if (obj instanceof GeneralName) { intf.encode(temp); } else { DerOutputStream gname = new DerOutputStream(); intf.encode(gname); int nameType = intf.getType(); // constructed form if (nameType == GeneralNameInterface.NAME_ANY || nameType == GeneralNameInterface.NAME_X400 || nameType == GeneralNameInterface.NAME_EDI) { temp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) nameType), gname); } else if (nameType == GeneralNameInterface.NAME_DIRECTORY) { // EXPLICIT tag because directoryName is a CHOICE temp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) nameType), gname); } else // primitive form temp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false, (byte) nameType), gname); } } out.write(DerValue.tag_Sequence, temp); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/GeneralNamesException.java000066400000000000000000000040031362106420000266100ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.security.GeneralSecurityException; /** * Generic General Names Exception. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.4 */ public class GeneralNamesException extends GeneralSecurityException { /** * */ private static final long serialVersionUID = -8320001725384815795L; /** * Constructs a GeneralNamesException with no detail message. */ public GeneralNamesException() { super(); } /** * Constructs the exception with the specified error message. * * @param message the requisite error message. */ public GeneralNamesException(String message) { super(message); } /** * Constructs the exception with the specified error message and cause. * * @param mesg the requisite error message. * @param cause the requisite cause of this error. */ public GeneralNamesException(String mesg, Throwable cause) { super(mesg, cause); } /** * Constructs the exception with the specified cause. * * @param cause the requisite cause of this error. */ public GeneralNamesException(Throwable cause) { super(cause); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/GeneralSubtree.java000066400000000000000000000125311362106420000253040ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.Serializable; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.PrettyPrintFormat; /** * Represent the GeneralSubtree ASN.1 object, whose syntax is: * *
 * GeneralSubtree ::= SEQUENCE {
 *    base             GeneralName,
 *    minimum  [0]     BaseDistance DEFAULT 0,
 *    maximum  [1]     BaseDistance OPTIONAL
 * }
 * BaseDistance ::= INTEGER (0..MAX)
 * 
* * @version 1.5 * @author Amit Kapoor * @author Hemma Prafullchandra */ public class GeneralSubtree implements Serializable { private static final long serialVersionUID = -2835481424013062770L; private static final byte TAG_MIN = 0; private static final byte TAG_MAX = 1; private static final int MIN_DEFAULT = 0; private GeneralName name; private int minimum = MIN_DEFAULT; private int maximum = -1; private transient PrettyPrintFormat pp = new PrettyPrintFormat(":"); /** * The default constructor for the class. * * @param name the GeneralName * @param min the minimum BaseDistance * @param max the maximum BaseDistance */ public GeneralSubtree(GeneralName name, int min, int max) { this.name = name; this.minimum = min; this.maximum = max; } /** * Create the object from its DER encoded form. * * @param val the DER encoded from of the same. */ public GeneralSubtree(DerValue val) throws IOException { if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for GeneralSubtree."); } name = new GeneralName(val.data.getDerValue()); // NB. this is always encoded with the IMPLICIT tag // The checks only make sense if we assume implicit tagging, // with explicit tagging the form is always constructed. while (val.data.available() != 0) { DerValue opt = val.data.getDerValue(); if (opt.isContextSpecific(TAG_MIN) && !opt.isConstructed()) { opt.resetTag(DerValue.tag_Integer); minimum = (opt.getInteger()).toInt(); } else if (opt.isContextSpecific(TAG_MAX) && !opt.isConstructed()) { opt.resetTag(DerValue.tag_Integer); maximum = (opt.getInteger()).toInt(); } else throw new IOException("Invalid encoding of GeneralSubtree."); } } /** * Return a printable string of the GeneralSubtree. */ public String toString() { String s = "\n GeneralSubtree: [\n" + " GeneralName: " + ((name == null) ? "" : name.toString()) + "\n Minimum: " + minimum; if (maximum == -1) { s += "\t Maximum: undefined"; } else s += "\t Maximum: " + maximum; s += " ]\n"; return (s); } public String toPrint(int indent) { String s = "\n" + pp.indent(indent) + "GeneralSubtree: [\n" + pp.indent(indent + 2) + "GeneralName: " + ((name == null) ? "" : name.toString()) + "\n" + pp.indent(indent + 2) + "Minimum: " + minimum; if (maximum == -1) { s += "\n" + pp.indent(indent + 2) + "Maximum: undefined"; } else s += "\n" + pp.indent(indent + 2) + "Maximum: " + maximum; s += "]\n"; return (s); } /** * Encode the GeneralSubtree. * * @param out the DerOutputStream to encode this object to. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream seq = new DerOutputStream(); name.encode(seq); if (minimum != MIN_DEFAULT) { DerOutputStream tmp = new DerOutputStream(); tmp.putInteger(new BigInt(minimum)); seq.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false, TAG_MIN), tmp); } if (maximum != -1) { DerOutputStream tmp = new DerOutputStream(); tmp.putInteger(new BigInt(maximum)); seq.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false, TAG_MAX), tmp); } out.write(DerValue.tag_Sequence, seq); } public GeneralName getGeneralName() { return name; } public int getMaxValue() { return maximum; } public int getMinValue() { return minimum; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/GeneralSubtrees.java000066400000000000000000000064621362106420000254750ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.Serializable; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.PrettyPrintFormat; /** * Represent the GeneralSubtrees ASN.1 object. * * @version 1.4 * * @author Amit Kapoor * @author Hemma Prafullchandra */ public class GeneralSubtrees implements Serializable { private static final long serialVersionUID = 6308776640697100848L; private Vector trees; private transient PrettyPrintFormat pp = new PrettyPrintFormat(":"); /** * The default constructor for the class. * * @param trees the sequence of GeneralSubtree. */ public GeneralSubtrees(Vector trees) { this.trees = trees; } /** * Create the object from the passed DER encoded form. * * @param val the DER encoded form of the same. */ public GeneralSubtrees(DerValue val) throws IOException { trees = new Vector(1, 1); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding of GeneralSubtrees."); } while (val.data.available() != 0) { DerValue opt = val.data.getDerValue(); GeneralSubtree tree = new GeneralSubtree(opt); trees.addElement(tree); } } /** * Return a printable string of the GeneralSubtree. */ public String toString() { String s = " GeneralSubtrees:\n" + trees.toString() + "\n"; return (s); } public String toPrint(int indent) { StringBuffer s = new StringBuffer(); GeneralSubtree element; for (Enumeration e = trees.elements(); e.hasMoreElements();) { element = e.nextElement(); s.append(pp.indent(indent + 4) + element.toPrint(indent) + "\n"); } return (s.toString()); } /** * Encode the GeneralSubtrees. * * @param out the DerOutputStrean to encode this object to. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream seq = new DerOutputStream(); for (int i = 0; i < trees.size(); i++) { trees.elementAt(i).encode(seq); } out.write(DerValue.tag_Sequence, seq); } public Vector getSubtrees() { return trees; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/GenericValueConverter.java000066400000000000000000000127311362106420000266400ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetEncoder; import org.mozilla.jss.netscape.security.util.ASN1CharStrConvMap; import org.mozilla.jss.netscape.security.util.DerValue; /** * A GenericValueConverter converts a string that is not associated with * a particular attribute to a DER encoded ASN.1 character string type. * Currently supports PrintableString, IA5String, BMPString T.61String and * Universal String. * *

* The conversion is done as follows. An encoder is obtained for the all the character sets from the global default * ASN1CharStrConvMap. The encoders are then used to convert the string to the smallest character set first -- * printableString. If the string contains characters outside of that character set, it is converted to the next * character set -- IA5String character set. If that is not enough it is converted to a BMPString, then Universal String * which contains all characters. * * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc. * */ public class GenericValueConverter implements AVAValueConverter { public GenericValueConverter() { } /** * Converts a string to a DER encoded ASN.1 primtable string, defined here * as a PrintableString, IA5String, T.61String, BMPString or * UniversalString. The string is not expected to be encoded in any form. * *

* If an encoder is not available for a character set that is needed to convert the string, the string cannot be * converted and an IOException is thrown. For example, if the string contains characters outside the * PrintableString character and only a PrintableString encoder is available then an IOException is thrown. * * @param s A string representing a generic attribute string value. * * @return The DER value of the attribute. * * @exception IOException if the string cannot be converted, such as * when an encoder needed is * unavailable. */ public DerValue getValue(String s) throws IOException { return getValue(s, null); } public DerValue getValue(String valueString, byte[] tags) throws IOException { // try to convert to printable, then t61 the universal - // i.e. from minimal coverage to the broadest. if (tags == null || tags.length == 0) tags = DefEncodingTags; for (int i = 0; i < tags.length; i++) { try { CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(tags[i]); if (encoder == null) continue; CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray()); ByteBuffer byteBuffer = encoder.encode(charBuffer); return new DerValue(tags[i], byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit()); } catch (CharacterCodingException e) { continue; } } throw new IOException( "Cannot convert the string value to a ASN.1 type"); } /** * Creates a DerValue from the byte array of BER encoded value. * * NOTE: currently only supports DER encoding (a form of BER) on input . * * @param berByteStream Byte array of a BER encoded value. * * @return DerValue object. * * @exception IOException If the BER value cannot be converted to a * valid Directory String DER value. */ public DerValue getValue(byte[] berByteStream) throws IOException { // accepts any tag. DerValue value = new DerValue(berByteStream); return value; } /** * Converts a DerValue of ASN1 Character string type to a java string * (the string is not encoded in any form). * * @param avaValue A DerValue * @return A string representing the attribute value. * @exception IOException if a decoder needed for the * conversion is not available or if BER value * is not one of the ASN1 character string types * here. */ public String getAsString(DerValue avaValue) throws IOException { return avaValue.getASN1CharString(); } private static byte DefEncodingTags[] = { DerValue.tag_PrintableString, DerValue.tag_IA5String, DerValue.tag_BMPString, DerValue.tag_UTF8String, DerValue.tag_T61String, DerValue.tag_UniversalString }; } jss-4.6.3/org/mozilla/jss/netscape/security/x509/HoldInstructionExtension.java000066400000000000000000000306351362106420000274270ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * Represent the CRL Hold Instruction Code Extension. * *

* The hold instruction code is a non-critical CRL entry extension that provides a registered instruction identifier * which indicates the action to be taken after encountering a certificate that has been placed on hold. * * @see Extension * @see CertAttrSet */ public class HoldInstructionExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -6706557233070964984L; /** * Attribute name. */ public static final String NAME = "HoldInstruction"; public static final String HOLD_INSTRUCTION = "value"; /** * The Object Identifier for this extension. */ public static final String OID = "2.5.29.23"; public static final String NONE_HOLD_INSTR_OID_STR = "1.2.840.10040.2.1"; public static final ObjectIdentifier NONE_HOLD_INSTR_OID = new ObjectIdentifier(NONE_HOLD_INSTR_OID_STR); public static final String CALL_ISSUER_HOLD_INSTR_OID_STR = "1.2.840.10040.2.2"; public static final ObjectIdentifier CALL_ISSUER_HOLD_INSTR_OID = new ObjectIdentifier(CALL_ISSUER_HOLD_INSTR_OID_STR); public static final String REJECT_HOLD_INSTR_OID_STR = "1.2.840.10040.2.3"; public static final ObjectIdentifier REJECT_HOLD_INSTR_OID = new ObjectIdentifier(REJECT_HOLD_INSTR_OID_STR); private ObjectIdentifier holdInstructionCodeOIDs[] = { NONE_HOLD_INSTR_OID, CALL_ISSUER_HOLD_INSTR_OID, REJECT_HOLD_INSTR_OID }; private ObjectIdentifier holdInstructionCodeOID = null; private String holdInstructionDescription[] = { "None", "Call Issuer", "Reject" }; static { try { OIDMap.addAttribute(HoldInstructionExtension.class.getName(), OID, NAME); } catch (CertificateException e) { } } private int getHoldInstructionCodeFromOID(ObjectIdentifier oid) { for (int i = 0; i < holdInstructionCodeOIDs.length; i++) { if (oid.equals(holdInstructionCodeOIDs[i])) return (i + 1); } return 0; } private String getHoldInstructionDescription(ObjectIdentifier oid) { String description = "Invalid"; if (oid != null) { int i = getHoldInstructionCodeFromOID(oid); if (i > 0 && i < 4) description = holdInstructionDescription[i - 1]; } return (description); } // Encode this extension value private void encodeThis() throws IOException { if (holdInstructionCodeOID == null) throw new IOException("Unintialized hold instruction extension"); try (DerOutputStream os = new DerOutputStream()) { os.putOID(holdInstructionCodeOID); this.extensionValue = os.toByteArray(); } } /** * Create a HoldInstructionExtension with the date. * The criticality is set to false. * * @param code the value to be set for the extension. */ public HoldInstructionExtension(int code) throws IOException { if (code < 1 || code > 3) throw new IOException("Invalid hold instruction code"); holdInstructionCodeOID = holdInstructionCodeOIDs[code - 1]; this.extensionId = PKIXExtensions.HoldInstructionCode_Id; this.critical = false; encodeThis(); } /** * Create a HoldInstructionExtension with the date. * The criticality is set to false. * * @param oidStr the value to be set for the extension. */ public HoldInstructionExtension(String oidStr) throws IOException { ObjectIdentifier oid = new ObjectIdentifier(oidStr); if (oid == null || getHoldInstructionCodeFromOID(oid) == 0) throw new IOException("Invalid hold instruction code"); holdInstructionCodeOID = oid; this.extensionId = PKIXExtensions.HoldInstructionCode_Id; this.critical = false; encodeThis(); } /** * Create a HoldInstructionExtension with the date. * The criticality is set to false. * * @param oid the value to be set for the extension. */ public HoldInstructionExtension(ObjectIdentifier oid) throws IOException { if (getHoldInstructionCodeFromOID(oid) == 0) throw new IOException("Invalid hold instruction code"); holdInstructionCodeOID = oid; this.extensionId = PKIXExtensions.HoldInstructionCode_Id; this.critical = false; encodeThis(); } /** * Create a HoldInstructionExtension with the date. * The criticality is set to false. * * @param critical true if the extension is to be treated as critical. * @param code the value to be set for the extension. */ public HoldInstructionExtension(Boolean critical, int code) throws IOException { if (code < 1 || code > 3) throw new IOException("Invalid hold instruction code"); holdInstructionCodeOID = holdInstructionCodeOIDs[code - 1]; this.extensionId = PKIXExtensions.HoldInstructionCode_Id; this.critical = critical.booleanValue(); encodeThis(); } /** * Create a HoldInstructionExtension with the date. * The criticality is set to false. * * @param critical true if the extension is to be treated as critical. * @param oidStr the value to be set for the extension. */ public HoldInstructionExtension(Boolean critical, String oidStr) throws IOException { ObjectIdentifier oid = new ObjectIdentifier(oidStr); if (oid == null || getHoldInstructionCodeFromOID(oid) == 0) throw new IOException("Invalid hold instruction code"); holdInstructionCodeOID = oid; this.extensionId = PKIXExtensions.HoldInstructionCode_Id; this.critical = critical.booleanValue(); encodeThis(); } /** * Create a HoldInstructionExtension with the date. * The criticality is set to false. * * @param critical true if the extension is to be treated as critical. * @param oid the value to be set for the extension. */ public HoldInstructionExtension(Boolean critical, ObjectIdentifier oid) throws IOException { if (getHoldInstructionCodeFromOID(oid) == 0) throw new IOException("Invalid hold instruction code"); holdInstructionCodeOID = oid; this.extensionId = PKIXExtensions.HoldInstructionCode_Id; this.critical = critical.booleanValue(); encodeThis(); } /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public HoldInstructionExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.HoldInstructionCode_Id; this.critical = critical.booleanValue(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; DerValue val = new DerValue(extValue); if (val.tag == DerValue.tag_ObjectId) { DerInputStream derInputStream = new DerInputStream(val.toByteArray()); holdInstructionCodeOID = derInputStream.getOID(); if (getHoldInstructionCodeFromOID(holdInstructionCodeOID) == 0) throw new IOException("Invalid encoding for HoldInstructionExtension"); } else { throw new IOException("Invalid encoding for HoldInstructionExtension"); } } /** * Get the hold instruction code. */ public ObjectIdentifier getHoldInstructionCode() { return holdInstructionCodeOID; } public String getHoldInstructionCodeDescription() { return getHoldInstructionDescription(holdInstructionCodeOID); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (name.equalsIgnoreCase(HOLD_INSTRUCTION)) { if (!(obj instanceof ObjectIdentifier)) { throw new IOException("Attribute must be of type String."); } holdInstructionCodeOID = (ObjectIdentifier) obj; } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:HoldInstructionCode."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(HOLD_INSTRUCTION)) { return holdInstructionCodeOID; } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:HoldInstructionCode."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(HOLD_INSTRUCTION)) { holdInstructionCodeOID = null; } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:HoldInstructionCode."); } } /** * Returns a printable representation of the HoldInstructionExtension. */ public String toString() { String s = super.toString() + "Hold Instruction Code: " + getHoldInstructionDescription(holdInstructionCodeOID) + "\n"; return (s); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { this.extensionId = PKIXExtensions.HoldInstructionCode_Id; this.critical = true; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(HOLD_INSTRUCTION); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/IA5StringConverter.java000066400000000000000000000103171362106420000260320ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetEncoder; import org.mozilla.jss.netscape.security.util.ASN1CharStrConvMap; import org.mozilla.jss.netscape.security.util.DerValue; /** * A AVAValueConverter that converts a IA5String attribute to a DerValue * and vice versa. An example an attribute that is a IA5String string is "E". * * @see AVAValueConverter * * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc. */ public class IA5StringConverter implements AVAValueConverter { // public constructors /* * Contructs a IA5String Converter. */ public IA5StringConverter() { } /* * Converts a string with ASN.1 IA5String characters to a DerValue. * * @param valueString a string with IA5String characters. * * @return a DerValue. * * @exception IOException if a IA5String encoder is not * available for the conversion. */ public DerValue getValue(String valueString) throws IOException { return getValue(valueString, null); } public DerValue getValue(String valueString, byte[] tags) throws IOException { try { CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(DerValue.tag_IA5String); if (encoder == null) throw new IOException("No encoder for IA5String"); CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray()); ByteBuffer byteBuffer = encoder.encode(charBuffer); return new DerValue(DerValue.tag_IA5String, byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit()); } catch (CharacterCodingException e) { throw new IllegalArgumentException("Invalid IA5String AVA Value string"); } } /* * Converts a BER encoded value of IA5String to a DER encoded value. * Checks if the BER encoded value is a IA5String. * NOTE only DER encoding is currently supported on for the BER * encoded value. * * @param berStream a byte array of the BER encoded value. * * @return a DerValue. * * @exception IOException if the BER value cannot be converted * to a IA5String DER value. */ public DerValue getValue(byte[] berStream) throws IOException { DerValue value = new DerValue(berStream); if (value.tag == DerValue.tag_IA5String) return value; if (value.tag == DerValue.tag_PrintableString) return value; throw new IOException("Invalid IA5String AVA Value."); } /* * Converts a DerValue of IA5String to a java string with IA5String * characters. * * @param avaValue a DerValue. * * @return a string with IA5String characters. * * @exception IOException if the DerValue is not a IA5String i.e. * The DerValue cannot be converted to a string * with IA5String characters. */ public String getAsString(DerValue avaValue) throws IOException { if (avaValue.tag == DerValue.tag_IA5String) return avaValue.getIA5String(); if (avaValue.tag == DerValue.tag_PrintableString) return avaValue.getPrintableString(); throw new IOException("Invalid IA5String AVA Value."); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/IPAddressName.java000066400000000000000000000227111362106420000250150ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.nio.ByteBuffer; import java.util.StringTokenizer; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class implements the IPAddressName as required by the GeneralNames * ASN.1 object. * * @see GeneralName * @see GeneralNameInterface * @see GeneralNames * * @version 1.2 * * @author Amit Kapoor * @author Hemma Prafullchandra */ public class IPAddressName implements GeneralNameInterface { /** * */ private static final long serialVersionUID = -4240184399679453666L; private byte[] address; /** * Create the IPAddressName object from the passed encoded Der value. * * @param derValue the encoded DER IPAddressName. * @exception IOException on error. */ public IPAddressName(DerValue derValue) throws IOException { address = derValue.getOctetString(); } /** * Create the IPAddressName object with the specified name. * * @param address the IPAddressName. */ public IPAddressName(byte[] address) { this.address = address; } protected static final char IPv4_LEN = 4; protected static final char IPv6_LEN = 16; /** * Create the IPAddressName object with a string representing the * ip address and a string representing the netmask, with encoding * having ip address encoding followed by the netmask encoding. * This form is needed for name constraints extension. * * @param s the ip address in the format: n.n.n.n or x:x:x:x:x:x:x:x (RFC 1884) * @param netmask the netmask address in the format: n.n.n.n or x:x:x:x:x:x:x:x (RFC 1884) */ public IPAddressName(String s, String netmask) { address = parseAddress(true, s); if (address.length == IPv4_LEN * 2) fillIPv4Address(netmask, address, address.length / 2); else fillIPv6Address(netmask, address, address.length / 2); } /** * IP address with CIDR netmask * * @param s a single IPv4 or IPv6 address * @param mask a CIDR netmask */ public IPAddressName(String s, CIDRNetmask mask) { address = parseAddress(true, s); mask.write(ByteBuffer.wrap( address, address.length / 2, address.length / 2)); } /** * Create the IPAddressName object with a string representing the * ip address. * * @param s the ip address in the format: n.n.n.n or x:x:x:x:x:x:x:x */ public IPAddressName(String s) { address = parseAddress(false, s); } /** * Initialise and return a byte[] and write the IP address into it. * If withNetmask == true, the byte[] will be double the size, * with the latter half uninitialised. * * @return byte[] of length 4 or 16 if withNetmask == false, * or length 8 or 32 if withNetmask == true. */ private static byte[] parseAddress(boolean withNetmask, String s) { if (s.indexOf(':') != -1) { byte[] address = new byte[IPv6_LEN * (withNetmask ? 2 : 1)]; fillIPv6Address(s, address, 0); return address; } else { byte[] address = new byte[IPv4_LEN * (withNetmask ? 2 : 1)]; fillIPv4Address(s, address, 0); return address; } } /** * Return the type of the GeneralName. */ public int getType() { return (GeneralNameInterface.NAME_IP); } @Override public boolean validSingle() { return address.length == IPv4_LEN || address.length == IPv6_LEN; } @Override public boolean validSubtree() { return address.length == 2*IPv4_LEN || address.length == 2*IPv6_LEN; } /** * Encode the IPAddress name into the DerOutputStream. * * @param out the DER stream to encode the IPAddressName to. * @exception IOException on encoding errors. */ public void encode(DerOutputStream out) throws IOException { out.putOctetString(address); } /** * Return a printable string of IPaddress */ public String toString() { StringBuilder r = new StringBuilder("IPAddress: "); ByteBuffer buf = ByteBuffer.wrap(address); if (address.length == IPv4_LEN) { writeIPv4(r, buf); } else if (address.length == IPv4_LEN * 2) { writeIPv4(r, buf); r.append(","); writeIPv4(r, buf); } else if (address.length == IPv6_LEN) { writeIPv6(r, buf); } else if (address.length == IPv6_LEN * 2) { writeIPv6(r, buf); r.append(","); writeIPv6(r, buf); } else { // shouldn't be possible r.append("0.0.0.0"); } return r.toString(); } private static void writeIPv4(StringBuilder r, ByteBuffer buf) { for (int i = 0; i < 4; i++) { if (i > 0) r.append("."); r.append(buf.get() & 0xff); } } private static void writeIPv6(StringBuilder r, ByteBuffer buf) { for (int i = 0; i < 8; i++) { if (i > 0) r.append(":"); r.append(Integer.toHexString(read16BitInt(buf))); } } /** * Read big-endian 16-bit int from buffer (advancing cursor) */ private static int read16BitInt(ByteBuffer buf) { return ((buf.get() & 0xff) << 8) + (buf.get() & 0xff); } /** * Gets an IP v4 address in the form n.n.n.n. */ public static int fillIPv4Address(String s, byte[] address, int start) { StringTokenizer st = new StringTokenizer(s, "."); int nt = st.countTokens(); if (nt != IPv4_LEN) throw new InvalidIPAddressException(s); try { int end = start + nt; for (int i = start; i < end; i++) { Integer j = new Integer(Integer.valueOf(st.nextToken())); address[i] = (byte) j.intValue(); } } catch (NumberFormatException e) { throw new InvalidIPAddressException(s); } return nt; } /** * Gets an IP address in the forms as defined in RFC1884:
*

    *
  • x:x:x:x:x:x:x:x *
  • ...::xxx (using :: shorthand) *
  • ...:n.n.n.n (with n.n.n.n at the end) *
*/ public static int fillIPv6Address(String s, byte[] address, int start) { int lastcolon = -2; int end = start + 16; int idx = start; for (int i = start; i < address.length; i++) address[i] = 0; if (s.indexOf('.') != -1) { // has n.n.n.n at the end lastcolon = s.lastIndexOf(':'); if (lastcolon == -1) throw new InvalidIPAddressException(s); end -= 4; fillIPv4Address(s.substring(lastcolon + 1), address, end); } try { String s1 = s; if (lastcolon != -2) s1 = s.substring(0, lastcolon + 1); int lastDoubleColon = s1.indexOf("::"); String l = s1, r = null; StringTokenizer lt = null, rt = null; if (lastDoubleColon != -1) { l = s1.substring(0, lastDoubleColon); r = s1.substring(lastDoubleColon + 2); if (l.length() == 0) l = null; if (r.length() == 0) r = null; } int at = 0; if (l != null) { lt = new StringTokenizer(l, ":", false); at += lt.countTokens(); } if (r != null) { rt = new StringTokenizer(r, ":", false); at += rt.countTokens(); } if (at > 8 || (lastcolon != -2 && (at > 6 || (lastDoubleColon == -1 && at != 6)))) throw new InvalidIPAddressException(s); if (l != null) { while (lt.hasMoreTokens()) { String tok = lt.nextToken(); int j = Integer.parseInt(tok, 16); address[idx++] = (byte) ((j >> 8) & 0xFF); address[idx++] = (byte) (j & 0xFF); } } if (r != null) { idx = end - (rt.countTokens() * 2); while (rt.hasMoreTokens()) { String tok = rt.nextToken(); int j = Integer.parseInt(tok, 16); address[idx++] = (byte) ((j >> 8) & 0xFF); address[idx++] = (byte) (j & 0xFF); } } } catch (NumberFormatException e) { throw new InvalidIPAddressException(s); } return 16; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/InvalidIPAddressException.java000066400000000000000000000027661362106420000274120ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; public class InvalidIPAddressException extends RuntimeException { /** * */ private static final long serialVersionUID = -1601934234587845028L; public InvalidIPAddressException() { super(); } public InvalidIPAddressException(String ip) { super("Invalid IP Address '" + ip + "'"); } public InvalidIPAddressException(String ip, Throwable cause) { super("Invalid IP Address '" + ip + "'", cause); } public InvalidIPAddressException(String ip, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super("Invalid IP Address '" + ip + "'", cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/InvalidNetmaskException.java000066400000000000000000000025431362106420000271670ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2018 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; public class InvalidNetmaskException extends RuntimeException { public InvalidNetmaskException(String netmask) { super("Invalid netmask (" + netmask + ")"); } public InvalidNetmaskException(String netmask, Throwable cause) { super("Invalid netmask (" + netmask + ")", cause); } public InvalidNetmaskException(String netmask, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super("Invalid netmask (" + netmask + ")", cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/InvalidityDateExtension.java000066400000000000000000000173051362106420000272100ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.security.cert.CertificateException; import java.util.Date; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the CRL Invalidity Date Extension. * *

* This CRL entry extension, if present, provides the date on which it is known or suspected that the private key was * compromised or that the certificate otherwise became invalid. Invalidity date may be earlier than the revocation * date. * * @see Extension * @see CertAttrSet */ public class InvalidityDateExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 2191026017389643053L; /** * Attribute name. */ public static final String NAME = "InvalidityDate"; public static final String INVALIDITY_DATE = "value"; /** * The Object Identifier for this extension. */ public static final String OID = "2.5.29.24"; private Date invalidityDate = null; static { try { OIDMap.addAttribute(InvalidityDateExtension.class.getName(), OID, NAME); } catch (CertificateException e) { } } // Encode this extension value private void encodeThis() throws IOException { if (invalidityDate == null) throw new IOException("Unintialized invalidity date extension"); try (DerOutputStream os = new DerOutputStream()) { os.putGeneralizedTime(this.invalidityDate); this.extensionValue = os.toByteArray(); } } /** * Create a InvalidityDateExtension with the date. * The criticality is set to false. * * @param dateOfInvalidity the value to be set for the extension. */ public InvalidityDateExtension(Date dateOfInvalidity) throws IOException { this.invalidityDate = dateOfInvalidity; this.extensionId = PKIXExtensions.InvalidityDate_Id; this.critical = false; encodeThis(); } /** * Create a InvalidityDateExtension with the date. * The criticality is set to false. * * @param critical true if the extension is to be treated as critical. * @param dateOfInvalidity the value to be set for the extension. */ public InvalidityDateExtension(Boolean critical, Date dateOfInvalidity) throws IOException { this.invalidityDate = dateOfInvalidity; this.extensionId = PKIXExtensions.InvalidityDate_Id; this.critical = critical.booleanValue(); encodeThis(); } /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public InvalidityDateExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.InvalidityDate_Id; this.critical = critical.booleanValue(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; DerValue val = new DerValue(extValue); if (val.tag == DerValue.tag_GeneralizedTime) { DerInputStream derInputStream = new DerInputStream(val.toByteArray()); this.invalidityDate = derInputStream.getGeneralizedTime(); } else { throw new IOException("Invalid encoding for InvalidityDateExtension"); } } /** * Get the invalidity date. */ public Date getInvalidityDate() { return invalidityDate; } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (name.equalsIgnoreCase(INVALIDITY_DATE)) { if (!(obj instanceof Date)) { throw new IOException("Attribute must be of type Date."); } invalidityDate = (Date) obj; } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:InvalidityDate."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(INVALIDITY_DATE)) { if (invalidityDate == null) return null; else return invalidityDate; } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:InvalidityDate."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(INVALIDITY_DATE)) { invalidityDate = null; } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:InvalidityDate."); } } /** * Returns a printable representation of the InvalidityDateExtension. */ public String toString() { String s = super.toString() + "Invalidity Date: " + ((invalidityDate == null) ? "" : invalidityDate.toString()) + "\n"; return (s); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { this.extensionId = PKIXExtensions.InvalidityDate_Id; this.critical = true; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(INVALIDITY_DATE); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/IssuerAlternativeNameExtension.java000066400000000000000000000171001362106420000305410ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This represents the Issuer Alternative Name Extension. * * This extension, if present, allows the issuer to specify multiple * alternative names. * *

* Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding * of the extension value). * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.7 * @see Extension * @see CertAttrSet */ public class IssuerAlternativeNameExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -269518027483586255L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.IssuerAlternativeName"; /** * Attribute names. */ public static final String NAME = "IssuerAlternativeName"; public static final String ISSUER_NAME = "issuer_name"; // private data members GeneralNames names; // Encode this extension private void encodeThis() throws IOException { DerOutputStream os = new DerOutputStream(); try { names.encode(os); } catch (GeneralNamesException e) { throw new IOException(e); } this.extensionValue = os.toByteArray(); } /** * Create a IssuerAlternativeNameExtension with the passed GeneralNames. * * @param critical true if the extension is to be treated as critical. * @param names the GeneralNames for the issuer. * @exception IOException on error. */ public IssuerAlternativeNameExtension(Boolean critical, GeneralNames names) throws IOException { this.names = names; this.extensionId = PKIXExtensions.IssuerAlternativeName_Id; this.critical = critical.booleanValue(); encodeThis(); } /** * Create a IssuerAlternativeNameExtension with the passed GeneralNames. * * @param names the GeneralNames for the issuer. * @exception IOException on error. */ public IssuerAlternativeNameExtension(GeneralNames names) throws IOException { this.names = names; this.extensionId = PKIXExtensions.IssuerAlternativeName_Id; this.critical = false; encodeThis(); } /** * Create a default IssuerAlternativeNameExtension. */ public IssuerAlternativeNameExtension() { extensionId = PKIXExtensions.IssuerAlternativeName_Id; critical = false; names = new GeneralNames(); } /** * Create the extension from the passed DER encoded value. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public IssuerAlternativeNameExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.IssuerAlternativeName_Id; this.critical = critical.booleanValue(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; DerValue val = new DerValue(extValue); try { names = new GeneralNames(val); } catch (GeneralNamesException e) { throw new IOException("IssuerAlternativeNameExtension: " + e, e); } } /** * Returns a printable representation of the IssuerAlternativeName. */ public String toString() { if (names == null) return ""; String s = super.toString() + "IssuerAlternativeName [\n" + names.toString() + "]\n"; return (s); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the OutputStream. * * @param out the OutputStream to write the extension to. * @exception IOException on encoding error. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.IssuerAlternativeName_Id; critical = false; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { clearValue(); if (name.equalsIgnoreCase(ISSUER_NAME)) { if (!(obj instanceof GeneralNames)) { throw new IOException("Attribute value should be of" + " type GeneralNames."); } names = (GeneralNames) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:IssuerAlternativeName."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(ISSUER_NAME)) { return (names); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:IssuerAlternativeName."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(ISSUER_NAME)) { names = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:IssuerAlternativeName."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(ISSUER_NAME); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/IssuingDistributionPoint.java000066400000000000000000000264611362106420000274370ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import org.mozilla.jss.netscape.security.util.BitArray; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BOOLEAN; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** *

 * issuingDistributionPoint ::= SEQUENCE {
 *         distributionPoint       [0] DistributionPointName OPTIONAL,
 *         onlyContainsUserCerts   [1] BOOLEAN DEFAULT FALSE,
 *         onlyContainsCACerts     [2] BOOLEAN DEFAULT FALSE,
 *         onlySomeReasons         [3] ReasonFlags OPTIONAL,
 *         indirectCRL             [4] BOOLEAN DEFAULT FALSE }
 *
 * DistributionPointName ::= CHOICE {
 *         fullName                [0]     GeneralNames,
 *         nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
 *
 * ReasonFlags ::= BIT STRING {
 *         unused                  (0),
 *         keyCompromise           (1),
 *         cACompromise            (2),
 *         affiliationChanged      (3),
 *         superseded              (4),
 *         cessationOfOperation    (5),
 *         certificateHold         (6) }
 *
 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
 *
 * GeneralName ::= CHOICE {
 *         otherName                       [0]     OtherName,
 *         rfc822Name                      [1]     IA5String,
 *         dNSName                         [2]     IA5String,
 *         x400Address                     [3]     ORAddress,
 *         directoryName                   [4]     Name,
 *         ediPartyName                    [5]     EDIPartyName,
 *         uniformResourceIdentifier       [6]     IA5String,
 *         iPAddress                       [7]     OCTET STRING,
 *         registeredID                    [8]     OBJECT IDENTIFIER}
 *
 * OtherName ::= SEQUENCE {
 *         type-id    OBJECT IDENTIFIER,
 *         value      [0] EXPLICIT ANY DEFINED BY type-id }
 *
 * EDIPartyName ::= SEQUENCE {
 *         nameAssigner            [0]     DirectoryString OPTIONAL,
 *         partyName               [1]     DirectoryString }
 *
 * RelativeDistinguishedName ::=
 *         SET OF AttributeTypeAndValue
 *
 * AttributeTypeAndValue ::= SEQUENCE {
 *         type     AttributeType,
 *         value    AttributeValue }
 *
 * AttributeType ::= OBJECT IDENTIFIER
 *
 * AttributeValue ::= ANY DEFINED BY AttributeType
 * 
* * See the documentation in CRLDistributionPoint for * the DistributionPointName and ReasonFlags ASN.1 types. */ public class IssuingDistributionPoint implements ASN1Value { // at most one of the following two may be specified. One or both can // be null. private GeneralNames fullName = null; private RDN relativeName = null; private boolean onlyContainsUserCerts = false; // DEFAULT FALSE private boolean onlyContainsCACerts = false; // DEFAULT FALSE private BitArray onlySomeReasons = null; // optional, may be null private boolean indirectCRL = false; // DEFAULT FALSE // cache encoding of fullName private ANY fullNameEncoding; /** * Returns the fullName of the DistributionPointName, which may be null. */ public GeneralNames getFullName() { return fullName; } /** * Returns the relativeName of the DistributionPointName, which may be null. */ public RDN getRelativeName() { return relativeName; } /** * Sets the fullName of the DistributionPointName. It may be set to null. * If it is set to a non-null value, relativeName will be * set to null, because at most one of these two attributes * can be specified at a time. * * @exception GeneralNamesException If an error occurs encoding the * name. */ public void setFullName(GeneralNames fullName) throws GeneralNamesException, IOException { this.fullName = fullName; if (fullName != null) { // encode the name to catch any problems with it DerOutputStream derOut = new DerOutputStream(); fullName.encode(derOut); try { ANY raw = new ANY(derOut.toByteArray()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); raw.encodeWithAlternateTag(Tag.get(0), bos); fullNameEncoding = new ANY(bos.toByteArray()); } catch (InvalidBERException e) { // assume this won't happen, since it would imply a bug // in DerOutputStream throw new GeneralNamesException(e.toString()); } this.relativeName = null; } } /** * Sets the relativeName of the DistributionPointName. It may be set to null. * If it is set to a non-null value, fullName will be * set to null, because at most one of these two attributes * can be specified at a time. */ public void setRelativeName(RDN relativeName) { this.relativeName = relativeName; if (relativeName != null) { this.fullName = null; } } public boolean getOnlyContainsUserCerts() { return onlyContainsUserCerts; } public void setOnlyContainsUserCerts(boolean b) { onlyContainsUserCerts = b; } public boolean getOnlyContainsCACerts() { return onlyContainsCACerts; } public void setOnlyContainsCACerts(boolean b) { onlyContainsCACerts = b; } /** * Returns the reason flags for this distribution point. May be null. */ public BitArray getOnlySomeReasons() { return onlySomeReasons; } /** * Sets the reason flags for this distribution point. May be set to null. */ public void setOnlySomeReasons(BitArray reasons) { this.onlySomeReasons = reasons; } public boolean getIndirectCRL() { return indirectCRL; } public void setIndirectCRL(boolean b) { indirectCRL = b; } ///////////////////////////////////////////////////////////// // DER encoding ///////////////////////////////////////////////////////////// private 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(); DerOutputStream derOut; try { // Encodes the DistributionPointName. Because DistributionPointName // is a CHOICE, the [0] tag is forced to be EXPLICIT. if (fullName != null) { EXPLICIT distPoint = new EXPLICIT(Tag.get(0), fullNameEncoding); seq.addElement(distPoint); } else if (relativeName != null) { derOut = new DerOutputStream(); relativeName.encode(derOut); ANY raw = new ANY(derOut.toByteArray()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); raw.encodeWithAlternateTag(Tag.get(1), bos); ANY distPointName = new ANY(bos.toByteArray()); EXPLICIT distPoint = new EXPLICIT(Tag.get(0), distPointName); seq.addElement(distPoint); } if (onlyContainsUserCerts != false) { seq.addElement(Tag.get(1), new BOOLEAN(true)); } if (onlyContainsCACerts != false) { seq.addElement(Tag.get(2), new BOOLEAN(true)); } // Encodes the ReasonFlags. if (onlySomeReasons != null) { derOut = new DerOutputStream(); derOut.putUnalignedBitString(onlySomeReasons); ANY raw = new ANY(derOut.toByteArray()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); raw.encodeWithAlternateTag(Tag.get(3), bos); ANY reasonEncoding = new ANY(bos.toByteArray()); seq.addElement(reasonEncoding); } if (indirectCRL != false) { seq.addElement(Tag.get(4), new BOOLEAN(true)); } seq.encode(implicitTag, ostream); } catch (InvalidBERException e) { // this shouldn't happen unless there is a bug in one of // the Sun encoding classes throw new IOException(e.toString()); } } public static void main(String args[]) { BufferedOutputStream bos = null; try { if (args.length != 1) { System.out.println("Usage: IssuingDistributionPoint "); System.exit(-1); } bos = new BufferedOutputStream( new FileOutputStream(args[0])); SEQUENCE idps = new SEQUENCE(); IssuingDistributionPoint idp = new IssuingDistributionPoint(); X500Name dn = new X500Name("CN=Skovw Wjasldk,E=nicolson@netscape.com" + ",OU=Certificate Server,O=Netscape,C=US"); GeneralNames generalNames = new GeneralNames(); generalNames.addElement(dn); idp.setFullName(generalNames); idps.addElement(idp); idp = new IssuingDistributionPoint(); URIName uri = new URIName("http://www.mycrl.com/go/here"); generalNames = new GeneralNames(); generalNames.addElement(uri); idp.setFullName(generalNames); idp.setOnlyContainsUserCerts(true); idp.setOnlyContainsCACerts(true); idp.setIndirectCRL(true); BitArray ba = new BitArray(5, new byte[] { (byte) 0x28 }); idp.setOnlySomeReasons(ba); idps.addElement(idp); idps.encode(bos); } catch (Exception e) { e.printStackTrace(); } finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/IssuingDistributionPointExtension.java000066400000000000000000000407631362106420000313350ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.CertificateException; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.netscape.security.util.BitArray; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * A critical CRL extension that identifies the CRL distribution point * for a particular CRL * *
 * issuingDistributionPoint ::= SEQUENCE {
 *         distributionPoint       [0] DistributionPointName OPTIONAL,
 *         onlyContainsUserCerts   [1] BOOLEAN DEFAULT FALSE,
 *         onlyContainsCACerts     [2] BOOLEAN DEFAULT FALSE,
 *         onlySomeReasons         [3] ReasonFlags OPTIONAL,
 *         indirectCRL             [4] BOOLEAN DEFAULT FALSE }
 *
 * DistributionPointName ::= CHOICE {
 *         fullName                [0]     GeneralNames,
 *         nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
 *
 * ReasonFlags ::= BIT STRING {
 *         unused                  (0),
 *         keyCompromise           (1),
 *         cACompromise            (2),
 *         affiliationChanged      (3),
 *         superseded              (4),
 *         cessationOfOperation    (5),
 *         certificateHold         (6) }
 *
 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
 *
 * GeneralName ::= CHOICE {
 *         otherName                       [0]     OtherName,
 *         rfc822Name                      [1]     IA5String,
 *         dNSName                         [2]     IA5String,
 *         x400Address                     [3]     ORAddress,
 *         directoryName                   [4]     Name,
 *         ediPartyName                    [5]     EDIPartyName,
 *         uniformResourceIdentifier       [6]     IA5String,
 *         iPAddress                       [7]     OCTET STRING,
 *         registeredID                    [8]     OBJECT IDENTIFIER}
 *
 * OtherName ::= SEQUENCE {
 *         type-id    OBJECT IDENTIFIER,
 *         value      [0] EXPLICIT ANY DEFINED BY type-id }
 *
 * EDIPartyName ::= SEQUENCE {
 *         nameAssigner            [0]     DirectoryString OPTIONAL,
 *         partyName               [1]     DirectoryString }
 *
 * RelativeDistinguishedName ::=
 *         SET OF AttributeTypeAndValue
 *
 * AttributeTypeAndValue ::= SEQUENCE {
 *         type     AttributeType,
 *         value    AttributeValue }
 *
 * AttributeType ::= OBJECT IDENTIFIER
 *
 * AttributeValue ::= ANY DEFINED BY AttributeType
 * 
*/ public class IssuingDistributionPointExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -1281544042375527550L; /** * The Object Identifier for this extension. */ public static final String OID = "2.5.29.28"; /** * Attribute names. */ public static final String NAME = "IssuingDistributionPoint"; public static final String ISSUING_DISTRIBUTION_POINT = "issuing_distribution_point"; // Private data members private IssuingDistributionPoint issuingDistributionPoint = null; // Cached DER-encoding to improve performance. private byte[] cachedEncoding = null; static { try { OIDMap.addAttribute(IssuingDistributionPointExtension.class.getName(), OID, NAME); } catch (CertificateException e) { } } /** * This constructor is very important, since it will be called * by the system. */ public IssuingDistributionPointExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.IssuingDistributionPoint_Id; this.critical = critical.booleanValue(); this.extensionValue = ((byte[]) value).clone(); byte[] extValue = this.extensionValue; issuingDistributionPoint = new IssuingDistributionPoint(); DerValue val = new DerValue(extValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding of IssuingDistributionPoint"); } while (val.data.available() != 0) { DerValue opt = val.data.getDerValue(); if (opt != null) { for (int i = 0; i < 5; i++) { if (opt.isContextSpecific((byte) i)) { if ((i == 0 && opt.isConstructed() && opt.data.available() != 0) || (i != 0 && (!opt.isConstructed()) && opt.data.available() != 0)) { if (i == 0) { DerValue opt1 = opt.data.getDerValue(); if (opt1 != null) { if (opt1.isContextSpecific((byte) 0)) { if (opt1.isConstructed() && opt1.data.available() != 0) { opt1.resetTag(DerValue.tag_Sequence); try { GeneralNames fullName = new GeneralNames(opt1); if (fullName != null) { issuingDistributionPoint.setFullName(fullName); } } catch (GeneralNamesException e) { throw new IOException("Invalid encoding of IssuingDistributionPoint " + e, e); } catch (IOException e) { throw new IOException("Invalid encoding of IssuingDistributionPoint " + e, e); } } else { throw new IOException("Invalid encoding of IssuingDistributionPoint"); } } else if (opt1.isContextSpecific((byte) 1)) { if (opt1.isConstructed() && opt1.data.available() != 0) { opt1.resetTag(DerValue.tag_Set); try { RDN relativeName = new RDN(opt1); if (relativeName != null) { issuingDistributionPoint.setRelativeName(relativeName); } } catch (IOException e) { throw new IOException("Invalid encoding of IssuingDistributionPoint " + e, e); } } else { throw new IOException("Invalid encoding of IssuingDistributionPoint"); } } } } else if (i == 3) { opt.resetTag(DerValue.tag_BitString); try { BitArray reasons = opt.getUnalignedBitString(); if (reasons == null) { throw new IOException("Unable to get the unaligned bit string."); } issuingDistributionPoint.setOnlySomeReasons(reasons); @SuppressWarnings("unused") byte[] a = reasons.toByteArray(); // check for errors } catch (IOException e) { throw new IOException("Invalid encoding of IssuingDistributionPoint " + e, e); } } else { opt.resetTag(DerValue.tag_Boolean); try { boolean b = opt.getBoolean(); if (i == 1) { issuingDistributionPoint.setOnlyContainsUserCerts(b); } else if (i == 2) { issuingDistributionPoint.setOnlyContainsCACerts(b); } else if (i == 4) { issuingDistributionPoint.setIndirectCRL(b); } } catch (IOException e) { throw new IOException("Invalid encoding of IssuingDistributionPoint " + e, e); } } } else { throw new IOException("Invalid encoding of IssuingDistributionPoint"); } } } } else { throw new IOException("Invalid encoding of IssuingDistributionPoint"); } } } /** * Creates a new IssuingDistributionPoint extension, with the given * issuing distribution point as the first element. */ public IssuingDistributionPointExtension(IssuingDistributionPoint idp) { this.extensionId = PKIXExtensions.IssuingDistributionPoint_Id; this.critical = true; issuingDistributionPoint = idp; } /** * Returns the issuing distribution point. */ public IssuingDistributionPoint getIssuingDistributionPoint() { return issuingDistributionPoint; } /** * Sets the criticality of this extension. PKIX dictates that this * extension SHOULD be critical, so applications can make it not critical * if they have a very good reason. By default, the extension is critical. */ public void setCritical(boolean critical) { this.critical = critical; } /** * Gets the criticality of this extension. PKIX dictates that this * extension SHOULD be critical, so by default, the extension is critical. */ public boolean getCritical(boolean critical) { return this.critical; } /** * Encodes this extension to the given DerOutputStream. * This method re-encodes each time it is called, so it is not very * efficient. */ public void encode(DerOutputStream out) throws IOException { extensionValue = ASN1Util.encode(issuingDistributionPoint); super.encode(out); } /** * Should be called if any change is made to this data structure * so that the cached DER encoding can be discarded. */ public void flushCachedEncoding() { cachedEncoding = null; } /** * Returns a printable representation of the IssuingDistributionPointExtension */ @Override public String toString() { return NAME; } /** * DER-encodes this extension to the given OutputStream. */ public void encode(OutputStream ostream) throws CertificateException, IOException { if (cachedEncoding == null) { // only re-encode if necessary DerOutputStream tmp = new DerOutputStream(); encode(tmp); cachedEncoding = tmp.toByteArray(); } ostream.write(cachedEncoding); } public void decode(InputStream in) throws CertificateException, IOException { throw new IOException("Not supported"); } public void set(String name, Object obj) throws CertificateException, IOException { if (name.equalsIgnoreCase(ISSUING_DISTRIBUTION_POINT)) { if (!(obj instanceof IssuingDistributionPoint)) { throw new IOException("Attribute value should be of type IssuingDistributionPoint."); } issuingDistributionPoint = (IssuingDistributionPoint) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:IssuingDistributionPointExtension"); } } public Object get(String name) throws CertificateException, IOException { if (name.equalsIgnoreCase(ISSUING_DISTRIBUTION_POINT)) { return issuingDistributionPoint; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:IssuingDistributionPointExtension"); } } public void delete(String name) throws CertificateException, IOException { if (name.equalsIgnoreCase(ISSUING_DISTRIBUTION_POINT)) { issuingDistributionPoint = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:IssuingDistributionPointExtension"); } } public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(ISSUING_DISTRIBUTION_POINT); return (elements.elements()); // return (new Vector()).elements(); } public String getName() { return NAME; } /** * Test driver. */ public static void main(String args[]) { BufferedOutputStream bos = null; try { if (args.length != 1) { System.out.println("Usage: IssuingDistributionPointExtension " + ""); System.exit(-1); } bos = new BufferedOutputStream( new FileOutputStream(args[0])); // URI only IssuingDistributionPoint idp = new IssuingDistributionPoint(); URIName uri = new URIName("http://www.mycrl.com/go/here"); GeneralNames generalNames = new GeneralNames(); generalNames.addElement(uri); idp.setFullName(generalNames); IssuingDistributionPointExtension idpExt = new IssuingDistributionPointExtension(idp); // DN only idp = new IssuingDistributionPoint(); X500Name dn = new X500Name("CN=Otis Smith,E=otis@fedoraproject.org" + ",OU=Certificate Server,O=Fedora,C=US"); generalNames = new GeneralNames(); generalNames.addElement(dn); idp.setFullName(generalNames); idpExt.set(IssuingDistributionPointExtension.ISSUING_DISTRIBUTION_POINT, idp); // DN + reason BitArray ba = new BitArray(5, new byte[] { (byte) 0x28 }); idp = new IssuingDistributionPoint(); idp.setFullName(generalNames); idp.setOnlySomeReasons(ba); idpExt.set(IssuingDistributionPointExtension.ISSUING_DISTRIBUTION_POINT, idp); // relative DN + reason + crlIssuer idp = new IssuingDistributionPoint(); RDN rdn = new RDN("OU=foobar dept"); idp.setRelativeName(rdn); idp.setOnlySomeReasons(ba); idp.setOnlyContainsCACerts(true); idp.setOnlyContainsUserCerts(true); idp.setIndirectCRL(true); idpExt.set(IssuingDistributionPointExtension.ISSUING_DISTRIBUTION_POINT, idp); idpExt.setCritical(false); idpExt.encode(bos); } catch (Exception e) { e.printStackTrace(); } finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/KeyIdentifier.java000066400000000000000000000051151362106420000251300ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the Key Identifier ASN.1 object. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.4 */ public class KeyIdentifier implements java.io.Serializable { /** * */ private static final long serialVersionUID = 2412286879441154979L; private byte[] octetString; /** * Create a KeyIdentifier with the passed bit settings. * * @param octetString the octet string identifying the key identifier. */ public KeyIdentifier(byte[] octetString) { this.octetString = octetString; } /** * Create a KeyIdentifier from the DER encoded value. * * @param val the DerValue */ public KeyIdentifier(DerValue val) throws IOException { octetString = val.getOctetString(); } /** * Return the value of the KeyIdentifier as byte array. */ public byte[] getIdentifier() { return octetString.clone(); } /** * Returns a printable representation of the KeyUsage. */ public String toString() { org.mozilla.jss.netscape.security.util.PrettyPrintFormat pp = new org.mozilla.jss.netscape.security.util.PrettyPrintFormat(" ", 20); String octetbits = pp.toHexString(octetString); String s = "KeyIdentifier [\n"; s += octetbits; s += "]\n"; return (s); } /** * Write the KeyIdentifier to the DerOutputStream. * * @param out the DerOutputStream to write the object to. * @exception IOException */ void encode(DerOutputStream out) throws IOException { out.putOctetString(octetString); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/KeyUsageExtension.java000066400000000000000000000342461362106420000260160ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.BitArray; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the Key Usage Extension. * *

* This extension, if present, defines the purpose (e.g., encipherment, signature, certificate signing) of the key * contained in the certificate. The usage restriction might be employed when a multipurpose key is to be restricted * (e.g., when an RSA key should be used only for signing or only for key encipherment). * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.9 * @see Extension * @see CertAttrSet */ public class KeyUsageExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 2899719374157256708L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.KeyUsage"; /** * Attribute names. */ public static final String NAME = "KeyUsage"; public static final String DIGITAL_SIGNATURE = "digital_signature"; public static final String NON_REPUDIATION = "non_repudiation"; public static final String KEY_ENCIPHERMENT = "key_encipherment"; public static final String DATA_ENCIPHERMENT = "data_encipherment"; public static final String KEY_AGREEMENT = "key_agreement"; public static final String KEY_CERTSIGN = "key_certsign"; public static final String CRL_SIGN = "crl_sign"; public static final String ENCIPHER_ONLY = "encipher_only"; public static final String DECIPHER_ONLY = "decipher_only"; public static final int DIGITAL_SIGNATURE_BIT = 0; public static final int NON_REPUDIATION_BIT = 1; public static final int KEY_ENCIPHERMENT_BIT = 2; public static final int DATA_ENCIPHERMENT_BIT = 3; public static final int KEY_AGREEMENT_BIT = 4; public static final int KEY_CERTSIGN_BIT = 5; public static final int CRL_SIGN_BIT = 6; public static final int ENCIPHER_ONLY_BIT = 7; public static final int DECIPHER_ONLY_BIT = 8; public static final int NBITS = 9; public static String[] names = new String[NBITS]; static { names[DIGITAL_SIGNATURE_BIT] = DIGITAL_SIGNATURE; names[NON_REPUDIATION_BIT] = NON_REPUDIATION; names[KEY_ENCIPHERMENT_BIT] = KEY_ENCIPHERMENT; names[DATA_ENCIPHERMENT_BIT] = DATA_ENCIPHERMENT; names[KEY_AGREEMENT_BIT] = KEY_AGREEMENT; names[KEY_CERTSIGN_BIT] = KEY_CERTSIGN; names[CRL_SIGN_BIT] = CRL_SIGN; names[ENCIPHER_ONLY_BIT] = ENCIPHER_ONLY; names[DECIPHER_ONLY_BIT] = DECIPHER_ONLY; } // Private data members private boolean[] bitString; // Encode this extension value private void encodeThis() throws IOException { try (DerOutputStream os = new DerOutputStream()) { os.putUnalignedBitString(this.bitString); this.extensionValue = os.toByteArray(); } } /** * Check if bit is set. * * @param position the position in the bit string to check. */ private boolean isSet(int position) { if (bitString.length <= position) return false; return bitString[position]; } /** * Set the bit at the specified position. */ private void set(int position, boolean val) { // enlarge bitString if necessary if (position >= bitString.length) { boolean[] tmp = new boolean[position + 1]; System.arraycopy(bitString, 0, tmp, 0, bitString.length); bitString = tmp; } bitString[position] = val; } /** * Create a KeyUsageExtension with the passed bit settings. The criticality * is set to true. * * @param bitString the bits to be set for the extension. */ public KeyUsageExtension(boolean critical, byte[] bitString) throws IOException { this.bitString = new BitArray(bitString.length * 8, bitString).toBooleanArray(); this.extensionId = PKIXExtensions.KeyUsage_Id; this.critical = critical; encodeThis(); } public KeyUsageExtension(byte[] bitString) throws IOException { this.bitString = new BitArray(bitString.length * 8, bitString).toBooleanArray(); this.extensionId = PKIXExtensions.KeyUsage_Id; this.critical = true; encodeThis(); } /** * Create a KeyUsageExtension with the passed bit settings. The criticality * is set to true. * * @param bitString the bits to be set for the extension. */ public KeyUsageExtension(boolean critical, boolean[] bitString) throws IOException { this.bitString = bitString; this.extensionId = PKIXExtensions.KeyUsage_Id; this.critical = critical; encodeThis(); } public KeyUsageExtension(boolean[] bitString) throws IOException { this.bitString = bitString; this.extensionId = PKIXExtensions.KeyUsage_Id; this.critical = true; encodeThis(); } /** * Create a KeyUsageExtension with the passed bit settings. The criticality * is set to true. * * @param bitString the bits to be set for the extension. */ public KeyUsageExtension(BitArray bitString) throws IOException { this.bitString = bitString.toBooleanArray(); this.extensionId = PKIXExtensions.KeyUsage_Id; this.critical = true; encodeThis(); } /** * Create the extension from the passed DER encoded value of the same. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public KeyUsageExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.KeyUsage_Id; this.critical = critical.booleanValue(); /* * The following check should be activated again after * the PKIX profiling work becomes standard and the check * is not a barrier to interoperability ! * if (!this.critical) { * throw new IOException("KeyUsageExtension not marked critical," * + " invalid profile."); * } */ int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; DerValue val = new DerValue(extValue); BitArray bitArray = val.getUnalignedBitString(); if (bitArray == null) { throw new IOException("Invalid bit string"); } this.bitString = bitArray.toBooleanArray(); } /** * Create a default key usage. */ public KeyUsageExtension() { extensionId = PKIXExtensions.KeyUsage_Id; critical = true; bitString = new boolean[0]; } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { clearValue(); if (!(obj instanceof Boolean)) { throw new IOException("Attribute must be of type Boolean."); } boolean val = ((Boolean) obj).booleanValue(); if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) { set(0, val); } else if (name.equalsIgnoreCase(NON_REPUDIATION)) { set(1, val); } else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) { set(2, val); } else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) { set(3, val); } else if (name.equalsIgnoreCase(KEY_AGREEMENT)) { set(4, val); } else if (name.equalsIgnoreCase(KEY_CERTSIGN)) { set(5, val); } else if (name.equalsIgnoreCase(CRL_SIGN)) { set(6, val); } else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) { set(7, val); } else if (name.equalsIgnoreCase(DECIPHER_ONLY)) { set(8, val); } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:KeyUsage."); } encodeThis(); } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) { return Boolean.valueOf(isSet(0)); } else if (name.equalsIgnoreCase(NON_REPUDIATION)) { return Boolean.valueOf(isSet(1)); } else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) { return Boolean.valueOf(isSet(2)); } else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) { return Boolean.valueOf(isSet(3)); } else if (name.equalsIgnoreCase(KEY_AGREEMENT)) { return Boolean.valueOf(isSet(4)); } else if (name.equalsIgnoreCase(KEY_CERTSIGN)) { return Boolean.valueOf(isSet(5)); } else if (name.equalsIgnoreCase(CRL_SIGN)) { return Boolean.valueOf(isSet(6)); } else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) { return Boolean.valueOf(isSet(7)); } else if (name.equalsIgnoreCase(DECIPHER_ONLY)) { return Boolean.valueOf(isSet(8)); } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:KeyUsage."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) { set(0, false); } else if (name.equalsIgnoreCase(NON_REPUDIATION)) { set(1, false); } else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) { set(2, false); } else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) { set(3, false); } else if (name.equalsIgnoreCase(KEY_AGREEMENT)) { set(4, false); } else if (name.equalsIgnoreCase(KEY_CERTSIGN)) { set(5, false); } else if (name.equalsIgnoreCase(CRL_SIGN)) { set(6, false); } else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) { set(7, false); } else if (name.equalsIgnoreCase(DECIPHER_ONLY)) { set(8, false); } else { throw new IOException("Attribute name not recognized by" + " CertAttrSet:KeyUsage."); } } /** * Returns a printable representation of the KeyUsage. */ public String toString() { String s = super.toString() + "KeyUsage [\n"; try { if (isSet(0)) { s += " DigitalSignature\n"; } if (isSet(1)) { s += " Non_repudiation\n"; } if (isSet(2)) { s += " Key_Encipherment\n"; } if (isSet(3)) { s += " Data_Encipherment\n"; } if (isSet(4)) { s += " Key_Agreement\n"; } if (isSet(5)) { s += " Key_CertSign\n"; } if (isSet(6)) { s += " Crl_Sign\n"; } if (isSet(7)) { s += " Encipher_Only\n"; } if (isSet(8)) { s += " Decipher_Only\n"; } } catch (ArrayIndexOutOfBoundsException ex) { } s += "]\n"; return (s); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { this.extensionId = PKIXExtensions.KeyUsage_Id; this.critical = true; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(DIGITAL_SIGNATURE); elements.addElement(NON_REPUDIATION); elements.addElement(KEY_ENCIPHERMENT); elements.addElement(DATA_ENCIPHERMENT); elements.addElement(KEY_AGREEMENT); elements.addElement(KEY_CERTSIGN); elements.addElement(CRL_SIGN); elements.addElement(ENCIPHER_ONLY); elements.addElement(DECIPHER_ONLY); return (elements.elements()); } public boolean[] getBits() { return bitString.clone(); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/LdapDNStrConverter.java000066400000000000000000000100711362106420000260550ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; /** * Abstract class that converts a Ldap DN String to an X500Name, RDN or AVA * and vice versa, except the string is a java string in unicode. * * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc. */ public abstract class LdapDNStrConverter { // // public parsing methods. // /** * Converts a Ldap DN string to a X500Name object. * * @param dn a Ldap DN String. * * @return an X500Name object for the Ldap DN String. */ public abstract X500Name parseDN(String dn) throws IOException; /** * Like parseDN with a specified DER encoding order for Directory Strings. */ public abstract X500Name parseDN(String dn, byte[] tags) throws IOException; /** * Converts a Ldap DN string to a RDN object. * * @param rdn a Ldap DN String * * @return an RDN object. */ public abstract RDN parseRDN(String rdn) throws IOException; /** * Like parseRDN with a specified DER encoding order for Directory Strings. */ public abstract RDN parseRDN(String rdn, byte[] tags) throws IOException; /** * Converts a Ldap DN string to a AVA object. * * @param ava a Ldap DN string. * @return an AVA object. */ public abstract AVA parseAVA(String ava) throws IOException; /** * Like parseAVA with a specified DER encoding order for Directory Strings. */ public abstract AVA parseAVA(String rdn, byte[] tags) throws IOException; // // public encoding methods. // /** * Converts a X500Name object to a Ldap dn string. * * @param dn an X500Name object. * @return a Ldap DN String. */ public abstract String encodeDN(X500Name dn) throws IOException; /** * Converts an RDN object to a Ldap dn string. * * @param rdn an RDN object. * @return a Ldap dn string. */ public abstract String encodeRDN(RDN rdn) throws IOException; /** * Converts an AVA object to a Ldap dn string. * * @param ava An AVA object. * @return A Ldap dn string. */ public abstract String encodeAVA(AVA ava) throws IOException; // // public static methods // /** * Gets a global default Ldap DN String converter. * Currently it is LdapV3DNStrConverter object using the default * X500NameAttrMap and accepts unknown OIDs. * * @see LdapV3DNStrConverter * * @return The global default LdapDNStrConverter instance. */ public static LdapDNStrConverter getDefault() { return defaultConverter; } /** * Set the global default LdapDNStrConverter object. * * @param defConverter A LdapDNStrConverter object to become * the global default. */ public static void setDefault(LdapDNStrConverter defConverter) { if (defConverter == null) throw new IllegalArgumentException( "The default Ldap DN String converter cannot be set to null."); defaultConverter = defConverter; } // // private static variables // private static LdapDNStrConverter defaultConverter = new LdapV3DNStrConverter(); } jss-4.6.3/org/mozilla/jss/netscape/security/x509/LdapV3DNStrConverter.java000066400000000000000000000665261362106420000263060ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.ByteArrayOutputStream; import java.io.CharArrayWriter; import java.io.IOException; import java.io.PushbackReader; import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.UnsupportedCharsetException; import java.util.Arrays; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * A converter that converts Ldap v3 DN strings as specified in * draft-ietf-asid-ldapv3-dn-03.txt to a X500Name, RDN or AVA and * vice versa. * * @see LdapDNStrConverter * @see X500Name * @see RDN * @see AVA * @see X500NameAttrMap * * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc. */ public class LdapV3DNStrConverter extends LdapDNStrConverter { // // Constructors // /** * Constructs a LdapV3DNStrConverter using the global default * X500NameAttrMap and accept OIDs not in the default X500NameAttrMap. * * @see X500NameAttrMap */ public LdapV3DNStrConverter() { attrMap = X500NameAttrMap.getDefault(); acceptUnknownOids = true; } /** * Constructs a LdapV3DNStrConverter using the specified X500NameAttrMap * and a boolean indicating whether to accept OIDs not listed in the * X500NameAttrMap. * * @param attributeMap a X500NameAttrMap * @param doAcceptUnknownOids whether to convert unregistered OIDs * (oids not in the X500NameAttrMap) * @see X500NameAttrMap */ public LdapV3DNStrConverter(X500NameAttrMap attributeMap, boolean doAcceptUnknownOids) { attrMap = attributeMap; acceptUnknownOids = doAcceptUnknownOids; } // // public parsing methods // From LdapDNStrConverter interface // /** * Parse a Ldap v3 DN string to a X500Name. * * @param dn a LDAP v3 DN String * @return a X500Name * @exception IOException if an error occurs during the conversion. */ public X500Name parseDN(String dn) throws IOException { return parseDN(dn, null); } /** * Like parseDN(String) with a DER encoding order given as argument for * Directory Strings. */ public X500Name parseDN(String dn, byte[] encodingOrder) throws IOException { StringReader dn_reader = new StringReader(dn); PushbackReader in = new PushbackReader(dn_reader, 5); return parseDN(in, encodingOrder); } /** * Parse a Ldap v3 DN string with a RDN component to a RDN * * @param rdn a LDAP v3 DN String * @return a RDN * @exception IOException if an error occurs during the conversion. */ public RDN parseRDN(String rdn) throws IOException { return parseRDN(rdn, null); } /** * Like parseRDN(String) with a DER encoding order given as argument for * Directory Strings. */ public RDN parseRDN(String rdn, byte[] encodingOrder) throws IOException { StringReader rdn_reader = new StringReader(rdn); PushbackReader in = new PushbackReader(rdn_reader, 5); return parseRDN(in, null); } /** * Parse a Ldap v3 DN string with a AVA component to a AVA. * * @param ava a LDAP v3 DN string * @return a AVA */ public AVA parseAVA(String ava) throws IOException { return parseAVA(ava, null); } /** * Like parseDN(String) with a DER encoding order given as argument for * Directory Strings. */ public AVA parseAVA(String ava, byte[] encodingOrder) throws IOException { StringReader ava_reader = new StringReader(ava); PushbackReader in = new PushbackReader(ava_reader, 5); return parseAVA(in, encodingOrder); } // // public parsing methods called by other methods. // /** * Parses a Ldap DN string in a string reader to a X500Name. * * @param in Pushback string reader for a Ldap DN string. * The pushback reader must have a pushback buffer * {@literal size > 2}. * * @return a X500Name * * @exception IOException if any reading or parsing error occurs. */ public X500Name parseDN(PushbackReader in) throws IOException { return parseDN(in, null); } /** * Like parseDN(PushbackReader in) with a DER encoding order given as * argument for Directory Strings. */ public X500Name parseDN(PushbackReader in, byte[] encodingOrder) throws IOException { RDN rdn; int lastChar; Vector rdnVector = new Vector(); RDN names[]; int i, j; do { rdn = parseRDN(in, encodingOrder); rdnVector.addElement(rdn); lastChar = in.read(); } while (lastChar == ',' || lastChar == ';'); names = new RDN[rdnVector.size()]; for (i = 0, j = rdnVector.size() - 1; i < rdnVector.size(); i++, j--) names[j] = rdnVector.elementAt(i); return new X500Name(names); } /** * Parses Ldap DN string with a rdn component * from a string reader to a RDN. The string reader will point * to the separator after the rdn component or -1 if at end of string. * * @param in Pushback string reader containing a Ldap DN string with * at least one rdn component. * The pushback reader must have a pushback buffer * {@literal size > 2}. * * @return RDN object of the first rdn component in the Ldap DN string. * * @exception IOException if any read or parse error occurs. */ public RDN parseRDN(PushbackReader in) throws IOException { return parseRDN(in, null); } /** * Like parseRDN(PushbackReader) with a DER encoding order given as * argument for Directory Strings. */ public RDN parseRDN(PushbackReader in, byte[] encodingOrder) throws IOException { Vector avaVector = new Vector(); AVA ava; int lastChar; AVA assertion[]; do { ava = parseAVA(in, encodingOrder); avaVector.addElement(ava); lastChar = in.read(); } while (lastChar == '+'); if (lastChar != -1) in.unread(lastChar); assertion = new AVA[avaVector.size()]; for (int i = 0; i < avaVector.size(); i++) assertion[i] = avaVector.elementAt(i); return new RDN(assertion); } /** * Parses a Ldap DN string with a AVA component * from a string reader to an AVA. The string reader will point * to the AVA separator after the ava string or -1 if end of string. * * @param in a Pushback reader containg a Ldap string with * at least one AVA component. * The Pushback reader must have a pushback buffer * {@literal size > 2}. * * @return AVA object of the first AVA component in the Ldap DN string. */ public AVA parseAVA(PushbackReader in) throws IOException { return parseAVA(in, null); } /** * Like parseAVA(PushbackReader) with a DER encoding order given as * argument for Directory Strings. */ public AVA parseAVA(PushbackReader in, byte[] encodingOrder) throws IOException { int c; ObjectIdentifier oid; DerValue value; StringBuffer keywordBuf; StringBuffer valueBuf; ByteArrayOutputStream berStream; char hexChar1, hexChar2; CharArrayWriter hexCharsBuf; String endChars; /* First get the keyword indicating the attribute's type, * and map it to the appropriate OID. */ keywordBuf = new StringBuffer(); for (;;) { c = in.read(); if (c == '=') break; if (c == -1) { throw new IOException("Bad AVA format: Missing '='"); } keywordBuf.append((char) c); } oid = parseAVAKeyword(keywordBuf.toString()); /* Now parse the value. "#hex", a quoted string, or a string * terminated by "+", ",", ";", ">". Whitespace before or after * the value is stripped. */ for (c = in.read(); c == ' '; c = in.read()) continue; if (c == -1) throw new IOException("Bad AVA format: Missing attribute value"); if (c == '#') { /* * NOTE per LDAPv3 dn string ietf standard the value represented * by this form is a BER value. But we only support DER value here * which is only a form of BER. */ berStream = new ByteArrayOutputStream(); int b; for (;;) { hexChar1 = (char) (c = in.read()); if (c == -1 || octoEndChars.indexOf(c) > 0) // end of value break; hexChar2 = (char) (c = in.read()); if (hexDigits.indexOf(hexChar1) == -1 || hexDigits.indexOf(hexChar2) == -1) throw new IOException("Bad AVA value: bad hex value."); b = (Character.digit(hexChar1, 16) << 4) + Character.digit(hexChar2, 16); berStream.write(b); } if (berStream.size() == 0) throw new IOException("bad AVA format: invalid hex value"); value = parseAVAValue(berStream.toByteArray(), oid); while (c == ' ' && c != -1) c = in.read(); } else { valueBuf = new StringBuffer(); boolean quoted = false; if (c == '"') { quoted = true; endChars = quotedEndChars; if ((c = in.read()) == -1) throw new IOException("Bad AVA format: Missing attrValue"); } else { endChars = valueEndChars; } // QUOTATION * ( quotechar / pair ) QUOTATION // quotechar = any character except '\' or QUOTATION // pair = '\' ( special | '\' | QUOTATION | hexpair ) while (c != -1 && endChars.indexOf(c) == -1) { if (c == '\\') { if ((c = in.read()) == -1) throw new IOException("Bad AVA format: expecting " + "escaped char."); // expect escaping of special chars, space and CR. if (specialChars.indexOf((char) c) != -1 || c == '\n' || c == '\\' || c == '"' || c == ' ') { valueBuf.append((char) c); } else if (hexDigits.indexOf(c) != -1) { hexCharsBuf = new CharArrayWriter(); // handle sequence of '\' hexpair do { hexChar1 = (char) c; hexChar2 = (char) (c = in.read()); if (hexDigits.indexOf((char) c) == -1) throw new IOException("Bad AVA format: " + "invalid escaped hex pair"); hexCharsBuf.write(hexChar1); hexCharsBuf.write(hexChar2); // read ahead to next '\' hex-char if any. if ((c = in.read()) == -1) break; if (c != '\\') { in.unread(c); break; } if ((c = in.read()) == -1) throw new IOException("Bad AVA format: " + "expecting escaped char."); if (hexDigits.indexOf((char) c) == -1) { in.unread(c); in.unread('\\'); break; } } while (true); valueBuf.append( getStringFromHexpairs(hexCharsBuf.toCharArray())); } else { throw new IOException("Bad AVA format: " + "invalid escaping"); } } else valueBuf.append((char) c); c = in.read(); } value = parseAVAValue( valueBuf.toString().trim(), oid, encodingOrder); if (quoted) { // move to next non-white space do { c = in.read(); } while (c == ' '); if (c != -1 && valueEndChars.indexOf(c) == -1) throw new IOException( "Bad AVA format: separator expected at end of ava."); } } if (c != -1) in.unread(c); return new AVA(oid, value); } /** * Converts a AVA keyword from a Ldap DN string to an ObjectIdentifier * from the attribute map or, if this keyword is an OID not * in the attribute map, create a new ObjectIdentifier for the keyword * if acceptUnknownOids is true. * * @param avaKeyword AVA keyword from a Ldap DN string. * * @return a ObjectIdentifier object * @exception IOException if the keyword is an OID not in the attribute * map and acceptUnknownOids is false, or * if an error occurs during conversion. */ public ObjectIdentifier parseAVAKeyword(String avaKeyword) throws IOException { String keyword = avaKeyword.toUpperCase().trim(); String oid_str = null; ObjectIdentifier oid, new_oid; if (Character.digit(keyword.charAt(0), 10) != -1) { // value is an oid string of 1.2.3.4 oid_str = keyword; } else if (keyword.startsWith("oid.") || keyword.startsWith("OID.")) { // value is an oid string of oid.1.2.3.4 or OID.1.2... oid_str = keyword.substring(4); } if (oid_str != null) { // value is an oid string of 1.2.3.4 or oid.1.2.3.4 or OID.1.2... new_oid = new ObjectIdentifier(oid_str); oid = attrMap.getOid(new_oid); if (oid == null) { if (!acceptUnknownOids) throw new IOException("Unknown AVA OID."); oid = new_oid; } } else { oid = attrMap.getOid(keyword); if (oid == null) throw new IOException("Unknown AVA keyword '" + keyword + "'."); } return oid; } /** * Converts a AVA value from a Ldap dn string to a * DerValue according the attribute type. For example, a value for * CN, OU or O is expected to be a Directory String and will be converted * to a DerValue of ASN.1 type PrintableString, T61String or * UniversalString. A Directory String is a ASN.1 CHOICE of Printable, * T.61 or Universal string. * * @param avaValueString a attribute value from a Ldap DN string. * @param oid OID of the attribute. * * @return DerValue for the value. * * @exception IOException if an error occurs during conversion. * @see AVAValueConverter */ public DerValue parseAVAValue(String avaValueString, ObjectIdentifier oid) throws IOException { return parseAVAValue(avaValueString, oid, null); } /** * Like parseAVAValue(String) with a DER encoding order given as argument * for Directory Strings. */ public DerValue parseAVAValue( String avaValueString, ObjectIdentifier oid, byte[] encodingOrder) throws IOException { AVAValueConverter valueConverter = attrMap.getValueConverter(oid); if (valueConverter == null) { if (!acceptUnknownOids) { throw new IllegalArgumentException( "Unrecognized OID for AVA value conversion"); } else { valueConverter = new GenericValueConverter(); } } return valueConverter.getValue(avaValueString, encodingOrder); } /** * Converts a value in BER encoding, for example given in octothorpe form * in a Ldap v3 dn string, to a DerValue. Checks if the BER encoded value * is a legal value for the attribute. *

* NOTE: only DER encoded values are supported for the BER encoded value. * * @param berValue a value in BER encoding * @param oid ObjectIdentifier of the attribute. * * @return DerValue for the BER encoded value * @exception IOException if an error occurs during conversion. */ public DerValue parseAVAValue(byte[] berValue, ObjectIdentifier oid) throws IOException { AVAValueConverter valueConverter = attrMap.getValueConverter(oid); if (valueConverter == null && !acceptUnknownOids) { throw new IllegalArgumentException( "Unrecognized OID for AVA value conversion"); } else { valueConverter = new GenericValueConverter(); } return valueConverter.getValue(berValue); } // // public encoding methods. // /** * Converts a X500Name object to a Ldap v3 DN string (except in unicode). * * @param x500name a X500Name * * @return a Ldap v3 DN String (except in unicode). * * @exception IOException if an error is encountered during conversion. */ public String encodeDN(X500Name x500name) throws IOException { RDN[] rdns = x500name.getNames(); // String fullname = null; StringBuffer fullname = new StringBuffer(); String s; int i; if (rdns.length == 0) return ""; i = rdns.length - 1; fullname.append(encodeRDN(rdns[i--])); while (i >= 0) { s = encodeRDN(rdns[i--]); fullname.append(","); fullname.append(s); } ; return fullname.toString(); } /** * Converts a RDN to a Ldap v3 DN string (except in unicode). * * @param rdn a RDN * * @return a LDAP v3 DN string (except in unicode). * * @exception IOException if an error is encountered during conversion. */ public String encodeRDN(RDN rdn) throws IOException { AVA[] avas = rdn.getAssertion(); // String relname = null; StringBuffer relname = new StringBuffer(); String s; int i = 0; relname.append(encodeAVA(avas[i++])); while (i < avas.length) { s = encodeAVA(avas[i++]); relname.append("+"); relname.append(s); } ; return relname.toString(); } /** * Converts a AVA to a Ldap v3 DN String (except in unicode). * * @param ava an AVA * * @return a Ldap v3 DN string (except in unicode). * * @exception IOException If an error is encountered during exception. */ public String encodeAVA(AVA ava) throws IOException { if (ava == null) { return ""; } ObjectIdentifier oid = ava.getOid(); DerValue value = ava.getValue(); String keyword, valueStr; // get attribute name keyword = encodeOID(oid); valueStr = encodeValue(value, oid); return keyword + "=" + valueStr; } /** * Converts an OID to a attribute keyword in a Ldap v3 DN string * - either a keyword if known or a string of "1.2.3.4" syntax. * * @param oid a ObjectIdentifier * * @return a keyword to use in a Ldap V3 DN string. * * @exception IOException if an error is encountered during conversion. */ public String encodeOID(ObjectIdentifier oid) throws IOException { String keyword = attrMap.getName(oid); if (keyword == null) { if (acceptUnknownOids) keyword = oid.toString(); else throw new IOException("Unknown OID"); } return keyword; } /** * Converts a value as a DerValue to a string in a Ldap V3 DN String. * If the value cannot be converted to a string it will be encoded in * octothorpe form. * * @param attrValue a value as a DerValue. * @param oid OID for the attribute. * @return a string for the value in a LDAP v3 DN String * @exception IOException if an error occurs during conversion. */ public String encodeValue(DerValue attrValue, ObjectIdentifier oid) throws IOException { /* * Construct the value with as little copying and garbage * production as practical. */ StringBuffer retval = new StringBuffer(30); int i; String temp = null; AVAValueConverter valueConverter; X500NameAttrMap lAttrMap = attrMap; if (attrValue.tag == DerValue.tag_UTF8String) { lAttrMap = X500NameAttrMap.getDirDefault(); } valueConverter = lAttrMap.getValueConverter(oid); if (valueConverter == null) { if (acceptUnknownOids) valueConverter = new GenericValueConverter(); else throw new IOException( "Unknown AVA type for encoding AVA value"); } try { temp = valueConverter.getAsString(attrValue); if (temp == null) { // convert to octothorpe form. byte data[] = attrValue.toByteArray(); retval.append('#'); for (i = 0; i < data.length; i++) { retval.append(hexDigits.charAt((data[i] >> 4) & 0x0f)); retval.append(hexDigits.charAt(data[i] & 0x0f)); } } else { retval.append(encodeString(temp)); } } catch (IOException e) { throw new IllegalArgumentException("malformed AVA DER Value"); } return retval.toString(); } /** * converts a raw value string to a string in Ldap V3 DN string format. * * @param valueStr a 'raw' value string. * @return a attribute value string in Ldap V3 DN string format. */ public String encodeString(String valueStr) { int i, j; int len; StringBuffer retval = new StringBuffer(); /* * generate string according to ldapv3 DN. escaping is used. * Strings generated this way are acceptable by rfc1779 * implementations. */ len = valueStr.length(); // get index of first space at the end of the string. for (j = len - 1; j >= 0 && valueStr.charAt(j) == ' '; j--) continue; // escape spaces at the beginning of the string. for (i = 0; i <= j && valueStr.charAt(i) == ' '; i++) { retval.append('\\'); retval.append(valueStr.charAt(i)); } // escape special characters in the middle of the string. for (; i <= j; i++) { if (valueStr.charAt(i) == '\\') { retval.append('\\'); retval.append(valueStr.charAt(i)); } else if (specialChars.indexOf(valueStr.charAt(i)) != -1) { retval.append('\\'); retval.append(valueStr.charAt(i)); } else if (valueStr.charAt(i) == '"') { retval.append('\\'); retval.append(valueStr.charAt(i)); } else retval.append(valueStr.charAt(i)); } // esacape spaces at the end. for (; i < valueStr.length(); i++) { retval.append('\\'); retval.append(' '); } return retval.toString(); } // // public get/set methods // /** * gets the X500NameAttrMap used by the converter. * * @return X500NameAttrMap used by this converter. */ public X500NameAttrMap getAttrMap() { return attrMap; } /** * returns true if the converter accepts unregistered attributes i.e. * OIDS not in the X500NameAttrMap. * * @return true if converter converts attributes not in the * X500NameAttrMap. */ public boolean getAcceptUnknownOids() { return acceptUnknownOids; } // // private and protected variables // protected X500NameAttrMap attrMap; protected boolean acceptUnknownOids; // // private and protected static variables & methods. // protected static final String specialChars = ",+=<>#;"; protected static final String valueEndChars = "+,;>"; protected static final String quotedEndChars = "\""; protected static final String octoEndChars = " " + valueEndChars; /* * Values that aren't printable strings are emitted as BER-encoded * hex data. */ protected static final String hexDigits = "0123456789ABCDEFabcdef"; /** * Parse a sequence of hex pairs, each pair a UTF8 byte to a java string. * For example, "4C75C48D" is "Luc", the last c with caron. */ protected static char[] getStringFromHexpairs(char[] hexPairs) throws UnsupportedEncodingException { try { byte[] buffer = new byte[hexPairs.length / 2]; for (int i = 0; i < buffer.length; i++) { buffer[i] = (byte) ((Character.digit(hexPairs[i * 2], 16) << 4) + Character.digit(hexPairs[i * 2 + 1], 16)); } Charset charset = Charset.forName("UTF-8"); CharsetDecoder decoder = charset.newDecoder(); CharBuffer charBuffer = decoder.decode(ByteBuffer.wrap(buffer)); return Arrays.copyOfRange(charBuffer.array(), charBuffer.arrayOffset(), charBuffer.arrayOffset() + charBuffer.limit()); } catch (UnsupportedCharsetException e) { throw new UnsupportedEncodingException( "No UTF8 byte to char converter to use for " + "parsing LDAP DN String"); } catch (CharacterCodingException e) { throw new IllegalArgumentException( "Invalid hex pair in LDAP DN String."); } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/NSCCommentExtension.java000066400000000000000000000157501362106420000262460ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; import org.mozilla.jss.netscape.security.util.PrettyPrintFormat; /** * This class defines the NSCCommentExtension * * @author asondhi * @see Extension * @see CertAttrSet */ public class NSCCommentExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 4066287070285105375L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.CommentExtension"; /** * Attribute names. */ public static final String NAME = "NSCCommentExtension"; public static final String INFOS = "infos"; public static final ObjectIdentifier OID = new ObjectIdentifier("2.16.840.1.113730.1.13"); public String mComment = null; // Private data members private Vector mInfos; private transient PrettyPrintFormat pp = new PrettyPrintFormat(":"); // Encode this extension value private void encodeThis() throws IOException { try (DerOutputStream os = new DerOutputStream()) { os.putIA5String(mComment); // DerOutputStream tmp = new DerOutputStream(); // os.write(DerValue.tag_Sequence,tmp); extensionValue = os.toByteArray(); } } /** * Create a NSCCommentExtension with the Vector of CertificatePolicyInfo. */ public NSCCommentExtension(boolean critical, String comment) throws IOException { this.mComment = comment; this.extensionId = new ObjectIdentifier("2.16.840.1.113730.1.13"); this.critical = critical; encodeThis(); } /** * Create a default NSCCommentExtension. */ public NSCCommentExtension(boolean critical) { this.extensionId = new ObjectIdentifier("2.16.840.1.113730.1.13"); this.critical = critical; mInfos = new Vector(1, 1); } /** * Create the extension from the passed DER encoded value. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public NSCCommentExtension(Boolean critical, Object value) throws IOException { this.extensionId = new ObjectIdentifier("2.16.840.1.113730.1.13"); this.critical = critical.booleanValue(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; DerValue val = new DerValue(extValue); mComment = val.getIA5String(); } /** * Returns a printable representation of the policy extension. */ public String toString() { if (mInfos == null) return ""; String s = super.toString() + "Netscape Comment [\n" + mInfos.toString() + "]\n"; return (s); } public String toPrint(int indent) { String s; s = "Comment :\n" + pp.indent(indent + 4) + ((mComment == null) ? "" : mComment.trim()) + "\n"; return (s); } /** * Write the extension to the OutputStream. * * @param out the OutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = new ObjectIdentifier("2.16.840.1.113730.1.13"); critical = false; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } public String getComment() { return mComment; } /** * Set the attribute value. */ @SuppressWarnings("unchecked") public void set(String name, Object obj) throws IOException { clearValue(); if (name.equalsIgnoreCase(INFOS)) { if (!(obj instanceof Vector)) { throw new IOException("Attribute value should be of" + " type Vector."); } mInfos = (Vector) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:NSCCommentExtension."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(INFOS)) { return (mInfos); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:NSCCommentExtension."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(INFOS)) { mInfos = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:NSCCommentExtension."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(INFOS); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/NameConstraintsExtension.java000066400000000000000000000267051362106420000274120ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.PrettyPrintFormat; /** * This class defines the Name Constraints Extension. *

* The name constraints extension provides permitted and excluded subtrees that place restrictions on names that may be * included within a certificate issued by a given CA. Restrictions may apply to the subject distinguished name or * subject alternative names. Any name matching a restriction in the excluded subtrees field is invalid regardless of * information appearing in the permitted subtrees. *

* The ASN.1 syntax for this is: * *

 * NameConstraints ::= SEQUENCE {
 *    permittedSubtrees [0]  GeneralSubtrees OPTIONAL,
 *    excludedSubtrees  [1]  GeneralSubtrees OPTIONAL
 * }
 * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
 * GeneralSubtree ::== SEQUENCE {
 *    base                   GeneralName,
 *    minimum           [0]  BaseDistance DEFAULT 0,
 *    maximum           [1]  BaseDistance OPTIONAL }
 * BaseDistance ::== INTEGER (0..MAX)
 * 
* * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.10 * @see Extension * @see CertAttrSet */ public class NameConstraintsExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -3506940192931244539L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.NameConstraints"; /** * Attribute names. */ public static final String NAME = "NameConstraints"; public static final String PERMITTED_SUBTREES = "permitted_subtrees"; public static final String EXCLUDED_SUBTREES = "excluded_subtrees"; // Private data members private static final byte TAG_PERMITTED = 0; private static final byte TAG_EXCLUDED = 1; private GeneralSubtrees permitted; private GeneralSubtrees excluded; private transient PrettyPrintFormat pp = new PrettyPrintFormat(":"); // Encode this extension value. private void encodeThis() throws IOException { try (DerOutputStream seq = new DerOutputStream()) { DerOutputStream tagged = new DerOutputStream(); if ((permitted != null) && (permitted.getSubtrees().size() > 0)) { DerOutputStream tmp = new DerOutputStream(); permitted.encode(tmp); tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_PERMITTED), tmp); } if ((excluded != null) && (excluded.getSubtrees().size() > 0)) { DerOutputStream tmp = new DerOutputStream(); excluded.encode(tmp); tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_EXCLUDED), tmp); } if (permitted == null && excluded == null) { extensionValue = null; // no need to encode this extension } else { seq.write(DerValue.tag_Sequence, tagged); this.extensionValue = seq.toByteArray(); } } } /** * The default constructor for this class. Either parameter * can be set to null to indicate it is omitted but both * cannot be null. * * @param permitted the permitted GeneralSubtrees (null for optional). * @param excluded the excluded GeneralSubtrees (null for optional). */ public NameConstraintsExtension(GeneralSubtrees permitted, GeneralSubtrees excluded) throws IOException { init(false, permitted, excluded); } public NameConstraintsExtension(boolean critical, GeneralSubtrees permitted, GeneralSubtrees excluded) throws IOException { init(critical, permitted, excluded); } private void init(boolean critical, GeneralSubtrees permitted, GeneralSubtrees excluded) throws IOException { if (permitted == null && excluded == null) { throw new IOException("NameConstraints: Invalid arguments"); } this.permitted = permitted; this.excluded = excluded; this.extensionId = PKIXExtensions.NameConstraints_Id; this.critical = critical; encodeThis(); } /** * Create the extension from the passed DER encoded value. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public NameConstraintsExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.NameConstraints_Id; this.critical = critical.booleanValue(); if (!(value instanceof byte[])) throw new IOException("Illegal argument type"); int len = Array.getLength(value); byte[] extValue = new byte[len]; System.arraycopy(value, 0, extValue, 0, len); this.extensionValue = extValue; DerValue val = new DerValue(extValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for" + " NameConstraintsExtension."); } // NB. this is always encoded with the IMPLICIT tag // The checks only make sense if we assume implicit tagging, // with explicit tagging the form is always constructed. while (val.data.available() != 0) { DerValue opt = val.data.getDerValue(); if (opt.isContextSpecific(TAG_PERMITTED) && opt.isConstructed()) { if (permitted != null) { throw new IOException("Duplicate permitted " + "GeneralSubtrees in NameConstraintsExtension."); } opt.resetTag(DerValue.tag_Sequence); permitted = new GeneralSubtrees(opt); } else if (opt.isContextSpecific(TAG_EXCLUDED) && opt.isConstructed()) { if (excluded != null) { throw new IOException("Duplicate excluded " + "GeneralSubtrees in NameConstraintsExtension."); } opt.resetTag(DerValue.tag_Sequence); excluded = new GeneralSubtrees(opt); } else throw new IOException("Invalid encoding of " + "NameConstraintsExtension."); } } /** * Return the printable string. */ public String toString() { return (super.toString() + "NameConstraints: [" + ((permitted == null) ? "" : ("\n Permitted:" + permitted.toString())) + ((excluded == null) ? "" : ("\n Excluded:" + excluded.toString())) + " ]\n"); } public String toPrint(int indent) { return ("GeneralSubtrees: " + ((permitted == null) ? "" : ("\n" + pp.indent(indent + 2) + "Permitted:" + permitted.toPrint(indent + 4))) + ((excluded == null) ? "" : ("\n" + pp.indent(indent + 2) + "Excluded:" + excluded.toPrint(indent + 4))) + "\n"); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the OutputStream. * * @param out the OutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (this.extensionValue == null) { this.extensionId = PKIXExtensions.NameConstraints_Id; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { clearValue(); if (name.equalsIgnoreCase(PERMITTED_SUBTREES)) { if (!(obj instanceof GeneralSubtrees)) { throw new IOException("Attribute value should be" + " of type GeneralSubtrees."); } permitted = (GeneralSubtrees) obj; } else if (name.equalsIgnoreCase(EXCLUDED_SUBTREES)) { if (!(obj instanceof GeneralSubtrees)) { throw new IOException("Attribute value should be " + "of type GeneralSubtrees."); } excluded = (GeneralSubtrees) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:NameConstraintsExtension."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(PERMITTED_SUBTREES)) { return (permitted); } else if (name.equalsIgnoreCase(EXCLUDED_SUBTREES)) { return (excluded); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:NameConstraintsExtension."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(PERMITTED_SUBTREES)) { permitted = null; } else if (name.equalsIgnoreCase(EXCLUDED_SUBTREES)) { excluded = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:NameConstraintsExtension."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(PERMITTED_SUBTREES); elements.addElement(EXCLUDED_SUBTREES); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/NoticeReference.java000066400000000000000000000062171362106420000254410ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.Serializable; import java.util.Vector; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the NoticeReference. * * NoticeReference ::= SEQUENCE { * organization DisplayText, * noticeNumbers SEQUENCE OF INTEGER * } * * @author Thomas Kwan */ public class NoticeReference implements Serializable { private static final long serialVersionUID = 1986080941078808200L; private DisplayText mOrg = null; private int mNumbers[] = null; public NoticeReference(DisplayText org, int numbers[]) { mOrg = org; mNumbers = numbers; } public NoticeReference(DerValue val) throws IOException { if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for NoticeReference"); } mOrg = new DisplayText(val.data.getDerValue()); DerValue integers = val.data.getDerValue(); if (integers.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for NoticeReference (integers)"); } Vector num = new Vector(); while (integers.data.available() != 0) { DerValue i = integers.data.getDerValue(); BigInt bigI = i.getInteger(); num.addElement(bigI); } if (num.size() <= 0) return; mNumbers = new int[num.size()]; for (int i = 0; i < num.size(); i++) { mNumbers[i] = num.elementAt(i).toInt(); } } public DisplayText getOrganization() { return mOrg; } public int[] getNumbers() { return mNumbers; } /** * Write the NoticeReference to the DerOutputStream. * * @param out the DerOutputStream to write the object to. * @exception IOException on errors. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); mOrg.encode(tmp); DerOutputStream iseq = new DerOutputStream(); for (int i = 0; i < mNumbers.length; i++) { iseq.putInteger(new BigInt(mNumbers[i])); } tmp.write(DerValue.tag_Sequence, iseq); out.write(DerValue.tag_Sequence, tmp); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/OIDMap.java000066400000000000000000000326421362106420000234530ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.cert.CertificateException; import java.util.Hashtable; import java.util.Iterator; import java.util.Properties; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * This class defines the mapping from OID and name to classes and vice * versa. Used by CertificateExtensions and PKCS10 to get the java * classes associated with a particular OID/name. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.12 */ public class OIDMap { /** * Location for where the OID/Classes maps are stored on * the local system. */ public static final String EXTENSIONS_HOME = (System.getProperty("java.home") + File.separator + "lib" + File.separator + "security" + File.separator + "cert" + File.separator); /** * File names for where OIDs and Classes are registered * for V3 extensions. */ public static final String EXTENSIONS_OIDS = "x509extensions.oid"; public static final String EXTENSIONS_CLASSES = "x509extensions.classes"; // Make default names easier private static final String ROOT = X509CertImpl.NAME + "." + X509CertInfo.NAME + "." + X509CertInfo.EXTENSIONS; private static final String AUTH_KEY_IDENTIFIER = ROOT + "." + AuthorityKeyIdentifierExtension.NAME; private static final String SUB_KEY_IDENTIFIER = ROOT + "." + SubjectKeyIdentifierExtension.NAME; private static final String KEY_USAGE = ROOT + "." + KeyUsageExtension.NAME; private static final String PRIVATE_KEY_USAGE = ROOT + "." + PrivateKeyUsageExtension.NAME; private static final String POLICY_MAPPINGS = ROOT + "." + PolicyMappingsExtension.NAME; private static final String SUB_ALT_NAME = ROOT + "." + SubjectAlternativeNameExtension.NAME; private static final String ISSUER_ALT_NAME = ROOT + "." + IssuerAlternativeNameExtension.NAME; private static final String BASIC_CONSTRAINTS = ROOT + "." + BasicConstraintsExtension.NAME; private static final String NAME_CONSTRAINTS = ROOT + "." + NameConstraintsExtension.NAME; private static final String POLICY_CONSTRAINTS = ROOT + "." + PolicyConstraintsExtension.NAME; private static final String CERT_POLICIES = //ROOT + "." + CertificatePoliciesExtension.NAME; private static final String SUBJ_DIR_ATTR = //ROOT + "." + SubjectDirAttributesExtension.NAME; public static final String EXT_KEY_USAGE_NAME = "ExtendedKeyUsageExtension"; public static final String EXT_INHIBIT_ANY_POLICY_NAME = "InhibitAnyPolicyExtension"; private static final String EXT_KEY_USAGE = //ROOT + "." + EXT_KEY_USAGE_NAME; private static final String CRL_NUMBER = ROOT + "." + CRLNumberExtension.NAME; private static final String CRL_REASON = ROOT + "." + CRLReasonExtension.NAME; private static final Hashtable oid2Name = new Hashtable(); private static final Hashtable name2OID = new Hashtable(); private static final Hashtable name2Class = new Hashtable(); // Initialize recognized extensions from EXTENSIONS_{OIDS/CLASSES} files static { loadNames(); loadClasses(); addClass(CRLDistributionPointsExtension.class); } // Load the default name to oid map (EXTENSIONS_OIDS) private static void loadNamesDefault(Properties props) { props.put(SUB_KEY_IDENTIFIER, "2.5.29.14"); props.put(KEY_USAGE, "2.5.29.15"); props.put(PRIVATE_KEY_USAGE, "2.5.29.16"); props.put(SUB_ALT_NAME, "2.5.29.17"); props.put(ISSUER_ALT_NAME, "2.5.29.18"); props.put(BASIC_CONSTRAINTS, "2.5.29.19"); props.put(CRL_NUMBER, "2.5.29.20"); props.put(CRL_REASON, "2.5.29.21"); props.put(NAME_CONSTRAINTS, "2.5.29.30"); props.put(POLICY_MAPPINGS, "2.5.29.33"); props.put(POLICY_CONSTRAINTS, "2.5.29.36"); props.put(CERT_POLICIES, "2.5.29.32"); props.put(AUTH_KEY_IDENTIFIER, "2.5.29.35"); props.put(SUBJ_DIR_ATTR, "2.5.29.9"); props.put(EXT_KEY_USAGE, "2.5.29.37"); } // Load the default name to class map (EXTENSIONS_CLASSES) private static void loadClassDefault(Properties props) { props.put(AUTH_KEY_IDENTIFIER, "org.mozilla.jss.netscape.security.x509.AuthorityKeyIdentifierExtension"); props.put(SUB_KEY_IDENTIFIER, "org.mozilla.jss.netscape.security.x509.SubjectKeyIdentifierExtension"); props.put(KEY_USAGE, "org.mozilla.jss.netscape.security.x509.KeyUsageExtension"); props.put(PRIVATE_KEY_USAGE, "org.mozilla.jss.netscape.security.x509.PrivateKeyUsageExtension"); props.put(POLICY_MAPPINGS, "org.mozilla.jss.netscape.security.x509.PolicyMappingsExtension"); props.put(SUB_ALT_NAME, "org.mozilla.jss.netscape.security.x509.SubjectAlternativeNameExtension"); props.put(ISSUER_ALT_NAME, "org.mozilla.jss.netscape.security.x509.IssuerAlternativeNameExtension"); props.put(BASIC_CONSTRAINTS, "org.mozilla.jss.netscape.security.x509.BasicConstraintsExtension"); props.put(NAME_CONSTRAINTS, "org.mozilla.jss.netscape.security.x509.NameConstraintsExtension"); props.put(POLICY_CONSTRAINTS, "org.mozilla.jss.netscape.security.x509.PolicyConstraintsExtension"); props.put(CERT_POLICIES, "org.mozilla.jss.netscape.security.x509.CertificatePoliciesExtension"); props.put(SUBJ_DIR_ATTR, "org.mozilla.jss.netscape.security.x509.SubjectDirAttributesExtension"); props.put(EXT_KEY_USAGE, "org.mozilla.jss.netscape.security.extensions.ExtendedKeyUsageExtension"); props.put(CRL_NUMBER, "org.mozilla.jss.netscape.security.x509.CRLNumberExtension"); props.put(CRL_REASON, "org.mozilla.jss.netscape.security.x509.CRLReasonExtension"); } // Return the file along with location private static File certificatePropFile(String fileName) { return (new File(EXTENSIONS_HOME + fileName)); } // Load the names to oid map private static void loadNames() { Properties props = new Properties(); File namesMap = certificatePropFile(EXTENSIONS_OIDS); if (!namesMap.exists()) { loadNamesDefault(props); } else { FileInputStream fis = null; try { fis = new FileInputStream(namesMap); props.load(fis); } catch (IOException e) { loadNamesDefault(props); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } Iterator names = props.stringPropertyNames().iterator(); while (names.hasNext()) { String name = names.next(); String oidName = props.getProperty(name); ObjectIdentifier oid = new ObjectIdentifier(oidName); name2OID.put(name, oid); oid2Name.put(oid, name); } } // Load the names to classes map private static void loadClasses() { Properties props = new Properties(); File classMap = certificatePropFile(EXTENSIONS_CLASSES); if (!classMap.exists()) { loadClassDefault(props); } else { FileInputStream fis = null; try { fis = new FileInputStream(classMap); props.load(fis); } catch (IOException e) { loadClassDefault(props); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } Iterator names = props.stringPropertyNames().iterator(); while (names.hasNext()) { String name = names.next(); String className = props.getProperty(name); name2Class.put(name, className); } } /** * Add an extension to the OIDMap. * * Assumes existence of static OID and NAME fields with unique values. */ public static void addClass(Class clazz) { try { addAttribute(clazz.getName(), (String) clazz.getField("OID").get(null), (String) clazz.getField("NAME").get(null)); } catch (Throwable e) { System.out.println( "Error adding class " + clazz.getName() + " to OIDMap: " + e); } } /** * Add a name to lookup table. * * @param className the name of the fully qualified class implementing * the asn object. * @param oid the string representation of the object identifier for * the class. * @param name the name of the attribute. * @exception CertificateException on errors. */ public static void addAttribute(String className, String oid, String name) throws CertificateException { ObjectIdentifier objId = new ObjectIdentifier(oid); if (oid2Name.get(objId) != null) { throw new CertificateException("Object identifier already exists."); } if (name2OID.get(name) != null) { throw new CertificateException("Name already exists."); } if (name2Class.get(className) != null) { throw new CertificateException("Class already exists."); } oid2Name.put(objId, name); name2OID.put(name, objId); name2Class.put(name, className); } /** * Return user friendly name associated with the OID. * * @param oid the name of the object identifier to be returned. * @return the user friendly name or null if no name * is registered for this oid. */ public static String getName(ObjectIdentifier oid) { return oid2Name.get(oid); } /** * Return Object identifier for user friendly name. * * @param name the user friendly name. * @return the Object Identifier or null if no oid * is registered for this name. */ public static ObjectIdentifier getOID(String name) { return name2OID.get(name); } /** * Return the java class object associated with the user friendly name. * * @param name the user friendly name. * @exception CertificateException if class cannot be instantiated. */ public static Class getClass(String name) throws CertificateException { String className = name2Class.get(name); if (className == null) return null; try { Class extClass = Class.forName(className); return (extClass); } catch (Exception e) { throw new CertificateException("Error instantiating class for " + name + " " + e.toString()); } } /** * Return the java class object associated with the object identifier.. * * @param oid the name of the object identifier to be returned. * @exception CertificateException if class cannot be instatiated. */ public static Class getClass(ObjectIdentifier oid) throws CertificateException { String name = getName(oid); if (name == null) return null; String className = name2Class.get(name); if (className == null) return null; try { Class extClass = Class.forName(className); return (extClass); } catch (Exception e) { throw new CertificateException("Error instantiating class for " + name + " " + e.toString()); } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/OIDName.java000066400000000000000000000050431362106420000236110ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * This class implements the OIDName as required by the GeneralNames * ASN.1 object. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.3 * @see GeneralName * @see GeneralNames * @see GeneralNameInterface */ public class OIDName implements GeneralNameInterface { /** * */ private static final long serialVersionUID = 9198510631835117121L; private ObjectIdentifier oid; /** * Create the OIDName object from the passed encoded Der value. * * @param derValue the encoded DER OIDName. * @exception IOException on error. */ public OIDName(DerValue derValue) throws IOException { oid = derValue.getOID(); } /** * Create the OIDName object with the specified name. * * @param oid the OIDName. */ public OIDName(ObjectIdentifier oid) { this.oid = oid; } public OIDName(String oid) { this.oid = new ObjectIdentifier(oid); } /** * Return the type of the GeneralName. */ public int getType() { return (GeneralNameInterface.NAME_OID); } /** * Encode the OID name into the DerOutputStream. * * @param out the DER stream to encode the OIDName to. * @exception IOException on encoding errors. */ public void encode(DerOutputStream out) throws IOException { out.putOID(oid); } /** * Convert the name into user readable string. */ public String toString() { return ("OIDName: " + oid.toString()); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/OtherName.java000066400000000000000000000146221362106420000242620ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * This class implements the OtherName as required by the GeneralNames * ASN.1 object. * * OtherName ::= SEQUENCE { * type-id OBJECT IDENTIFIER, * value [0] EXPLICIT ANY DEFINED BY type-id * } * * @see GeneralName * @see GeneralNameInterface * @see GeneralNames * * @version 1.2 * * @author Amit Kapoor * @author Hemma Prafullchandra */ public class OtherName implements GeneralNameInterface { /** * */ private static final long serialVersionUID = -3533614377346132611L; private ObjectIdentifier mOID = null; private byte[] mData = null; /** * Create the IPAddressName object from the passed encoded Der value. * * @param derValue the encoded DER IPAddressName. * @exception IOException on error. */ public OtherName(DerValue derValue) throws IOException { decodeThis(derValue); } public OtherName(ObjectIdentifier oid, byte data[]) throws IOException { mOID = oid; DerOutputStream dos = new DerOutputStream(); try { dos.putDerValue(new DerValue(data)); } catch (IOException e) { } finally { dos.close(); } mData = dos.toByteArray(); } /** * Constructs a string-based other name. */ public OtherName(ObjectIdentifier oid, byte tag, String value) throws IOException { mOID = oid; DerOutputStream dos = new DerOutputStream(); try { if (tag == DerValue.tag_PrintableString) { dos.putPrintableString(value); } else if (tag == DerValue.tag_IA5String) { dos.putIA5String(value); } else if (tag == DerValue.tag_BMPString) { dos.putBMPString(value); } else if (tag == DerValue.tag_UTF8String) { dos.putUTF8String(value); } } catch (IOException e) { } finally { dos.close(); } mData = dos.toByteArray(); } public OtherName(ObjectIdentifier oid, String value) throws IOException { mOID = oid; DerOutputStream dos = new DerOutputStream(); try { dos.putPrintableString(value); } catch (IOException e) { } finally { dos.close(); } mData = dos.toByteArray(); } public OtherName(byte[] data) { try { decodeThis(new DerValue(data)); } catch (IOException e) { } } public ObjectIdentifier getOID() { return mOID; } /** * Return the type of the GeneralName. */ public int getType() { return (GeneralNameInterface.NAME_ANY); } /** * Encode the IPAddress name into the DerOutputStream. * * @param out the DER stream to encode the IPAddressName to. * @exception IOException on encoding errors. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); //encoding the attributes tmp.putOID(mOID); DerOutputStream tmp1 = new DerOutputStream(); tmp1.write(mData); tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x80), tmp1); out.write(DerValue.tag_SequenceOf, tmp); } public void decode(InputStream in) throws IOException { DerValue val = new DerValue(in); decodeThis(val); } // Decode this extension value private void decodeThis(DerValue derVal) throws IOException { // if (derVal.tag != DerValue.tag_Sequence) { // throw new IOException("Invalid encoding for other name"); // } // Decode all the Attributes mOID = derVal.data.getOID(); // skip tag DerValue tag = derVal.data.getDerValue(); // read data DerValue data = tag.data.getDerValue(); mData = data.toByteArray(); } public byte[] getValue() { return mData; } /** * Return a printable string of IPaddress */ public String toString() { if (mData != null) { try { DerValue data = new DerValue(mData); if (data.tag == DerValue.tag_PrintableString) { return "OtherName: (PrintableString)" + mOID + "," + data.getPrintableString(); } else if (data.tag == DerValue.tag_IA5String) { return "OtherName: (IA5String)" + mOID + "," + data.getIA5String(); } else if (data.tag == DerValue.tag_BMPString) { return "OtherName: (BMPString)" + mOID + "," + data.getIA5String(); } else if (data.tag == DerValue.tag_UTF8String) { return "OtherName: (UTF8String)" + mOID + "," + data.getUTF8String(); } else { return "OtherName: (Any)" + mOID + "," + toStr(data.toByteArray()); } } catch (IOException e) { return "OtherName: (Any)" + mOID + "," + toStr(mData); } } else { return "OtherName: "; } } public String toStr(byte data[]) { StringBuffer b = new StringBuffer(); for (int i = 0; i < data.length; i++) { if ((data[i] & 0xff) < 16) { b.append("0"); } b.append(Integer.toString((data[i] & 0xff), 0x10)); } return b.toString(); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/PKIXExtensions.java000066400000000000000000000173401362106420000252330ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * Lists all the object identifiers of the X509 extensions of the PKIX profile. * *

* Extensions are addiitonal attributes which can be inserted in a X509 v3 certificate. For example a * "Driving License Certificate" could have the driving license number as a extension. * *

* Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding * of the extension value). * * @see Extension * * @version 1.4 * * @author Amit Kapoor * @author Hemma Prafullchandra */ public class PKIXExtensions { // The object identifiers private static final int AuthorityKey_data[] = { 2, 5, 29, 35 }; private static final int SubjectKey_data[] = { 2, 5, 29, 14 }; private static final int KeyUsage_data[] = { 2, 5, 29, 15 }; private static final int PrivateKeyUsage_data[] = { 2, 5, 29, 16 }; private static final int CertificatePolicies_data[] = { 2, 5, 29, 32 }; private static final int PolicyMappings_data[] = { 2, 5, 29, 33 }; private static final int SubjectAlternativeName_data[] = { 2, 5, 29, 17 }; private static final int IssuerAlternativeName_data[] = { 2, 5, 29, 18 }; private static final int SubjectDirectoryAttributes_data[] = { 2, 5, 29, 9 }; private static final int BasicConstraints_data[] = { 2, 5, 29, 19 }; private static final int NameConstraints_data[] = { 2, 5, 29, 30 }; private static final int PolicyConstraints_data[] = { 2, 5, 29, 36 }; private static final int CRLDistributionPoints_data[] = { 2, 5, 29, 31 }; private static final int CRLNumber_data[] = { 2, 5, 29, 20 }; private static final int IssuingDistributionPoint_data[] = { 2, 5, 29, 28 }; private static final int DeltaCRLIndicator_data[] = { 2, 5, 29, 27 }; private static final int ReasonCode_data[] = { 2, 5, 29, 21 }; private static final int HoldInstructionCode_data[] = { 2, 5, 29, 23 }; private static final int InvalidityDate_data[] = { 2, 5, 29, 24 }; private static final int CertificateIssuer_data[] = { 2, 5, 29, 29 }; private static final int FreshestCRL_data[] = { 2, 5, 29, 46 }; /** * Identifies the particular public key used to sign the certificate. */ public static final ObjectIdentifier AuthorityKey_Id = new ObjectIdentifier(AuthorityKey_data); /** * Identifies the particular public key used in an application. */ public static final ObjectIdentifier SubjectKey_Id = new ObjectIdentifier(SubjectKey_data); /** * Defines the purpose of the key contained in the certificate. */ public static final ObjectIdentifier KeyUsage_Id = new ObjectIdentifier(KeyUsage_data); /** * Allows the certificate issuer to specify a different validity period * for the private key than the certificate. */ public static final ObjectIdentifier PrivateKeyUsage_Id = new ObjectIdentifier(PrivateKeyUsage_data); /** * Contains the sequence of policy information terms. */ public static final ObjectIdentifier CertificatePolicies_Id = new ObjectIdentifier(CertificatePolicies_data); /** * Lists pairs of objectidentifiers of policies considered equivalent by the * issuing CA to the subject CA. */ public static final ObjectIdentifier PolicyMappings_Id = new ObjectIdentifier(PolicyMappings_data); /** * Allows additional identities to be bound to the subject of the certificate. */ public static final ObjectIdentifier SubjectAlternativeName_Id = new ObjectIdentifier(SubjectAlternativeName_data); /** * Allows additional identities to be associated with the certificate issuer. */ public static final ObjectIdentifier IssuerAlternativeName_Id = new ObjectIdentifier(IssuerAlternativeName_data); /** * Identifies additional directory attributes. * This extension is always non-critical. */ public static final ObjectIdentifier SubjectDirectoryAttributes_Id = new ObjectIdentifier( SubjectDirectoryAttributes_data); /** * Identifies whether the subject of the certificate is a CA and how deep * a certification path may exist through that CA. */ public static final ObjectIdentifier BasicConstraints_Id = new ObjectIdentifier(BasicConstraints_data); /** * Provides for permitted and excluded subtrees that place restrictions * on names that may be included within a certificate issued by a given CA. */ public static final ObjectIdentifier NameConstraints_Id = new ObjectIdentifier(NameConstraints_data); /** * Used to either prohibit policy mapping or limit the set of policies * that can be in subsequent certificates. */ public static final ObjectIdentifier PolicyConstraints_Id = new ObjectIdentifier(PolicyConstraints_data); /** * Identifies how CRL information is obtained. */ public static final ObjectIdentifier CRLDistributionPoints_Id = new ObjectIdentifier(CRLDistributionPoints_data); /** * Conveys a monotonically increasing sequence number for each CRL * issued by a given CA. */ public static final ObjectIdentifier CRLNumber_Id = new ObjectIdentifier(CRLNumber_data); /** * Identifies the CRL distribution point for a particular CRL. */ public static final ObjectIdentifier IssuingDistributionPoint_Id = new ObjectIdentifier( IssuingDistributionPoint_data); /** * Identifies the delta CRL. */ public static final ObjectIdentifier DeltaCRLIndicator_Id = new ObjectIdentifier(DeltaCRLIndicator_data); /** * Identifies the reason for the certificate revocation. */ public static final ObjectIdentifier ReasonCode_Id = new ObjectIdentifier(ReasonCode_data); /** * This extension provides a registered instruction identifier indicating * the action to be taken, after encountering a certificate that has been * placed on hold. */ public static final ObjectIdentifier HoldInstructionCode_Id = new ObjectIdentifier(HoldInstructionCode_data); /** * Identifies the date on which it is known or suspected that the private * key was compromised or that the certificate otherwise became invalid. */ public static final ObjectIdentifier InvalidityDate_Id = new ObjectIdentifier(InvalidityDate_data); /** * Identifies the date on which it is known or suspected that the private * key was compromised or that the certificate otherwise became invalid. */ public static final ObjectIdentifier CertificateIssuer_Id = new ObjectIdentifier(CertificateIssuer_data); /** * Identifies how delta CRL information is obtained. */ public static final ObjectIdentifier FreshestCRL_Id = new ObjectIdentifier(FreshestCRL_data); } jss-4.6.3/org/mozilla/jss/netscape/security/x509/PolicyConstraint.java000066400000000000000000000113771362106420000257100ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the PolicyConstraint ASN.1 object. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.4 */ public class PolicyConstraint { private static final byte TAG_SET = 0; private static final byte TAG_REQUIRE = 1; private static final byte TAG_INHIBIT = 2; private CertificatePolicySet set = null; private int require = -1; private int inhibit = -1; /** * The default constructor for this object * * @param set the CertificatePolicySet (null for optional). * @param require require explicit policy (-1 for optional). * @param inhibit inhibit policy mapping (-1 for optional). */ public PolicyConstraint(CertificatePolicySet set, int require, int inhibit) { this.set = set; this.require = require; this.inhibit = inhibit; } /** * Create the PolicyConstraint from the DerValue. * * @param val the DerValue of the PolicyConstraint. * @exception IOException on decoding errors. */ public PolicyConstraint(DerValue val) throws IOException { if (val.tag != DerValue.tag_Sequence) { throw new IOException("Sequence tag missing for PolicyConstraint."); } DerInputStream in = val.data; while (in != null && in.available() != 0) { DerValue next = in.getDerValue(); switch (next.tag & 0x1f) { case TAG_SET: this.set = new CertificatePolicySet(next.data); break; case TAG_REQUIRE: next = next.data.getDerValue(); this.require = (next.getInteger()).toInt(); break; case TAG_INHIBIT: next = next.data.getDerValue(); this.inhibit = (next.getInteger()).toInt(); break; default: throw new IOException("Invalid tag option for PolicyConstraint."); } } } /** * Return user readable form of the object. */ public String toString() { String s = ((set != null) ? "PolicyConstraint: [\n" + " PolicySet:[" + set.toString() + "]\n" + " Require:" + require + "\n" + " Inhibit:" + inhibit + "\n" + "]\n" : "PolicyConstraint: [\n" + " PolicySet:[null]\n" + " Require:" + require + "\n" + " Inhibit:" + inhibit + "\n" + "]\n"); return (s); } /** * Encode the object to the output stream. * * @param out the DerOutputStream to encode the object to. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tagged = new DerOutputStream(); if (set != null) { DerOutputStream tmp = new DerOutputStream(); set.encode(tmp); tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_SET), tmp); } if (require != -1) { DerOutputStream tmp = new DerOutputStream(); tmp.putInteger(new BigInt(require)); tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_REQUIRE), tmp); } if (inhibit != -1) { DerOutputStream tmp = new DerOutputStream(); tmp.putInteger(new BigInt(inhibit)); tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_INHIBIT), tmp); } out.write(DerValue.tag_Sequence, tagged); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/PolicyConstraintsExtension.java000066400000000000000000000244451362106420000277700ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the certificate extension which specifies the * Policy constraints. *

* The policy constraints extension can be used in certificates issued to CAs. The policy constraints extension * constrains path validation in two ways. It can be used to prohibit policy mapping or require that each certificate in * a path contain an acceptable policy identifier. *

* The ASN.1 syntax for this is (IMPLICIT tagging is defined in the module definition): * *

 * PolicyConstraints ::= SEQUENCE {
 *     requireExplicitPolicy [0] SkipCerts OPTIONAL,
 *     inhibitPolicyMapping  [1] SkipCerts OPTIONAL
 * }
 * SkipCerts ::= INTEGER (0..MAX)
 * 
* * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.9 * @see Extension * @see CertAttrSet */ public class PolicyConstraintsExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -3723759691127622370L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.PolicyConstraints"; /** * Attribute names. */ public static final String NAME = "PolicyConstraints"; public static final String REQUIRE = "require"; public static final String INHIBIT = "inhibit"; private static final byte TAG_REQUIRE = 0; private static final byte TAG_INHIBIT = 1; private int require = -1; private int inhibit = -1; // Encode this extension value. private void encodeThis() throws IOException { try (DerOutputStream seq = new DerOutputStream()) { DerOutputStream tagged = new DerOutputStream(); if (require != -1) { DerOutputStream tmp = new DerOutputStream(); tmp.putInteger(new BigInt(require)); tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false, TAG_REQUIRE), tmp); } if (inhibit != -1) { DerOutputStream tmp = new DerOutputStream(); tmp.putInteger(new BigInt(inhibit)); tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false, TAG_INHIBIT), tmp); } seq.write(DerValue.tag_Sequence, tagged); extensionValue = seq.toByteArray(); } } /** * Create a PolicyConstraintsExtension object with criticality and * both require explicit policy and inhibit policy mapping. * * @param crit whether this extension should be critical * @param require require explicit policy (-1 for optional). * @param inhibit inhibit policy mapping (-1 for optional). */ public PolicyConstraintsExtension(boolean crit, int require, int inhibit) throws IOException { init(crit, require, inhibit); } /** * Create a PolicyConstraintsExtension object with both * require explicit policy and inhibit policy mapping. * * @param require require explicit policy (-1 for optional). * @param inhibit inhibit policy mapping (-1 for optional). */ public PolicyConstraintsExtension(int require, int inhibit) throws IOException { init(false, require, inhibit); } private void init(boolean crit, int require, int inhibit) throws IOException { this.require = require; this.inhibit = inhibit; this.extensionId = PKIXExtensions.PolicyConstraints_Id; this.critical = crit; encodeThis(); } /** * Create the extension from its DER encoded value and criticality. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public PolicyConstraintsExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.PolicyConstraints_Id; this.critical = critical.booleanValue(); if (!(value instanceof byte[])) throw new IOException("Illegal argument type"); int len = Array.getLength(value); byte[] extValue = new byte[len]; System.arraycopy(value, 0, extValue, 0, len); this.extensionValue = extValue; DerValue val = new DerValue(extValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Sequence tag missing for PolicyConstraint."); } DerInputStream in = val.data; while (in != null && in.available() != 0) { DerValue next = in.getDerValue(); if (next.isContextSpecific(TAG_REQUIRE) && !next.isConstructed()) { if (this.require != -1) throw new IOException("Duplicate requireExplicitPolicy" + "found in the PolicyConstraintsExtension"); next.resetTag(DerValue.tag_Integer); this.require = (next.getInteger()).toInt(); } else if (next.isContextSpecific(TAG_INHIBIT) && !next.isConstructed()) { if (this.inhibit != -1) throw new IOException("Duplicate inhibitPolicyMapping" + "found in the PolicyConstraintsExtension"); next.resetTag(DerValue.tag_Integer); this.inhibit = (next.getInteger()).toInt(); } else throw new IOException("Invalid encoding of PolicyConstraint"); } } /** * Return the extension as user readable string. */ public String toString() { String s; s = super.toString() + "PolicyConstraints: [" + " Require: "; if (require == -1) s += "unspecified;"; else s += require + ";"; s += "\tInhibit: "; if (inhibit == -1) s += "unspecified"; else s += inhibit; s += " ]\n"; return s; } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.PolicyConstraints_Id; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { clearValue(); if (!(obj instanceof Integer)) { throw new IOException("Attribute value should be of type Integer."); } if (name.equalsIgnoreCase(REQUIRE)) { require = ((Integer) obj).intValue(); } else if (name.equalsIgnoreCase(INHIBIT)) { inhibit = ((Integer) obj).intValue(); } else { throw new IOException("Attribute name " + "[" + name + "]" + " not recognized by " + "CertAttrSet:PolicyConstraints."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(REQUIRE)) { return Integer.valueOf(require); } else if (name.equalsIgnoreCase(INHIBIT)) { return Integer.valueOf(inhibit); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:PolicyConstraints."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(REQUIRE)) { require = -1; } else if (name.equalsIgnoreCase(INHIBIT)) { inhibit = -1; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:PolicyConstraints."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(REQUIRE); elements.addElement(INHIBIT); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } /** * returns the requireExplicitMapping parameter. */ public int getRequireExplicitMapping() { return require; } /** * returns the inhibitPolicyMapping parameter. */ public int getInhibitPolicyMapping() { return inhibit; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/PolicyMappingsExtension.java000066400000000000000000000204071362106420000272310ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the Policy Mappings Extension. * * This extension, if present, identifies the certificate policies considered * identical between the issuing and the subject CA. *

* Extensions are addiitonal attributes which can be inserted in a X509 v3 certificate. For example a * "Driving License Certificate" could have the driving license number as a extension. * *

* Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding * of the extension value). * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.7 * @see Extension * @see CertAttrSet */ public class PolicyMappingsExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -4023336164621135851L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.PolicyMappings"; /** * Attribute names. */ public static final String NAME = "PolicyMappings"; public static final String MAP = "map"; // Private data members private Vector maps = null; // Encode this extension value private void encodeThis() throws IOException { try (DerOutputStream os = new DerOutputStream()) { DerOutputStream tmp = new DerOutputStream(); for (int i = 0; i < maps.size(); i++) { maps.elementAt(i).encode(tmp); } os.write(DerValue.tag_Sequence, tmp); extensionValue = os.toByteArray(); } } /** * Create a PolicyMappings with the Vector of CertificatePolicyMap. * * @param map the Vector of CertificatePolicyMap. */ public PolicyMappingsExtension(Vector map) throws IOException { init(false, map); } /** * Create a PolicyMappings with the Vector of CertificatePolicyMap. * * @param critical true if the extension is to be treated as critical. * @param map the Vector of CertificatePolicyMap. */ public PolicyMappingsExtension(boolean critical, Vector map) throws IOException { init(critical, map); } /** * init policy with criticality and map. */ private void init(boolean critical, Vector map) throws IOException { this.maps = map; this.extensionId = PKIXExtensions.PolicyMappings_Id; this.critical = critical; encodeThis(); } /** * Create a default PolicyMappingsExtension. */ public PolicyMappingsExtension() { extensionId = PKIXExtensions.PolicyMappings_Id; critical = false; maps = new Vector(1, 1); } /** * Create the extension from the passed DER encoded value. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public PolicyMappingsExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.PolicyMappings_Id; this.critical = critical.booleanValue(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; DerValue val = new DerValue(extValue); if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for " + "PolicyMappingsExtension."); } maps = new Vector(1, 1); while (val.data.available() != 0) { DerValue seq = val.data.getDerValue(); CertificatePolicyMap map = new CertificatePolicyMap(seq); maps.addElement(map); } } /** * Returns a printable representation of the policy map. */ public String toString() { if (maps == null) return ""; String s = super.toString() + "PolicyMappings [\n" + maps.toString() + "]\n"; return (s); } /** * Write the extension to the OutputStream. * * @param out the OutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.PolicyMappings_Id; critical = false; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Set the attribute value. */ @SuppressWarnings("unchecked") public void set(String name, Object obj) throws IOException { clearValue(); if (name.equalsIgnoreCase(MAP)) { if (!(obj instanceof Vector)) { throw new IOException("Attribute value should be of" + " type Vector."); } maps = (Vector) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:PolicyMappingsExtension."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(MAP)) { return (maps); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:PolicyMappingsExtension."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(MAP)) { maps = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:PolicyMappingsExtension."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(MAP); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } /** * Returns an enumeration of the mappings in the extension. */ public Enumeration getMappings() { if (maps == null) return null; return maps.elements(); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/PolicyQualifierInfo.java000066400000000000000000000071531362106420000263160ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * Represent the PolicyQualifierInfo. * * policyQualifierInfo ::= SEQUENCE { * policyQualifierId PolicyQualifierId * qualifier ANY DEFINED BY policyQualifierId * } * * @author Thomas Kwan */ public class PolicyQualifierInfo implements java.io.Serializable { /** * */ private static final long serialVersionUID = -2930016944517192379L; public static final int OID_CPS[] = { 1, 3, 6, 1, 5, 5, 7, 2, 1 }; public static final ObjectIdentifier QT_CPS = new ObjectIdentifier(OID_CPS); public static final int OID_UNOTICE[] = { 1, 3, 6, 1, 5, 5, 7, 2, 2 }; public static final ObjectIdentifier QT_UNOTICE = new ObjectIdentifier(OID_UNOTICE); private ObjectIdentifier mId = null; private Qualifier mQualifier = null; /** * Create a PolicyQualifierInfo * * @param id the ObjectIdentifier for the policy id. */ public PolicyQualifierInfo(ObjectIdentifier id, Qualifier qualifier) { mId = id; mQualifier = qualifier; } /** * Create the object from its Der encoded value. * * @param val the DER encoded value for the same. */ public PolicyQualifierInfo(DerValue val) throws IOException { if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for PolicyQualifierInfo."); } DerValue did = val.data.getDerValue(); mId = did.getOID(); if (val.data.available() != 0) { DerValue qualifier = val.data.getDerValue(); if (qualifier.tag == DerValue.tag_IA5String) { mQualifier = new CPSuri(qualifier); } else { mQualifier = new UserNotice(qualifier); } } } public ObjectIdentifier getId() { return mId; } /** * Returns object of type CPSuri or UserNotice. */ public Qualifier getQualifier() { return mQualifier; } /** * Returns a printable representation of the CertificatePolicyId. */ public String toString() { String s = "PolicyQualifierInfo: ["; s = s + getId() + " " + getQualifier(); s = s + "]\n"; return (s); } /** * Write the PolicyQualifier to the DerOutputStream. * * @param out the DerOutputStream to write the object to. * @exception IOException on errors. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); tmp.putOID(mId); mQualifier.encode(tmp); out.write(DerValue.tag_Sequence, tmp); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/PolicyQualifiers.java000066400000000000000000000061571362106420000256700ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the PolicyQualifiers. * * policyQualifiers ::= SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo * * @author Thomas Kwan */ public class PolicyQualifiers implements java.io.Serializable { /** * */ private static final long serialVersionUID = 6932694408774694516L; private Vector mInfo = new Vector(); /** * Create a PolicyQualifiers with the ObjectIdentifier. */ public PolicyQualifiers() { } /** * Create the object from its Der encoded value. * * @param val the DER encoded value for the same. */ public PolicyQualifiers(DerValue val) throws IOException { if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for " + "PolicyQualifiers."); } while (val.data.available() != 0) { DerValue pq = val.data.getDerValue(); PolicyQualifierInfo info = new PolicyQualifierInfo(pq); add(info); } } public void add(PolicyQualifierInfo info) { mInfo.addElement(info); } public int size() { return mInfo.size(); } public PolicyQualifierInfo getInfoAt(int i) { return mInfo.elementAt(i); } /** * Returns a printable representation of the CertificatePolicyId. */ public String toString() { StringBuffer s = new StringBuffer("PolicyQualifiers: ["); for (int i = 0; i < mInfo.size(); i++) { PolicyQualifierInfo pq = mInfo.elementAt(i); s.append(pq.toString()); } s.append("]\n"); return s.toString(); } /** * Write the PolicyQualifiers to the DerOutputStream. * * @param out the DerOutputStream to write the object to. * @exception IOException on errors. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); for (int i = 0; i < mInfo.size(); i++) { PolicyQualifierInfo pq = mInfo.elementAt(i); pq.encode(tmp); } out.write(DerValue.tag_Sequence, tmp); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/PrintableConverter.java000066400000000000000000000077511362106420000262150ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetEncoder; import org.mozilla.jss.netscape.security.util.ASN1CharStrConvMap; import org.mozilla.jss.netscape.security.util.DerValue; /** * A AVAValueConverter that converts a Printable String attribute to a DerValue * and vice versa. An example an attribute that is a printable string is "C". * * @see ASN1CharStrConvMap * @see AVAValueConverter * * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc. */ public class PrintableConverter implements AVAValueConverter { // public constructors. public PrintableConverter() { } /** * Converts a string with ASN.1 Printable characters to a DerValue. * * @param valueString a string with Printable characters. * * @return a DerValue. * * @exception IOException if a Printable encoder is not * available for the conversion. */ public DerValue getValue(String valueString) throws IOException { return getValue(valueString, null); } public DerValue getValue(String valueString, byte[] tags) throws IOException { try { CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(DerValue.tag_PrintableString); if (encoder == null) throw new IOException("No encoder for printable"); CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray()); ByteBuffer byteBuffer = encoder.encode(charBuffer); return new DerValue(DerValue.tag_PrintableString, byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit()); } catch (CharacterCodingException e) { throw new IllegalArgumentException("Invalid Printable String AVA Value", e); } } /** * Converts a BER encoded value of PrintableString to a DER encoded value. * Checks if the BER encoded value is a PrintableString. * NOTE only DER encoded values are currently accepted on input. * * @param berStream A byte array of the BER encoded value. * * @return A DerValue. * * @exception IOException if the BER value cannot be converted to a * PrintableString DER value. */ public DerValue getValue(byte[] berStream) throws IOException { DerValue value = new DerValue(berStream); if (value.tag != DerValue.tag_PrintableString) throw new IOException("Invalid Printable String AVA Value"); return value; } /** * Converts a DerValue of PrintableString to a java string with * PrintableString characters. * * @param avaValue a DerValue. * * @return a string with PrintableString characters. * * @exception IOException if the DerValue is not a PrintableString i.e. * The DerValue cannot be converted to a string * with PrintableString characters. */ public String getAsString(DerValue avaValue) throws IOException { return avaValue.getPrintableString(); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/PrivateKeyUsageExtension.java000066400000000000000000000276071362106420000273540ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import java.util.Date; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the Private Key Usage Extension. * *

* The Private Key Usage Period extension allows the certificate issuer to specify a different validity period for the * private key than the certificate. This extension is intended for use with digital signature keys. This extension * consists of two optional components notBefore and notAfter. The private key associated with the certificate should * not be used to sign objects before or after the times specified by the two components, respectively. * *

 * PrivateKeyUsagePeriod ::= SEQUENCE {
 *     notBefore  [0]  GeneralizedTime OPTIONAL,
 *     notAfter   [1]  GeneralizedTime OPTIONAL }
 * 
* * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.12 * @see Extension * @see CertAttrSet */ public class PrivateKeyUsageExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -7623695233957629936L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.PrivateKeyUsage"; /** * Sub attributes name for this CertAttrSet. */ public static final String NAME = "PrivateKeyUsage"; public static final String NOT_BEFORE = "not_before"; public static final String NOT_AFTER = "not_after"; // Private data members private static final byte TAG_BEFORE = 0; private static final byte TAG_AFTER = 1; private Date notBefore; private Date notAfter; // Encode this extension value. private void encodeThis() throws IOException { try (DerOutputStream seq = new DerOutputStream()) { DerOutputStream tagged = new DerOutputStream(); if (notBefore != null) { DerOutputStream tmp = new DerOutputStream(); tmp.putGeneralizedTime(notBefore); tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false, TAG_BEFORE), tmp); } if (notAfter != null) { DerOutputStream tmp = new DerOutputStream(); tmp.putGeneralizedTime(notAfter); tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false, TAG_AFTER), tmp); } seq.write(DerValue.tag_Sequence, tagged); extensionValue = seq.toByteArray(); } } /** * The default constructor for PrivateKeyUsageExtension. * * @param notBefore the date/time before which the private key * should not be used. * @param notAfter the date/time after which the private key * should not be used. */ public PrivateKeyUsageExtension(Date notBefore, Date notAfter) throws IOException { this.notBefore = notBefore; this.notAfter = notAfter; this.extensionId = PKIXExtensions.PrivateKeyUsage_Id; this.critical = false; encodeThis(); } /** * Create the extension from the passed DER encoded value. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * * @exception CertificateException on certificate parsing errors. * @exception IOException on error. */ public PrivateKeyUsageExtension(Boolean critical, Object value) throws CertificateException, IOException { this.extensionId = PKIXExtensions.PrivateKeyUsage_Id; this.critical = critical.booleanValue(); if (!(value instanceof byte[])) throw new CertificateException("Illegal argument type"); int len = Array.getLength(value); byte[] extValue = new byte[len]; System.arraycopy(value, 0, extValue, 0, len); this.extensionValue = extValue; DerInputStream str = new DerInputStream(extValue); DerValue[] seq = str.getSequence(2); // NB. this is always encoded with the IMPLICIT tag // The checks only make sense if we assume implicit tagging, // with explicit tagging the form is always constructed. for (int i = 0; i < seq.length; i++) { DerValue opt = seq[i]; if (opt.isContextSpecific(TAG_BEFORE) && !opt.isConstructed()) { if (notBefore != null) { throw new CertificateParsingException( "Duplicate notBefore in PrivateKeyUsage."); } opt.resetTag(DerValue.tag_GeneralizedTime); str = new DerInputStream(opt.toByteArray()); notBefore = str.getGeneralizedTime(); } else if (opt.isContextSpecific(TAG_AFTER) && !opt.isConstructed()) { if (notAfter != null) { throw new CertificateParsingException( "Duplicate notAfter in PrivateKeyUsage."); } opt.resetTag(DerValue.tag_GeneralizedTime); str = new DerInputStream(opt.toByteArray()); notAfter = str.getGeneralizedTime(); } else throw new IOException("Invalid encoding of " + "PrivateKeyUsageExtension"); } } /** * Return the printable string. */ public String toString() { return (super.toString() + "PrivateKeyUsage: [From: " + ((notBefore == null) ? "" : notBefore.toString()) + ", To: " + ((notAfter == null) ? "" : notAfter.toString()) + "]\n"); } /** * Return notBefore date */ public Date getNotBefore() { return (notBefore); } /** * Return notAfter date */ public Date getNotAfter() { return (notAfter); } /** * Verify that that the current time is within the validity period. * * @exception CertificateExpiredException if the certificate has expired. * @exception CertificateNotYetValidException if the certificate is not * yet valid. */ public void valid() throws CertificateNotYetValidException, CertificateExpiredException { Date now = new Date(); valid(now); } /** * Verify that that the passed time is within the validity period. * * @exception CertificateExpiredException if the certificate has expired * with respect to the Date supplied. * @exception CertificateNotYetValidException if the certificate is not * yet valid with respect to the Date supplied. * */ public void valid(Date now) throws CertificateNotYetValidException, CertificateExpiredException { /* * we use the internal Dates rather than the passed in Date * because someone could override the Date methods after() * and before() to do something entirely different. */ if (notBefore.after(now)) { throw new CertificateNotYetValidException("NotBefore: " + notBefore.toString()); } if (notAfter.before(now)) { throw new CertificateExpiredException("NotAfter: " + notAfter.toString()); } } /** * Write the extension to the OutputStream. * * @param out the OutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.PrivateKeyUsage_Id; critical = false; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception CertificateException on decoding errors. */ public void decode(InputStream in) throws CertificateException { throw new CertificateException("Method not to be called directly."); } /** * Set the attribute value. * * @exception CertificateException on attribute handling errors. */ public void set(String name, Object obj) throws CertificateException { clearValue(); if (!(obj instanceof Date)) { throw new CertificateException("Attribute must be of type Date."); } if (name.equalsIgnoreCase(NOT_BEFORE)) { notBefore = (Date) obj; } else if (name.equalsIgnoreCase(NOT_AFTER)) { notAfter = (Date) obj; } else { throw new CertificateException("Attribute name not recognized by" + " CertAttrSet:PrivateKeyUsage."); } } /** * Get the attribute value. * * @exception CertificateException on attribute handling errors. */ public Object get(String name) throws CertificateException { if (name.equalsIgnoreCase(NOT_BEFORE)) { return (new Date(notBefore.getTime())); } else if (name.equalsIgnoreCase(NOT_AFTER)) { return (new Date(notAfter.getTime())); } else { throw new CertificateException("Attribute name not recognized by" + " CertAttrSet:PrivateKeyUsage."); } } /** * Delete the attribute value. * * @exception CertificateException on attribute handling errors. */ public void delete(String name) throws CertificateException { if (name.equalsIgnoreCase(NOT_BEFORE)) { notBefore = null; } else if (name.equalsIgnoreCase(NOT_AFTER)) { notAfter = null; } else { throw new CertificateException("Attribute name not recognized by" + " CertAttrSet:PrivateKeyUsage."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(NOT_BEFORE); elements.addElement(NOT_AFTER); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/Qualifier.java000066400000000000000000000033221362106420000243140ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the Qualifier. * * Qualifier ::= CHOICE { * cPRuri CPSuri, * userNotice UserNotice * } * * @author Thomas Kwan */ public class Qualifier implements java.io.Serializable { /** * */ private static final long serialVersionUID = 2214531407387992974L; /** * Create a PolicyQualifierInfo */ public Qualifier() { } public Qualifier(DerValue val) throws IOException { // needs to override this } /** * Write the PolicyQualifier to the DerOutputStream. * * @param out the DerOutputStream to write the object to. * @exception IOException on errors. */ public void encode(DerOutputStream out) throws IOException { // needs to override this } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/RDN.java000066400000000000000000000211161362106420000230170ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.util.Arrays; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * RDNs are a set of {attribute = value} assertions. Some of those * attributes are "distinguished" (unique w/in context). Order is * never relevant. * * Some X.500 names include only a single distinguished attribute * per RDN. This style is currently common. * * Note that DER-encoded RDNs sort AVAs by assertion OID ... so that * when we parse this data we don't have to worry about canonicalizing * it, but we'll need to sort them when we expose the RDN class more. * * @see X500Name * @see AVA * @see LdapDNStrConverter */ public class RDN { // public constructors /** * Constructs a RDN from a Ldap DN String with one RDN component * using the global default LdapDNStrConverter. * * @see LdapDNStrConverter * @param rdnString a Ldap DN string with one RDN component, e.g. as * defined in RFC1779. * @exception IOException if error occurs while parsing the string. */ public RDN(String rdnString) throws IOException { RDN rdn = LdapDNStrConverter.getDefault().parseRDN(rdnString); assertion = rdn.getAssertion(); } /** * Like RDN(String) with a DER encoding order given as argument for * Directory Strings. */ public RDN(String rdnString, byte[] tags) throws IOException { RDN rdn = LdapDNStrConverter.getDefault().parseRDN(rdnString, tags); assertion = rdn.getAssertion(); } /** * Constructs a RDN from a Ldap DN string with one RDN component * using the specified Ldap DN Str converter. * For example, RFC1779StrConverter can be passed to parse a Ldap * DN string in RFC1779 format. * * @see LdapDNStrConverter * @param rdnString Ldap DN string. * @param ldapDNStrConverter a LdapDNStrConverter. */ public RDN(String rdnString, LdapDNStrConverter ldapDNStrConverter) throws IOException { RDN rdn = ldapDNStrConverter.parseRDN(rdnString); assertion = rdn.getAssertion(); } /** * Constructs a RDN from a DerValue. * * @param set Der value of a set of AVAs. */ public RDN(DerValue set) throws IOException { if (set.tag != DerValue.tag_Set) throw new CertParseError("X500 RDN"); int j_max = 50; // XXX j_max = f(data)!! int j; int i; AVA[] avas = new AVA[j_max]; // create a temporary array big enough for a huge set of AVA's for (j = 0; j < j_max; j++) { avas[j] = new AVA(set.data); if (set.data.available() == 0) break; } // copy the elements into it if (j >= j_max - 1) { assertion = new AVA[j + 1]; } else { assertion = new AVA[j + 1]; for (i = 0; i < (j + 1); i++) { assertion[i] = avas[i]; } } /* if (set.data.available () != 0) // throw new CertParseError ("X500 RDN 2"); System.out.println (" ... RDN parse, ignored bytes = " + set.data.available ()); */ } /** * Constructs a RDN from a Der Input Stream. * * @param in a Der Input Stream. */ public RDN(DerInputStream in) throws IOException { /* an RDN is a SET of avas */ DerValue avaset[] = in.getSet(1); int i; assertion = new AVA[avaset.length]; for (i = 0; i < assertion.length; i++) assertion[i] = new AVA(avaset[i].data); } /** * Constructs a RDN from an array of AVA. * * @param avas a AVA Array. */ public RDN(AVA avas[]) { assertion = avas.clone(); } /** * convenience method. */ public RDN(Vector avaVector) { int size = avaVector.size(); assertion = new AVA[size]; for (int i = 0; i < size; i++) { assertion[i] = avaVector.elementAt(i); } } /** * returns an array of AVA in the RDN. * * @return array of AVA in this RDN. */ public AVA[] getAssertion() { return assertion.clone(); } /** * returns the number of AVAs in the RDN. * * @return number of AVAs in this RDN. */ public int getAssertionLength() { return assertion.length; } private AVA assertion[]; private class AVAEnumerator implements Enumeration { private int index; public AVAEnumerator() { index = 0; } public boolean hasMoreElements() { return (index < assertion.length); } public AVA nextElement() { if (index >= assertion.length) return null; return assertion[index++]; } } // other public methods. @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(assertion); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; RDN other = (RDN) obj; if (!Arrays.equals(assertion, other.assertion)) return false; return true; } DerValue findAttribute(ObjectIdentifier oid) { int i; for (i = 0; i < assertion.length; i++) if (assertion[i].oid.equals(oid)) return assertion[i].value; return null; } /** * Encodes this RDN to a Der output stream. * * @param out the Der Output Stream. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); int i; for (i = 0; i < assertion.length; i++) assertion[i].encode(tmp); out.write(DerValue.tag_Set, tmp); } /** * returns an enumeration of AVAs that make up this RDN. * * @return an enumeration of AVAs that make up this RDN. */ public Enumeration getAVAs() { return new AVAEnumerator(); } /** * Returns a Ldap DN string with one RDN component using the * global default LdapDNStrConverter. * * @see LdapDNStrConverter * @return the Ldap DN String of this RDN. * @exception IOException if an error occurs during the conversion. */ public String toLdapDNString() throws IOException { return LdapDNStrConverter.getDefault().encodeRDN(this); } /** * Returns a Ldap DN String with this RDN component using the specified * LdapDNStrConverter. * * @see LdapDNStrConverter * @param ldapDNStrConverter a LdapDNStrConverter. * @return a Ldap DN String. * @exception IOException if an error occurs in the conversion. */ public String toLdapDNString(LdapDNStrConverter ldapDNStrConverter) throws IOException { return ldapDNStrConverter.encodeRDN(this); } /** * Returns a Ldap DN string with this RDN component using the global * default LdapDNStrConverter. * * @see LdapDNStrConverter * @return the Ldap DN String with this RDN component, null if an error * occurs in the conversion. */ public String toString() { String s; try { s = toLdapDNString(); } catch (IOException e) { return null; } return s; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/RFC1779StrConverter.java000066400000000000000000000065061362106420000257250ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * Converts a RFC 1779 string to a X500Name, RDN or AVA object and vice versa. * * @see LdapDNStrConverter * @see LdapV3DNStrConverter * * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc. */ public class RFC1779StrConverter extends LdapV3DNStrConverter { // // Constructors. // /** * Constructs a RFC1779StrConverter using the global default * X500NameAttrMap and accepts OIDs not listed in the attribute map. */ public RFC1779StrConverter() { super(); } /** * Constructs a RFC1779StrConverter using the specified X500NameAttrMap * and boolean for whether to accept OIDs not in the X500NameAttrMap. * * @param attributeMap A X500NameAttrMap to use for this converter. * @param doAcceptUnknownOids Accept unregistered attributes, i.e. OIDs * not in the map). */ public RFC1779StrConverter(X500NameAttrMap attributeMap, boolean doAcceptUnknownOids) { super(attributeMap, doAcceptUnknownOids); } // // overriding methods. // /** * Converts a OID to a attribute keyword in a Ldap DN string or * to a "OID.1.2.3.4" string syntax as defined in RFC1779. * * @param oid an ObjectIdentifier. * * @return a attribute keyword or "OID.1.2.3.4" string. * * @exception IOException if an error occurs during the conversion. */ public String encodeOID(ObjectIdentifier oid) throws IOException { String keyword = attrMap.getName(oid); if (keyword == null) if (!acceptUnknownOids) throw new IllegalArgumentException("Unrecognized OID"); else keyword = "OID" + "." + oid.toString(); return keyword; } /** * Converts a attribute value as a DerValue to a string in a * RFC1779 Ldap DN string. * * @param attrValue an attribute value. * @param oid ObjectIdentifier for the attribute. * @return a string in RFC1779 syntax. * @exception IOException if an error occurs during the conversion. */ public String encodeValue(DerValue attrValue, ObjectIdentifier oid) throws IOException { String s = super.encodeValue(attrValue, oid); if (s.indexOf('\n') != -1) return "\"" + s + "\""; else return s; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/RFC822Name.java000066400000000000000000000046471362106420000240550ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class implements the RFC822Name as required by the GeneralNames * ASN.1 object. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.3 * @see GeneralName * @see GeneralNames * @see GeneralNameInterface */ public class RFC822Name implements GeneralNameInterface { /** * */ private static final long serialVersionUID = -1453025303548809007L; private String name; /** * Create the RFC822Name object from the passed encoded Der value. * * @param derValue the encoded DER RFC822Name. * @exception IOException on error. */ public RFC822Name(DerValue derValue) throws IOException { name = derValue.getIA5String(); } /** * Create the RFC822Name object with the specified name. * * @param name the RFC822Name. */ public RFC822Name(String name) { this.name = name; } /** * Return the type of the GeneralName. */ public int getType() { return (GeneralNameInterface.NAME_RFC822); } /** * Encode the RFC822 name into the DerOutputStream. * * @param out the DER stream to encode the RFC822Name to. * @exception IOException on encoding errors. */ public void encode(DerOutputStream out) throws IOException { out.putIA5String(name); } /** * Convert the name into user readable string. */ public String toString() { return ("RFC822Name: " + name); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/ReasonFlags.java000066400000000000000000000225651362106420000246110ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.BitArray; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the CRL Reason Flags. * *

* This extension, if present, defines the identifies the reason for the certificate revocation. * * @author Hemma Prafullchandra * @version 1.3 * @see Extension * @see CertAttrSet */ public class ReasonFlags { /** * Reasons */ public static final String UNUSED = "unused"; public static final String KEY_COMPROMISE = "key_compromise"; public static final String CA_COMPROMISE = "ca_compromise"; public static final String AFFLIATION_CHANGED = "affliation_changed"; public static final String SUPERSEDED = "superseded"; public static final String CESSATION_OF_OPERATION = "cessation_of_operation"; public static final String CERTIFICATION_HOLD = "certification_hold"; public static final String PRIVILEGE_WITHDRAWN = "privilege_withdrawn"; public static final String AA_COMPROMISE = "aa_compromise"; // Private data members private boolean[] bitString; /** * Check if bit is set. * * @param position the position in the bit string to check. */ private boolean isSet(int position) { return bitString[position]; } /** * Set the bit at the specified position. */ private void set(int position, boolean val) { // enlarge bitString if necessary if (position >= bitString.length) { boolean[] tmp = new boolean[position + 1]; System.arraycopy(bitString, 0, tmp, 0, bitString.length); bitString = tmp; } bitString[position] = val; } /** * Create a ReasonFlags with the passed bit settings. * * @param reasons the bits to be set for the ReasonFlags. */ public ReasonFlags(byte[] reasons) { bitString = new BitArray(reasons.length * 8, reasons).toBooleanArray(); } /** * Create a ReasonFlags with the passed bit settings. * * @param reasons the bits to be set for the ReasonFlags. */ public ReasonFlags(boolean[] reasons) { this.bitString = reasons; } /** * Create a ReasonFlags with the passed bit settings. * * @param reasons the bits to be set for the ReasonFlags. */ public ReasonFlags(BitArray reasons) { this.bitString = reasons.toBooleanArray(); } /** * Create the object from the passed DER encoded value. * * @param in the DerInputStream to read the ReasonFlags from. * @exception IOException on decoding errors. */ public ReasonFlags(DerInputStream in) throws IOException { DerValue derVal = in.getDerValue(); this.bitString = derVal.getUnalignedBitString(true).toBooleanArray(); } /** * Create the object from the passed DER encoded value. * * @param derVal the DerValue decoded from the stream. * @exception IOException on decoding errors. */ public ReasonFlags(DerValue derVal) throws IOException { this.bitString = derVal.getUnalignedBitString(true).toBooleanArray(); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { if (!(obj instanceof Boolean)) { throw new IOException("Attribute must be of type Boolean."); } boolean val = ((Boolean) obj).booleanValue(); if (name.equalsIgnoreCase(UNUSED)) { set(0, val); } else if (name.equalsIgnoreCase(KEY_COMPROMISE)) { set(1, val); } else if (name.equalsIgnoreCase(CA_COMPROMISE)) { set(2, val); } else if (name.equalsIgnoreCase(AFFLIATION_CHANGED)) { set(3, val); } else if (name.equalsIgnoreCase(SUPERSEDED)) { set(4, val); } else if (name.equalsIgnoreCase(CESSATION_OF_OPERATION)) { set(5, val); } else if (name.equalsIgnoreCase(CERTIFICATION_HOLD)) { set(6, val); } else if (name.equalsIgnoreCase(PRIVILEGE_WITHDRAWN)) { set(7, val); } else if (name.equalsIgnoreCase(AA_COMPROMISE)) { set(8, val); } else { throw new IOException("Name not recognized by ReasonFlags"); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(UNUSED)) { return Boolean.valueOf(isSet(0)); } else if (name.equalsIgnoreCase(KEY_COMPROMISE)) { return Boolean.valueOf(isSet(1)); } else if (name.equalsIgnoreCase(CA_COMPROMISE)) { return Boolean.valueOf(isSet(2)); } else if (name.equalsIgnoreCase(AFFLIATION_CHANGED)) { return Boolean.valueOf(isSet(3)); } else if (name.equalsIgnoreCase(SUPERSEDED)) { return Boolean.valueOf(isSet(4)); } else if (name.equalsIgnoreCase(CESSATION_OF_OPERATION)) { return Boolean.valueOf(isSet(5)); } else if (name.equalsIgnoreCase(CERTIFICATION_HOLD)) { return Boolean.valueOf(isSet(6)); } else if (name.equalsIgnoreCase(PRIVILEGE_WITHDRAWN)) { return Boolean.valueOf(isSet(7)); } else if (name.equalsIgnoreCase(AA_COMPROMISE)) { return Boolean.valueOf(isSet(8)); } else { throw new IOException("Name not recognized by ReasonFlags"); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(UNUSED)) { set(0, false); } else if (name.equalsIgnoreCase(KEY_COMPROMISE)) { set(1, false); } else if (name.equalsIgnoreCase(CA_COMPROMISE)) { set(2, false); } else if (name.equalsIgnoreCase(AFFLIATION_CHANGED)) { set(3, false); } else if (name.equalsIgnoreCase(SUPERSEDED)) { set(4, false); } else if (name.equalsIgnoreCase(CESSATION_OF_OPERATION)) { set(5, false); } else if (name.equalsIgnoreCase(CERTIFICATION_HOLD)) { set(6, false); } else if (name.equalsIgnoreCase(PRIVILEGE_WITHDRAWN)) { set(7, false); } else if (name.equalsIgnoreCase(AA_COMPROMISE)) { set(8, false); } else { throw new IOException("Name not recognized by ReasonFlags"); } } /** * Returns a printable representation of the ReasonFlags. */ public String toString() { String s = super.toString() + "Reason Flags [\n"; try { if (isSet(0)) { s += " Unused\n"; } if (isSet(1)) { s += " Key Compromise\n"; } if (isSet(2)) { s += " CA_Compromise\n"; } if (isSet(3)) { s += " Affiliation_Changed\n"; } if (isSet(4)) { s += " Superseded\n"; } if (isSet(5)) { s += " Cessation Of Operation\n"; } if (isSet(6)) { s += " Certificate Hold\n"; } if (isSet(7)) { s += " Privilege Withdrawn\n"; } if (isSet(8)) { s += " AA Compromise\n"; } } catch (ArrayIndexOutOfBoundsException ex) { } s += "]\n"; return (s); } /** * Write the extension to the DerOutputStream. * * @param out the DerOutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(DerOutputStream out) throws IOException { out.putUnalignedBitString(new BitArray(this.bitString)); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getElements() { Vector elements = new Vector(); elements.addElement(UNUSED); elements.addElement(KEY_COMPROMISE); elements.addElement(CA_COMPROMISE); elements.addElement(AFFLIATION_CHANGED); elements.addElement(SUPERSEDED); elements.addElement(CESSATION_OF_OPERATION); elements.addElement(CERTIFICATION_HOLD); elements.addElement(PRIVILEGE_WITHDRAWN); elements.addElement(AA_COMPROMISE); return (elements.elements()); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/RevocationReason.java000066400000000000000000000106231362106420000256560ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; /** * Represent the enumerated type used in CRLReason Extension of CRL entry. * * * @author galperin * @version $Revision$, $Date$ */ public final class RevocationReason implements Serializable { private static final long serialVersionUID = -2582403666913588806L; public static final Collection INSTANCES = new ArrayList(); public static final Map CODES = new LinkedHashMap(); public static final Map LABELS = new LinkedHashMap(); /** * Reasons */ public static final RevocationReason UNSPECIFIED = new RevocationReason(0, "Unspecified"); public static final RevocationReason KEY_COMPROMISE = new RevocationReason(1, "Key_Compromise"); public static final RevocationReason CA_COMPROMISE = new RevocationReason(2, "CA_Compromise"); public static final RevocationReason AFFILIATION_CHANGED = new RevocationReason(3, "Affiliation_Changed"); public static final RevocationReason SUPERSEDED = new RevocationReason(4, "Superseded"); public static final RevocationReason CESSATION_OF_OPERATION = new RevocationReason(5, "Cessation_of_Operation"); public static final RevocationReason CERTIFICATE_HOLD = new RevocationReason(6, "Certificate_Hold"); public static final RevocationReason REMOVE_FROM_CRL = new RevocationReason(8, "Remove_from_CRL"); public static final RevocationReason PRIVILEGE_WITHDRAWN = new RevocationReason(9, "Privilege_Withdrawn"); public static final RevocationReason AA_COMPROMISE = new RevocationReason(10, "AA_Compromise"); // Private data members private int code; private String label; /** * Create a RevocationReason with the passed integer value and string label. * * @param reason integer value of the enumeration alternative. * @param label string value of the enumeration alternative. */ private RevocationReason(int reason, String label) { this.code = reason; this.label = label; INSTANCES.add(this); CODES.put(reason, this); LABELS.put(label.toLowerCase(), this); } public int getCode() { return code; } public String getLabel() { return label; } public static RevocationReason fromInt(int reason) { return valueOf(reason); } public static RevocationReason valueOf(int reason) { return CODES.get(reason); } public static RevocationReason valueOf(String string) { return LABELS.get(string.toLowerCase()); } public int toInt() { return code; } public String toString() { return label; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; RevocationReason other = (RevocationReason) obj; if (code != other.code) return false; if (label == null) { if (other.label != null) return false; } else if (!label.equals(other.label)) return false; return true; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + code; result = prime * result + ((label == null) ? 0 : label.hashCode()); return result; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/RevocationReasonAdapter.java000066400000000000000000000026351362106420000271630ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2012 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import javax.xml.bind.annotation.adapters.XmlAdapter; import org.apache.commons.lang.StringUtils; /** * The RevocationReasonAdapter class provides custom marshaling for RevocationReason. * * @author Endi S. Dewata */ public class RevocationReasonAdapter extends XmlAdapter { public RevocationReason unmarshal(String value) throws Exception { return StringUtils.isEmpty(value) ? null : RevocationReason.valueOf(value); } public String marshal(RevocationReason value) throws Exception { return value == null ? null : value.toString(); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/RevokedCertImpl.java000066400000000000000000000352151362106420000254400ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.math.BigInteger; import java.security.cert.CRLException; import java.util.Date; import java.util.Enumeration; import java.util.LinkedHashSet; import java.util.Set; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** *

* Abstract class for a revoked certificate in a CRL. This class is for each entry in the * revokedCertificates, so it deals with the inner SEQUENCE. The ASN.1 definition for this is: * *

 * revokedCertificates    SEQUENCE OF SEQUENCE  {
 *     userCertificate    CertificateSerialNumber,
 *     revocationDate     ChoiceOfTime,
 *     crlEntryExtensions Extensions OPTIONAL
 *                        -- if present, must be v2
 * }  OPTIONAL
 *
 * CertificateSerialNumber  ::=  INTEGER
 *
 * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
 *
 * Extension  ::=  SEQUENCE  {
 *     extnId        OBJECT IDENTIFIER,
 *     critical      BOOLEAN DEFAULT FALSE,
 *     extnValue     OCTET STRING
 *                   -- contains a DER encoding of a value
 *                   -- of the type registered for use with
 *                   -- the extnId object identifier value
 * }
 * 
* * @author Hemma Prafullchandra * @version 1.6 97/12/10 */ public class RevokedCertImpl extends RevokedCertificate implements Serializable { /** * */ private static final long serialVersionUID = -3449642360223397701L; private SerialNumber serialNumber; private Date revocationDate; private CRLExtensions extensions = null; private byte[] revokedCert; private final static boolean isExplicit = false; /** * Default constructor. */ public RevokedCertImpl() { } /** * Constructs a revoked certificate entry using the serial number and * revocation date. * * @param num * the serial number of the revoked certificate. * @param date * the Date on which revocation took place. */ public RevokedCertImpl(BigInteger num, Date date) { this.serialNumber = new SerialNumber(num); this.revocationDate = date; } /** * Constructs a revoked certificate entry using the serial number, * revocation date and the entry extensions. * * @param num * the serial number of the revoked certificate. * @param date * the Date on which revocation took place. * @param crlEntryExts * the extensions for this entry. */ public RevokedCertImpl(BigInteger num, Date date, CRLExtensions crlEntryExts) { this.serialNumber = new SerialNumber(num); this.revocationDate = date; this.extensions = crlEntryExts; } public byte[] getEncoded() throws CRLException { // XXX NOT IMPLEMENTED if (revokedCert == null) { DerOutputStream os = new DerOutputStream(); try { encode(os); } catch (Exception e) { // revokedCert = null; } revokedCert = os.toByteArray(); } return revokedCert; } public boolean hasUnsupportedCriticalExtension() { // XXX NOT IMPLEMENTED return true; } /** * Sets extensions for this impl. * * @param crlEntryExts * CRLExtensions */ public void setExtensions(CRLExtensions crlEntryExts) { this.extensions = crlEntryExts; } /** * Unmarshals a revoked certificate from its encoded form. * * @param revokedCert * the encoded bytes. * @exception CRLException * on parsing errors. * @exception X509ExtensionException * on extension handling errors. */ public RevokedCertImpl(byte[] revokedCert) throws CRLException, X509ExtensionException { try { DerValue derValue = new DerValue(revokedCert); parse(derValue); } catch (IOException e) { throw new CRLException("Parsing error: " + e.toString()); } } /** * Unmarshals a revoked certificate from its encoded form. * * @param derValue * the DER value containing the revoked certificate. * @exception CRLException * on parsing errors. * @exception X509ExtensionException * on extension handling errors. */ public RevokedCertImpl(DerValue derValue) throws CRLException, X509ExtensionException { parse(derValue); } /** * Returns true if this revoked certificate entry has extensions, otherwise * false. * * @return true if this CRL entry has extensions, otherwise false. */ public boolean hasExtensions() { if (extensions == null) return false; else return true; } /** * Decode a revoked certificate from an input stream. * * @param inStrm * an input stream holding at least one revoked certificate * @exception CRLException * on parsing errors. * @exception X509ExtensionException * on extension handling errors. */ public void decode(InputStream inStrm) throws CRLException, X509ExtensionException { try { DerValue derValue = new DerValue(inStrm); parse(derValue); } catch (IOException e) { throw new CRLException("Parsing error: " + e.toString()); } } /** * Encodes the revoked certificate to an output stream. * * @param outStrm * an output stream to which the encoded revoked certificate is * written. * @exception CRLException * on encoding errors. * @exception X509ExtensionException * on extension handling errors. */ public void encode(DerOutputStream outStrm) throws CRLException, X509ExtensionException { try (DerOutputStream seq = new DerOutputStream()) { if (revokedCert == null) { DerOutputStream tmp = new DerOutputStream(); // sequence { serialNumber, revocationDate, extensions } serialNumber.encode(tmp); // from 2050 should encode GeneralizedTime tmp.putUTCTime(revocationDate); if (extensions != null) extensions.encode(tmp, isExplicit); seq.write(DerValue.tag_Sequence, tmp); revokedCert = seq.toByteArray(); } outStrm.write(revokedCert); } catch (IOException e) { throw new CRLException("Encoding error: " + e.toString()); } } /** * Gets the serial number for this RevokedCertificate, the userCertificate. * * @return the serial number. */ public BigInteger getSerialNumber() { return serialNumber.getNumber().toBigInteger(); } /** * Gets the revocation date for this RevokedCertificate, the revocationDate. * * @return the revocation date. */ public Date getRevocationDate() { return (new Date(revocationDate.getTime())); } /** * Returns extensions for this impl. * * @return the CRLExtensions */ public CRLExtensions getExtensions() { return extensions; } /** * Returns a printable string of this revoked certificate. * * @return value of this revoked certificate in a printable form. */ public String toString() { StringBuffer sb = new StringBuffer(serialNumber.toString() + " On: " + revocationDate.toString()); if (extensions != null) { sb.append("\n"); for (int i = 0; i < extensions.size(); i++) sb.append("Entry Extension[" + i + "]: " + (extensions.elementAt(i)).toString()); } sb.append("\n"); return (sb.toString()); } /** * Gets a Set of the extension(s) marked CRITICAL in the * RevokedCertificate by OID strings. * * @return a set of the extension oid strings in the * Object that are marked critical. */ public Set getCriticalExtensionOIDs() { if (extensions == null) return null; Set extSet = new LinkedHashSet(); Extension ex; for (Enumeration e = extensions.getElements(); e.hasMoreElements();) { ex = e.nextElement(); if (ex.isCritical()) extSet.add(ex.getExtensionId().toString()); } return extSet; } /** * Gets a Set of the extension(s) marked NON-CRITICAL in the * RevokedCertificate by OID strings. * * @return a set of the extension oid strings in the * Object that are marked critical. */ public Set getNonCriticalExtensionOIDs() { if (extensions == null) return null; Set extSet = new LinkedHashSet(); Extension ex; for (Enumeration e = extensions.getElements(); e.hasMoreElements();) { ex = e.nextElement(); if (!ex.isCritical()) extSet.add(ex.getExtensionId().toString()); } return extSet; } /** * Gets the DER encoded OCTET string for the extension value * (extnValue) identified by the passed in oid String. * The oid string is * represented by a set of positive whole number separated * by ".", that means,
* <positive whole number>.<positive whole number>.<positive * whole number>.<...> * * @param oid the Object Identifier value for the extension. * @return the DER encoded octet string of the extension value. */ public byte[] getExtensionValue(String oid) { if (extensions == null) return null; try (DerOutputStream out = new DerOutputStream()) { String extAlias = OIDMap.getName(new ObjectIdentifier(oid)); Extension crlExt = null; if (extAlias == null) { // may be unknown ObjectIdentifier findOID = new ObjectIdentifier(oid); Extension ex = null; ObjectIdentifier inCertOID; for (Enumeration e = extensions.getElements(); e.hasMoreElements();) { ex = e.nextElement(); inCertOID = ex.getExtensionId(); if (inCertOID.equals(findOID)) { crlExt = ex; break; } } } else crlExt = extensions.get(extAlias); if (crlExt == null) return null; byte[] extData = crlExt.getExtensionValue(); if (extData == null) return null; out.putOctetString(extData); return out.toByteArray(); } catch (Exception e) { return null; } } private void parse(DerValue derVal) throws CRLException, X509ExtensionException { if (derVal.tag != DerValue.tag_Sequence) { throw new CRLException("Invalid encoded RevokedCertificate, " + "starting sequence tag missing."); } if (derVal.data.available() == 0) throw new CRLException("No data encoded for RevokedCertificates"); // serial number try { DerInputStream in = derVal.toDerInputStream(); DerValue val = in.getDerValue(); this.serialNumber = new SerialNumber(val); } catch (IOException e) { throw new CRLException("Parsing Serial Number error: " + e.toString()); } // revocationDate try { int nextByte = derVal.data.peekByte(); if ((byte) nextByte == DerValue.tag_UtcTime) { this.revocationDate = derVal.data.getUTCTime(); } else if ((byte) nextByte == DerValue.tag_GeneralizedTime) { this.revocationDate = derVal.data.getGeneralizedTime(); } else { throw new CRLException("Invalid encoding for RevokedCertificates"); } } catch (IOException e) { throw new CRLException("Parsing Revocation Date error: " + e.toString()); } if (derVal.data.available() == 0) return; // no extensions // crlEntryExtensions try { this.extensions = new CRLExtensions(derVal.toDerInputStream()); } catch (IOException e) { throw new CRLException("Parsing CRL Entry Extensions error: " + e.toString()); } } /** * Serialization write ... X.509 certificates serialize as themselves, and * they're parsed when they get read back. (Actually they serialize as some * type data from the serialization subsystem, then the cert data.) */ private void writeObject(ObjectOutputStream stream) throws CRLException, X509ExtensionException, IOException { DerOutputStream dos = new DerOutputStream(); encode(dos); dos.derEncode(stream); } /** * Serialization read ... X.509 certificates serialize as themselves, and * they're parsed when they get read back. */ private void readObject(ObjectInputStream stream) throws CRLException, X509ExtensionException, IOException { decode(stream); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/RevokedCertificate.java000066400000000000000000000055251362106420000261440ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.math.BigInteger; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.util.Date; /** *

* Abstract class for a revoked certificate in a CRL (Certificate Revocation List). * * The ASN.1 definition for revokedCertificates is: * *

 *  revokedCertificates    SEQUENCE OF SEQUENCE  {
 *      userCertificate    CertificateSerialNumber,
 *      revocationDate     ChoiceOfTime,
 *      crlEntryExtensions Extensions OPTIONAL
 *                         -- if present, must be v2
 *  }  OPTIONAL
 *  CertificateSerialNumber  ::=  INTEGER
 *  Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
 *  Extension  ::=  SEQUENCE  {
 *      extnId        OBJECT IDENTIFIER,
 *      critical      BOOLEAN DEFAULT FALSE,
 *      extnValue     OCTET STRING
 *                    -- contains a DER encoding of a value
 *                    -- of the type registered for use with
 *                    -- the extnId object identifier value
 *  }
 * 
* * @see X509CRL * * @author Hemma Prafullchandra * @version 1.4 97/12/10 */ public abstract class RevokedCertificate extends X509CRLEntry { /* implements X509Extension { */ /** * Gets the serial number for this RevokedCertificate, * the userCertificate. * * @return the serial number. */ public abstract BigInteger getSerialNumber(); /** * Gets the revocation date for this RevokedCertificate, * the revocationDate. * * @return the revocation date. */ public abstract Date getRevocationDate(); /** * Returns true if this revoked certificate entry has * extensions. * * @return true if this entry has extensions, false otherwise. */ public abstract boolean hasExtensions(); /** * Returns a string representation of this revoked certificate. * * @return a string representation of this revoked certificate. */ public abstract String toString(); public abstract CRLExtensions getExtensions(); } jss-4.6.3/org/mozilla/jss/netscape/security/x509/SerialNumber.java000066400000000000000000000074741362106420000247770ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.math.BigInteger; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the SerialNumber class used by certificates. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.5 */ public class SerialNumber implements Serializable { private static final long serialVersionUID = 1600956411497203535L; private BigInt serialNum; // Construct the class from the DerValue private void construct(DerValue derVal) throws IOException { serialNum = derVal.getInteger(); if (derVal.data.available() != 0) { throw new IOException("Excess SerialNumber data"); } } /** * The default constructor for this class using BigInteger. * * @param num the BigInteger number used to create the serial number. */ public SerialNumber(BigInteger num) { serialNum = new BigInt(num); } public SerialNumber(BigInt num) { serialNum = num; } /** * The default constructor for this class using int. * * @param num the BigInteger number used to create the serial number. */ public SerialNumber(int num) { serialNum = new BigInt(num); } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the SerialNumber from. * @exception IOException on decoding errors. */ public SerialNumber(DerInputStream in) throws IOException { DerValue derVal = in.getDerValue(); construct(derVal); } /** * Create the object, decoding the values from the passed DerValue. * * @param val the DerValue to read the SerialNumber from. * @exception IOException on decoding errors. */ public SerialNumber(DerValue val) throws IOException { construct(val); } /** * Create the object, decoding the values from the passed stream. * * @param in the InputStream to read the SerialNumber from. * @exception IOException on decoding errors. */ public SerialNumber(InputStream in) throws IOException { DerValue derVal = new DerValue(in); construct(derVal); } /** * Return the SerialNumber as user readable string. */ public String toString() { return ("SerialNumber: [" + serialNum.toString() + "]"); } /** * Encode the SerialNumber in DER form to the stream. * * @param out the DerOutputStream to marshal the contents to. * @exception IOException on errors. */ public void encode(DerOutputStream out) throws IOException { out.putInteger(serialNum); } /** * Return the serial number. */ public BigInt getNumber() { return (serialNum); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/SubjectAlternativeNameExtension.java000066400000000000000000000176341362106420000307020ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This represents the Subject Alternative Name Extension. * * This extension, if present, allows the subject to specify multiple * alternative names. * *

* Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding * of the extension value). *

* The ASN.1 syntax for this is: * *

 * SubjectAltName ::= GeneralNames
 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
 * 
* * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.9 * @see Extension * @see CertAttrSet */ public class SubjectAlternativeNameExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -4022446008355607196L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.SubjectAlternativeName"; /** * Attribute names. */ public static final String NAME = "SubjectAlternativeName"; public static final String SUBJECT_NAME = "subject_name"; // private data members GeneralNames names; // Encode this extension private void encodeThis() throws IOException { DerOutputStream os = new DerOutputStream(); try { names.encode(os); } catch (GeneralNamesException e) { throw new IOException("SubjectAlternativeName: " + e); } extensionValue = os.toByteArray(); } /** * Create a SubjectAlternativeNameExtension with the passed GeneralNames. * * @param names the GeneralNames for the subject. * @exception IOException on error. */ public SubjectAlternativeNameExtension(boolean critical, GeneralNames names) throws IOException { this.names = names; this.extensionId = PKIXExtensions.SubjectAlternativeName_Id; this.critical = critical; encodeThis(); } public SubjectAlternativeNameExtension(GeneralNames names) throws IOException { this.names = names; this.extensionId = PKIXExtensions.SubjectAlternativeName_Id; this.critical = false; encodeThis(); } /** * Create a default SubjectAlternativeNameExtension. */ public SubjectAlternativeNameExtension() { extensionId = PKIXExtensions.SubjectAlternativeName_Id; critical = false; names = new GeneralNames(); } /** * Create the extension from the passed DER encoded value. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public SubjectAlternativeNameExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.SubjectAlternativeName_Id; this.critical = critical.booleanValue(); if (!(value instanceof byte[])) throw new IOException("SubjectAlternativeName: " + "Illegal argument type"); int len = Array.getLength(value); byte[] extValue = new byte[len]; System.arraycopy(value, 0, extValue, 0, len); this.extensionValue = extValue; DerValue val = new DerValue(extValue); try { names = new GeneralNames(val); } catch (GeneralNamesException e) { throw new IOException("SubjectAlternativeName: " + e, e); } } /** * Returns a printable representation of the SubjectAlternativeName. */ public String toString() { if (names == null) return ""; String s = super.toString() + "SubjectAlternativeName [\n" + names.toString() + "]\n"; return (s); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Write the extension to the OutputStream. * * @param out the OutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.SubjectAlternativeName_Id; //critical = false; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { clearValue(); if (name.equalsIgnoreCase(SUBJECT_NAME)) { if (!(obj instanceof GeneralNames)) { throw new IOException("Attribute value should be of " + "type GeneralNames."); } names = (GeneralNames) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:SubjectAlternativeName."); } } /** * Set the GeneralNames of this extension. */ public void setGeneralNames(GeneralNames names) { clearValue(); this.names = names; } /** * Get the GeneralNames of this extension. */ public GeneralNames getGeneralNames() { return names; } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(SUBJECT_NAME)) { return (names); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:SubjectAlternativeName."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(SUBJECT_NAME)) { names = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:SubjectAlternativeName."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(SUBJECT_NAME); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/SubjectDirAttributesExtension.java000066400000000000000000000211321362106420000303740ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class represents the Subject Directory Attributes Extension. * *

* The subject directory attributes extension is not recommended as an essential part of this profile, but it may be * used in local environments. This extension MUST be non-critical. * *

 * The ASN.1 syntax for this extension is:
 *
 *    SubjectDirectoryAttributes ::= SEQUENCE (1..MAX) OF Attribute
 *
 *    Attribute	::= SEQUENCE {
 * type		AttributeType,
 * 	value		SET OF AttributeValue
 *              	-- at least one value is required --}
 *
 *    AttributeType	::= OBJECT IDENTIFIER
 *
 *    AttributeValue	::= ANY
 *
 * 
* * @author Christine Ho * @version 1.7 * * @see CertAttrSet * @see Extension */ public class SubjectDirAttributesExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = -1215458115428197688L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ //public static final String IDENT = "x509.info.extensions.SubjectDirectoryAttributes"; public static final String IDENT = "Subject Directory Attributes"; /** * Attribute names. */ public static final String NAME = "SubjectDirectoryAttributes"; // Private data members private Vector attrList = new Vector(); // Encode this extension value private void encodeThis() throws IOException { try (DerOutputStream out = new DerOutputStream()) { DerOutputStream tmp = new DerOutputStream(); //encoding the attributes Enumeration attrs = attrList.elements(); while (attrs.hasMoreElements()) { Attribute attr = attrs.nextElement(); attr.encode(tmp); } out.write(DerValue.tag_SequenceOf, tmp); this.extensionValue = out.toByteArray(); } } // Decode this extension value private void decodeThis(DerValue derVal) throws IOException { if (derVal.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for " + "Subject Directory Attribute extension."); } if (derVal.data.available() == 0) { throw new IOException(NAME + " No data available in " + "passed DER encoded value."); } // Decode all the Attributes while (derVal.data.available() != 0) { DerValue encAttr = derVal.data.getDerValue(); Attribute attr = new Attribute(encAttr); attrList.addElement(attr); } } /** * Default constructor for this object. * * @param derVal Der encoded value of this extension */ public SubjectDirAttributesExtension(DerValue derVal) throws IOException { this.extensionId = PKIXExtensions.SubjectDirectoryAttributes_Id; this.critical = false; decodeThis(derVal); } /** * Default constructor for this object. * * @param list Attribute object list */ public SubjectDirAttributesExtension(Attribute[] list) throws IOException { this.extensionId = PKIXExtensions.SubjectDirectoryAttributes_Id; this.critical = false; if ((list == null) || (list.length == 0)) { throw new IOException("No data available in " + "passed Attribute List."); } // add the Attributes for (int i = 0; i < list.length; i++) { attrList.addElement(list[i]); } } /** * Constructor from parsing extension */ public SubjectDirAttributesExtension(Boolean crit, Object value) throws IOException { this.extensionId = PKIXExtensions.SubjectDirectoryAttributes_Id; this.critical = crit.booleanValue(); if (!(value instanceof byte[])) throw new IOException(NAME + "Illegal argument type"); int len = Array.getLength(value); byte[] extValue = new byte[len]; System.arraycopy(value, 0, extValue, 0, len); this.extensionValue = extValue; decodeThis(new DerValue(extValue)); } /** * Constructor for this object. * * @param list Attribute object list * @param critical The criticality */ public SubjectDirAttributesExtension(Attribute[] list, boolean critical) throws IOException { this.extensionId = PKIXExtensions.SubjectDirectoryAttributes_Id; this.critical = critical; if ((list == null) || (list.length == 0)) { throw new IOException("No data available in " + "passed Attribute List."); } // add the Attributes for (int i = 0; i < list.length; i++) { attrList.addElement(list[i]); } } /** * Return user readable form of extension. */ public String toString() { String s = super.toString() + "SubjectDirectoryAttributes:[\n"; Enumeration attrs = attrList.elements(); StringBuffer tempBuffer = new StringBuffer(); while (attrs.hasMoreElements()) { Attribute attr = attrs.nextElement(); tempBuffer.append(attr.toString()); } s += tempBuffer.toString(); return (s + "]\n"); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { DerValue val = new DerValue(in); decodeThis(val); } /** * Encode this extension value to the output stream. * * @param out the DerOutputStream to encode the extension to. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { this.extensionId = PKIXExtensions.SubjectDirectoryAttributes_Id; this.critical = false; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { throw new IOException("Attribute name not recognized by " + "CertAttrSet:SubjectDirectoryAttributes."); } /** * Get the attribute value. */ public Object get(String name) throws IOException { throw new IOException("Attribute name not recognized by " + "CertAttrSet:SubjectDirectoryAttributes."); } /** * Delete the attribute value. */ public void delete(String name) throws IOException { throw new IOException("Attribute name not recognized by " + "CertAttrSet:SubjectDirectoryAttributes."); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } /** * Returns an enumeration of attributes in the extension. */ public Enumeration getAttributesList() { if (attrList == null) return null; return attrList.elements(); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/SubjectKeyIdentifierExtension.java000066400000000000000000000160221362106420000303440ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the Subject Key Identifier Extension. * * This extension, if present, provides a means of identifying the particular * public key used in an application. This extension by default is marked * non-critical. * *

* Extensions are addiitonal attributes which can be inserted in a X509 v3 certificate. For example a * "Driving License Certificate" could have the driving license number as a extension. * *

* Extensions are represented as a sequence of the extension identifier (Object Identifier), a boolean flag stating * whether the extension is to be treated as being critical and the extension value itself (this is again a DER encoding * of the extension value). * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.7 * @see Extension * @see CertAttrSet */ public class SubjectKeyIdentifierExtension extends Extension implements CertAttrSet { /** * */ private static final long serialVersionUID = 2457721262590880939L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info.extensions.SubjectKeyIdentifier"; /** * Attribute names. */ public static final String NAME = "SubjectKeyIdentifier"; public static final String KEY_ID = "key_id"; // Private data member private KeyIdentifier id; // Encode this extension value private void encodeThis() throws IOException { DerOutputStream os = new DerOutputStream(); id.encode(os); extensionValue = os.toByteArray(); } /** * Create a SubjectKeyIdentifierExtension with the passed octet string. * The criticality is set to False. * * @param octetString the octet string identifying the key identifier. */ public SubjectKeyIdentifierExtension(boolean critical, byte[] octetString) throws IOException { id = new KeyIdentifier(octetString); this.extensionId = PKIXExtensions.SubjectKey_Id; this.critical = critical; encodeThis(); } public SubjectKeyIdentifierExtension(byte[] octetString) throws IOException { id = new KeyIdentifier(octetString); this.extensionId = PKIXExtensions.SubjectKey_Id; this.critical = false; encodeThis(); } /** * Create the extension from the passed DER encoded value. * * @param critical true if the extension is to be treated as critical. * @param value Array of DER encoded bytes of the actual value. * @exception IOException on error. */ public SubjectKeyIdentifierExtension(Boolean critical, Object value) throws IOException { this.extensionId = PKIXExtensions.SubjectKey_Id; this.critical = critical.booleanValue(); int len = Array.getLength(value); byte[] extValue = new byte[len]; for (int i = 0; i < len; i++) { extValue[i] = Array.getByte(value, i); } this.extensionValue = extValue; DerValue val = new DerValue(extValue); this.id = new KeyIdentifier(val); } /** * Returns a printable representation. */ public String toString() { if (id == null) return ""; String s = super.toString() + "SubjectKeyIdentifier [\n" + id.toString() + "]\n"; return (s); } /** * Write the extension to the OutputStream. * * @param out the OutputStream to write the extension to. * @exception IOException on encoding errors. */ public void encode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.SubjectKey_Id; critical = false; encodeThis(); } super.encode(tmp); out.write(tmp.toByteArray()); } /** * Decode the extension from the InputStream. * * @param in the InputStream to unmarshal the contents from. * @exception IOException on decoding or validity errors. */ public void decode(InputStream in) throws IOException { throw new IOException("Method not to be called directly."); } /** * Set the attribute value. */ public void set(String name, Object obj) throws IOException { clearValue(); if (name.equalsIgnoreCase(KEY_ID)) { if (!(obj instanceof KeyIdentifier)) { throw new IOException("Attribute value should be of" + " type KeyIdentifier."); } id = (KeyIdentifier) obj; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:SubjectKeyIdentifierExtension."); } } /** * Get the attribute value. */ public Object get(String name) throws IOException { if (name.equalsIgnoreCase(KEY_ID)) { return (id); } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:SubjectKeyIdentifierExtension."); } } /** * Delete the attribute value. */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(KEY_ID)) { id = null; } else { throw new IOException("Attribute name not recognized by " + "CertAttrSet:SubjectKeyIdentifierExtension."); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(KEY_ID); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/URIName.java000066400000000000000000000046021362106420000236350ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class implements the URIName as required by the GeneralNames * ASN.1 object. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.3 * @see GeneralName * @see GeneralNames * @see GeneralNameInterface */ public class URIName implements GeneralNameInterface { /** * */ private static final long serialVersionUID = 8340049830612859508L; private String name; /** * Create the URIName object from the passed encoded Der value. * * @param derValue the encoded DER URIName. * @exception IOException on error. */ public URIName(DerValue derValue) throws IOException { name = derValue.getIA5String(); } /** * Create the URIName object with the specified name. * * @param name the URIName. */ public URIName(String name) { this.name = name; } /** * Return the type of the GeneralName. */ public int getType() { return (GeneralNameInterface.NAME_URI); } /** * Encode the URI name into the DerOutputStream. * * @param out the DER stream to encode the URIName to. * @exception IOException on encoding errors. */ public void encode(DerOutputStream out) throws IOException { out.putIA5String(name); } /** * Convert the name into user readable string. */ public String toString() { return ("URIName: " + name); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/UniqueIdentity.java000066400000000000000000000064521362106420000253620ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.BitArray; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * This class defines the UniqueIdentity class used by certificates. * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.6 */ public class UniqueIdentity { // Private data members private BitArray id; /** * The default constructor for this class. * * @param id the byte array containing the unique identifier. */ public UniqueIdentity(BitArray id) { this.id = id; } /** * The default constructor for this class. * * @param id the byte array containing the unique identifier. */ public UniqueIdentity(byte[] id) { this.id = new BitArray(id.length * 8, id); } /** * Create the object, decoding the values from the passed DER stream. * * @param in the DerInputStream to read the UniqueIdentity from. * @exception IOException on decoding errors. */ public UniqueIdentity(DerInputStream in) throws IOException { DerValue derVal = in.getDerValue(); id = derVal.getUnalignedBitString(true); } /** * Create the object, decoding the values from the passed DER stream. * * @param derVal the DerValue decoded from the stream. * @exception IOException on decoding errors. */ public UniqueIdentity(DerValue derVal) throws IOException { id = derVal.getUnalignedBitString(true); } /** * Return the UniqueIdentity as a printable string. */ public String toString() { return ("UniqueIdentity:" + id.toString() + "\n"); } /** * Encode the UniqueIdentity in DER form to the stream. * * @param out the DerOutputStream to marshal the contents to. * @param tag enocode it under the following tag. * @exception IOException on errors. */ public void encode(DerOutputStream out, byte tag) throws IOException { byte[] bytes = id.toByteArray(); int excessBits = bytes.length * 8 - id.length(); out.write(tag); out.putLength(bytes.length + 1); out.write(excessBits); out.write(bytes); } /** * Return the unique id. */ public boolean[] getId() { if (id == null) return null; return id.toBooleanArray(); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/UserNotice.java000066400000000000000000000056351362106420000244640ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Represent the UserNotice Qualifier. * * UserNotice ::= SEQUENCE { * noticeRef NoticeReference OPTIONAL, * explicitText DisplayText OPTIONAL * } * * @author Thomas Kwan */ public class UserNotice extends Qualifier { /** * */ private static final long serialVersionUID = 5770869942793748051L; private NoticeReference mNoticeReference = null; private DisplayText mDisplayText = null; public UserNotice(NoticeReference ref, DisplayText text) { mNoticeReference = ref; mDisplayText = text; } public UserNotice(DerValue val) throws IOException { if (val.tag != DerValue.tag_Sequence) { throw new IOException("Invalid encoding for UserNotice"); } // case 0: no element if (val.data.available() == 0) return; // case 1: 1 element DerValue inSeq = val.data.getDerValue(); if (inSeq.tag == DerValue.tag_Sequence) { mNoticeReference = new NoticeReference(inSeq); } else { mDisplayText = new DisplayText(inSeq); } if (val.data.available() == 0) return; // case 2: 2 elements mDisplayText = new DisplayText(val.data.getDerValue()); } public NoticeReference getNoticeReference() { return mNoticeReference; } public DisplayText getDisplayText() { return mDisplayText; } /** * Write the UserNotice to the DerOutputStream. * * @param out the DerOutputStream to write the object to. * @exception IOException on errors. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); // OPTIONAL if (mNoticeReference != null) { mNoticeReference.encode(tmp); } // OPTIONAL if (mDisplayText != null) { mDisplayText.encode(tmp); } out.write(DerValue.tag_Sequence, tmp); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/X500Name.java000066400000000000000000000533711362106420000236410ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.security.Principal; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * X.500 names are used to identify entities, such as those which are * identified by X.509 certificates. They are world-wide, hierarchical, * and descriptive. Entities can be identified by attributes, and in * some systems can be searched for according to those attributes. * *

* This class exposes only partial X.500 name functionality. Most * notably, it works best if Relative Distinguished Names only have one * (unique) attribute each, and if only the most common attributes need * to be visible to applications. This limitation, and others, will * be lifted over time. * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.35 * @see GeneralName * @see GeneralNames * @see GeneralNameInterface * @see RDN * @see AVA * @see LdapDNStrConverter */ public class X500Name implements Principal, GeneralNameInterface { /** * */ private static final long serialVersionUID = -730790062013191108L; /** * Constructs a name from a Ldap DN string, such * as "CN=Dave, OU=JavaSoft, O=Sun Microsystems, C=US". The * older "/C=US/O=Sun Microsystems, Inc/OU=JavaSoft/CN=Dave" syntax * is not currently supported. (The former is RFC 1779 style.) * * @param ldapDNString a Ldap DN String e.g. as defined in RFC1779 */ public X500Name(String ldapDNString) throws IOException { X500Name x500name; if (ldapDNString == null || ldapDNString.equals("")) { clear(); return; } x500name = LdapDNStrConverter.getDefault().parseDN(ldapDNString); names = x500name.getNames(); } /** * Constructs a X500Name from a Ldap DN String using the specified * LdapDNStrConverter. Also use the input tags. * * @see LdapDNStrConverter * * @param ldapDNString a Ldap DN String e.g. as defined in RFC1779. * @param ldapDNStrConverter A LdapDNStrConverter */ public X500Name(String ldapDNString, LdapDNStrConverter ldapDNStrConverter, byte[] tags) throws IOException { if (ldapDNString == null || ldapDNString.equals("")) { clear(); return; } X500Name x500name; x500name = ldapDNStrConverter.parseDN(ldapDNString, tags); names = x500name.getNames(); } public X500Name(String ldapDNString, byte[] tags) throws IOException { if (ldapDNString == null || ldapDNString.equals("")) { clear(); return; } X500Name x500name; x500name = LdapDNStrConverter.getDefault().parseDN(ldapDNString, tags); names = x500name.getNames(); } /** * Constructs a X500Name from a Ldap DN String using the specified * LdapDNStrConverter. * * @see LdapDNStrConverter * * @param ldapDNString a Ldap DN String e.g. as defined in RFC1779. * @param ldapDNStrConverter A LdapDNStrConverter */ public X500Name(String ldapDNString, LdapDNStrConverter ldapDNStrConverter) throws IOException { if (ldapDNString == null || ldapDNString.equals("")) { clear(); return; } X500Name x500name; x500name = ldapDNStrConverter.parseDN(ldapDNString); names = x500name.getNames(); } /** * Constructs a X500Name from fields common in enterprise application * environments. * * @param commonName common name of a person, e.g. "Vivette Davis" * @param organizationUnit small organization name, e.g. "Purchasing" * @param organizationName large organization name, e.g. "Onizuka, Inc." * @param country two letter country code, e.g. "CH" */ public X500Name( String commonName, String organizationUnit, String organizationName, String country) throws IOException { DirStrConverter dirStrConverter = new DirStrConverter(); PrintableConverter printableConverter = new PrintableConverter(); AVA[] assertion = new AVA[1]; // array is cloned in constructors. int i = 4; names = new RDN[i]; /* * NOTE: it's only on output that little-endian * ordering is used. */ assertion[0] = new AVA(commonName_oid, dirStrConverter.getValue(commonName)); names[--i] = new RDN(assertion); assertion[0] = new AVA(orgUnitName_oid, dirStrConverter.getValue(organizationUnit)); names[--i] = new RDN(assertion); assertion[0] = new AVA(orgName_oid, dirStrConverter.getValue(organizationName)); names[--i] = new RDN(assertion); assertion[0] = new AVA(countryName_oid, printableConverter.getValue(country)); names[--i] = new RDN(assertion); } /** * Constructs a X500Name from fields common in Internet application * environments. * * @param commonName common name of a person, e.g. "Vivette Davis" * @param organizationUnit small organization name, e.g. "Purchasing" * @param organizationName large organization name, e.g. "Onizuka, Inc." * @param localityName locality (city) name, e.g. "Palo Alto" * @param stateName state name, e.g. "California" * @param country two letter country code, e.g. "CH" */ public X500Name( String commonName, String organizationUnit, String organizationName, String localityName, String stateName, String country) throws IOException { DirStrConverter dirStrConverter = new DirStrConverter(); PrintableConverter printableConverter = new PrintableConverter(); AVA[] assertion = new AVA[1]; // array is cloned in constructors. int i = 6; names = new RDN[i]; /* * NOTE: it's only on output that little-endian * ordering is used. */ assertion[0] = new AVA(commonName_oid, dirStrConverter.getValue(commonName)); names[--i] = new RDN(assertion); assertion[0] = new AVA(orgUnitName_oid, dirStrConverter.getValue(organizationUnit)); names[--i] = new RDN(assertion); assertion[0] = new AVA(orgName_oid, dirStrConverter.getValue(organizationName)); names[--i] = new RDN(assertion); assertion[0] = new AVA(localityName_oid, dirStrConverter.getValue(localityName)); names[--i] = new RDN(assertion); assertion[0] = new AVA(stateName_oid, dirStrConverter.getValue(stateName)); names[--i] = new RDN(assertion); assertion[0] = new AVA(countryName_oid, printableConverter.getValue(country)); names[--i] = new RDN(assertion); } /** * Constructs a name from an ASN.1 encoded value. The encoding * of the name in the stream uses DER (a BER/1 subset). * * @param value a DER-encoded value holding an X.500 name. */ public X500Name(DerValue value) throws IOException { this(value.toDerInputStream()); } /** * Constructs a name from an ASN.1 encoded input stream. The encoding * of the name in the stream uses DER (a BER/1 subset). * * @param in DER-encoded data holding an X.500 name. */ public X500Name(DerInputStream in) throws IOException { parseDER(in); } /** * Constructs a name from an ASN.1 encoded byte array. * * @param name DER-encoded byte array holding an X.500 name. */ public X500Name(byte[] name) throws IOException { DerInputStream in = new DerInputStream(name); parseDER(in); } /** * Constructs a X500Name from array of RDN. The RDNs are expected to * be in big endian order i.e. most significant first. * * @param rdns an array of RDN. */ public X500Name(RDN[] rdns) throws IOException { names = rdns.clone(); } /** * convenience method. * * @param rdnVector a vector of rdns. */ public X500Name(Vector rdnVector) throws IOException { int size = rdnVector.size(); names = new RDN[size]; for (int i = 0; i < size; i++) { names[i] = rdnVector.elementAt(i); } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(names); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; X500Name other = (X500Name) obj; if (!Arrays.equals(names, other.names)) return false; return true; } /** * Sets private data to a null state */ private void clear() { dn = ""; names = null; } /** * Returns the name component as a Java string, regardless of its * encoding restrictions. */ private String getString(DerValue attribute) throws IOException { String value = attribute.getAsString(); if (value == null) throw new IOException("not a DER string encoding, " + attribute.tag); else return value; } /** * Return type of GeneralName. */ public int getType() { return (GeneralNameInterface.NAME_DIRECTORY); } /** * Returns a "Country" name component. If more than one * such attribute exists, the topmost one is returned. * * @return "C=" component of the name, if any. */ public String getCountry() throws IOException { DerValue attr = findAttribute(countryName_oid); return getString(attr); } /** * Returns an "Organization" name component. If more than * one such attribute exists, the topmost one is returned. * * @return "O=" component of the name, if any. */ public String getOrganization() throws IOException { DerValue attr = findAttribute(orgName_oid); return getString(attr); } /** * Returns an "Organizational Unit" name component. If more * than one such attribute exists, the topmost one is returned. * * @return "OU=" component of the name, if any. */ public String getOrganizationalUnit() throws IOException { DerValue attr = findAttribute(orgUnitName_oid); return getString(attr); } /** * Returns a "Common Name" component. If more than one such * attribute exists, the topmost one is returned. * * @return "CN=" component of the name, if any. */ public String getCommonName() throws IOException { DerValue attr = findAttribute(commonName_oid); return getString(attr); } /** * Returns a "UID" component. If more than one such * attribute exists, the topmost one is returned. * * @return "UID=" component of the name, if any. */ public String getUserID() throws IOException { DerValue attr = findAttribute(uidName_oid); return getString(attr); } /** * Returns a "Locality" name component. If more than one * such component exists, the topmost one is returned. * * @return "L=" component of the name, if any. */ public String getLocality() throws IOException { DerValue attr = findAttribute(localityName_oid); return getString(attr); } /** * Returns a "State" name component. If more than one * such component exists, the topmost one is returned. * * @return "S=" component of the name, if any. */ public String getState() throws IOException { DerValue attr = findAttribute(stateName_oid); return getString(attr); } /** * Returns a "Email" name component. If more than one * such component exists, the topmost one is returned. * * @return "E=" component of the name, if any. */ public String getEmail() throws IOException { DerValue attr = findAttribute(email_oid); if (attr == null) return null; return getString(attr); } /** * Returns a Ldap DN String from the X500Name using the global default * LdapDNStrConverter * * @see LdapDNStrConverter * @return Ldap DN string of this X500Name using the default converter. */ public String toLdapDNString() throws IOException { if (dn == null) generateDN(LdapDNStrConverter.getDefault()); return dn; } /** * Return a list of attributes of the given type. * * The "most specific" value comes last. * * If there are no name attributes of the given type, an empty * list is returned. */ public List getAttributesForOid(ObjectIdentifier oid) throws IOException { List xs = new ArrayList<>(); for (int i = 0; i < names.length; i++) { DerValue v = names[i].findAttribute(oid); if (v != null) xs.add(getString(v)); } return xs; } /** * Returns a Ldap DN String from the X500Name * using the specified LdapDNStrconverter. * For example, RFC1779String converter can be passed to convert the * DN to RFC1779 string syntax. * * @see LdapDNStrConverter * @param ldapDNStrConverter a LdapDNStrConverter * @return Ldap DN string of the X500Name */ public String toLdapDNString(LdapDNStrConverter ldapDNStrConverter) throws IOException { if (dn == null) generateDN(ldapDNStrConverter); return dn; } /** * Returns a Ldap DN string, using the global default LdapDNStrConverter * or null if an error occurs in the conversion. */ public String toString() { String s; if (names == null) { s = ""; return s; } try { s = toLdapDNString(); } catch (IOException e) { return null; } return s; } /** * Returns the value of toString(). This call is needed to * implement the java.security.Principal interface. */ public String getName() { return toString(); } private String dn; // RFC 1779 style DN, or null private RDN names[]; // RDNs /** * Find the first instance of this attribute in a "top down" * search of all the attributes in the name. */ private DerValue findAttribute(ObjectIdentifier attribute) { int i; DerValue retval = null; for (i = 0; i < names.length; i++) { retval = names[i].findAttribute(attribute); if (retval != null) break; } return retval; } /** * Returns an enumerator of RDNs in the X500Name. * * @return enumeration of rdns in this X500Name. */ public Enumeration getRDNs() { return new RDNEnumerator(); } /** * Returns an array of RDN in the X500Name. * * @return array of RDN in this X500name. */ public RDN[] getNames() { return names.clone(); } /** * Returns the number of RDNs in the X500Name. * * @return number of RDNs in this X500Name. */ public int getNamesLength() { return names.length; } /****************************************************************/ private void parseDER(DerInputStream in) throws IOException { // // X.500 names are a "SEQUENCE OF" RDNs, which means one or // more and order matters. We scan them in order, which // conventionally is big-endian. // DerValue nameseq[] = in.getSequence(5); int i; if (nameseq.length != 0) { names = new RDN[nameseq.length]; } else { clear(); } for (i = 0; i < nameseq.length; i++) names[i] = new RDN(nameseq[i]); } /** * Encodes the name in DER-encoded form. * * @param out where to put the DER-encoded X.500 name */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); int i; int len = 0; if (names == null) { len = 0; } else { len = names.length; } for (i = 0; i < len; i++) names[i].encode(tmp); out.write(DerValue.tag_Sequence, tmp); } /** * Gets the name in DER-encoded form. * * @return the DER encoded byte array of this name, * null if no names are present. */ public byte[] getEncoded() throws IOException { try (DerOutputStream out = new DerOutputStream()) { DerOutputStream tmp = new DerOutputStream(); int len = 0; if (names == null) { len = 0; } else { len = names.length; } for (int i = 0; i < len; i++) names[i].encode(tmp); out.write(DerValue.tag_Sequence, tmp); return out.toByteArray(); } } /* * Dump the printable form of a distinguished name. Each relative * name is separated from the next by a ",", and assertions in the * relative names have "label=value" syntax. * * Uses RFC 1779 syntax (i.e. little-endian, comma separators) * */ private void generateDN(LdapDNStrConverter ldapDNStrConverter) throws IOException { if (names == null) return; dn = ldapDNStrConverter.encodeDN(this); } private class RDNEnumerator implements Enumeration { private int index; public RDNEnumerator() { index = 0; } public boolean hasMoreElements() { return (index < names.length); } public RDN nextElement() { if (index >= names.length) return null; return names[index++]; } } /****************************************************************/ /* * Maybe return a preallocated OID, to reduce storage costs * and speed recognition of common X.500 attributes. */ static ObjectIdentifier intern(ObjectIdentifier oid) throws IOException { return X500NameAttrMap.getDefault().getOid(oid); } /* * Selected OIDs from X.520 */ /** OID for the "CN=" attribute, denoting a person's common name. */ public static final ObjectIdentifier commonName_oid = X500NameAttrMap.getDefault().getOid("CN"); /** OID for the "UID=" attribute, denoting a person's ID. */ public static final ObjectIdentifier uidName_oid = X500NameAttrMap.getDefault().getOid("UID"); /** OID for the "C=" attribute, denoting a country. */ public static final ObjectIdentifier countryName_oid = X500NameAttrMap.getDefault().getOid("C"); /** OID for the "L=" attribute, denoting a locality (such as a city) */ public static final ObjectIdentifier localityName_oid = X500NameAttrMap.getDefault().getOid("L"); /** OID for the "O=" attribute, denoting an organization name */ public static final ObjectIdentifier orgName_oid = X500NameAttrMap.getDefault().getOid("O"); /** OID for the "OU=" attribute, denoting an organizational unit name */ public static final ObjectIdentifier orgUnitName_oid = X500NameAttrMap.getDefault().getOid("OU"); /** OID for the "S=" attribute, denoting a state (such as Delaware) */ public static final ObjectIdentifier stateName_oid = X500NameAttrMap.getDefault().getOid("ST"); /** OID for the "STREET=" attribute, denoting a street address. */ public static final ObjectIdentifier streetAddress_oid = X500NameAttrMap.getDefault().getOid("STREET"); /** OID for the "T=" attribute, denoting a person's title. */ public static final ObjectIdentifier title_oid = X500NameAttrMap.getDefault().getOid("TITLE"); /** OID for the "E=" attribute, denoting a person's email address. */ public static final ObjectIdentifier email_oid = X500NameAttrMap.getDefault().getOid("E"); /* * OIDs from other sources which show up in X.500 names we * expect to deal with often */ private static final int ipAddress_data[] = // SKIP { 1, 3, 6, 1, 4, 1, 42, 2, 11, 2, 1 }; /** OID for "IP=" IP address attributes, used with SKIP. */ public static final ObjectIdentifier ipAddress_oid = new ObjectIdentifier(ipAddress_data); } jss-4.6.3/org/mozilla/jss/netscape/security/x509/X500NameAttrMap.java000066400000000000000000000313341362106420000251250ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.util.Enumeration; import java.util.Hashtable; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * Maps an attribute name in an X500 AVA to its OID and a * converter for the attribute type. The converter converts from a string to * its DER encoded attribute value. * For example, "CN" maps to its OID of * 2.5.4.3 and the Directory String Converter. The Directory String * Converter converts from a string to a DerValue with tag Printable, T.61 or * UniversalString. * * @author Lily Hsiao, Slava Galperin at Netscape Communications, Inc. * */ public class X500NameAttrMap { // // public constructors. // /** * Construct a X500NameAttrMap. */ public X500NameAttrMap() { } // // public get methods. // /** * Get the attribute name (keyword) of the specified OID. * * @param oid An ObjectIdentifier * * @return An attribute name (keyword string) for the OID. */ public String getName(ObjectIdentifier oid) { // XXX assert oid != null return oid2Name.get(oid); } /** * Get the ObjectIdentifier of the attribute name. * * @param name An attribute name (string of ascii characters) * * @return An ObjectIdentifier for the attribute. */ public ObjectIdentifier getOid(String name) { // XXX assert name != null return name2OID.get(name.toUpperCase()); } /** * Get the Attribute Value Converter for the specified attribute name. * * @param name An attribute name * * @return An attribute value converter for the attribute name */ public AVAValueConverter getValueConverter(String name) { ObjectIdentifier oid = name2OID.get(name.toUpperCase()); if (oid == null) return null; return oid2ValueConverter.get(oid); } /** * Get the Attribute Value Converter for the specified ObjectIdentifier. * * @param oid An ObjectIdentifier * * @return An AVAValueConverter for the OID. */ public AVAValueConverter getValueConverter(ObjectIdentifier oid) { return oid2ValueConverter.get(oid); } /** * Get an Enumeration of all attribute names in this map. * * @return An Enumeration of all attribute names. */ public Enumeration getAllNames() { return name2OID.keys(); } /** * Get an Enumeration of all ObjectIdentifiers in this map. * * @return An Enumeration of all OIDs in this map. */ public Enumeration getAllOIDs() { return oid2Name.keys(); } /** * Get the ObjectIdentifier object in the map for the specified OID. * * @param oid An ObjectIdentifier. * @return The ObjectIdentifier object in this map for the OID. */ public ObjectIdentifier getOid(ObjectIdentifier oid) { String name = oid2Name.get(oid); if (name == null) return null; return name2OID.get(name); } // // public add methods. // /** * Adds a attribute name, ObjectIdentifier, AVAValueConverter entry * to the map. * * @param name An attribute name (string of ascii chars) * @param oid The ObjectIdentifier for the attribute. * @param valueConverter An AVAValueConverter object for converting * an value for this attribute from a string to * a DerValue and vice versa. */ public void addNameOID(String name, ObjectIdentifier oid, AVAValueConverter valueConverter) { // normalize name for case insensitive compare. ObjectIdentifier theOid; Class expValueConverter; theOid = name2OID.get(name); if (theOid != null) { expValueConverter = oid2ValueConverter.get(theOid).getClass(); if (!theOid.equals(oid) || expValueConverter != valueConverter.getClass()) { throw new IllegalArgumentException( "Another keyword-oid-valueConverter triple already " + "exists in the X500NameAttrMap "); } return; } name2OID.put(name.toUpperCase(), oid); oid2Name.put(oid, name.toUpperCase()); oid2ValueConverter.put(oid, valueConverter); } // // public static methods. // /** * Get the global default X500NameAttrMap. * * @return The global default X500NameAttrMap. */ public static X500NameAttrMap getDefault() { return defMap; } /** * Get the global default X500NamAttrMap using the DirStrConverter. * * @return The global default X500NameAttrMap using the DirStrConverter. */ public static X500NameAttrMap getDirDefault() { return defDirMap; } /** * Set the global default X500NameAttrMap. * * @param newDefault The new default X500NameAttrMap. */ public static void setDefault(X500NameAttrMap newDefault) { // XXX assert newDef != null defMap = newDefault; } // // private variables // Hashtable name2OID = new Hashtable(); Hashtable oid2Name = new Hashtable(); Hashtable oid2ValueConverter = new Hashtable(); // // global defaults. // private static X500NameAttrMap defMap; private static X500NameAttrMap defDirMap; /* * Create the default maps on initialization. */ static { defMap = new X500NameAttrMap(); AVAValueConverter directoryStr = new DirStrConverter(), ia5Str = new IA5StringConverter(); defMap.addNameOID("CN", new ObjectIdentifier("2.5.4.3"), directoryStr); defMap.addNameOID("OU", new ObjectIdentifier("2.5.4.11"), directoryStr); defMap.addNameOID("O", new ObjectIdentifier("2.5.4.10"), directoryStr); // serialNumber added for CEP support defMap.addNameOID("SERIALNUMBER", new ObjectIdentifier("2.5.4.5"), new PrintableConverter()); defMap.addNameOID("C", new ObjectIdentifier("2.5.4.6"), new PrintableConverter()); defMap.addNameOID("L", new ObjectIdentifier("2.5.4.7"), directoryStr); defMap.addNameOID("ST", new ObjectIdentifier("2.5.4.8"), directoryStr); defMap.addNameOID("STREET", new ObjectIdentifier("2.5.4.9"), directoryStr); defMap.addNameOID("TITLE", new ObjectIdentifier("2.5.4.12"), directoryStr); // RFC 1274 UserId, rfc822MailBox defMap.addNameOID("UID", new ObjectIdentifier("0.9.2342.19200300.100.1.1"), directoryStr); defMap.addNameOID("MAIL", new ObjectIdentifier("0.9.2342.19200300.100.1.3"), ia5Str); // PKCS9 e-mail address defMap.addNameOID("E", new ObjectIdentifier("1.2.840.113549.1.9.1"), ia5Str); // DC definition from draft-ietf-asid-ldap-domains-02.txt defMap.addNameOID("DC", new ObjectIdentifier("0.9.2342.19200300.100.1.25"), ia5Str); // more defined in RFC2459 used in Subject Directory Attr extension defMap.addNameOID("SN", // surname new ObjectIdentifier("2.5.4.4"), directoryStr); defMap.addNameOID("GIVENNAME", new ObjectIdentifier("2.5.4.42"), directoryStr); defMap.addNameOID("INITIALS", new ObjectIdentifier("2.5.4.43"), directoryStr); defMap.addNameOID("GENERATIONQUALIFIER", new ObjectIdentifier("2.5.4.44"), directoryStr); defMap.addNameOID("DNQUALIFIER", new ObjectIdentifier("2.5.4.46"), directoryStr); // these two added mainly for CEP support // PKCS9 unstructured name defMap.addNameOID("UNSTRUCTUREDNAME", new ObjectIdentifier("1.2.840.113549.1.9.2"), ia5Str); // PKCS9 unstructured address defMap.addNameOID("UNSTRUCTUREDADDRESS", new ObjectIdentifier("1.2.840.113549.1.9.8"), new PrintableConverter()); }; static { defDirMap = new X500NameAttrMap(); AVAValueConverter directoryStr = new DirStrConverter(); defDirMap.addNameOID("CN", new ObjectIdentifier("2.5.4.3"), directoryStr); defDirMap.addNameOID("OU", new ObjectIdentifier("2.5.4.11"), directoryStr); defDirMap.addNameOID("O", new ObjectIdentifier("2.5.4.10"), directoryStr); // serialNumber added for CEP support defDirMap.addNameOID("SERIALNUMBER", new ObjectIdentifier("2.5.4.5"), directoryStr); defDirMap.addNameOID("C", new ObjectIdentifier("2.5.4.6"), directoryStr); defDirMap.addNameOID("L", new ObjectIdentifier("2.5.4.7"), directoryStr); defDirMap.addNameOID("ST", new ObjectIdentifier("2.5.4.8"), directoryStr); defDirMap.addNameOID("STREET", new ObjectIdentifier("2.5.4.9"), directoryStr); defDirMap.addNameOID("TITLE", new ObjectIdentifier("2.5.4.12"), directoryStr); // RFC 1274 UserId, rfc822MailBox defDirMap.addNameOID("UID", new ObjectIdentifier("0.9.2342.19200300.100.1.1"), directoryStr); defDirMap.addNameOID("MAIL", new ObjectIdentifier("0.9.2342.19200300.100.1.3"), directoryStr); // PKCS9 e-mail address defDirMap.addNameOID("E", new ObjectIdentifier("1.2.840.113549.1.9.1"), directoryStr); // DC definition from draft-ietf-asid-ldap-domains-02.txt defDirMap.addNameOID("DC", new ObjectIdentifier("0.9.2342.19200300.100.1.25"), directoryStr); // more defined in RFC2459 used in Subject Directory Attr extension defDirMap.addNameOID("SN", // surname new ObjectIdentifier("2.5.4.4"), directoryStr); defDirMap.addNameOID("GIVENNAME", new ObjectIdentifier("2.5.4.42"), directoryStr); defDirMap.addNameOID("INITIALS", new ObjectIdentifier("2.5.4.43"), directoryStr); defDirMap.addNameOID("GENERATIONQUALIFIER", new ObjectIdentifier("2.5.4.44"), directoryStr); defDirMap.addNameOID("DNQUALIFIER", new ObjectIdentifier("2.5.4.46"), directoryStr); // these two added mainly for CEP support // PKCS9 unstructured name defDirMap.addNameOID("UNSTRUCTUREDNAME", new ObjectIdentifier("1.2.840.113549.1.9.2"), directoryStr); // PKCS9 unstructured address defDirMap.addNameOID("UNSTRUCTUREDADDRESS", new ObjectIdentifier("1.2.840.113549.1.9.8"), directoryStr); }; } jss-4.6.3/org/mozilla/jss/netscape/security/x509/X500Signer.java000066400000000000000000000066671362106420000242160ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.security.NoSuchAlgorithmException; import java.security.Signature; import java.security.SignatureException; /** * This class provides a binding between a Signature object and an * authenticated X.500 name (from an X.509 certificate chain), which * is needed in many public key signing applications. * *

* The name of the signer is important, both because knowing it is the whole point of the signature, and because the * associated X.509 certificate is always used to verify the signature. * *

* The X.509 certificate chain is temporarily not associated with * the signer, but this omission will be resolved. * * @version 1.18 * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra */ public final class X500Signer { private Signature sig; private X500Name agent; // XXX should be X509CertChain private AlgorithmId algid; /** * Called for each chunk of the data being signed. That * is, you can present the data in many chunks, so that * it doesn't need to be in a single sequential buffer. * * @param buf buffer holding the next chunk of the data to be signed * @param offset starting point of to-be-signed data * @param len how many bytes of data are to be signed * @exception SignatureException on errors. */ public void update(byte buf[], int offset, int len) throws SignatureException { sig.update(buf, offset, len); } /** * Produces the signature for the data processed by update(). * * @exception SignatureException on errors. */ public byte[] sign() throws SignatureException { return sig.sign(); } /** * Returns the algorithm used to sign. */ public AlgorithmId getAlgorithmId() { return algid; } /** * Returns the name of the signing agent. */ public X500Name getSigner() { return agent; } /* * Constructs a binding between a signature and an X500 name * from an X.509 certificate. */ // package private ----hmmmmm ????? public X500Signer(Signature sig, X500Name agent) { if (sig == null || agent == null) throw new IllegalArgumentException("null parameter"); this.sig = sig; this.agent = agent; try { String alg = sig.getAlgorithm(); if (alg.equals("DSA")) { alg = "SHA1withDSA"; } this.algid = AlgorithmId.get(alg); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("internal error! " + e.getMessage()); } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/X509AttributeName.java000066400000000000000000000034621362106420000255320ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; /** * This class is used to parse attribute names like "x509.info.extensions". * * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.4 */ public class X509AttributeName { // Public members private static final char SEPARATOR = '.'; // Private data members private String prefix = null; private String suffix = null; /** * Default constructor for the class. Name is of the form * "x509.info.extensions". * * @param name the attribute name. */ public X509AttributeName(String name) { int i = name.indexOf(SEPARATOR); if (i == (-1)) { prefix = name; } else { prefix = name.substring(0, i); suffix = name.substring(i + 1); } } /** * Return the prefix of the name. */ public String getPrefix() { return (prefix); } /** * Return the suffix of the name. */ public String getSuffix() { return (suffix); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/X509CRLImpl.java000066400000000000000000001132721362106420000242310ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CRLException; import java.security.cert.Certificate; import java.security.cert.X509CRL; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.LinkedHashSet; import java.util.Set; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** *

* An implmentation for X509 CRL (Certificate Revocation List). *

* The X.509 v2 CRL format is described below in ASN.1: * *

 * 
*

* CertificateList ::= SEQUENCE { tbsCertList TBSCertList, signatureAlgorithm AlgorithmIdentifier, signature BIT STRING * } *

* A good description and profiling is provided in the IETF PKIX WG draft, Part I: X.509 Certificate and CRL Profile, * <draft-ietf-pkix-ipki-part1-06.txt>. *

* The ASN.1 definition of tbsCertList is: * *

 * TBSCertList  ::=  SEQUENCE  {
 *     version                 Version OPTIONAL,
 *                             -- if present, must be v2
 *     signature               AlgorithmIdentifier,
 *     issuer                  Name,
 *     thisUpdate              ChoiceOfTime,
 *     nextUpdate              ChoiceOfTime OPTIONAL,
 *     revokedCertificates     SEQUENCE OF SEQUENCE  {
 *         userCertificate         CertificateSerialNumber,
 *         revocationDate          ChoiceOfTime,
 *         crlEntryExtensions      Extensions OPTIONAL
 *                                 -- if present, must be v2
 *         }  OPTIONAL,
 *     crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
 *                                  -- if present, must be v2
 *     }
 * 
* * @author Hemma Prafullchandra * @version 1.8 * @see X509CRL */ public class X509CRLImpl extends X509CRL { // CRL data, and its envelope private byte[] signedCRL = null; // DER encoded crl private byte[] signature = null; // raw signature bits private byte[] tbsCertList = null; // DER encoded "to-be-signed" CRL private AlgorithmId sigAlgId; // sig alg in CRL // crl information private int version; private AlgorithmId infoSigAlgId; // sig alg in "to-be-signed" crl private X500Name issuer; private Date thisUpdate = null; private Date nextUpdate = null; // private static final Hashtable revokedCerts = new Hashtable(); private Hashtable revokedCerts = new Hashtable(); // private static CRLExtensions extensions = null; private CRLExtensions extensions = null; private boolean entriesIncluded = true; private final static boolean isExplicit = true; private boolean readOnly = false; /** * Unmarshals an X.509 CRL from its encoded form, parsing the encoded * bytes. This form of constructor is used by agents which * need to examine and use CRL contents. Note that the buffer * must include only one CRL, and no "garbage" may be left at * the end. * * @param crlData the encoded bytes, with no trailing padding. * @exception CRLException on parsing errors. * @exception X509ExtensionException on extension handling errors. */ public X509CRLImpl(byte[] crlData) throws CRLException, X509ExtensionException { try { DerValue in = new DerValue(crlData); parse(in); signedCRL = crlData; } catch (IOException e) { throw new CRLException("Parsing error: " + e.getMessage()); } } public X509CRLImpl(byte[] crlData, boolean includeEntries) throws CRLException, X509ExtensionException { try { entriesIncluded = includeEntries; DerValue in = new DerValue(crlData); parse(in, includeEntries); signedCRL = crlData; } catch (IOException e) { throw new CRLException("Parsing error: " + e.getMessage()); } } /** * Unmarshals an X.509 CRL from an input stream. Only one CRL * is expected at the end of the input stream. * * @param inStrm an input stream holding at least one CRL * @exception CRLException on parsing errors. * @exception X509ExtensionException on extension handling errors. */ public X509CRLImpl(InputStream inStrm) throws CRLException, X509ExtensionException { try { DerValue val = new DerValue(inStrm); parse(val); signedCRL = val.toByteArray(); } catch (IOException e) { throw new CRLException("Parsing error: " + e.getMessage()); } } /** * Initial CRL constructor, no revoked certs, and no extensions. * * @param issuer the name of the CA issuing this CRL. * @param thisDate the Date of this issue. * @param nextDate the Date of the next CRL. */ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate) { this.issuer = issuer; this.thisUpdate = thisDate; this.nextUpdate = nextDate; } /** * CRL constructor, revoked certs, no extensions. * * @param issuer the name of the CA issuing this CRL. * @param thisDate the Date of this issue. * @param nextDate the Date of the next CRL. * @param badCerts the array of revoked certificates. * * @exception CRLException on parsing/construction errors. * @exception X509ExtensionException on extension handling errors. */ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate, RevokedCertificate[] badCerts) throws CRLException, X509ExtensionException { this.issuer = issuer; this.thisUpdate = thisDate; this.nextUpdate = nextDate; if (badCerts != null) { for (int i = 0; i < badCerts.length; i++) this.revokedCerts.put(badCerts[i].getSerialNumber(), badCerts[i]); } } /** * CRL constructor, revoked certs and extensions. * * @param issuer the name of the CA issuing this CRL. * @param thisDate the Date of this issue. * @param nextDate the Date of the next CRL. * @param badCerts the array of revoked certificates. * @param crlExts the CRL extensions. * * @exception CRLException on parsing/construction errors. * @exception X509ExtensionException on extension handling errors. */ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate, RevokedCertificate[] badCerts, CRLExtensions crlExts) throws CRLException, X509ExtensionException { this.issuer = issuer; this.thisUpdate = thisDate; this.nextUpdate = nextDate; if (badCerts != null) { for (int i = 0; i < badCerts.length; i++) { if (badCerts[i] != null) { this.revokedCerts.put(badCerts[i].getSerialNumber(), badCerts[i]); if (badCerts[i].hasExtensions()) this.version = 1; } } } if (crlExts != null) { this.extensions = crlExts; this.version = 1; } } /** * CRL constructor, revoked certs and extensions. * This will be used by code that constructs CRL and uses * encodeInfo() in order to sign it using external means * (other than sign() method) * * @param issuer the name of the CA issuing this CRL. * @param algId signing algorithm id * @param thisDate the Date of this issue. * @param nextDate the Date of the next CRL. * @param badCerts the array of revoked certificates. * @param crlExts the CRL extensions. */ public X509CRLImpl(X500Name issuer, AlgorithmId algId, Date thisDate, Date nextDate, RevokedCertificate[] badCerts, CRLExtensions crlExts) throws CRLException, X509ExtensionException { this(issuer, thisDate, nextDate, badCerts, crlExts); infoSigAlgId = algId; } /** * CRL constructor, revoked certs and extensions. * * @param issuer the name of the CA issuing this CRL. * @param algId signing algorithm id * @param thisDate the Date of this issue. * @param nextDate the Date of the next CRL. * @param badCerts the hashtable of revoked certificates. * @param crlExts the CRL extensions. * * @exception CRLException on parsing/construction errors. * @exception X509ExtensionException on extension handling errors. */ public X509CRLImpl(X500Name issuer, AlgorithmId algId, Date thisDate, Date nextDate, Hashtable badCerts, CRLExtensions crlExts) throws CRLException, X509ExtensionException { this.issuer = issuer; this.thisUpdate = thisDate; this.nextUpdate = nextDate; this.revokedCerts = badCerts; if (crlExts != null) { this.extensions = crlExts; this.version = 1; } infoSigAlgId = algId; } /** * Returns the ASN.1 DER encoded form of this CRL. * * @exception CRLException if an encoding error occurs. */ public byte[] getEncoded() throws CRLException { if (signedCRL == null) throw new CRLException("Null CRL to encode"); byte[] dup = new byte[signedCRL.length]; System.arraycopy(signedCRL, 0, dup, 0, dup.length); return dup; } /** * Returns true if signedCRL was set. * * @param crl byte array of containing signed CRL. */ public boolean setSignedCRL(byte[] crl) { boolean done = false; if (tbsCertList != null && signedCRL == null) { signedCRL = new byte[crl.length]; System.arraycopy(crl, 0, signedCRL, 0, signedCRL.length); done = true; } return done; } public boolean hasUnsupportedCriticalExtension() { // XXX NOT IMPLEMENTED return true; } /** * Encodes the "to-be-signed" CRL to the OutputStream. * * @param out the OutputStream to write to. * @exception CRLException on encoding errors. * @exception X509ExtensionException on extension encoding errors. */ public void encodeInfo(OutputStream out) throws CRLException, X509ExtensionException { try (DerOutputStream seq = new DerOutputStream()) { DerOutputStream tmp = new DerOutputStream(); DerOutputStream rCerts = new DerOutputStream(); if (version != 0) // v2 crl encode version tmp.putInteger(new BigInt(version)); infoSigAlgId.encode(tmp); issuer.encode(tmp); // from 2050 should encode GeneralizedTime tmp.putUTCTime(thisUpdate); if (nextUpdate != null) tmp.putUTCTime(nextUpdate); if (!revokedCerts.isEmpty()) { for (Enumeration e = revokedCerts.elements(); e.hasMoreElements();) ((RevokedCertImpl) e.nextElement()).encode(rCerts); tmp.write(DerValue.tag_Sequence, rCerts); } if (extensions != null) extensions.encode(tmp, isExplicit); seq.write(DerValue.tag_Sequence, tmp); tbsCertList = seq.toByteArray(); out.write(tbsCertList); } catch (IOException e) { throw new CRLException("Encoding error: " + e.getMessage()); } } /** * Verifies that this CRL was signed using the * private key that corresponds to the specified public key. * * @param key the PublicKey used to carry out the verification. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException if there's no default provider. * @exception SignatureException on signature errors. * @exception CRLException on encoding errors. */ public void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { String sigProvider = null; verify(key, sigProvider); } /** * Verifies that this CRL was signed using the * private key that corresponds to the specified public key, * and that the signature verification was computed by * the given provider. * * @param key the PublicKey used to carry out the verification. * @param sigProvider the name of the signature provider. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException on incorrect provider. * @exception SignatureException on signature errors. * @exception CRLException on encoding errors. */ public void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { if (signedCRL == null) { throw new CRLException("Uninitialized CRL"); } Signature sigVerf = null; String sigAlg = sigAlgId.getName(); if (sigProvider != null && sigProvider.equals("Mozilla-JSS")) { if (sigAlg.equals("MD5withRSA")) { sigAlg = "MD5/RSA"; } else if (sigAlg.equals("MD2withRSA")) { sigAlg = "MD2/RSA"; } else if (sigAlg.equals("SHA1withRSA")) { sigAlg = "SHA1/RSA"; } else if (sigAlg.equals("SHA1withDSA")) { sigAlg = "SHA1/DSA"; } else if (sigAlg.equals("SHA1withEC")) { sigAlg = "SHA1/EC"; } else if (sigAlg.equals("SHA256withRSA")) { sigAlg = "SHA256/RSA"; } else if (sigAlg.equals("SHA384withRSA")) { sigAlg = "SHA384/RSA"; } else if (sigAlg.equals("SHA512withRSA")) { sigAlg = "SHA512/RSA"; } else if (sigAlg.equals("SHA256withEC")) { sigAlg = "SHA256/EC"; } else if (sigAlg.equals("SHA384withEC")) { sigAlg = "SHA384/EC"; } else if (sigAlg.equals("SHA512withEC")) { sigAlg = "SHA512/EC"; } } sigVerf = Signature.getInstance(sigAlg, sigProvider); sigVerf.initVerify(key); if (tbsCertList == null) throw new CRLException("Uninitialized CRL"); sigVerf.update(tbsCertList, 0, tbsCertList.length); if (!sigVerf.verify(signature)) { throw new CRLException("Signature does not match."); } } /** * Encodes an X.509 CRL, and signs it using the key * passed. * * @param key the private key used for signing. * @param algorithm the name of the signature algorithm used. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException on incorrect provider. * @exception SignatureException on signature errors. * @exception CRLException if any mandatory data was omitted. * @exception X509ExtensionException on any extension errors. */ public void sign(PrivateKey key, String algorithm) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException, X509ExtensionException { sign(key, algorithm, null); } /** * Encodes an X.509 CRL, and signs it using the key * passed. * * @param key the private key used for signing. * @param algorithm the name of the signature algorithm used. * @param provider the name of the provider. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException on incorrect provider. * @exception SignatureException on signature errors. * @exception CRLException if any mandatory data was omitted. * @exception X509ExtensionException on any extension errors. */ public void sign(PrivateKey key, String algorithm, String provider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException, X509ExtensionException { try (DerOutputStream out = new DerOutputStream()){ if (readOnly) throw new CRLException("cannot over-write existing CRL"); Signature sigEngine = null; if (provider == null) sigEngine = Signature.getInstance(algorithm); else sigEngine = Signature.getInstance(algorithm, provider); sigEngine.initSign(key); // in case the name is reset sigAlgId = AlgorithmId.get(sigEngine.getAlgorithm()); infoSigAlgId = sigAlgId; DerOutputStream tmp = new DerOutputStream(); // encode crl info encodeInfo(tmp); // encode algorithm identifier sigAlgId.encode(tmp); // Create and encode the signature itself. sigEngine.update(tbsCertList, 0, tbsCertList.length); signature = sigEngine.sign(); tmp.putBitString(signature); // Wrap the signed data in a SEQUENCE { data, algorithm, sig } out.write(DerValue.tag_Sequence, tmp); signedCRL = out.toByteArray(); readOnly = true; } catch (IOException e) { throw new CRLException("Error while encoding data: " + e.getMessage()); } } /** * Returns a printable string of this CRL. * * @return value of this CRL in a printable form. */ public String toString() { StringBuffer sb = new StringBuffer("X.509 CRL v" + (version + 1) + "\n" + "Signature Algorithm: " + sigAlgId + ", OID=" + sigAlgId.getOID() + "\n" + "Issuer: " + issuer + "\n" + "\nThis Update: " + thisUpdate + "\n"); if (nextUpdate != null) sb.append("Next Update: " + nextUpdate + "\n"); if (revokedCerts.isEmpty()) sb.append("\nNO certificates have been revoked\n"); else { sb.append("\nRevoked Certificates:\n"); for (Enumeration e = revokedCerts.elements(); e.hasMoreElements();) sb.append(e.nextElement()); } if (extensions != null) { for (int i = 0; i < extensions.size(); i++) { sb.append("\nCRL Extension[" + i + "]: " + extensions.elementAt(i)); } } org.mozilla.jss.netscape.security.util.PrettyPrintFormat pp = new org.mozilla.jss.netscape.security.util.PrettyPrintFormat(" ", 20); String signaturebits = pp.toHexString(signature); sb.append("\nSignature:\n" + signaturebits); return sb.toString(); } /** * Checks whether the given serial number is on this CRL. * * @param serialNumber the number to check for. * @return true if the given serial number is on this CRL, * false otherwise. */ public boolean isRevoked(BigInteger serialNumber) { if (revokedCerts == null || revokedCerts.isEmpty()) return false; return revokedCerts.containsKey(serialNumber); } public boolean isRevoked(Certificate cert) { if (cert == null) return false; if (cert instanceof X509Certificate) { return isRevoked(((X509Certificate) cert).getSerialNumber()); } else { return false; } } /** * Gets the version number from the CRL. * The ASN.1 definition for this is: * *
     * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
     *             -- v3 does not apply to CRLs but appears for consistency
     *             -- with definition of Version for certs
     * 
* * @return the version number. */ public int getVersion() { return version; } /** * Gets the issuer distinguished name from this CRL. * The issuer name identifies the entity who has signed (and * issued the CRL). The issuer name field contains an * X.500 distinguished name (DN). * The ASN.1 definition for this is: * *
     * issuer    Name
     *
     * Name ::= CHOICE { RDNSequence }
     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
     * RelativeDistinguishedName ::=
     *     SET OF AttributeValueAssertion
     *
     * AttributeValueAssertion ::= SEQUENCE {
     *                               AttributeType,
     *                               AttributeValue }
     * AttributeType ::= OBJECT IDENTIFIER
     * AttributeValue ::= ANY
     * 
* * The Name describes a hierarchical name composed of attributes, * such as country name, and corresponding values, such as US. * The type of the component AttributeValue is determined by the * AttributeType; in general it will be a directoryString. * A directoryString is usually one of PrintableString, * TeletexString or UniversalString. * * @return the issuer name. */ public Principal getIssuerDN() { return issuer; } /** * Gets the thisUpdate date from the CRL. * The ASN.1 definition for this is: * * @return the thisUpdate date from the CRL. */ public Date getThisUpdate() { return (new Date(thisUpdate.getTime())); } /** * Gets the nextUpdate date from the CRL. * * @return the nextUpdate date from the CRL, or null if * not present. */ public Date getNextUpdate() { if (nextUpdate == null) return null; return (new Date(nextUpdate.getTime())); } /** * Get the revoked certificate from the CRL by the serial * number provided. * * @return the revoked certificate or null if there is * no entry in the CRL marked with the provided serial number. * @see RevokedCertificate */ public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) { if (revokedCerts == null || revokedCerts.isEmpty()) return null; return revokedCerts.get(serialNumber); } /** * Gets all the revoked certificates from the CRL. * A Set of RevokedCertificate. * * @return all the revoked certificates or null if there are * none. * @see RevokedCertificate */ public Set getRevokedCertificates() { if (revokedCerts == null || revokedCerts.isEmpty()) return null; else { Set certSet = new LinkedHashSet(revokedCerts.values()); return certSet; } } @SuppressWarnings("unchecked") public Hashtable getListOfRevokedCertificates() { if (revokedCerts == null) { return null; } else { return (Hashtable) revokedCerts.clone(); } } public int getNumberOfRevokedCertificates() { if (revokedCerts == null) return -1; else return revokedCerts.size(); } /** * Gets the DER encoded CRL information, the tbsCertList from this CRL. * This can be used to verify the signature independently. * * @return the DER encoded CRL information. * @exception CRLException on parsing errors. */ public byte[] getTBSCertList() throws CRLException { if (tbsCertList == null) throw new CRLException("Uninitialized CRL"); byte[] dup = new byte[tbsCertList.length]; System.arraycopy(tbsCertList, 0, dup, 0, dup.length); return dup; } /** * Gets the raw Signature bits from the CRL. * * @return the signature. */ public byte[] getSignature() { if (signature == null) return null; byte[] dup = new byte[signature.length]; System.arraycopy(signature, 0, dup, 0, dup.length); return dup; } /** * Returns true if signature was set. * * @param crlSignature byte array of containing CRL signature. */ public boolean setSignature(byte[] crlSignature) { boolean done = false; if (tbsCertList != null && signature == null) { signature = new byte[crlSignature.length]; System.arraycopy(crlSignature, 0, signature, 0, signature.length); done = true; } return done; } /** * Gets the signature algorithm name for the CRL * signature algorithm. For example, the string "SHA1withDSA". * The ASN.1 definition for this is: * *
     * AlgorithmIdentifier  ::=  SEQUENCE  {
     *     algorithm               OBJECT IDENTIFIER,
     *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
     *                             -- contains a value of the type
     *                             -- registered for use with the
     *                             -- algorithm object identifier value
     * 
* * @return the signature algorithm name. */ public String getSigAlgName() { if (sigAlgId == null) return null; return sigAlgId.getName(); } /** * Gets the signature algorithm OID string from the CRL. * An OID is represented by a set of positive whole number separated * by ".", that means,
* <positive whole number>.<positive whole number>.<...> * For example, the string "1.2.840.10040.4.3" identifies the SHA-1 * with DSA signature algorithm, as per the PKIX part I. * * @return the signature algorithm oid string. */ public String getSigAlgOID() { if (sigAlgId == null) return null; ObjectIdentifier oid = sigAlgId.getOID(); return oid.toString(); } /** * Gets the DER encoded signature algorithm parameters from this * CRL's signature algorithm. In most cases, the signature * algorithm parameters are null, the parameters are usually * supplied with the Public Key. * * @return the DER encoded signature algorithm parameters, or * null if no parameters are present. */ public byte[] getSigAlgParams() { if (sigAlgId == null) return null; try { return sigAlgId.getEncodedParams(); } catch (IOException e) { return null; } } /** * Gets a Set of the extension(s) marked CRITICAL in the * CRL by OID strings. * * @return a set of the extension oid strings in the * CRL that are marked critical. */ public Set getCriticalExtensionOIDs() { if (extensions == null) return null; Set extSet = new LinkedHashSet(); Extension ex; for (Enumeration e = extensions.getElements(); e.hasMoreElements();) { ex = e.nextElement(); if (ex.isCritical()) { extSet.add(ex.getExtensionId().toString()); } } return extSet; } /** * Gets a Set of the extension(s) marked NON-CRITICAL in the * CRL by OID strings. * * @return a set of the extension oid strings in the * CRL that are NOT marked critical. */ public Set getNonCriticalExtensionOIDs() { if (extensions == null) return null; Set extSet = new LinkedHashSet(); Extension ex; for (Enumeration e = extensions.getElements(); e.hasMoreElements();) { ex = e.nextElement(); if (!ex.isCritical()) extSet.add(ex.getExtensionId().toString()); } return extSet; } /** * Gets the DER encoded OCTET string for the extension value * (extnValue) identified by the passed in oid String. * The oid string is * represented by a set of positive whole number separated * by ".", that means,
* <positive whole number>.<positive whole number>.<...> * * @param oid the Object Identifier value for the extension. * @return the der encoded octet string of the extension value. */ public byte[] getExtensionValue(String oid) { if (extensions == null) return null; try (DerOutputStream out = new DerOutputStream()) { String extAlias = OIDMap.getName(new ObjectIdentifier(oid)); Extension crlExt = null; if (extAlias == null) { // may be unknown ObjectIdentifier findOID = new ObjectIdentifier(oid); Extension ex = null; ObjectIdentifier inCertOID; for (Enumeration e = extensions.getElements(); e.hasMoreElements();) { ex = e.nextElement(); inCertOID = ex.getExtensionId(); if (inCertOID.equals(findOID)) { crlExt = ex; break; } } } else crlExt = extensions.get(extAlias); if (crlExt == null) return null; byte[] extData = crlExt.getExtensionValue(); if (extData == null) return null; out.putOctetString(extData); return out.toByteArray(); } catch (Exception e) { return null; } } public BigInteger getCRLNumber() { try { CRLExtensions exts = getExtensions(); if (exts == null) return null; Enumeration e = exts.getElements(); while (e.hasMoreElements()) { Extension ext = e.nextElement(); if (ext instanceof CRLNumberExtension) { CRLNumberExtension numExt = (CRLNumberExtension) ext; return (BigInteger) numExt.get(CRLNumberExtension.NUMBER); } } } catch (Exception e) { } return null; } public BigInteger getDeltaBaseCRLNumber() { try { CRLExtensions exts = getExtensions(); if (exts == null) return null; Enumeration e = exts.getElements(); while (e.hasMoreElements()) { Extension ext = e.nextElement(); if (ext instanceof DeltaCRLIndicatorExtension) { DeltaCRLIndicatorExtension numExt = (DeltaCRLIndicatorExtension) ext; return (BigInteger) numExt.get(DeltaCRLIndicatorExtension.NUMBER); } } } catch (Exception e) { } return null; } public boolean isDeltaCRL() { try { CRLExtensions exts = getExtensions(); if (exts == null) return false; Enumeration e = exts.getElements(); while (e.hasMoreElements()) { Extension ext = e.nextElement(); if (ext instanceof DeltaCRLIndicatorExtension) { return true; } } } catch (Exception e) { } return false; } /** * Returns extensions for this impl. */ public CRLExtensions getExtensions() { return extensions; } public boolean areEntriesIncluded() { return entriesIncluded; } /*********************************************************************/ /* * Parses an X.509 CRL, should be used only by constructors. */ private void parse(DerValue val) throws CRLException, IOException, X509ExtensionException { parse(val, true); } private void parse(DerValue val, boolean includeEntries) throws CRLException, IOException, X509ExtensionException { // check if can over write the certificate if (readOnly) throw new CRLException("cannot over-write existing CRL"); readOnly = true; DerValue seq[] = new DerValue[3]; seq[0] = val.data.getDerValue(); seq[1] = val.data.getDerValue(); seq[2] = val.data.getDerValue(); if (val.data.available() != 0) throw new CRLException("signed overrun, bytes = " + val.data.available()); if (seq[0].tag != DerValue.tag_Sequence) throw new CRLException("signed CRL fields invalid"); sigAlgId = AlgorithmId.parse(seq[1]); signature = seq[2].getBitString(); if (seq[1].data.available() != 0) throw new CRLException("AlgorithmId field overrun"); if (seq[2].data.available() != 0) throw new CRLException("Signature field overrun"); // the tbsCertsList tbsCertList = seq[0].toByteArray(); // parse the information DerInputStream derStrm = seq[0].data; DerValue tmp; byte nextByte; // version (optional if v1) version = 0; // by default, version = v1 == 0 nextByte = (byte) derStrm.peekByte(); if (nextByte == DerValue.tag_Integer) { version = derStrm.getInteger().toInt(); if (version != 1) // i.e. v2 throw new CRLException("Invalid version"); } tmp = derStrm.getDerValue(); // signature { AlgorithmId tmpId = AlgorithmId.parse(tmp); if (!tmpId.equals(sigAlgId)) throw new CRLException("Signature algorithm mismatch"); infoSigAlgId = tmpId; } // issuer issuer = new X500Name(derStrm); // thisUpdate // check if UTCTime encoded or GeneralizedTime nextByte = (byte) derStrm.peekByte(); if (nextByte == DerValue.tag_UtcTime) { thisUpdate = derStrm.getUTCTime(); } else if (nextByte == DerValue.tag_GeneralizedTime) { thisUpdate = derStrm.getGeneralizedTime(); } else { throw new CRLException("Invalid encoding for thisUpdate" + " (tag=" + nextByte + ")"); } if (derStrm.available() == 0) return; // done parsing no more optional fields present // nextUpdate (optional) nextByte = (byte) derStrm.peekByte(); if (nextByte == DerValue.tag_UtcTime) { nextUpdate = derStrm.getUTCTime(); } else if (nextByte == DerValue.tag_GeneralizedTime) { nextUpdate = derStrm.getGeneralizedTime(); } // else it is not present if (derStrm.available() == 0) return; // done parsing no more optional fields present // revokedCertificates (optional) nextByte = (byte) derStrm.peekByte(); if ((nextByte == DerValue.tag_SequenceOf) && (!((nextByte & 0x0c0) == 0x080))) { if (includeEntries) { DerValue[] badCerts = derStrm.getSequence(4); for (int i = 0; i < badCerts.length; i++) { RevokedCertImpl entry = new RevokedCertImpl(badCerts[i]); if (entry.hasExtensions() && (version == 0)) throw new CRLException("Invalid encoding, extensions" + " not supported in CRL v1 entries."); revokedCerts.put(entry.getSerialNumber(), entry); } } else { derStrm.skipSequence(4); } } if (derStrm.available() == 0) return; // done parsing no extensions // crlExtensions (optional) tmp = derStrm.getDerValue(); if (tmp.isConstructed() && tmp.isContextSpecific((byte) 0)) { if (version == 0) throw new CRLException("Invalid encoding, extensions not" + " supported in CRL v1."); extensions = new CRLExtensions(tmp.data); } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/X509Cert.java000066400000000000000000000703651362106420000236710ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.OutputStream; import java.io.Serializable; import java.security.Certificate; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.util.Date; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * @author David Brownell * @version 1.5 * * @see CertAndKeyGen * @deprecated Use the new X509Certificate class. * This class is only restored for backwards compatibility. */ @Deprecated public class X509Cert implements Certificate, Serializable { /** * */ private static final long serialVersionUID = -6968141532738786900L; /* The algorithm id */ protected AlgorithmId algid; /** * Construct a uninitialized X509 Cert on which * decode must later be called (or which may be deserialized). */ // XXX deprecated, delete this public X509Cert() { } /** * Unmarshals a certificate from its encoded form, parsing the * encoded bytes. This form of constructor is used by agents which * need to examine and use certificate contents. That is, this is * one of the more commonly used constructors. Note that the buffer * must include only a certificate, and no "garbage" may be left at * the end. If you need to ignore data at the end of a certificate, * use another constructor. * * @param cert the encoded bytes, with no terminatu (CONSUMED) * @exception IOException when the certificate is improperly encoded. */ public X509Cert( byte cert[]) throws IOException { DerValue in = new DerValue(cert); parse(in); if (in.data.available() != 0) throw new CertParseError("garbage at end"); signedCert = cert; } /** * Unmarshals a certificate from its encoded form, parsing the * encoded bytes. This form of constructor is used by agents which * need to examine and use certificate contents. That is, this is * one of the most commonly used constructors. * * @param buf the buffer holding the encoded bytes * @param offset the offset in the buffer where the bytes begin * @param len how many bytes of certificate exist * * @exception IOException when the certificate is improperly encoded. */ public X509Cert( byte buf[], int offset, int len) throws IOException { DerValue in = new DerValue(buf, offset, len); parse(in); if (in.data.available() != 0) throw new CertParseError("garbage at end"); signedCert = new byte[len]; System.arraycopy(buf, offset, signedCert, 0, len); } /** * Unmarshal a certificate from its encoded form, parsing a DER value. * This form of constructor is used by agents which need to examine * and use certificate contents. * * @param derVal the der value containing the encoded cert. * @exception IOException when the certificate is improperly encoded. */ public X509Cert(DerValue derVal) throws IOException { parse(derVal); if (derVal.data.available() != 0) throw new CertParseError("garbage at end"); signedCert = derVal.toByteArray(); } /** * Partially constructs a certificate from descriptive parameters. * This constructor may be used by Certificate Authority (CA) code, * which later signs and encodes the * certificate. Also, self-signed certificates serve as CA certificates, * and are sometimes used as certificate requests. * *

* Until the certificate has been signed and encoded, some of the mandatory fields in the certificate will not be * available via accessor functions: the serial number, issuer name and signing algorithm, and of course the signed * certificate. The fields passed to this constructor are available, and must be non-null. * *

* Note that the public key being signed is generally independent of the signature algorithm being used. So for * example Diffie-Hellman keys (which do not support signatures) can be placed in X.509 certificates when some other * signature algorithm (e.g. DSS/DSA, or one of the RSA based algorithms) is used. * * @see CertAndKeyGen * * @param subjectName the X.500 distinguished name being certified * @param subjectPublicKey the public key being certified. This * must be an "X509Key" implementing the "PublicKey" interface. * @param notBefore the first time the certificate is valid * @param notAfter the last time the certificate is valid * * @exception CertException if the public key is inappropriate */ public X509Cert( X500Name subjectName, X509Key subjectPublicKey, Date notBefore, Date notAfter) throws CertException { subject = subjectName; if (subjectPublicKey == null) throw new CertException(CertException.err_INVALID_PUBLIC_KEY, "Public Key is NULL"); /* * The X509 cert API requires X509 keys, else things break. */ pubkey = subjectPublicKey; notbefore = notBefore; notafter = notAfter; version = 0; } /** * Decode an X.509 certificate from an input stream. * * @param in an input stream holding at least one certificate * @exception IOException when the certificate is improperly encoded. */ public void decode(InputStream in) throws IOException { DerValue val = new DerValue(in); parse(val); if (val.data.available() != 0) throw new CertParseError("garbage at end"); signedCert = val.toByteArray(); } /** * Appends the certificate to an output stream. * * @param out an input stream to which the certificate is appended. * @exception IOException when appending fails. */ public void encode(OutputStream out) throws IOException { out.write(getSignedCert()); } /** * Compares two certificates. This is false if the * certificates are not both X.509 certs, otherwise it * compares them as binary data. * * @param other the object being compared with this one * @return true iff the certificates are equivalent */ public boolean equals(Object other) { if (other instanceof X509Cert) return equals((X509Cert) other); else return false; } /** * Compares two certificates, returning false if any data * differs between the two. * * @param src the object being compared with this one * @return true iff the certificates are equivalent */ public boolean equals(X509Cert src) { if (this == src) return true; if (signedCert == null || src.signedCert == null) return false; if (signedCert.length != src.signedCert.length) return false; for (int i = 0; i < signedCert.length; i++) if (signedCert[i] != src.signedCert[i]) return false; return true; } /** Returns the "X.509" format identifier. */ public String getFormat() // for Certificate { return "X.509"; } /** Returns getIssuerName */ public Principal getGuarantor() // for Certificate { return getIssuerName(); } /** Returns getSubjectName */ public Principal getPrincipal() { return getSubjectName(); } /** * Throws an exception if the certificate is invalid because it is * now outside of the certificate's validity period, or because it * was not signed using the verification key provided. Successfully * verifying a certificate does not indicate that one should * trust the entity which it represents. * *

* Note that since this class represents only a single X.509 * certificate, it cannot know anything about the certificate chain * which is used to provide the verification key and to establish trust. * Other code must manage and use those cert chains. * * For now, you must walk the cert chain being used to verify any * given cert. Start at the root, which is a self-signed certificate; * verify it using the key inside the certificate. Then use that to * verify the next certificate in the chain, issued by that CA. In * this manner, verify each certificate until you reach the particular * certificate you wish to verify. You should not use a certificate * if any of the verification operations for its certificate chain * were unsuccessful. * * * @param issuerPublicKey the public key of the issuing CA * @exception CertException when the certificate is not valid. */ public void verify(PublicKey issuerPublicKey) throws CertException { Date now = new Date(); if (now.before(notbefore)) throw new CertException(CertException.verf_INVALID_NOTBEFORE); if (now.after(notafter)) throw new CertException(CertException.verf_INVALID_EXPIRED); if (signedCert == null) throw new CertException(CertException.verf_INVALID_SIG, "?? certificate is not signed yet ??"); // // Verify the signature ... // String algName = null; try { Signature sigVerf = null; algName = issuerSigAlg.getName(); sigVerf = Signature.getInstance(algName); sigVerf.initVerify(issuerPublicKey); sigVerf.update(rawCert, 0, rawCert.length); if (!sigVerf.verify(signature)) { throw new CertException(CertException.verf_INVALID_SIG, "Signature ... by <" + issuer + "> for <" + subject + ">"); } // Gag -- too many catch clauses, let most through. } catch (NoSuchAlgorithmException e) { throw new CertException(CertException.verf_INVALID_SIG, "Unsupported signature algorithm (" + algName + ")"); } catch (InvalidKeyException e) { // e.printStackTrace(); throw new CertException(CertException.err_INVALID_PUBLIC_KEY, "Algorithm (" + algName + ") rejected public key"); } catch (SignatureException e) { throw new CertException(CertException.verf_INVALID_SIG, "Signature by <" + issuer + "> for <" + subject + ">"); } } /** * Creates an X.509 certificate, and signs it using the issuer * passed (associating a signature algorithm and an X.500 name). * This operation is used to implement the certificate generation * functionality of a certificate authority. * * @see #getSignedCert * @see #getSigner * @see CertAndKeyGen * * @param serial the serial number of the certificate (non-null) * @param issuer the certificate issuer (CA) (non-null) * @return the signed certificate, as returned by getSignedCert * * @exception IOException if any of the data could not be encoded, * or when any mandatory data was omitted * @exception SignatureException on signing failures */ public byte[] encodeAndSign( BigInt serial, X500Signer issuer ) throws IOException, SignatureException { rawCert = null; /* * Get the remaining cert parameters, and make sure we have enough. * * We deduce version based on what attribute data are available * For now, we have no attributes, so we always deduce X.509v1 ! */ version = 0; serialnum = serial; this.issuer = issuer.getSigner(); issuerSigAlg = issuer.getAlgorithmId(); if (subject == null || pubkey == null || notbefore == null || notafter == null) throw new IOException("not enough cert parameters"); /* * Encode the raw cert, create its signature and put it * into the envelope. */ rawCert = DERencode(); signedCert = sign(issuer, rawCert); return signedCert; } /** * Returns an X500Signer that may be used to create signatures. Those * signature may in turn be verified using this certificate (or a * copy of it). * *

* NOTE: If the private key is by itself capable of * creating signatures, this fact may not be recognized at this time. * Specifically, the case of DSS/DSA keys which get their algorithm * parameters from higher in the certificate chain is not supportable * without using an X509CertChain API, and there is no current support * for other sources of algorithm parameters. * * @param algorithmId the signature algorithm to be used. Note that a * given public/private key pair may support several such algorithms. * @param privateKey the private key used to create the signature, * which must correspond to the public key in this certificate * @return the Signer object * * @exception NoSuchAlgorithmException if the signature * algorithm is not supported * @exception InvalidKeyException if either the key in the certificate, * or the private key parameter, does not support the requested * signature algorithm */ public X500Signer getSigner(AlgorithmId algorithmId, PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeyException { String algorithm; Signature sig; if (privateKey != null) { Key key = privateKey; algorithm = key.getAlgorithm(); } else { throw new InvalidKeyException("Private Key is NULL"); } sig = Signature.getInstance(algorithmId.getName()); if (!pubkey.getAlgorithm().equals(algorithm)) { throw new InvalidKeyException("Private key algorithm " + algorithm + " incompatible with certificate " + pubkey.getAlgorithm()); } sig.initSign(privateKey); return new X500Signer(sig, subject); } /** * Returns a signature object that may be used to verify signatures * created using a specified signature algorithm and the public key * contained in this certificate. * *

* NOTE: If the public key in this certificate is not by * itself capable of verifying signatures, this may not be recognized * at this time. Specifically, the case of DSS/DSA keys which get * their algorithm parameters from higher in the certificate chain * is not supportable without using an X509CertChain API, and there * is no current support for other sources of algorithm parameters. * * @param algorithm the algorithm of the signature to be verified * @return the Signature object * @exception NoSuchAlgorithmException if the signature * algorithm is not supported * @exception InvalidKeyException if the key in the certificate * does not support the requested signature algorithm */ public Signature getVerifier(String algorithm) throws NoSuchAlgorithmException, InvalidKeyException { Signature sig; sig = Signature.getInstance(algorithm); sig.initVerify(pubkey); return sig; } /** * Return the signed X.509 certificate as a byte array. * The bytes are in standard DER marshaled form. * Null is returned in the case of a partially constructed cert. */ public byte[] getSignedCert() { return signedCert; } /** * Returns the certificate's serial number. * Null is returned in the case of a partially constructed cert. */ public BigInt getSerialNumber() { return serialnum; } /** * Returns the subject's X.500 distinguished name. */ public X500Name getSubjectName() { return subject; } /** * Returns the certificate issuer's X.500 distinguished name. * Null is returned in the case of a partially constructed cert. */ public X500Name getIssuerName() { return issuer; } /** * Returns the algorithm used by the issuer to sign the certificate. * Null is returned in the case of a partially constructed cert. */ public AlgorithmId getIssuerAlgorithmId() { return issuerSigAlg; } /** * Returns the first time the certificate is valid. */ public Date getNotBefore() { return notbefore; } /** * Returns the last time the certificate is valid. */ public Date getNotAfter() { return notafter; } /** * Returns the subject's public key. Note that some public key * algorithms support an optional certificate generation policy * where the keys in the certificates are not in themselves sufficient * to perform a public key operation. Those keys need to be augmented * by algorithm parameters, which the certificate generation policy * chose not to place in the certificate. * *

* Two such public key algorithms are: DSS/DSA, where algorithm parameters could be acquired from a CA certificate * in the chain of issuers; and Diffie-Hellman, with a similar solution although the CA then needs both a * Diffie-Hellman certificate and a signature capable certificate. */ public PublicKey getPublicKey() { return pubkey; } /** * Returns the X.509 version number of this certificate, zero based. * That is, "2" indicates an X.509 version 3 (1993) certificate, * and "0" indicates X.509v1 (1988). * Zero is returned in the case of a partially constructed cert. */ public int getVersion() { return version; } /** * Calculates a hash code value for the object. Objects * which are equal will also have the same hashcode. */ public int hashCode() { int retval = 0; for (int i = 0; i < signedCert.length; i++) retval += signedCert[i] * i; return retval; } /** * Returns a printable representation of the certificate. This does not * contain all the information available to distinguish this from any * other certificate. The certificate must be fully constructed * before this function may be called; in particular, if you are * creating certificates you must call encodeAndSign() before calling * this function. */ public String toString() { String s; if (subject == null || pubkey == null || notbefore == null || notafter == null || issuer == null || issuerSigAlg == null || serialnum == null) throw new NullPointerException("X.509 cert is incomplete"); s = " X.509v" + (version + 1) + " certificate,\n"; s += " Subject is " + subject + "\n"; s += " Key: " + pubkey; s += " Validity <" + notbefore + "> until <" + notafter + ">\n"; s += " Issuer is " + issuer + "\n"; s += " Issuer signature used " + issuerSigAlg.toString() + "\n"; s += " Serial number = " + serialnum + "\n"; // optional v2, v3 extras return "[\n" + s + "]"; } /** * Returns a printable representation of the certificate. * * @param detailed true iff lots of detail is requested */ public String toString(boolean detailed) { return toString(); } /* * Certificate data, and its envelope */ private byte rawCert[]; private byte signature[]; private byte signedCert[]; /* * X509.v1 data (parsed) */ private X500Name subject; // from subject private X509Key pubkey; private Date notafter; // from CA (constructor) private Date notbefore; private int version; // from CA (signAndEncode) private BigInt serialnum; private X500Name issuer; private AlgorithmId issuerSigAlg; /* * X509.v2 extensions */ /* * X509.v3 extensions */ /* * Other extensions ... Netscape, Verisign, SET, etc */ /************************************************************/ /* * Cert is a SIGNED ASN.1 macro, a three elment sequence: * * - Data to be signed (ToBeSigned) -- the "raw" cert * - Signature algorithm (SigAlgId) * - The signature bits * * This routine unmarshals the certificate, saving the signature * parts away for later verification. */ private void parse(DerValue val) throws IOException { DerValue seq[] = new DerValue[3]; seq[0] = val.data.getDerValue(); seq[1] = val.data.getDerValue(); seq[2] = val.data.getDerValue(); if (val.data.available() != 0) throw new CertParseError("signed overrun, bytes = " + val.data.available()); if (seq[0].tag != DerValue.tag_Sequence) throw new CertParseError("signed fields invalid"); rawCert = seq[0].toByteArray(); // XXX slow; fixme! issuerSigAlg = AlgorithmId.parse(seq[1]); signature = seq[2].getBitString(); if (seq[1].data.available() != 0) { // XXX why was this error check commented out? // It was originally part of the next check. throw new CertParseError("algid field overrun"); } if (seq[2].data.available() != 0) throw new CertParseError("signed fields overrun"); /* * Let's have fun parsing the cert itself. */ DerInputStream in; DerValue tmp; in = seq[0].data; /* * Version -- this is optional (default zero). If it's there it's * the first field and is specially tagged. * * Both branches leave "tmp" holding a value for the serial * number that comes next. */ version = 0; tmp = in.getDerValue(); if (tmp.isConstructed() && tmp.isContextSpecific()) { version = tmp.data.getInteger().toInt(); if (tmp.data.available() != 0) throw new IOException("X.509 version, bad format"); tmp = in.getDerValue(); } /* * serial number ... an integer */ serialnum = tmp.getInteger(); /* * algorithm type for CA's signature ... needs to match the * one on the envelope, and that's about it! different IDs * may represent a signature attack. In general we want to * inherit parameters. */ tmp = in.getDerValue(); { AlgorithmId algid; algid = AlgorithmId.parse(tmp); if (!algid.equals(issuerSigAlg)) throw new CertParseError("CA Algorithm mismatch!"); this.algid = algid; } /* * issuer name */ issuer = new X500Name(in); /* * validity: SEQUENCE { start date, end date } */ tmp = in.getDerValue(); if (tmp.tag != DerValue.tag_Sequence) throw new CertParseError("corrupt validity field"); notbefore = tmp.data.getUTCTime(); notafter = tmp.data.getUTCTime(); if (tmp.data.available() != 0) throw new CertParseError("excess validity data"); /* * subject name and public key */ subject = new X500Name(in); tmp = in.getDerValue(); pubkey = X509Key.parse(tmp); /* * XXX for v2 and later, a bunch of tagged options follow */ if (in.available() != 0) { /* * Until we parse V2/V3 data ... ignore it. * // throw new CertParseError ("excess cert data"); System.out.println ( "@end'o'cert, optional V2/V3 data unparsed: " + in.available () + " bytes" ); */ } } /* * Encode only the parts that will later be signed. */ private byte[] DERencode() throws IOException { DerOutputStream raw = new DerOutputStream(); encode(raw); return raw.toByteArray(); } /* * Marshal the contents of a "raw" certificate into a DER sequence. */ private void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); /* * encode serial number, issuer signing algorithm, * and issuer name into the data we'll return */ tmp.putInteger(serialnum); issuerSigAlg.encode(tmp); issuer.encode(tmp); /* * Validity is a two element sequence ... encode the * elements, then wrap them into the data we'll return */ { DerOutputStream seq = new DerOutputStream(); seq.putUTCTime(notbefore); seq.putUTCTime(notafter); tmp.write(DerValue.tag_Sequence, seq); } /* * Encode subject (principal) and associated key */ subject.encode(tmp); pubkey.encode(tmp); /* * Wrap the data; encoding of the "raw" cert is now complete. */ out.write(DerValue.tag_Sequence, tmp); } /* * Calculate the signature of the "raw" certificate, * and marshal the cert with the signature and a * description of the signing algorithm. */ private byte[] sign(X500Signer issuer, byte data[]) throws IOException, SignatureException { /* * Encode the to-be-signed data, then the algorithm used * to create the signature. */ try (DerOutputStream out = new DerOutputStream()) { DerOutputStream tmp = new DerOutputStream(); tmp.write(data); issuer.getAlgorithmId().encode(tmp); /* * Create and encode the signature itself. */ issuer.update(data, 0, data.length); signature = issuer.sign(); tmp.putBitString(signature); /* * Wrap the signed data in a SEQUENCE { data, algorithm, sig } */ out.write(DerValue.tag_Sequence, tmp); return out.toByteArray(); } } /** * Serialization write ... X.509 certificates serialize as * themselves, and they're parsed when they get read back. * (Actually they serialize as some type data from the * serialization subsystem, then the cert data.) */ private void writeObject(java.io.ObjectOutputStream stream) throws IOException { encode(stream); } /** * Serialization read ... X.509 certificates serialize as * themselves, and they're parsed when they get read back. */ private void readObject(ObjectInputStream stream) throws IOException { decode(stream); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/X509CertImpl.java000066400000000000000000001263431362106420000245110ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateFactory; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Enumeration; import java.util.LinkedHashSet; import java.util.Set; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerEncoder; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.util.ObjectIdentifier; /** * The X509CertImpl class represents an X.509 certificate. These certificates * are widely used to support authentication and other functionality in * Internet security systems. Common applications include Privacy Enhanced * Mail (PEM), Transport Layer Security (SSL), code signing for trusted * software distribution, and Secure Electronic Transactions (SET). There * is a commercial infrastructure ready to manage large scale deployments * of X.509 identity certificates. * *

* These certificates are managed and vouched for by Certificate * Authorities (CAs). CAs are services which create certificates by placing data in the X.509 standard format and * then digitally signing that data. Such signatures are quite difficult to forge. CAs act as trusted third parties, * making introductions between agents who have no direct knowledge of each other. CA certificates are either signed by * themselves, or by some other CA such as a "root" CA. * *

* RFC 1422 is very informative, though it does not describe much of the recent work being done with X.509 certificates. * That includes a 1996 version (X.509v3) and a variety of enhancements being made to facilitate an explosion of * personal certificates used as "Internet Drivers' Licences", or with SET for credit card transactions. * *

* More recent work includes the IETF PKIX Working Group efforts, especially part 1. * * @author Dave Brownell * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.94 97/12/10 * @see X509CertInfo */ public class X509CertImpl extends X509Certificate implements Serializable, DerEncoder { // Serialization compatibility with the X509CertImpl in x509v1.jar // supporting the subset of X509Certificate on JDK1.1.x platforms. static final long serialVersionUID = -2048442350420423405L; private static final String DOT = "."; /** * Public attribute names. */ public static final String NAME = "x509"; public static final String INFO = X509CertInfo.NAME; public static final String ALG_ID = "algorithm"; public static final String SIGNATURE = "signature"; public static final String SIGNED_CERT = "signed_cert"; /** * The following are defined for ease-of-use. These * are the most frequently retrieved attributes. */ // x509.info.subject.dname public static final String SUBJECT_DN = NAME + DOT + INFO + DOT + X509CertInfo.SUBJECT + DOT + CertificateSubjectName.DN_NAME; // x509.info.issuer.dname public static final String ISSUER_DN = NAME + DOT + INFO + DOT + X509CertInfo.ISSUER + DOT + CertificateIssuerName.DN_NAME; // x509.info.serialNumber.number public static final String SERIAL_ID = NAME + DOT + INFO + DOT + X509CertInfo.SERIAL_NUMBER + DOT + CertificateSerialNumber.NUMBER; // x509.info.key.value public static final String PUBLIC_KEY = NAME + DOT + INFO + DOT + X509CertInfo.KEY + DOT + CertificateX509Key.KEY; // x509.algorithm public static final String SIG_ALG = NAME + DOT + ALG_ID; // x509.signature public static final String SIG = NAME + DOT + SIGNATURE; // when we sign and decode we set this to true // this is our means to make certificates immutable private boolean readOnly = false; // Certificate data, and its envelope private byte[] signedCert; protected X509CertInfo info = null; protected AlgorithmId algId; protected byte[] signature; // recognized extension OIDS private static final String KEY_USAGE_OID = "2.5.29.15"; private static final String BASIC_CONSTRAINT_OID = "2.5.29.19"; /** * Default constructor. */ public X509CertImpl() { } /** * Unmarshals a certificate from its encoded form, parsing the * encoded bytes. This form of constructor is used by agents which * need to examine and use certificate contents. That is, this is * one of the more commonly used constructors. Note that the buffer * must include only a certificate, and no "garbage" may be left at * the end. If you need to ignore data at the end of a certificate, * use another constructor. * * @param certData the encoded bytes, with no trailing padding. * @exception CertificateException on parsing and initialization errors. */ public X509CertImpl(byte[] certData) throws CertificateException { this(certData, null); } /** * As a special optimization, this constructor acts as X509CertImpl(byte[]) * except that it takes an X509CertInfo which it uses as a 'hint' for * how to construct one field. * * @param certData the encode bytes, with no traiing padding * @param certInfo the certInfo which has already been constructed * from the certData */ public X509CertImpl(byte[] certData, X509CertInfo certInfo) throws CertificateException { // setting info here causes it to skip decoding in the parse() // method info = certInfo; try { DerValue in = new DerValue(certData); parse(in); signedCert = certData; } catch (IOException e) { throw new CertificateException("Unable to parse certificate data: " + e.getMessage(), e); } } /** * unmarshals an X.509 certificate from an input stream. * * @param in an input stream holding at least one certificate * @exception CertificateException on parsing and initialization errors. */ public X509CertImpl(InputStream in) throws CertificateException { try { DerValue val = new DerValue(in); parse(val); signedCert = val.toByteArray(); } catch (IOException e) { throw new CertificateException("Unable to parse certificate data: " + e.getMessage(), e); } } /** * Construct an initialized X509 Certificate. The certificate is stored * in raw form and has to be signed to be useful. * * @param certInfo the X509CertificateInfo which the Certificate is to be * created from. */ public X509CertImpl(X509CertInfo certInfo) { this.info = certInfo; } /** * Unmarshal a certificate from its encoded form, parsing a DER value. * This form of constructor is used by agents which need to examine * and use certificate contents. * * @param derVal the der value containing the encoded cert. * @exception CertificateException on parsing and initialization errors. */ public X509CertImpl(DerValue derVal) throws CertificateException { try { parse(derVal); signedCert = derVal.toByteArray(); } catch (IOException e) { throw new CertificateException("Unable to parse certificate data: " + e.getMessage(), e); } } public boolean hasUnsupportedCriticalExtension() { // XXX NOT IMPLEMENTED return true; } /** * Decode an X.509 certificate from an input stream. * * @param in an input stream holding at least one certificate * @exception CertificateException on parsing errors. * @exception IOException on other errors. */ public void decode(InputStream in) throws CertificateException, IOException { DerValue val = new DerValue(in); parse(val); signedCert = val.toByteArray(); } /** * Appends the certificate to an output stream. * * @param out an input stream to which the certificate is appended. * @exception CertificateEncodingException on encoding errors. */ public void encode(OutputStream out) throws CertificateEncodingException { if (signedCert == null) throw new CertificateEncodingException( "Missing certificate to encode"); try { out.write(signedCert); } catch (IOException e) { throw new CertificateEncodingException("Unable to encode certificate: " + e.getMessage(), e); } } /** * DER encode this object onto an output stream. * Implements the DerEncoder interface. * * @param out * the output stream on which to write the DER encoding. * * @exception IOException on encoding error. */ public void derEncode(OutputStream out) throws IOException { if (signedCert == null) throw new IOException("Missing certificate to encode"); out.write(signedCert); } /** * Returns the encoded form of this certificate. It is * assumed that each certificate type would have only a single * form of encoding; for example, X.509 certificates would * be encoded as ASN.1 DER. * * @exception CertificateEncodingException if an encoding error occurs. */ public byte[] getEncoded() throws CertificateEncodingException { if (signedCert == null) throw new CertificateEncodingException( "Missing certificate to encode"); byte[] dup = new byte[signedCert.length]; System.arraycopy(signedCert, 0, dup, 0, dup.length); return dup; } /** * Throws an exception if the certificate was not signed using the * verification key provided. Successfully verifying a certificate * does not indicate that one should trust the entity which * it represents. * * @param key the public key used for verification. * * @exception InvalidKeyException on incorrect key. * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception NoSuchProviderException if there's no default provider. * @exception SignatureException on signature errors. * @exception CertificateException on encoding errors. */ public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { String sigProvider = null; verify(key, sigProvider); } /** * Throws an exception if the certificate was not signed using the * verification key provided. Successfully verifying a certificate * does not indicate that one should trust the entity which * it represents. * * @param key the public key used for verification. * @param sigProvider the name of the provider. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException on incorrect provider. * @exception SignatureException on signature errors. * @exception CertificateException on encoding errors. */ public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { if (signedCert == null) { throw new CertificateEncodingException("Missing certificate"); } // Verify the signature ... Signature sigVerf = null; sigVerf = Signature.getInstance(algId.getName(), sigProvider); sigVerf.initVerify(key); byte[] rawCert = info.getEncodedInfo(); sigVerf.update(rawCert, 0, rawCert.length); if (!sigVerf.verify(signature)) { throw new SignatureException("Signature does not match"); } } /** * Creates an X.509 certificate, and signs it using the key * passed (associating a signature algorithm and an X.500 name). * This operation is used to implement the certificate generation * functionality of a certificate authority. * * @param key the private key used for signing. * @param algorithm the name of the signature algorithm used. * * @exception InvalidKeyException on incorrect key. * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception NoSuchProviderException if there's no default provider. * @exception SignatureException on signature errors. * @exception CertificateException on encoding errors. */ public void sign(PrivateKey key, String algorithm) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { sign(key, algorithm, null); } /** * Creates an X.509 certificate, and signs it using the key * passed (associating a signature algorithm and an X.500 name). * This operation is used to implement the certificate generation * functionality of a certificate authority. * * @param key the private key used for signing. * @param algorithm the name of the signature algorithm used. * @param provider the name of the provider. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException on incorrect provider. * @exception SignatureException on signature errors. * @exception CertificateException on encoding errors. */ public void sign(PrivateKey key, String algorithm, String provider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { try (DerOutputStream out = new DerOutputStream()){ if (readOnly) throw new CertificateEncodingException( "Cannot overwrite existing certificate"); Signature sigEngine = null; if (provider == null) sigEngine = Signature.getInstance(algorithm); else sigEngine = Signature.getInstance(algorithm, provider); sigEngine.initSign(key); // in case the name is reset algId = AlgorithmId.get(sigEngine.getAlgorithm()); DerOutputStream tmp = new DerOutputStream(); // encode certificate info info.encode(tmp); byte[] rawCert = tmp.toByteArray(); // encode algorithm identifier algId.encode(tmp); // Create and encode the signature itself. sigEngine.update(rawCert, 0, rawCert.length); signature = sigEngine.sign(); tmp.putBitString(signature); // Wrap the signed data in a SEQUENCE { data, algorithm, sig } out.write(DerValue.tag_Sequence, tmp); signedCert = out.toByteArray(); readOnly = true; } catch (IOException e) { throw new CertificateEncodingException("Unable to sign certificate: " + e.getMessage(), e); } } /** * Checks that the certificate is currently valid, i.e. the current * time is within the specified validity period. * * @exception CertificateExpiredException if the certificate has expired. * @exception CertificateNotYetValidException if the certificate is not * yet valid. */ public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { Date date = new Date(); checkValidity(date); } /** * Checks that the specified date is within the certificate's * validity period, or basically if the certificate would be * valid at the specified date/time. * * @param date the Date to check against to see if this certificate * is valid at that date/time. * * @exception CertificateExpiredException if the certificate has expired * with respect to the date supplied. * @exception CertificateNotYetValidException if the certificate is not * yet valid with respect to the date supplied. */ public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException { CertificateValidity interval = null; try { interval = (CertificateValidity) info.get(CertificateValidity.NAME); } catch (Exception e) { throw new CertificateNotYetValidException("Incorrect validity period: " + e.getMessage()); } if (interval == null) throw new CertificateNotYetValidException("Null validity period"); interval.valid(date); } /** * Return the requested attribute from the certificate. * * @param name the name of the attribute. * @exception CertificateParsingException on invalid attribute identifier. */ public Object get(String name) throws CertificateParsingException { X509AttributeName attr = new X509AttributeName(name); String id = attr.getPrefix(); if (!(id.equalsIgnoreCase(NAME))) { throw new CertificateParsingException("Invalid root of " + "attribute name, expected [" + NAME + "], received " + "[" + id + "]"); } attr = new X509AttributeName(attr.getSuffix()); id = attr.getPrefix(); if (id.equalsIgnoreCase(INFO)) { if (attr.getSuffix() != null) { try { return info.get(attr.getSuffix()); } catch (IOException e) { throw new CertificateParsingException("Unable to get certificate attribute: " + e.getMessage(), e); } catch (CertificateException e) { throw new CertificateParsingException("Unable to get certificate attribute: " + e.getMessage(), e); } } else { return (info); } } else if (id.equalsIgnoreCase(ALG_ID)) { return (algId); } else if (id.equalsIgnoreCase(SIGNATURE)) { return (signature); } else if (id.equalsIgnoreCase(SIGNED_CERT)) { return (signedCert); } else { throw new CertificateParsingException("Attribute name not " + "recognized or get() not allowed for the same: " + id); } } /** * Set the requested attribute in the certificate. * * @param name the name of the attribute. * @param obj the value of the attribute. * @exception CertificateException on invalid attribute identifier. * @exception IOException on encoding error of attribute. */ public void set(String name, Object obj) throws CertificateException, IOException { // check if immutable if (readOnly) throw new CertificateException("Cannot overwrite existing certificate"); X509AttributeName attr = new X509AttributeName(name); String id = attr.getPrefix(); if (!(id.equalsIgnoreCase(NAME))) { throw new CertificateException("Invalid root of attribute name," + " expected [" + NAME + "], received " + id); } attr = new X509AttributeName(attr.getSuffix()); id = attr.getPrefix(); if (id.equalsIgnoreCase(INFO)) { if (attr.getSuffix() == null) { if (!(obj instanceof X509CertInfo)) { throw new CertificateException("Attribute value should" + " be of type X509CertInfo."); } info = (X509CertInfo) obj; signedCert = null; //reset this as certificate data has changed } else { info.set(attr.getSuffix(), obj); signedCert = null; //reset this as certificate data has changed } } else { throw new CertificateException("Attribute name not recognized or " + "set() not allowed for the same: " + id); } } /** * Delete the requested attribute from the certificate. * * @param name the name of the attribute. * @exception CertificateException on invalid attribute identifier. * @exception IOException on other errors. */ public void delete(String name) throws CertificateException, IOException { // check if immutable if (readOnly) throw new CertificateException("Cannot overwrite existing certificate"); X509AttributeName attr = new X509AttributeName(name); String id = attr.getPrefix(); if (!(id.equalsIgnoreCase(NAME))) { throw new CertificateException("Invalid root of attribute name," + " expected [" + NAME + "], received " + id); } attr = new X509AttributeName(attr.getSuffix()); id = attr.getPrefix(); if (id.equalsIgnoreCase(INFO)) { if (attr.getSuffix() != null) { info = null; } else { info.delete(attr.getSuffix()); } } else if (id.equalsIgnoreCase(ALG_ID)) { algId = null; } else if (id.equalsIgnoreCase(SIGNATURE)) { signature = null; } else if (id.equalsIgnoreCase(SIGNED_CERT)) { signedCert = null; } else { throw new CertificateException("Attribute name not recognized or " + "delete() not allowed for the same: " + id); } } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getElements() { Vector elements = new Vector(); elements.addElement(NAME + DOT + INFO); elements.addElement(NAME + DOT + ALG_ID); elements.addElement(NAME + DOT + SIGNATURE); elements.addElement(NAME + DOT + SIGNED_CERT); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } /** * Returns a printable representation of the certificate. This does not * contain all the information available to distinguish this from any * other certificate. The certificate must be fully constructed * before this function may be called. */ public String toString() { if (info == null || algId == null || signature == null) return ""; StringBuffer sb = new StringBuffer("[\n"+info.toString() + "\n" + " Algorithm: [" + algId.toString() + "]\n"); org.mozilla.jss.netscape.security.util.PrettyPrintFormat pp = new org.mozilla.jss.netscape.security.util.PrettyPrintFormat(" ", 20); String signaturebits = pp.toHexString(signature); sb.append(" Signature:\n" + signaturebits); sb.append("]"); return sb.toString(); } // the strongly typed gets, as per java.security.cert.X509Certificate /** * Gets the publickey from this certificate. * * @return the publickey. */ public PublicKey getPublicKey() { if (info == null) return null; try { PublicKey key = (PublicKey) info.get(CertificateX509Key.NAME + DOT + CertificateX509Key.KEY); return key; } catch (Exception e) { return null; } } /** * Gets the version number from the certificate. * * @return the version number. */ public int getVersion() { if (info == null) return -1; try { int vers = ((Integer) info.get(CertificateVersion.NAME + DOT + CertificateVersion.VERSION)).intValue(); return vers; } catch (Exception e) { return -1; } } /** * Gets the serial number from the certificate. * * @return the serial number. */ public BigInteger getSerialNumber() { if (info == null) return null; try { SerialNumber ser = (SerialNumber) info.get( CertificateSerialNumber.NAME + DOT + CertificateSerialNumber.NUMBER); return ser.getNumber().toBigInteger(); } catch (Exception e) { return null; } } /** * Gets the subject distinguished name from the certificate. * * @return the subject name. */ public Principal getSubjectDN() { if (info == null) return null; try { Principal subject = (Principal) info.get( CertificateSubjectName.NAME + DOT + CertificateSubjectName.DN_NAME); return subject; } catch (Exception e) { return null; } } public CertificateSubjectName getSubjectObj() { return info.getSubjectObj(); } public X509CertInfo getInfo() { return info; } /** * Gets the issuer distinguished name from the certificate. * * @return the issuer name. */ public Principal getIssuerDN() { if (info == null) return null; try { Principal issuer = (Principal) info.get( CertificateIssuerName.NAME + DOT + CertificateIssuerName.DN_NAME); return issuer; } catch (Exception e) { return null; } } public CertificateIssuerName getIssuerObj() { return info.getIssuerObj(); } /** * Gets the notBefore date from the validity period of the certificate. * * @return the start date of the validity period. */ public Date getNotBefore() { if (info == null) return null; try { Date d = (Date) info.get(CertificateValidity.NAME + DOT + CertificateValidity.NOT_BEFORE); return d; } catch (Exception e) { return null; } } /** * Gets the notAfter date from the validity period of the certificate. * * @return the end date of the validity period. */ public Date getNotAfter() { if (info == null) return null; try { Date d = (Date) info.get(CertificateValidity.NAME + DOT + CertificateValidity.NOT_AFTER); return d; } catch (Exception e) { return null; } } /** * Gets the DER encoded certificate informations, the tbsCertificate from this certificate. * This can be used to verify the signature independently. * * @return the DER encoded certificate information. * @exception CertificateEncodingException if an encoding error occurs. */ public byte[] getTBSCertificate() throws CertificateEncodingException { if (info != null) { return info.getEncodedInfo(); } else throw new CertificateEncodingException("Uninitialized certificate"); } /** * Gets the raw Signature bits from the certificate. * * @return the signature. */ public byte[] getSignature() { if (signature == null) return null; byte[] dup = new byte[signature.length]; System.arraycopy(signature, 0, dup, 0, dup.length); return dup; } /** * Gets the signature algorithm name for the certificate * signature algorithm. * For example, the string "SHA-1/DSA" or "DSS". * * @return the signature algorithm name. */ public String getSigAlgName() { if (algId == null) return null; return (algId.getName()); } /** * Gets the signature algorithm OID string from the certificate. * For example, the string "1.2.840.10040.4.3" * * @return the signature algorithm oid string. */ public String getSigAlgOID() { if (algId == null) return null; ObjectIdentifier oid = algId.getOID(); return (oid.toString()); } /** * Gets the DER encoded signature algorithm parameters from this * certificate's signature algorithm. * * @return the DER encoded signature algorithm parameters, or * null if no parameters are present. */ public byte[] getSigAlgParams() { if (algId == null) return null; try { return algId.getEncodedParams(); } catch (IOException e) { return null; } } /** * Gets the Issuer Unique Identity from the certificate. * * @return the Issuer Unique Identity. */ public boolean[] getIssuerUniqueID() { if (info == null) return null; try { UniqueIdentity id = (UniqueIdentity) info.get( CertificateIssuerUniqueIdentity.NAME + DOT + CertificateIssuerUniqueIdentity.ID); if (id == null) return null; else return (id.getId()); } catch (Exception e) { return null; } } /** * Gets the Subject Unique Identity from the certificate. * * @return the Subject Unique Identity. */ public boolean[] getSubjectUniqueID() { if (info == null) return null; try { UniqueIdentity id = (UniqueIdentity) info.get( CertificateSubjectUniqueIdentity.NAME + DOT + CertificateSubjectUniqueIdentity.ID); if (id == null) return null; else return (id.getId()); } catch (Exception e) { return null; } } /** * Gets a Set of the extension(s) marked CRITICAL in the * certificate by OID strings. * * @return a set of the extension oid strings in the * certificate that are marked critical. */ public Set getCriticalExtensionOIDs() { if (info == null) return null; try { CertificateExtensions exts = (CertificateExtensions) info.get( CertificateExtensions.NAME); if (exts == null) return null; Set extSet = new LinkedHashSet(); Extension ex; for (Enumeration e = exts.getAttributes(); e.hasMoreElements();) { ex = e.nextElement(); if (ex.isCritical()) extSet.add(ex.getExtensionId().toString()); } return extSet; } catch (Exception e) { return null; } } /** * Gets a Set of the extension(s) marked NON-CRITICAL in the * certificate by OID strings. * * @return a set of the extension oid strings in the * certificate that are NOT marked critical. */ public Set getNonCriticalExtensionOIDs() { if (info == null) return null; try { CertificateExtensions exts = (CertificateExtensions) info.get( CertificateExtensions.NAME); if (exts == null) return null; Set extSet = new LinkedHashSet(); Extension ex; for (Enumeration e = exts.getAttributes(); e.hasMoreElements();) { ex = e.nextElement(); if (!ex.isCritical()) extSet.add(ex.getExtensionId().toString()); } return extSet; } catch (Exception e) { return null; } } public Extension getExtension(String oid) { try { CertificateExtensions exts = (CertificateExtensions) info.get( CertificateExtensions.NAME); if (exts == null) return null; ObjectIdentifier findOID = new ObjectIdentifier(oid); Extension ex = null; ; ObjectIdentifier inCertOID; for (Enumeration e = exts.getAttributes(); e.hasMoreElements();) { ex = e.nextElement(); inCertOID = ex.getExtensionId(); if (inCertOID.equals(findOID)) { return ex; } } } catch (Exception e) { } return null; } /** * Gets the DER encoded extension identified by the passed * in oid String. * * @param oid the Object Identifier value for the extension. */ public byte[] getExtensionValue(String oid) { DerOutputStream out = null; try { String extAlias = OIDMap.getName(new ObjectIdentifier(oid)); Extension certExt = null; if (extAlias == null) { // may be unknown // get the extensions, search thru' for this oid CertificateExtensions exts = (CertificateExtensions) info.get( CertificateExtensions.NAME); if (exts == null) return null; ObjectIdentifier findOID = new ObjectIdentifier(oid); Extension ex = null; ; ObjectIdentifier inCertOID; for (Enumeration e = exts.getAttributes(); e.hasMoreElements();) { ex = e.nextElement(); inCertOID = ex.getExtensionId(); if (inCertOID.equals(findOID)) { certExt = ex; break; } } } else { // there's sub-class that can handle this extension certExt = (Extension) this.get(extAlias); } if (certExt == null) return null; byte[] extData = certExt.getExtensionValue(); if (extData == null) return null; out = new DerOutputStream(); out.putOctetString(extData); return out.toByteArray(); } catch (Exception e) { return null; } finally { if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Get a boolean array representing the bits of the KeyUsage extension, * (oid = 2.5.29.15). * * @return the bit values of this extension as an array of booleans. */ public boolean[] getKeyUsage() { try { String extAlias = OIDMap.getName(new ObjectIdentifier( KEY_USAGE_OID)); if (extAlias == null) return null; KeyUsageExtension certExt = (KeyUsageExtension) this.get(extAlias); if (certExt == null) return null; return certExt.getBits(); } catch (Exception e) { return null; } } /** * Get the certificate constraints path length from the * the critical BasicConstraints extension, (oid = 2.5.29.19). * * @return the length of the constraint. */ public int getBasicConstraints() { try { String extAlias = OIDMap.getName(new ObjectIdentifier( BASIC_CONSTRAINT_OID)); if (extAlias == null) return -1; BasicConstraintsExtension certExt = (BasicConstraintsExtension) this.get(extAlias); if (certExt == null) return -1; if (((Boolean) certExt.get(BasicConstraintsExtension.IS_CA)).booleanValue() == true) return ((Integer) certExt.get( BasicConstraintsExtension.PATH_LEN)).intValue(); else return -1; } catch (Exception e) { return -1; } } public boolean getBasicConstraintsIsCA() { boolean isCA = false; try { String extAlias = OIDMap.getName(new ObjectIdentifier( BASIC_CONSTRAINT_OID)); if (extAlias == null) return false; BasicConstraintsExtension certExt = (BasicConstraintsExtension) this.get(extAlias); if (certExt == null) return false; isCA = ((Boolean) certExt.get(BasicConstraintsExtension.IS_CA)).booleanValue(); } catch (Exception e) { return false; } return isCA; } /************************************************************/ /* * Cert is a SIGNED ASN.1 macro, a three elment sequence: * * - Data to be signed (ToBeSigned) -- the "raw" cert * - Signature algorithm (SigAlgId) * - The signature bits * * This routine unmarshals the certificate, saving the signature * parts away for later verification. */ private void parse(DerValue val) throws CertificateException, IOException { // check if can over write the certificate if (readOnly) throw new CertificateParsingException("Cannot overwrite existing certificate"); readOnly = true; DerValue seq[] = new DerValue[3]; seq[0] = val.data.getDerValue(); seq[1] = val.data.getDerValue(); seq[2] = val.data.getDerValue(); if (val.data.available() != 0) { throw new CertificateParsingException("signed overrun, bytes = " + val.data.available()); } if (seq[0].tag != DerValue.tag_Sequence) { throw new CertificateParsingException("signed fields invalid"); } algId = AlgorithmId.parse(seq[1]); signature = seq[2].getBitString(); if (seq[1].data.available() != 0) { throw new CertificateParsingException("algid field overrun"); } if (seq[2].data.available() != 0) throw new CertificateParsingException("signed fields overrun"); // The CertificateInfo if (info == null) { info = new X509CertInfo(seq[0]); } } /** * Serialization write ... X.509 certificates serialize as * themselves, and they're parsed when they get read back. * (Actually they serialize as some type data from the * serialization subsystem, then the cert data.) */ private void writeObject(ObjectOutputStream stream) throws CertificateException, IOException { encode(stream); } /** * Serialization read ... X.509 certificates serialize as * themselves, and they're parsed when they get read back. */ private void readObject(ObjectInputStream stream) throws CertificateException, IOException { decode(stream); } protected static class CertificateRep1 implements java.io.Serializable { /** * */ private static final long serialVersionUID = -5207881613631592409L; private String type1; private byte[] data1; /** * Construct the alternate Certificate class with the Certificate * type and Certificate encoding bytes. * *

* * @param type the standard name of the Certificate type. *

* * @param data the Certificate data. */ protected CertificateRep1(String type, byte[] data) { this.type1 = type; this.data1 = data; } /** * Resolve the Certificate Object. * *

* * @return the resolved Certificate Object. * * @throws java.io.ObjectStreamException if the Certificate could not * be resolved. */ protected Object readResolve() throws java.io.ObjectStreamException { try { @SuppressWarnings("unused") CertificateFactory cf = CertificateFactory.getInstance(type1); // check for errors return new X509CertImpl(data1); /* return cf.generateCertificate (new java.io.ByteArrayInputStream(data1)); */ } catch (CertificateException e) { throw new java.io.NotSerializableException("java.security.cert.Certificate: " + type1 + ": " + e.getMessage()); } } } protected Object writeReplace() throws java.io.ObjectStreamException { try { return new CertificateRep1("X.509", getEncoded()); } catch (CertificateException e) { throw new java.io.NotSerializableException("java.security.cert.Certificate: " + "X.509" + ": " + e.getMessage()); } } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/X509CertInfo.java000066400000000000000000001014371362106420000245000ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateParsingException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * The X509CertInfo class represents X.509 certificate information. * *

* X.509 certificates have several base data elements, including: *

    * *
  • The Subject Name, an X.500 Distinguished Name for the entity (subject) for which the certificate was * issued. * *
  • The Subject Public Key, the public key of the subject. This is one of the most important parts of the * certificate. * *
  • The Validity Period, a time period (e.g. six months) within which the certificate is valid (unless * revoked). * *
  • The Issuer Name, an X.500 Distinguished Name for the Certificate Authority (CA) which issued the * certificate. * *
  • A Serial Number assigned by the CA, for use in certificate revocation and other applications. * *
* * @author Amit Kapoor * @author Hemma Prafullchandra * @version 1.16 * @see CertAttrSet * @see Serializable * @see X509CertImpl */ public class X509CertInfo implements CertAttrSet, Serializable { /** * */ private static final long serialVersionUID = -5094073467876311577L; /** * Identifier for this attribute, to be used with the * get, set, delete methods of Certificate, x509 type. */ public static final String IDENT = "x509.info"; // Certificate attribute names public static final String NAME = "info"; public static final String VERSION = CertificateVersion.NAME; public static final String SERIAL_NUMBER = CertificateSerialNumber.NAME; public static final String ALGORITHM_ID = CertificateAlgorithmId.NAME; public static final String ISSUER = CertificateIssuerName.NAME; public static final String VALIDITY = CertificateValidity.NAME; public static final String SUBJECT = CertificateSubjectName.NAME; public static final String KEY = CertificateX509Key.NAME; public static final String ISSUER_ID = CertificateIssuerUniqueIdentity.NAME; public static final String SUBJECT_ID = CertificateSubjectUniqueIdentity.NAME; public static final String EXTENSIONS = CertificateExtensions.NAME; // X509.v1 data protected CertificateVersion version = new CertificateVersion(); protected CertificateSerialNumber serialNum = null; protected CertificateAlgorithmId algId = null; protected CertificateIssuerName issuer = null; protected CertificateValidity interval = null; protected CertificateSubjectName subject = null; protected CertificateX509Key pubKey = null; // X509.v2 & v3 extensions protected CertificateIssuerUniqueIdentity issuerUniqueId = null; protected CertificateSubjectUniqueIdentity subjectUniqueId = null; // X509.v3 extensions protected CertificateExtensions extensions = null; // Attribute numbers for internal manipulation private static final int ATTR_VERSION = 1; private static final int ATTR_SERIAL = 2; private static final int ATTR_ALGORITHM = 3; private static final int ATTR_ISSUER = 4; private static final int ATTR_VALIDITY = 5; private static final int ATTR_SUBJECT = 6; private static final int ATTR_KEY = 7; private static final int ATTR_ISSUER_ID = 8; private static final int ATTR_SUBJECT_ID = 9; private static final int ATTR_EXTENSIONS = 10; // DER encoded CertificateInfo data private byte[] rawCertInfo = null; // The certificate attribute name to integer mapping stored here private static final Hashtable map = new Hashtable(); static { map.put(VERSION, Integer.valueOf(ATTR_VERSION)); map.put(SERIAL_NUMBER, Integer.valueOf(ATTR_SERIAL)); map.put(ALGORITHM_ID, Integer.valueOf(ATTR_ALGORITHM)); map.put(ISSUER, Integer.valueOf(ATTR_ISSUER)); map.put(VALIDITY, Integer.valueOf(ATTR_VALIDITY)); map.put(SUBJECT, Integer.valueOf(ATTR_SUBJECT)); map.put(KEY, Integer.valueOf(ATTR_KEY)); map.put(ISSUER_ID, Integer.valueOf(ATTR_ISSUER_ID)); map.put(SUBJECT_ID, Integer.valueOf(ATTR_SUBJECT_ID)); map.put(EXTENSIONS, Integer.valueOf(ATTR_EXTENSIONS)); } /** * Construct an uninitialized X509CertInfo on which * decode must later be called (or which may be deserialized). */ public X509CertInfo() { } /** * Unmarshals a certificate from its encoded form, parsing the * encoded bytes. This form of constructor is used by agents which * need to examine and use certificate contents. That is, this is * one of the more commonly used constructors. Note that the buffer * must include only a certificate, and no "garbage" may be left at * the end. If you need to ignore data at the end of a certificate, * use another constructor. * * @param cert the encoded bytes, with no trailing data. * @exception CertificateParsingException on parsing errors. */ public X509CertInfo(byte[] cert) throws CertificateParsingException { try { DerValue in = new DerValue(cert); parse(in); } catch (IOException e) { throw new CertificateParsingException(e); } } /** * Unmarshal a certificate from its encoded form, parsing a DER value. * This form of constructor is used by agents which need to examine * and use certificate contents. * * @param derVal the der value containing the encoded cert. * @exception CertificateParsingException on parsing errors. */ public X509CertInfo(DerValue derVal) throws CertificateParsingException { try { parse(derVal); } catch (IOException e) { throw new CertificateParsingException(e); } } /** * Decode an X.509 certificate from an input stream. * * @param in an input stream holding at least one certificate * @exception CertificateParsingException on decoding errors. * @exception IOException on other errors. */ public void decode(InputStream in) throws CertificateParsingException, IOException { DerValue val = new DerValue(in); parse(val); } /** * Appends the certificate to an output stream. * * @param out an output stream to which the certificate is appended. * @exception CertificateException on encoding errors. * @exception IOException on other errors. */ public void encode(OutputStream out) throws CertificateException, IOException { encode(out, false); } /** * Appends the certificate to an output stream. * * @param out An output stream to which the certificate is appended. * @param ignoreCache Whether to ignore the internal cache when encoding. * (the cache can easily become out of date). */ public void encode(OutputStream out, boolean ignoreCache) throws IOException, CertificateException { if (ignoreCache || (rawCertInfo == null)) { DerOutputStream tmp = new DerOutputStream(); emit(tmp); rawCertInfo = tmp.toByteArray(); } out.write(rawCertInfo); } /** * Return an enumeration of names of attributes existing within this * attribute. */ public Enumeration getAttributeNames() { Vector elements = new Vector(); elements.addElement(VERSION); elements.addElement(SERIAL_NUMBER); elements.addElement(ALGORITHM_ID); elements.addElement(ISSUER); elements.addElement(VALIDITY); elements.addElement(SUBJECT); elements.addElement(KEY); elements.addElement(ISSUER_ID); elements.addElement(SUBJECT_ID); elements.addElement(EXTENSIONS); return (elements.elements()); } /** * Return the name of this attribute. */ public String getName() { return (NAME); } /** * Returns the encoded certificate info. * * @exception CertificateEncodingException on encoding information errors. */ public byte[] getEncodedInfo() throws CertificateEncodingException { return getEncodedInfo(false); } public byte[] getEncodedInfo(boolean ignoreCache) throws CertificateEncodingException { try { if (ignoreCache || (rawCertInfo == null)) { DerOutputStream tmp = new DerOutputStream(); emit(tmp); rawCertInfo = tmp.toByteArray(); } byte[] dup = new byte[rawCertInfo.length]; System.arraycopy(rawCertInfo, 0, dup, 0, dup.length); return dup; } catch (IOException e) { throw new CertificateEncodingException(e); } catch (CertificateException e) { throw new CertificateEncodingException(e); } } /** * Compares two X509CertInfo objects. This is false if the * certificates are not both X.509 certs, otherwise it * compares them as binary data. * * @param other the object being compared with this one * @return true iff the certificates are equivalent */ public boolean equals(Object other) { if (other instanceof X509CertInfo) { return equals((X509CertInfo) other); } else { return false; } } /** * Compares two certificates, returning false if any data * differs between the two. * * @param other the object being compared with this one * @return true iff the certificates are equivalent */ public boolean equals(X509CertInfo other) { if (this == other) { return (true); } else if (rawCertInfo == null || other.rawCertInfo == null) { return (false); } else if (rawCertInfo.length != other.rawCertInfo.length) { return (false); } for (int i = 0; i < rawCertInfo.length; i++) { if (rawCertInfo[i] != other.rawCertInfo[i]) { return (false); } } return (true); } /** * Calculates a hash code value for the object. Objects * which are equal will also have the same hashcode. */ public int hashCode() { int retval = 0; for (int i = 1; i < rawCertInfo.length; i++) { retval += rawCertInfo[i] * i; } return (retval); } /** * Returns a printable representation of the certificate. */ public String toString() { if (subject == null || pubKey == null || interval == null || issuer == null || algId == null || serialNum == null) { throw new NullPointerException("X.509 cert is incomplete"); } StringBuffer sb = new StringBuffer("[\n" + " " + version.toString() + "\n" + " Subject: " + subject.toString() + "\n" + " Signature Algorithm: " + algId.toString() + "\n" + " Key: " + pubKey.toString() + "\n"); sb.append(" " + interval.toString() + "\n" + " Issuer: " + issuer.toString() + "\n" + " " + serialNum.toString() + "\n"); // optional v2, v3 extras if (issuerUniqueId != null) { sb.append(" Issuer Id:\n" + issuerUniqueId.toString() + "\n"); } if (subjectUniqueId != null) { sb.append(" Subject Id:\n" + subjectUniqueId.toString() + "\n"); } if (extensions != null) { org.mozilla.jss.netscape.security.util.PrettyPrintFormat pp = new org.mozilla.jss.netscape.security.util.PrettyPrintFormat(" ", 20); for (int i = 0; i < extensions.size(); i++) { sb.append(" Extension[" + i + "] = "); Extension ext = extensions.elementAt(i); DerOutputStream out = null; try { if (OIDMap.getClass(ext.getExtensionId()) == null) { sb.append(ext.toString()); byte[] extValue = ext.getExtensionValue(); if (extValue != null) { out = new DerOutputStream(); out.putOctetString(extValue); extValue = out.toByteArray(); String extValuebits = pp.toHexString(extValue); sb.append("Extension unknown: " + "DER encoded OCTET string =\n" + extValuebits); } } else sb.append(ext.toString()); //sub-class exists } catch (CertificateException e) { sb.append(", Error parsing this extension"); } catch (IOException e) { sb.append(", Error parsing this extension"); } finally { if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } } sb.append("\n]"); return sb.toString(); } /** * Set the certificate attribute. * * @param name the name of the Certificate attribute. * @param val the value of the Certificate attribute. * @exception CertificateException on invalid attributes. * @exception IOException on other errors. */ public void set(String name, Object val) throws CertificateException, IOException { X509AttributeName attrName = new X509AttributeName(name); int attr = attributeMap(attrName.getPrefix()); if (attr == 0) { throw new CertificateException("Attribute name not recognized: " + name); } // set rawCertInfo to null, so that we are forced to re-encode rawCertInfo = null; switch (attr) { case ATTR_VERSION: if (attrName.getSuffix() == null) { setVersion(val); } else { version.set(attrName.getSuffix(), val); } break; case ATTR_SERIAL: if (attrName.getSuffix() == null) { setSerialNumber(val); } else { serialNum.set(attrName.getSuffix(), val); } break; case ATTR_ALGORITHM: if (attrName.getSuffix() == null) { setAlgorithmId(val); } else { algId.set(attrName.getSuffix(), val); } break; case ATTR_ISSUER: if (attrName.getSuffix() == null) { setIssuer(val); } else { issuer.set(attrName.getSuffix(), val); } break; case ATTR_VALIDITY: if (attrName.getSuffix() == null) { setValidity(val); } else { interval.set(attrName.getSuffix(), val); } break; case ATTR_SUBJECT: if (attrName.getSuffix() == null) { setSubject(val); } else { subject.set(attrName.getSuffix(), val); } break; case ATTR_KEY: if (attrName.getSuffix() == null) { setKey(val); } else { pubKey.set(attrName.getSuffix(), val); } break; case ATTR_ISSUER_ID: if (attrName.getSuffix() == null) { setIssuerUniqueId(val); } else { issuerUniqueId.set(attrName.getSuffix(), val); } break; case ATTR_SUBJECT_ID: if (attrName.getSuffix() == null) { setSubjectUniqueId(val); } else { subjectUniqueId.set(attrName.getSuffix(), val); } break; case ATTR_EXTENSIONS: if (attrName.getSuffix() == null) { setExtensions(val); } else { extensions.set(attrName.getSuffix(), val); } break; } } /** * Delete the certificate attribute. * * @param name the name of the Certificate attribute. * @exception CertificateException on invalid attributes. * @exception IOException on other errors. */ public void delete(String name) throws CertificateException, IOException { X509AttributeName attrName = new X509AttributeName(name); int attr = attributeMap(attrName.getPrefix()); if (attr == 0) { throw new CertificateException("Attribute name not recognized: " + name); } // set rawCertInfo to null, so that we are forced to re-encode rawCertInfo = null; switch (attr) { case ATTR_VERSION: if (attrName.getSuffix() == null) { version = null; } else { version.delete(attrName.getSuffix()); } break; case (ATTR_SERIAL): if (attrName.getSuffix() == null) { serialNum = null; } else { serialNum.delete(attrName.getSuffix()); } break; case (ATTR_ALGORITHM): if (attrName.getSuffix() == null) { algId = null; } else { algId.delete(attrName.getSuffix()); } break; case (ATTR_ISSUER): if (attrName.getSuffix() == null) { issuer = null; } else { issuer.delete(attrName.getSuffix()); } break; case (ATTR_VALIDITY): if (attrName.getSuffix() == null) { interval = null; } else { interval.delete(attrName.getSuffix()); } break; case (ATTR_SUBJECT): if (attrName.getSuffix() == null) { subject = null; } else { subject.delete(attrName.getSuffix()); } break; case (ATTR_KEY): if (attrName.getSuffix() == null) { pubKey = null; } else { pubKey.delete(attrName.getSuffix()); } break; case (ATTR_ISSUER_ID): if (attrName.getSuffix() == null) { issuerUniqueId = null; } else { issuerUniqueId.delete(attrName.getSuffix()); } break; case (ATTR_SUBJECT_ID): if (attrName.getSuffix() == null) { subjectUniqueId = null; } else { subjectUniqueId.delete(attrName.getSuffix()); } break; case (ATTR_EXTENSIONS): if (attrName.getSuffix() == null) { extensions = null; } else { extensions.delete(attrName.getSuffix()); } break; } } /** * Get the certificate attribute. * * @param name the name of the Certificate attribute. * * @exception CertificateException on invalid attributes. * @exception IOException on other errors. */ public Object get(String name) throws CertificateException, IOException { X509AttributeName attrName = new X509AttributeName(name); int attr = attributeMap(attrName.getPrefix()); if (attr == 0) { throw new CertificateParsingException( "Attribute name not recognized: " + name); } switch (attr) { case (ATTR_VERSION): if (attrName.getSuffix() == null) { return (version); } else { return (version.get(attrName.getSuffix())); } case (ATTR_SERIAL): if (attrName.getSuffix() == null) { return (serialNum); } else { return (serialNum.get(attrName.getSuffix())); } case (ATTR_ALGORITHM): if (attrName.getSuffix() == null) { return (algId); } else { return (algId.get(attrName.getSuffix())); } case (ATTR_ISSUER): if (attrName.getSuffix() == null) { return (issuer); } else { return (issuer.get(attrName.getSuffix())); } case (ATTR_VALIDITY): if (attrName.getSuffix() == null) { return (interval); } else { return (interval.get(attrName.getSuffix())); } case (ATTR_SUBJECT): if (attrName.getSuffix() == null) { return (subject); } else { return (subject.get(attrName.getSuffix())); } case (ATTR_KEY): if (attrName.getSuffix() == null) { return (pubKey); } else { return (pubKey.get(attrName.getSuffix())); } case (ATTR_ISSUER_ID): if (attrName.getSuffix() == null) { return (issuerUniqueId); } else { if (issuerUniqueId == null) return null; else return (issuerUniqueId.get(attrName.getSuffix())); } case (ATTR_SUBJECT_ID): if (attrName.getSuffix() == null) { return (subjectUniqueId); } else { if (subjectUniqueId == null) return null; else return (subjectUniqueId.get(attrName.getSuffix())); } case (ATTR_EXTENSIONS): if (attrName.getSuffix() == null) { return (extensions); } else { if (extensions == null) return null; else return (extensions.get(attrName.getSuffix())); } } return null; } /* * This routine unmarshals the certificate information. */ private void parse(DerValue val) throws CertificateParsingException, IOException { DerInputStream in; DerValue tmp; if (val.tag != DerValue.tag_Sequence) { throw new CertificateParsingException("signed fields invalid"); } rawCertInfo = val.toByteArray(); in = val.data; // Version tmp = in.getDerValue(); if (tmp.isContextSpecific((byte) 0)) { version = new CertificateVersion(tmp); tmp = in.getDerValue(); } // Serial number ... an integer serialNum = new CertificateSerialNumber(tmp); // Algorithm Identifier algId = new CertificateAlgorithmId(in); // Issuer name issuer = new CertificateIssuerName(in); // validity: SEQUENCE { start date, end date } interval = new CertificateValidity(in); // subject name subject = new CertificateSubjectName(in); // public key pubKey = new CertificateX509Key(in); // If more data available, make sure version is not v1. if (in.available() != 0) { if (version.compare(CertificateVersion.V1) == 0) { throw new CertificateParsingException("excess cert data"); } } else { return; } // Get the issuerUniqueId if present tmp = in.getDerValue(); if (tmp.isContextSpecific((byte) 1)) { issuerUniqueId = new CertificateIssuerUniqueIdentity(tmp); if (in.available() == 0) { return; } tmp = in.getDerValue(); } // Get the subjectUniqueId if present. if (tmp.isContextSpecific((byte) 2)) { subjectUniqueId = new CertificateSubjectUniqueIdentity(tmp); if (in.available() == 0) { return; } tmp = in.getDerValue(); } // Get the extensions. if (version.compare(CertificateVersion.V3) != 0) { throw new CertificateParsingException("excess cert data"); } if (tmp.isConstructed() && tmp.isContextSpecific((byte) 3)) { extensions = new CertificateExtensions(tmp.data); } } /* * Marshal the contents of a "raw" certificate into a DER sequence. */ private void emit(DerOutputStream out) throws CertificateException, IOException { DerOutputStream tmp = new DerOutputStream(); // version number, iff not V1 version.encode(tmp); // Encode serial number, issuer signing algorithm, issuer name // and validity serialNum.encode(tmp); algId.encode(tmp); issuer.encode(tmp); interval.encode(tmp); // Encode subject (principal) and associated key subject.encode(tmp); pubKey.encode(tmp); // Encode issuerUniqueId & subjectUniqueId. if (issuerUniqueId != null) { issuerUniqueId.encode(tmp); } if (subjectUniqueId != null) { subjectUniqueId.encode(tmp); } // Write all the extensions. if (extensions != null) { extensions.encode(tmp); } // Wrap the data; encoding of the "raw" cert is now complete. out.write(DerValue.tag_Sequence, tmp); } /** * Serialization write ... X.509 certificates serialize as * themselves, and they're parsed when they get read back. * (Actually they serialize as some type data from the * serialization subsystem, then the cert data.) */ private void writeObject(ObjectOutputStream stream) throws CertificateException, IOException { encode(stream); } /** * Serialization read ... X.509 certificates serialize as * themselves, and they're parsed when they get read back. */ private void readObject(ObjectInputStream stream) throws CertificateException, IOException { decode(stream); } /** * Returns the integer attribute number for the passed attribute name. */ private int attributeMap(String name) { Integer num = map.get(name); if (num == null) { return (0); } return (num.intValue()); } /** * Set the version number of the certificate. * * @param val the Object class value for the Extensions * @exception CertificateException on invalid data. */ private void setVersion(Object val) throws CertificateException { if (!(val instanceof CertificateVersion)) { throw new CertificateException("Version class type invalid."); } version = (CertificateVersion) val; } /** * Set the serial number of the certificate. * * @param val the Object class value for the CertificateSerialNumber * @exception CertificateException on invalid data. */ private void setSerialNumber(Object val) throws CertificateException { if (!(val instanceof CertificateSerialNumber)) { throw new CertificateException("SerialNumber class type invalid."); } serialNum = (CertificateSerialNumber) val; } /** * Set the algorithm id of the certificate. * * @param val the Object class value for the AlgorithmId * @exception CertificateException on invalid data. */ private void setAlgorithmId(Object val) throws CertificateException { if (!(val instanceof CertificateAlgorithmId)) { throw new CertificateException( "AlgorithmId class type invalid."); } algId = (CertificateAlgorithmId) val; } /** * Set the issuer name of the certificate. * * @param val the Object class value for the issuer * @exception CertificateException on invalid data. */ private void setIssuer(Object val) throws CertificateException { if (!(val instanceof CertificateIssuerName)) { throw new CertificateException( "Issuer class type invalid."); } issuer = (CertificateIssuerName) val; } public CertificateIssuerName getIssuerObj() { return issuer; } /** * Set the validity interval of the certificate. * * @param val the Object class value for the CertificateValidity * @exception CertificateException on invalid data. */ private void setValidity(Object val) throws CertificateException { if (!(val instanceof CertificateValidity)) { throw new CertificateException( "CertificateValidity class type invalid."); } interval = (CertificateValidity) val; } /** * Set the subject name of the certificate. * * @param val the Object class value for the Subject * @exception CertificateException on invalid data. */ private void setSubject(Object val) throws CertificateException { if (!(val instanceof CertificateSubjectName)) { throw new CertificateException( "Subject class type invalid."); } subject = (CertificateSubjectName) val; } public CertificateSubjectName getSubjectObj() { return subject; } /** * Set the public key in the certificate. * * @param val the Object class value for the PublicKey * @exception CertificateException on invalid data. */ private void setKey(Object val) throws CertificateException { if (!(val instanceof CertificateX509Key)) { throw new CertificateException( "Key class type invalid."); } pubKey = (CertificateX509Key) val; } /** * Set the Issuer Unique Identity in the certificate. * * @param val the Object class value for the IssuerUniqueId * @exception CertificateException */ private void setIssuerUniqueId(Object val) throws CertificateException { if (version.compare(CertificateVersion.V2) < 0) { throw new CertificateException("Invalid version"); } if (!(val instanceof CertificateIssuerUniqueIdentity)) { throw new CertificateException( "IssuerUniqueId class type invalid."); } issuerUniqueId = (CertificateIssuerUniqueIdentity) val; } /** * Set the Subject Unique Identity in the certificate. * * @param val the Object class value for the SubjectUniqueId * @exception CertificateException */ private void setSubjectUniqueId(Object val) throws CertificateException { if (version.compare(CertificateVersion.V2) < 0) { throw new CertificateException("Invalid version"); } if (!(val instanceof CertificateSubjectUniqueIdentity)) { throw new CertificateException( "SubjectUniqueId class type invalid."); } subjectUniqueId = (CertificateSubjectUniqueIdentity) val; } /** * Set the extensions in the certificate. * * @param val the Object class value for the Extensions * @exception CertificateException */ private void setExtensions(Object val) throws CertificateException { if (version.compare(CertificateVersion.V3) < 0) { throw new CertificateException("Invalid version"); } if (!(val instanceof CertificateExtensions)) { throw new CertificateException( "Extensions class type invalid."); } extensions = (CertificateExtensions) val; } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/X509ExtensionException.java000066400000000000000000000043611362106420000266200ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.security.GeneralSecurityException; /** * X.509 Extension Exception. * * @author Hemma Prafullchandra * 1.2 */ public class X509ExtensionException extends GeneralSecurityException { /** * */ private static final long serialVersionUID = 8152491877676477910L; /** * Constructs an X509ExtensionException with no detail message. A * detail message is a String that describes this particular * exception. */ public X509ExtensionException() { super(); } /** * Constructs the exception with the specified detail * message. A detail message is a String that describes this * particular exception. * * @param mesg the detail message. */ public X509ExtensionException(String mesg) { super(mesg); } /** * Constructs the exception with the specified detail * message and cause of this exception. A detail message is a * String that describes this particular exception. * * @param mesg the detail message. * @param cause the cause of this exception. */ public X509ExtensionException(String mesg, Throwable cause) { super(mesg, cause); } /** * Constructs the exception with the specified cause of * this exception. * * @param cause the cause of this exception. */ public X509ExtensionException(Throwable cause) { super(cause); } } jss-4.6.3/org/mozilla/jss/netscape/security/x509/X509Key.java000066400000000000000000000422061362106420000235150ustar00rootroot00000000000000// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package org.mozilla.jss.netscape.security.x509; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.PublicKey; import java.security.Security; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; /** * Holds an X.509 key, for example a public key found in an X.509 * certificate. Includes a description of the algorithm to be used * with the key; these keys normally are used as * "SubjectPublicKeyInfo". * *

* While this class can represent any kind of X.509 key, it may be desirable to provide subclasses which understand how * to parse keying data. For example, RSA public keys have two members, one for the public modulus and one for the prime * exponent. If such a class is provided, it is used when parsing X.509 keys. If one is not provided, the key still * parses correctly. * * @version 1.74, 97/12/10 * @author David Brownell */ public class X509Key implements PublicKey { /** use serialVersionUID from JDK 1.1. for interoperability */ private static final long serialVersionUID = -5359250853002055002L; /* The algorithm information (name, parameters, etc). */ protected AlgorithmId algid; /* The key bytes, without the algorithm information */ protected byte[] key; /* The encoding for the key. */ protected byte[] encodedKey; /** * Default constructor. The key constructed must have its key * and algorithm initialized before it may be used, for example * by using decode. */ public X509Key() { } /* * Build and initialize as a "default" key. All X.509 key * data is stored and transmitted losslessly, but no knowledge * about this particular algorithm is available. */ public X509Key(AlgorithmId algid, byte[] key) throws InvalidKeyException { this.algid = algid; this.key = key; encode(); } /** * Construct X.509 subject public key from a DER value. If * the runtime environment is configured with a specific class for * this kind of key, a subclass is returned. Otherwise, a generic * X509Key object is returned. * *

* This mechanism gurantees that keys (and algorithms) may be freely manipulated and transferred, without risk of * losing information. Also, when a key (or algorithm) needs some special handling, that specific need can be * accomodated. * * @param in the DER-encoded SubjectPublicKeyInfo value * @exception IOException on data format errors */ public static X509Key parse(DerValue in) throws IOException { AlgorithmId algorithm; X509Key subjectKey; if (in.tag != DerValue.tag_Sequence) throw new IOException("corrupt subject key"); algorithm = AlgorithmId.parse(in.data.getDerValue()); try { subjectKey = buildX509Key(algorithm, in.data.getBitString()); } catch (InvalidKeyException e) { throw new IOException("subject key, " + e.getMessage()); } if (in.data.available() != 0) throw new IOException("excess subject key"); return subjectKey; } /** * Parse the key bits. This may be redefined by subclasses to take * advantage of structure within the key. For example, RSA public * keys encapsulate two unsigned integers (modulus and exponent) as * DER values within the key bits; Diffie-Hellman and * DSS/DSA keys encapsulate a single unsigned integer. * *

* This function is called when creating X.509 SubjectPublicKeyInfo values using the X509Key member functions, such * as parse and decode. * * @exception IOException on parsing errors. * @exception InvalidKeyException on invalid key encodings. */ protected void parseKeyBits() throws IOException, InvalidKeyException { encode(); } /* * Factory interface, building the kind of key associated with this * specific algorithm ID or else returning this generic base class. * See the description above. */ static X509Key buildX509Key(AlgorithmId algid, byte[] key) throws IOException, InvalidKeyException { /* * Use the algid and key parameters to produce the ASN.1 encoding * of the key, which will then be used as the input to the * key factory. */ DerOutputStream x509EncodedKeyStream = new DerOutputStream(); encode(x509EncodedKeyStream, algid, key); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(x509EncodedKeyStream.toByteArray()); try { // Instantiate the key factory of the appropriate algorithm KeyFactory keyFac = null; if (Security.getProvider("Mozilla-JSS") == null) { keyFac = KeyFactory.getInstance(algid.getName()); } else { keyFac = KeyFactory.getInstance(algid.getName(), "Mozilla-JSS"); } // Generate the public key PublicKey pubKey = keyFac.generatePublic(x509KeySpec); if (pubKey instanceof X509Key) { /* * Return specialized X509Key, where the structure within the * key has been parsed */ return (X509Key) pubKey; } } catch (NoSuchAlgorithmException e) { // Return generic X509Key with opaque key data (see below) } catch (InvalidKeySpecException e) { throw new InvalidKeyException(e.toString()); } catch (Exception e) { throw new InvalidKeyException(e.toString()); } /* * Try again using JDK1.1-style for backwards compatibility. */ String classname = ""; try { Provider sunProvider; sunProvider = Security.getProvider("SUN"); if (sunProvider == null) throw new InstantiationException(); classname = sunProvider.getProperty("PublicKey.X.509." + algid.getName()); if (classname == null) { throw new InstantiationException(); } Class keyClass = Class.forName(classname); Object inst; X509Key result; inst = keyClass.getConstructor().newInstance( sunProvider.getProperty("PublicKey.X.509." + algid.getName())); if (inst instanceof X509Key) { result = (X509Key) inst; result.algid = algid; result.key = key; result.parseKeyBits(); return result; } } catch (ClassNotFoundException e) { } catch (InstantiationException e) { } catch (IllegalAccessException e) { throw new IOException("IllegalAccessException : " + e.getMessage(), e); } catch (NoSuchMethodException e) { } catch (InvocationTargetException e) { throw new IOException("InvocationTargetException : " + e.getMessage(), e); } X509Key result = new X509Key(); result.algid = algid; result.key = key; return result; } /** * Returns the algorithm to be used with this key. */ public String getAlgorithm() { return algid.getName(); } /** * Returns the algorithm ID to be used with this key. */ public AlgorithmId getAlgorithmId() { return algid; } /** * Encode SubjectPublicKeyInfo sequence on the DER output stream. * * @exception IOException on encoding errors. */ public final void encode(DerOutputStream out) throws IOException { encode(out, this.algid, this.key); } /** * Returns the DER-encoded form of the key as a byte array. */ public synchronized byte[] getEncoded() { byte[] result = null; try { result = encode(); } catch (InvalidKeyException e) { } return result; } /** * Returns the format for this key: "X.509" */ public String getFormat() { return "X.509"; } /** * Returns the raw key as a byte array */ public byte[] getKey() { return key; } /** * Returns the DER-encoded form of the key as a byte array. * * @exception InvalidKeyException on encoding errors. */ public byte[] encode() throws InvalidKeyException { if (encodedKey == null) { try { DerOutputStream out; out = new DerOutputStream(); encode(out); encodedKey = out.toByteArray(); } catch (IOException e) { throw new InvalidKeyException("IOException : " + e.getMessage()); } } return copyEncodedKey(encodedKey); } /* * Returns a printable representation of the key */ public String toString() { org.mozilla.jss.netscape.security.util.PrettyPrintFormat pp = new org.mozilla.jss.netscape.security.util.PrettyPrintFormat(" ", 20); String keybits = pp.toHexString(key); return "algorithm = " + algid.toString() + ", unparsed keybits = \n" + keybits; } /** * Initialize an X509Key object from an input stream. The data on that * input stream must be encoded using DER, obeying the X.509 SubjectPublicKeyInfo format. That is, the * data is a * sequence consisting of an algorithm ID and a bit string which holds * the key. (That bit string is often used to encapsulate another DER * encoded sequence.) * *

* Subclasses should not normally redefine this method; they should instead provide a parseKeyBits * method to parse any fields inside the key member. * *

* The exception to this rule is that since private keys need not be encoded using the X.509 * SubjectPublicKeyInfo format, private keys may override this method, encode, and of * course getFormat. * * @param in an input stream with a DER-encoded X.509 * SubjectPublicKeyInfo value * @exception InvalidKeyException on parsing errors. */ public void decode(InputStream in) throws InvalidKeyException { DerValue val; try { val = new DerValue(in); if (val.tag != DerValue.tag_Sequence) throw new InvalidKeyException("invalid key format"); algid = AlgorithmId.parse(val.data.getDerValue()); key = val.data.getBitString(); parseKeyBits(); if (val.data.available() != 0) throw new InvalidKeyException("excess key data"); } catch (IOException e) { // e.printStackTrace (); throw new InvalidKeyException("IOException : " + e.getMessage()); } } public void decode(byte[] encodedKey) throws InvalidKeyException { decode(new ByteArrayInputStream(encodedKey)); } /** * Serialization write ... X.509 keys serialize as * themselves, and they're parsed when they get read back. */ private void writeObject(java.io.ObjectOutputStream stream) throws IOException { stream.write(getEncoded()); } /** * Serialization read ... X.509 keys serialize as * themselves, and they're parsed when they get read back. */ private void readObject(ObjectInputStream stream) throws IOException { try { decode(stream); } catch (InvalidKeyException e) { e.printStackTrace(); throw new IOException("deserialized key is invalid: " + e.getMessage()); } } public boolean equals(Object object) { if (this == object) { return true; } if (object instanceof Key) { Key key = (Key) object; byte[] b1; if (encodedKey != null) { b1 = encodedKey; } else { b1 = getEncoded(); } byte[] b2 = key.getEncoded(); return java.security.MessageDigest.isEqual(b1, b2); } return false; } /** * Calculates a hash code value for the object. Objects * which are equal will also have the same hashcode. */ public int hashCode() { int retval = 0; byte[] b1 = getEncoded(); for (int i = 1; i < b1.length; i++) { retval += b1[i] * i; } return (retval); } /* * Make a copy of the encoded key. */ private byte[] copyEncodedKey(byte[] encodedKey) { int len = encodedKey.length; byte[] copy = new byte[len]; System.arraycopy(encodedKey, 0, copy, 0, len); return copy; } /* * Produce SubjectPublicKey encoding from algorithm id and key material. */ static void encode(DerOutputStream out, AlgorithmId algid, byte[] key) throws IOException { DerOutputStream tmp = new DerOutputStream(); algid.encode(tmp); tmp.putBitString(key); out.write(DerValue.tag_Sequence, tmp); } /* * parsePublicKey returns a PublicKey for use with package JSS from within netscape.security.*. * This function provide an interim solution for migrating from using the netscape.security.* package * to using the JSS package. */ public static PublicKey parsePublicKey(DerValue in) throws IOException { AlgorithmId algorithm; PublicKey subjectKey; if (in.tag != DerValue.tag_Sequence) throw new IOException("corrupt subject key"); algorithm = AlgorithmId.parse(in.data.getDerValue()); try { subjectKey = buildPublicKey(algorithm, in.data.getBitString()); } catch (InvalidKeyException e) { throw new IOException("subject key, " + e.getMessage()); } if (in.data.available() != 0) throw new IOException("excess subject key"); return subjectKey; } /* buildPublicKey returns a PublicKey for use with the JSS package from within netscape.security.*. * This function provide an interim solution for migrating from using the netscape.security.* package * to using the JSS package. */ static PublicKey buildPublicKey(AlgorithmId algid, byte[] key) throws IOException, InvalidKeyException { /* * Use the algid and key parameters to produce the ASN.1 encoding * of the key, which will then be used as the input to the * key factory. */ DerOutputStream x509EncodedKeyStream = new DerOutputStream(); encode(x509EncodedKeyStream, algid, key); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(x509EncodedKeyStream.toByteArray()); try { // Instantiate the key factory of the appropriate algorithm KeyFactory keyFac = null; if (Security.getProvider("Mozilla-JSS") == null) { keyFac = KeyFactory.getInstance(algid.getName()); } else { keyFac = KeyFactory.getInstance(algid.getName(), "Mozilla-JSS"); } // Generate the public key PublicKey pubKey = keyFac.generatePublic(x509KeySpec); /* * Return specialized X509Key, where the structure within the * key has been parsed */ return pubKey; } catch (NoSuchAlgorithmException e) { // Return generic X509Key with opaque key data (see below) throw new InvalidKeyException(e.toString()); } catch (InvalidKeySpecException e) { throw new InvalidKeyException(e.toString()); } catch (Exception e) { throw new InvalidKeyException(e.toString()); } } } jss-4.6.3/org/mozilla/jss/nss/000077500000000000000000000000001362106420000161555ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/nss/Buffer.c000066400000000000000000000102551362106420000175350ustar00rootroot00000000000000#include #include #include #include #include "jssutil.h" #include "BufferProxy.h" #include "j_buffer.h" #include "_jni/org_mozilla_jss_nss_Buffer.h" JNIEXPORT jobject JNICALL Java_org_mozilla_jss_nss_Buffer_Create(JNIEnv *env, jclass clazz, jlong length) { j_buffer *buf = NULL; PR_ASSERT(env != NULL && length > 0); buf = jb_alloc((size_t) length); PR_ASSERT(buf != NULL); return JSS_PR_wrapJBuffer(env, &buf); } JNIEXPORT jlong JNICALL Java_org_mozilla_jss_nss_Buffer_Capacity(JNIEnv *env, jclass clazz, jobject buf) { j_buffer *real_buf = NULL; PR_ASSERT(env != NULL && buf != NULL); if (JSS_PR_unwrapJBuffer(env, buf, &real_buf) != PR_SUCCESS) { return 0; } return jb_capacity(real_buf); } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_nss_Buffer_CanRead(JNIEnv *env, jclass clazz, jobject buf) { j_buffer *real_buf = NULL; PR_ASSERT(env != NULL && buf != NULL); if (JSS_PR_unwrapJBuffer(env, buf, &real_buf) != PR_SUCCESS) { return false; } return jb_can_read(real_buf); } JNIEXPORT jlong JNICALL Java_org_mozilla_jss_nss_Buffer_ReadCapacity(JNIEnv *env, jclass clazz, jobject buf) { j_buffer *real_buf = NULL; PR_ASSERT(env != NULL && buf != NULL); if (JSS_PR_unwrapJBuffer(env, buf, &real_buf) != PR_SUCCESS) { return 0; } return jb_read_capacity(real_buf); } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_nss_Buffer_CanWrite(JNIEnv *env, jclass clazz, jobject buf) { j_buffer *real_buf = NULL; PR_ASSERT(env != NULL && buf != NULL); if (JSS_PR_unwrapJBuffer(env, buf, &real_buf) != PR_SUCCESS) { return false; } return jb_can_write(real_buf); } JNIEXPORT jlong JNICALL Java_org_mozilla_jss_nss_Buffer_WriteCapacity(JNIEnv *env, jclass clazz, jobject buf) { j_buffer *real_buf = NULL; PR_ASSERT(env != NULL && buf != NULL); if (JSS_PR_unwrapJBuffer(env, buf, &real_buf) != PR_SUCCESS) { return 0; } return jb_write_capacity(real_buf); } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_nss_Buffer_Read(JNIEnv *env, jclass clazz, jobject buf, jlong length) { j_buffer *real_buf = NULL; size_t read_amount = 0; uint8_t *tmp = NULL; jbyteArray result = NULL; PR_ASSERT(env != NULL && buf != NULL && length > 0); if (JSS_PR_unwrapJBuffer(env, buf, &real_buf) != PR_SUCCESS) { return NULL; } tmp = calloc(length, sizeof(uint8_t)); read_amount = jb_read(real_buf, tmp, (size_t) length); result = JSS_ToByteArray(env, tmp, read_amount); free(tmp); return result; } JNIEXPORT jlong JNICALL Java_org_mozilla_jss_nss_Buffer_Write(JNIEnv *env, jclass clazz, jobject buf, jbyteArray input) { j_buffer *real_buf = NULL; size_t input_length = 0; uint8_t *real_input = NULL; long write_amount = -1; PR_ASSERT(env != NULL && buf != NULL); if (JSS_PR_unwrapJBuffer(env, buf, &real_buf) != PR_SUCCESS) { return write_amount; } if (!JSS_FromByteArray(env, input, &real_input, &input_length)) { return write_amount; } write_amount = jb_write(real_buf, real_input, input_length); free(real_input); return write_amount; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_nss_Buffer_Get(JNIEnv *env, jclass clazz, jobject buf) { j_buffer *real_buf = NULL; PR_ASSERT(env != NULL && buf != NULL); if (JSS_PR_unwrapJBuffer(env, buf, &real_buf) != PR_SUCCESS) { return -1; } return jb_get(real_buf); } JNIEXPORT jint JNICALL Java_org_mozilla_jss_nss_Buffer_Put(JNIEnv *env, jclass clazz, jobject buf, jbyte input) { j_buffer *real_buf = NULL; PR_ASSERT(env != NULL && buf != NULL); if (JSS_PR_unwrapJBuffer(env, buf, &real_buf) != PR_SUCCESS) { return -1; } return jb_put(real_buf, (uint8_t) input); } JNIEXPORT void JNICALL Java_org_mozilla_jss_nss_Buffer_Free(JNIEnv *env, jclass clazz, jobject buf) { j_buffer *real_buf = NULL; PR_ASSERT(env != NULL && buf != NULL); if (JSS_PR_unwrapJBuffer(env, buf, &real_buf) != PR_SUCCESS || real_buf == NULL) { return; } jb_free(real_buf); JSS_clearPtrFromProxy(env, buf); } jss-4.6.3/org/mozilla/jss/nss/Buffer.java000066400000000000000000000045751362106420000202440ustar00rootroot00000000000000package org.mozilla.jss.nss; public class Buffer { /** * Create a new j_buffer object with the specified number of bytes. * * See also: jb_alloc in org/mozilla/jss/ssl/javax/j_buffer.h */ public static native BufferProxy Create(long length); /** * Check the total capacity of a buffer object. * * See also: jb_capacity in org/mozilla/jss/ssl/javax/j_buffer.h */ public static native long Capacity(BufferProxy buf); /** * Check whether or not the buffer can be read from (i.e., is non-empty). * * See also: jb_can_read in org/mozilla/jss/ssl/javax/j_buffer.h */ public static native boolean CanRead(BufferProxy buf); /** * Check the remaining number of bytes that can be read from the * buffer. * * See also: jb_read_capacity in org/mozilla/jss/ssl/javax/j_buffer.h */ public static native long ReadCapacity(BufferProxy buf); /** * Check whether or not the buffer can be written to (i.e., is not full). * * See also: jb_can_write in org/mozilla/jss/ssl/javax/j_buffer.h */ public static native boolean CanWrite(BufferProxy buf); /** * Check the remaining number of bytes that can be written to the * buffer. * * See also: jb_write_capacity in org/mozilla/jss/ssl/javax/j_buffer.h */ public static native long WriteCapacity(BufferProxy buf); /** * Read the specified number of bytes from the buffer. * * See also: jb_read in org/mozilla/jss/ssl/javax/j_buffer.h */ public static native byte[] Read(BufferProxy buf, long length); /** * Write the specified bytes to the buffer. * * See also: jb_write in org/mozilla/jss/ssl/javax/j_buffer.h */ public static native long Write(BufferProxy buf, byte[] input); /** * Get a single character from the buffer. * * See also: jb_get in org/mozilla/jss/ssl/javax/j_buffer.h */ public static native int Get(BufferProxy buf); /** * Put a single character into the buffer. * * See also: jb_put in org/mozilla/jss/ssl/javax/j_buffer.h */ public static native int Put(BufferProxy buf, byte input); /** * Destroy a buffer object, freeing its resources. * * See also: jb_free in org/mozilla/jss/ssl/javax/j_buffer.h */ public static native void Free(BufferProxy buf); } jss-4.6.3/org/mozilla/jss/nss/BufferProxy.c000066400000000000000000000023601362106420000205750ustar00rootroot00000000000000#include #include #include "java_ids.h" #include "jssutil.h" #include "BufferProxy.h" jobject JSS_PR_wrapJBuffer(JNIEnv *env, j_buffer **buffer) { jbyteArray pointer = NULL; jclass proxyClass; jmethodID constructor; jobject bufferObj = NULL; PR_ASSERT(env != NULL && buffer != NULL && *buffer != NULL); /* convert pointer to byte array */ pointer = JSS_ptrToByteArray(env, *buffer); /* * Lookup the class and constructor */ proxyClass = (*env)->FindClass(env, BUFFER_PROXY_CLASS_NAME); if(proxyClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID(env, proxyClass, PLAIN_CONSTRUCTOR, BUFFER_PROXY_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* call the constructor */ bufferObj = (*env)->NewObject(env, proxyClass, constructor, pointer); finish: *buffer = NULL; PR_ASSERT(bufferObj || (*env)->ExceptionOccurred(env)); return bufferObj; } PRStatus JSS_PR_unwrapJBuffer(JNIEnv *env, jobject buffer_proxy, j_buffer **buffer) { return JSS_getPtrFromProxy(env, buffer_proxy, (void**)buffer); } jss-4.6.3/org/mozilla/jss/nss/BufferProxy.h000066400000000000000000000005321362106420000206010ustar00rootroot00000000000000#include #include "j_buffer.h" #pragma once /* Wrap a j_buffer object into a BufferProxy, freeing the buffer on error. */ jobject JSS_PR_wrapJBuffer(JNIEnv *env, j_buffer **buffer); /* Extract a j_buffer pointer from an instance of a BufferProxy. */ PRStatus JSS_PR_unwrapJBuffer(JNIEnv *env, jobject buffer_proxy, j_buffer **buffer); jss-4.6.3/org/mozilla/jss/nss/BufferProxy.java000066400000000000000000000007361362106420000213010ustar00rootroot00000000000000package org.mozilla.jss.nss; public class BufferProxy extends org.mozilla.jss.util.NativeProxy { public BufferProxy(byte[] pointer) { super(pointer); } /** * It is usually better to call org.mozilla.jss.nss.Buffer.Free(...) * instead. * * But this does it for you. */ protected void releaseNativeResources() { Buffer.Free(this); } protected void finalize() throws Throwable { super.finalize(); } } jss-4.6.3/org/mozilla/jss/nss/PR.c000066400000000000000000000231721362106420000166470ustar00rootroot00000000000000#include #include #include #include #include "jssutil.h" #include "PRFDProxy.h" #include "BufferProxy.h" #include "BufferPRFD.h" #include "_jni/org_mozilla_jss_nss_PR.h" JNIEXPORT jobject JNICALL Java_org_mozilla_jss_nss_PR_Open(JNIEnv *env, jclass clazz, jstring name, jint flags, jint mode) { PRFileDesc *fd; const char *path; PR_ASSERT(env != NULL); PR_SetError(0, 0); path = JSS_RefJString(env, name); if (path == NULL) { return NULL; } fd = PR_Open(path, flags, mode); if (fd == NULL) { JSS_DerefJString(env, name, path); return NULL; } JSS_DerefJString(env, name, path); return JSS_PR_wrapPRFDProxy(env, &fd); } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_nss_PR_NewTCPSocket(JNIEnv *env, jclass clazz) { PRFileDesc *fd; PR_ASSERT(env != NULL); PR_SetError(0, 0); fd = PR_NewTCPSocket(); if (fd == NULL) { return NULL; } return JSS_PR_wrapPRFDProxy(env, &fd); } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_nss_PR_NewBufferPRFD(JNIEnv *env, jclass clazz, jobject read_buf, jobject write_buf, jbyteArray peer_info) { j_buffer *real_read_buf = NULL; j_buffer *real_write_buf = NULL; uint8_t *real_peer_info = NULL; size_t peer_info_len = 0; PRFileDesc *buf_prfd; jobject result = NULL; PR_ASSERT(env != NULL && read_buf != NULL && write_buf != NULL); PR_SetError(0, 0); if (JSS_PR_unwrapJBuffer(env, read_buf, &real_read_buf) != PR_SUCCESS) { return result; } if (JSS_PR_unwrapJBuffer(env, write_buf, &real_write_buf) != PR_SUCCESS) { return result; } if (peer_info != NULL && !JSS_FromByteArray(env, peer_info, &real_peer_info, &peer_info_len)) { return result; } buf_prfd = newBufferPRFileDesc(real_read_buf, real_write_buf, real_peer_info, peer_info_len); if (buf_prfd == NULL) { return result; } result = JSS_PR_wrapPRFDProxy(env, &buf_prfd); free(real_peer_info); return result; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PR_Close(JNIEnv *env, jclass clazz, jobject fd) { PRFileDesc *real_fd = NULL; PR_ASSERT(env != NULL); PR_SetError(0, 0); if (fd == NULL) { return PR_SUCCESS; } if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return PR_FAILURE; } PRStatus ret = PR_Close(real_fd); if (ret == PR_SUCCESS) { JSS_clearPtrFromProxy(env, fd); } return ret; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PR_Shutdown(JNIEnv *env, jclass clazz, jobject fd, jint how) { PRFileDesc *real_fd = NULL; PR_ASSERT(env != NULL); PR_SetError(0, 0); if (fd == NULL) { return PR_SUCCESS; } if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return PR_FAILURE; } return PR_Shutdown(real_fd, how); } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_nss_PR_Read(JNIEnv *env, jclass clazz, jobject fd, jint amount) { PRFileDesc *real_fd = NULL; jobject result = NULL; int read_amount = 0; int this_read = 0; uint8_t *buffer = NULL; PRSocketOptionData opt = { 0 }; PRDescType fd_type; PR_ASSERT(env != NULL && fd != NULL && amount >= 0); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return NULL; } fd_type = PR_GetDescType(real_fd); opt.value.non_blocking = PR_FALSE; if (fd_type == PR_DESC_SOCKET_TCP || fd_type == PR_DESC_SOCKET_UDP || fd_type == PR_DESC_LAYERED) { opt.option = PR_SockOpt_Nonblocking; if (PR_GetSocketOption(real_fd, &opt) != PR_SUCCESS) { /* Unable to get the value of non_blocking status; so error on * the side of caution. */ opt.value.non_blocking = PR_FALSE; } } PR_ASSERT(real_fd != NULL); buffer = calloc(amount, sizeof(uint8_t)); /* Work around a bug in NSS/NSPR: sometimes PR_Read returns a much smaller * read than expected, when it could read much more. */ while (read_amount < amount) { this_read = PR_Read(real_fd, buffer + read_amount, amount - read_amount); if (this_read <= 0) { if (PR_GetError() == PR_WOULD_BLOCK_ERROR && read_amount > 0) { /* If we've previously gotten data and we would block this * time, then we're at the end of our data. Reset the error * status and break, rather than exiting with an error. */ PR_SetError(0, 0); break; } goto done; } else { read_amount += this_read; if (opt.value.non_blocking != PR_TRUE) { /* When we're not non-blocking, it isn't necessarily safe to * call PR_Read again -- a call that would've not blocked will * now block. */ break; } } } result = JSS_ToByteArray(env, buffer, read_amount); done: free(buffer); return result; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PR_Write(JNIEnv *env, jclass clazz, jobject fd, jbyteArray buf) { PRFileDesc *real_fd = NULL; unsigned int real_length = 0; int max_length = 0; uint8_t *buffer = NULL; int result = 0; PR_ASSERT(env != NULL && fd != NULL && buf != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return 0; } PR_ASSERT(real_fd != NULL); real_length = (*env)->GetArrayLength(env, buf); if (real_length > INT_MAX) { max_length = INT_MAX; } else { max_length = (int)(real_length % INT_MAX); } buffer = (uint8_t*)((*env)->GetByteArrayElements(env, buf, NULL)); if (buffer == NULL) { return 0; } result = PR_Write(real_fd, buffer, max_length); (*env)->ReleaseByteArrayElements(env, buf, (jbyte *)buffer, JNI_ABORT); return result; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_nss_PR_Recv(JNIEnv *env, jclass clazz, jobject fd, jint amount, jint flags, jlong timeout) { PRFileDesc *real_fd = NULL; PRIntervalTime timeout_interval = (PRIntervalTime)(timeout % UINT32_MAX); jobject result = NULL; int read_amount = 0; uint8_t *buffer = NULL; PR_ASSERT(env != NULL && fd != NULL && amount >= 0 && flags >= 0 && timeout >= 0 && timeout <= UINT32_MAX); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return NULL; } PR_ASSERT(real_fd != NULL); buffer = calloc(amount, sizeof(uint8_t)); read_amount = PR_Recv(real_fd, buffer, amount, flags, timeout_interval); if (read_amount <= 0) { goto done; } result = JSS_ToByteArray(env, buffer, read_amount); done: free(buffer); return result; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PR_Send(JNIEnv *env, jclass clazz, jobject fd, jbyteArray buf, jint flags, jlong timeout) { PRFileDesc *real_fd = NULL; unsigned int real_length = 0; int max_length = 0; uint8_t *buffer = NULL; PRIntervalTime timeout_interval = (PRIntervalTime)(timeout % UINT32_MAX); int result = 0; PR_ASSERT(env != NULL && fd != NULL && buf != NULL && flags >= 0 && timeout >= 0 && timeout <= UINT32_MAX); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return 0; } PR_ASSERT(real_fd != NULL); real_length = (*env)->GetArrayLength(env, buf); if (real_length > INT_MAX) { max_length = INT_MAX; } else { max_length = (int)(real_length % INT_MAX); } buffer = (uint8_t*)((*env)->GetByteArrayElements(env, buf, NULL)); if (buffer == NULL) { return 0; } result = PR_Send(real_fd, buffer, max_length, flags, timeout_interval); (*env)->ReleaseByteArrayElements(env, buf, (jbyte *)buffer, JNI_ABORT); return result; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PR_GetError(JNIEnv *env, jclass clazz) { return PR_GetError(); } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_nss_PR_GetErrorTextNative(JNIEnv *env, jclass clazz) { ssize_t error_size; char *error_text = NULL; jbyteArray result = NULL; PR_ASSERT(env != NULL); error_size = PR_GetErrorTextLength(); if (error_size < 0) { return NULL; } error_text = calloc(error_size + 1, sizeof(char)); if (PR_GetErrorText(error_text) == 0) { free(error_text); return NULL; } result = JSS_ToByteArray(env, error_text, error_size); free(error_text); return result; } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_nss_PR_ErrorToNameNative(JNIEnv *env, jclass clazz, jint error_code) { size_t error_size; const char *error_name = NULL; jbyteArray result = NULL; PR_ASSERT(env != NULL); error_name = PR_ErrorToName(error_code); if (error_name == NULL) { return NULL; } error_size = strlen(error_name); result = JSS_ToByteArray(env, error_name, error_size); return result; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PR_getPRShutdownRcv(JNIEnv *env, jclass clazz) { return PR_SHUTDOWN_RCV; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PR_getPRShutdownSend(JNIEnv *env, jclass clazz) { return PR_SHUTDOWN_SEND; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PR_getPRShutdownBoth(JNIEnv *env, jclass clazz) { return PR_SHUTDOWN_BOTH; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PR_getPRSuccess(JNIEnv *env, jclass clazz) { return PR_SUCCESS; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PR_getPRFailure(JNIEnv *env, jclass clazz) { return PR_FAILURE; } jss-4.6.3/org/mozilla/jss/nss/PR.java000066400000000000000000000120741362106420000173450ustar00rootroot00000000000000package org.mozilla.jss.nss; /** * This class provides static access to raw NSPS calls with the PR prefix, * and handles the usage of NativeProxy objects. */ public class PR { /** * Shut down the receiving side of the TCP connection. * * See also: Shutdown */ public static final int SHUTDOWN_RCV = getPRShutdownRcv(); /** * Shut down the sending side of the TCP connection. * * See also: Shutdown */ public static final int SHUTDOWN_SEND = getPRShutdownSend(); /** * Shut down both sides of the TCP connection. * * See also: Shutdown */ public static final int SHUTDOWN_BOTH = getPRShutdownBoth(); /** * Return value on success from NSPR functions. * * See also: PR_SUCCESS in /usr/include/nspr4/prtypes.h */ public static final int SUCCESS = getPRSuccess(); /** * Return value on failure from NSPR functions. * * See also: PR_FAILURE in /usr/include/nspr4/prtypes.h */ public static final int FAILURE = getPRFailure(); /** * Open the file at name (with the specified flags and mode) and create * a new PRFDProxy (to a NSPR PRFileDesc *) for that file. * * See also: PR_Open in /usr/include/nspr4/prio.h */ public static native PRFDProxy Open(String name, int flags, int mode); /** * Open a new TCP Socket and create a new PRFDProxy for that socket. * * See also: PR_NewTCPSocket in /usr/include/nspr4/prio.h */ public static native PRFDProxy NewTCPSocket(); /** * Create a new j_buffer backed PRFileDesc, mimicing a TCP socket with * the specified peer_info. * * See also: newBufferPRFileDesc in org/mozilla/jss/ssl/javax/BufferPRFD.h */ public static native PRFDProxy NewBufferPRFD(BufferProxy read_buf, BufferProxy write_buf, byte[] peer_info); /** * Close an existing PRFDProxy. * * See also: PR_Close in /usr/include/nspr4/prio.h */ public static native int Close(PRFDProxy fd); /** * Close an existing SSLFDProxy. * * See also: org.mozilla.jss.nss.PR.Close * org.mozilla.jss.nss.SSLFD.releaseNativeResources */ public static int Close(SSLFDProxy fd) throws Exception { int ret = PR.Close((PRFDProxy) fd); fd.close(); return ret; } /** * Shutdown an existing PRFDProxy. * This is usually used with TCP modes. * * See also: PR_Shutdown in /usr/include/nspr4/prio.h */ public static native int Shutdown(PRFDProxy fd, int how); /** * Read up to amount bytes from a PRFDProxy. * * See also: PR_Read in /usr/include/nspr4/prio.h */ public static native byte[] Read(PRFDProxy fd, int amount); /** * Recv up to amount bytes from a PRFDProxy, given the specified receive * flags and timeout value. * * See also: PR_Recv in /usr/include/nspr4/prio.h */ public static native byte[] Recv(PRFDProxy fd, int amount, int flags, long timeout); /** * Write the specified bytes to the PRFDProxy. * * Note: Unlike PR_Write, this method assumes the entire buffer is being * written. * * See also: PR_Write in /usr/include/nspr4/prio.h */ public static native int Write(PRFDProxy fd, byte[] buf); /** * Send the specified bytes via the PRFDProxy, given the specified * send flags and timeout value. * * See also: PR_Send in /usr/include/nspr4/prio.h */ public static native int Send(PRFDProxy fd, byte[] buf, int flags, long timeout); /** * Get the value of the current PR error. This is cleared on each NSPR * call. * * See also: PR_GetError in /usr/include/nspr4/prio.h */ public static native int GetError(); /** * Get the error text of the current PR error. This is cleared on each * NSPR call. * * See also: PR_GetErrorText in /usr/include/nspr4/prio.h */ public static String GetErrorText() { byte[] text = GetErrorTextNative(); if (text == null) { return ""; } return new String(text); } private static native byte[] GetErrorTextNative(); /** * Get the constant name of the current PR error. This is cleared on each * NSPR call. * * See also: PR_ErrorToName in /usr/include/nspr4/prio.h */ public static String ErrorToName(int code) { byte[] name = ErrorToNameNative(code); if (name == null) { return ""; } return new String(name); } private static native byte[] ErrorToNameNative(int code); /* Internal methods for querying constants. */ private static native int getPRShutdownRcv(); private static native int getPRShutdownSend(); private static native int getPRShutdownBoth(); private static native int getPRSuccess(); private static native int getPRFailure(); } jss-4.6.3/org/mozilla/jss/nss/PRErrors.c000066400000000000000000000007711362106420000200440ustar00rootroot00000000000000#include #include #include #include #include "jssutil.h" #include "PRFDProxy.h" #include "BufferProxy.h" #include "BufferPRFD.h" #include "_jni/org_mozilla_jss_nss_PRErrors.h" JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PRErrors_getWouldBlockError(JNIEnv *env, jclass clazz) { return PR_WOULD_BLOCK_ERROR; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_PRErrors_getSocketShutdownError(JNIEnv *env, jclass clazz) { return PR_SOCKET_SHUTDOWN_ERROR; } jss-4.6.3/org/mozilla/jss/nss/PRErrors.java000066400000000000000000000014141362106420000205360ustar00rootroot00000000000000package org.mozilla.jss.nss; /** * This class provides access to useful NSPR errors, getting their values from * a JNI call. Note that it *isn't* an enum as the NSPR wrappers return int. * This saves us from having to wrap every NSPR error. */ public class PRErrors { /** * The call would block. * * See also: PR_WOULD_BLOCK_ERROR in /usr/include/nspr4/prerr.h */ public static final int WOULD_BLOCK_ERROR = getWouldBlockError(); /** * The socket is shutdown. * * See also: PR_SOCKET_SHUTDOWN_ERROR in /usr/include/nspr4/prerr.h */ public static final int SOCKET_SHUTDOWN_ERROR = getSocketShutdownError(); private static native int getWouldBlockError(); private static native int getSocketShutdownError(); } jss-4.6.3/org/mozilla/jss/nss/PRFDProxy.c000066400000000000000000000031601362106420000201160ustar00rootroot00000000000000#include #include #include "java_ids.h" #include "jssutil.h" #include "PRFDProxy.h" static jobject JSS_PR_wrapFDProxy(JNIEnv *env, PRFileDesc **fd, const char *className, const char *conSig) { jbyteArray pointer = NULL; jclass proxyClass; jmethodID constructor; jobject fdObj = NULL; PR_ASSERT(env != NULL && fd != NULL && *fd != NULL); /* convert pointer to byte array */ pointer = JSS_ptrToByteArray(env, *fd); /* Lookup the class and constructor */ proxyClass = (*env)->FindClass(env, className); if(proxyClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID(env, proxyClass, PLAIN_CONSTRUCTOR, conSig); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* call the constructor */ fdObj = (*env)->NewObject(env, proxyClass, constructor, pointer); finish: if (fdObj == NULL && *fd != NULL) { /* didn't work, so free resources */ PR_Close(*fd); } *fd = NULL; PR_ASSERT(fdObj || (*env)->ExceptionOccurred(env)); return fdObj; } jobject JSS_PR_wrapPRFDProxy(JNIEnv *env, PRFileDesc **fd) { return JSS_PR_wrapFDProxy(env, fd, PRFD_PROXY_CLASS_NAME, PRFD_PROXY_CONSTRUCTOR_SIG); } jobject JSS_PR_wrapSSLFDProxy(JNIEnv *env, PRFileDesc **fd) { return JSS_PR_wrapFDProxy(env, fd, SSLFD_PROXY_CLASS_NAME, SSLFD_PROXY_CONSTRUCTOR_SIG); } PRStatus JSS_PR_getPRFileDesc(JNIEnv *env, jobject prfd_proxy, PRFileDesc **fd) { return JSS_getPtrFromProxy(env, prfd_proxy, (void**)fd); } jss-4.6.3/org/mozilla/jss/nss/PRFDProxy.h000066400000000000000000000007471362106420000201330ustar00rootroot00000000000000#include #include #pragma once /* Wrap a C/NSPR PRFileDesc into a Java PRFDProxy, closing the fd on error. */ jobject JSS_PR_wrapPRFDProxy(JNIEnv *env, PRFileDesc **fd); /* Wrap a C/NSPR PRFileDesc into a Java SSLFDProxy, closing the fd on error. */ jobject JSS_PR_wrapSSLFDProxy(JNIEnv *env, PRFileDesc **fd); /* Extract the C/NSPR PRFileDesc from an instance of a Java PRFDProxy. */ PRStatus JSS_PR_getPRFileDesc(JNIEnv *env, jobject prfd_proxy, PRFileDesc **fd); jss-4.6.3/org/mozilla/jss/nss/PRFDProxy.java000066400000000000000000000004561362106420000206220ustar00rootroot00000000000000package org.mozilla.jss.nss; public class PRFDProxy extends org.mozilla.jss.util.NativeProxy { public PRFDProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); } } jss-4.6.3/org/mozilla/jss/nss/SSL.c000066400000000000000000000331241362106420000167650ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "jssl.h" #include "java_ids.h" #include "jss_exceptions.h" #include "jssutil.h" #include "pk11util.h" #include "PRFDProxy.h" #include "SSLFDProxy.h" #include "SSLVersionRange.h" #include "_jni/org_mozilla_jss_nss_SSL.h" jobject JSS_NewSecurityStatusResult(JNIEnv *env, int on, char *cipher, int keySize, int secretKeySize, char *issuer, char *subject) { jclass resultClass; jmethodID constructor; jobject result = NULL; jbyteArray cipher_java = NULL; jbyteArray issuer_java = NULL; jbyteArray subject_java = NULL; PR_ASSERT(env != NULL); resultClass = (*env)->FindClass(env, SECURITY_STATUS_CLASS_NAME); if (resultClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID(env, resultClass, PLAIN_CONSTRUCTOR, SECURITY_STATUS_CONSTRUCTOR_SIG); if (constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } if (cipher) { cipher_java = JSS_ToByteArray(env, cipher, strlen(cipher)); } if (issuer) { issuer_java = JSS_ToByteArray(env, issuer, strlen(issuer)); } if (subject) { subject_java = JSS_ToByteArray(env, subject, strlen(subject)); } result = (*env)->NewObject(env, resultClass, constructor, on, cipher_java, keySize, secretKeySize, issuer_java, subject_java); finish: return result; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_nss_SSL_ImportFD(JNIEnv *env, jclass clazz, jobject model, jobject fd) { PRFileDesc *result = NULL; PRFileDesc *real_model = NULL; PRFileDesc *real_fd = NULL; PR_ASSERT(env != NULL); PR_SetError(0, 0); /* Note: NSS calling semantics state that either model or fd can be * NULL; so when the Java Object is not-NULL, dereference it. */ if (model != NULL && JSS_PR_getPRFileDesc(env, model, &real_model) != PR_SUCCESS) { return NULL; } if (fd != NULL && JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return NULL; } result = SSL_ImportFD(real_model, real_fd); return JSS_PR_wrapSSLFDProxy(env, &result); } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_SSL_OptionSet(JNIEnv *env, jclass clazz, jobject fd, jint option, jint val) { PRFileDesc *real_fd = NULL; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return SECFailure; } return SSL_OptionSet(real_fd, option, val); } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_SSL_OptionGet(JNIEnv *env, jclass clazz, jobject fd, jint option) { PRFileDesc *real_fd = NULL; int result = -1; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "Unable to dereference fd object"); return result; } if (SSL_OptionGet(real_fd, option, &result) != SECSuccess) { JSS_throwMsg(env, ILLEGAL_ARGUMENT_EXCEPTION, "Unknown option to get or getting option failed"); } return result; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_SSL_SetURL(JNIEnv *env, jclass clazz, jobject fd, jstring url) { PRFileDesc *real_fd = NULL; SECStatus ret = SECFailure; const char *real_url = NULL; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return ret; } real_url = JSS_RefJString(env, url); if (real_url == NULL) { return ret; } ret = SSL_SetURL(real_fd, real_url); JSS_DerefJString(env, url, real_url); return ret; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_SSL_CipherPrefSet(JNIEnv *env, jclass clazz, jobject fd, jint cipher, jboolean enabled) { PRFileDesc *real_fd = NULL; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return SECFailure; } return SSL_CipherPrefSet(real_fd, cipher, enabled); } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_nss_SSL_CipherPrefGet(JNIEnv *env, jclass clazz, jobject fd, jint cipher) { PRFileDesc *real_fd = NULL; int enabled = false; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "Unable to dereference fd object"); return enabled; } if (SSL_CipherPrefGet(real_fd, cipher, &enabled) != SECSuccess) { JSS_throwMsg(env, ILLEGAL_ARGUMENT_EXCEPTION, "Unknown cipher suite to get or getting its value failed"); return enabled; } return enabled; } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_SSL_VersionRangeSetNative(JNIEnv *env, jclass clazz, jobject fd, jint min_ssl, jint max_ssl) { PRFileDesc *real_fd = NULL; SSLVersionRange vrange; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (min_ssl < 0 || min_ssl >= JSSL_enums_size || max_ssl < 0 || max_ssl >= JSSL_enums_size) { char buf[128]; snprintf(buf, 128, "SSL.VersionRangeSetNative(): for min=%d max=%d failed - out of range for array JSSL_enums size: %d", min_ssl, max_ssl, JSSL_enums_size); JSSL_throwSSLSocketException(env, buf); return SECFailure; } if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "Unable to dereference fd object"); return SECFailure; } vrange.min = JSSL_enums[min_ssl]; vrange.max = JSSL_enums[max_ssl]; return SSL_VersionRangeSet(real_fd, &vrange); } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_nss_SSL_VersionRangeGet(JNIEnv *env, jclass clazz, jobject fd) { PRFileDesc *real_fd = NULL; SSLVersionRange vrange; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "Unable to dereference fd object"); return NULL; } if (SSL_VersionRangeGet(real_fd, &vrange) != SECSuccess) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "Unable to dereference fd object"); return NULL; } return JSS_SSL_wrapVersionRange(env, vrange); } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_nss_SSL_SecurityStatus(JNIEnv *env, jclass clazz, jobject fd) { PRFileDesc *real_fd = NULL; int on; char *cipher; int keySize; int secretKeySize; char *issuer; char *subject; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return NULL; } if (SSL_SecurityStatus(real_fd, &on, &cipher, &keySize, &secretKeySize, &issuer, &subject) != SECSuccess) { return NULL; } return JSS_NewSecurityStatusResult(env, on, cipher, keySize, secretKeySize, issuer, subject); } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_SSL_ResetHandshake(JNIEnv *env, jclass clazz, jobject fd, jboolean asServer) { PRFileDesc *real_fd = NULL; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return SECFailure; } return SSL_ResetHandshake(real_fd, asServer); } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_SSL_ForceHandshake(JNIEnv *env, jclass clazz, jobject fd) { PRFileDesc *real_fd = NULL; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return SECFailure; } return SSL_ForceHandshake(real_fd); } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_SSL_ConfigSecureServer(JNIEnv *env, jclass clazz, jobject fd, jobject cert, jobject key, jint kea) { PRFileDesc *real_fd = NULL; CERTCertificate *real_cert = NULL; SECKEYPrivateKey *real_key = NULL; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return SECFailure; } if (JSS_PK11_getCertPtr(env, cert, &real_cert) != PR_SUCCESS) { return SECFailure; } if (JSS_PK11_getPrivKeyPtr(env, key, &real_key) != PR_SUCCESS) { return SECFailure; } return SSL_ConfigSecureServer(real_fd, real_cert, real_key, kea); } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_SSL_ConfigServerCert(JNIEnv *env, jclass clazz, jobject fd, jobject cert, jobject key) { PRFileDesc *real_fd = NULL; CERTCertificate *real_cert = NULL; SECKEYPrivateKey *real_key = NULL; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return SECFailure; } if (JSS_PK11_getCertPtr(env, cert, &real_cert) != PR_SUCCESS) { return SECFailure; } if (JSS_PK11_getPrivKeyPtr(env, key, &real_key) != PR_SUCCESS) { return SECFailure; } return SSL_ConfigServerCert(real_fd, real_cert, real_key, NULL, 0); } JNIEXPORT int JNICALL Java_org_mozilla_jss_nss_SSL_ConfigServerSessionIDCache(JNIEnv *env, jclass clazz, jint maxCacheEntries, jlong timeout, jlong ssl3_timeout, jstring directory) { const char *dir_path; SECStatus ret = SECFailure; PR_ASSERT(env != NULL); PR_SetError(0, 0); dir_path = JSS_RefJString(env, directory); ret = SSL_ConfigServerSessionIDCache(maxCacheEntries, timeout, ssl3_timeout, dir_path); JSS_DerefJString(env, directory, dir_path); return ret; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_nss_SSL_PeerCertificate(JNIEnv *env, jclass clazz, jobject fd) { PRFileDesc *real_fd = NULL; CERTCertificate *cert = NULL; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return NULL; } cert = SSL_PeerCertificate(real_fd); if (cert == NULL) { return NULL; } return JSS_PK11_wrapCert(env, &cert); } JNIEXPORT jobjectArray JNICALL Java_org_mozilla_jss_nss_SSL_PeerCertificateChain(JNIEnv *env, jclass clazz, jobject fd) { PRFileDesc *real_fd = NULL; CERTCertList *chain = NULL; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return NULL; } chain = SSL_PeerCertificateChain(real_fd); int error = PORT_GetError(); if (chain == NULL && error == SSL_ERROR_NO_CERTIFICATE) { return NULL; } else if (chain == NULL /* && error != SSL_ERROR_NO_CERTIFICATE */) { JSS_throwMsgPrErrArg(env, SECURITY_EXCEPTION, "Unable to construct peer certificate chain.", error); return NULL; } return JSS_PK11_wrapCertChain(env, &chain); } JNIEXPORT jint JNICALL Java_org_mozilla_jss_nss_SSL_AttachClientCertCallback(JNIEnv *env, jclass clazz, jobject fd) { PRFileDesc *real_fd = NULL; CERTCertificate *real_cert = NULL; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return SECFailure; } if (JSS_NSS_getSSLClientCert(env, fd, &real_cert) != PR_SUCCESS) { return SECFailure; } /* When the returned cert is empty and no error occurred, there was no * client certificate specified via SSLFD.SetClientCert(...). Don't add * the certificate selection callback handler. */ if (real_cert == NULL) { return SECSuccess; } return SSL_GetClientAuthDataHook(real_fd, JSSL_SSLFDCertSelectionCallback, (void *)real_cert); } JNIEXPORT jint JNICALL Java_org_mozilla_jss_nss_SSL_EnableAlertLoggingNative(JNIEnv *env, jclass clazz, jobject fd) { PRFileDesc *real_fd = NULL; jobject fd_ref = NULL; SECStatus ret = SECFailure; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return ret; } if (JSS_NSS_addGlobalRef(env, fd, &fd_ref) != PR_SUCCESS) { return ret; } ret = SSL_AlertReceivedCallback(real_fd, JSSL_SSLFDAlertReceivedCallback, fd_ref); if (ret != SECSuccess) { return ret; } ret = SSL_AlertSentCallback(real_fd, JSSL_SSLFDAlertSentCallback, fd_ref); return ret; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_nss_SSL_ConfigJSSDefaultCertAuthCallback(JNIEnv *env, jclass clazz, jobject fd) { PRFileDesc *real_fd = NULL; PR_ASSERT(env != NULL && fd != NULL); PR_SetError(0, 0); if (JSS_PR_getPRFileDesc(env, fd, &real_fd) != PR_SUCCESS) { return SECFailure; } return SSL_AuthCertificateHook(real_fd, JSSL_DefaultCertAuthCallback, NULL); } JNIEXPORT jint JNICALL Java_org_mozilla_jss_nss_SSL_getSSLRequestCertificate(JNIEnv *env, jclass clazz) { return SSL_REQUEST_CERTIFICATE; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_nss_SSL_getSSLRequireCertificate(JNIEnv *env, jclass clazz) { return SSL_REQUIRE_CERTIFICATE; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_nss_SSL_getSSLSECSuccess(JNIEnv *env, jclass clazz) { return SECSuccess; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_nss_SSL_getSSLSECFailure(JNIEnv *env, jclass clazz) { return SECFailure; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_nss_SSL_getSSLSECWouldBlock(JNIEnv *env, jclass clazz) { return SECWouldBlock; } jss-4.6.3/org/mozilla/jss/nss/SSL.java000066400000000000000000000167471362106420000175000ustar00rootroot00000000000000package org.mozilla.jss.nss; /** * This class provides static access to raw NSS calls with the SSL prefix, * and handles the usage of NativeProxy objects. */ import java.util.ArrayList; import org.mozilla.jss.pkcs11.PK11Cert; import org.mozilla.jss.pkcs11.PK11PrivKey; import org.mozilla.jss.ssl.SSLAlertEvent; import org.mozilla.jss.ssl.SSLVersionRange; public class SSL { /** * Request certificate from the remote peer. Value for use with OptionGet * and OptionSet. * * See also: SSL_REQUEST_CERTIFICATE in /usr/include/nss3/ssl.h */ public static final int REQUEST_CERTIFICATE = getSSLRequestCertificate(); /** * Require certificate from the remote peer. Value for use with OptionGet * and OptionSet. * * See also: SSL_REQUIRE_CERTIFICATE in /usr/include/nss3/ssl.h */ public static final int REQUIRE_CERTIFICATE = getSSLRequireCertificate(); /** * Return value on success from NSS functions. * * See also: SECSuccess in /usr/include/nss3/seccomon.h */ public static final int SECSuccess = getSSLSECSuccess(); /** * Return value on failure from NSS functions. * * See also: SECFailure in /usr/include/nss3/seccomon.h */ public static final int SECFailure = getSSLSECFailure(); /** * Return value from NSS functions when the operation would block. * * See also: SECWouldBlock in /usr/include/nss3/seccomon.h */ public static final int SECWouldBlock = getSSLSECWouldBlock(); /** * Import a file descriptor to create a new SSL file descriptor out of it. * * See also: SSL_ImportFD in /usr/include/nss3/ssl.h */ public static native SSLFDProxy ImportFD(PRFDProxy model, PRFDProxy fd); /** * Set the value of a SSL option on the specified PRFileDesc. * * See also: SSL_OptionSet in /usr/include/nss3/ssl.h */ public static native int OptionSet(SSLFDProxy fd, int option, int val); /** * Get the value of a SSL option on the specified PRFileDesc. Note that * this raises an exception in the case of an invalid option. * * See also: SSL_OptionGet in /usr/include/nss3/ssl.h */ public static native int OptionGet(SSLFDProxy fd, int option) throws Exception; /** * Set the hostname of a handshake on the specified PRFileDesc. * * See also: SSL_SetURL in /usr/include/nss3/ssl.h */ public static native int SetURL(SSLFDProxy fd, String url); /** * Set the preference for a specific cipher suite on the specified * PRFileDesc. * * See also: SSL_CipherPrefSet in /usr/include/nss3/ssl.h */ public static native int CipherPrefSet(SSLFDProxy fd, int cipher, boolean enabled); /** * Get the preference for a specific cipher suite on the specified * PRFileDesc. Note that this can raise an Exception when the cipher * is unknown. * * See also: SSL_CipherPrefGet in /usr/include/nss3/ssl.h */ public static native boolean CipherPrefGet(SSLFDProxy fd, int cipher) throws Exception; /** * Set the range of TLS versions enabled by this server by SSLVersionRange. * * See also: SSL_VersionRangeSet in /usr/include/nss3/ssl.h */ public static int VersionRangeSet(SSLFDProxy fd, SSLVersionRange range) { return VersionRangeSetNative(fd, range.getMinEnum(), range.getMaxEnum()); } /** * Set the range of TLS versions enabled by this server. The integer * parameters are values of the SSLVersion enum. * * See also: SSL_VersionRangeSet in /usr/include/nss3/ssl.h */ private static native int VersionRangeSetNative(SSLFDProxy fd, int min_ssl, int max_ssl); /** * Get the range of TLS versions enabled by this server. * * See also: SSL_VersionRangeSet in /usr/include/nss3/ssl.h */ public static native SSLVersionRange VersionRangeGet(SSLFDProxy fd) throws Exception; /** * Check the security status of a SSL handshake. * * See also: SSL_SecurityStatus in /usr/include/nss3/ssl.h */ public static native SecurityStatusResult SecurityStatus(SSLFDProxy fd); /** * Reset the handshake status, optionally handshaking as a server. * * See also: SSL_ResetHandshake in /usr/include/nss3/ssl.h */ public static native int ResetHandshake(SSLFDProxy fd, boolean asServer); /** * Force a handshake to occur if not started, else step one. * * See also: SSL_ForceHandshake in /usr/include/nss3/ssl.h */ public static native int ForceHandshake(SSLFDProxy fd); /** * Configure the certificate and private key for a server socket. * * @deprecated replaced with ConfigServerCert * See also: SSL_ConfigSecureServer in /usr/include/nss3/ssl.h */ @Deprecated public static native int ConfigSecureServer(SSLFDProxy fd, PK11Cert cert, PK11PrivKey key, int kea); /** * Configure the certificate and private key for a server socket. This * form assumes no additional data is passed. * * See also: SSL_ConfigServerCert in /usr/include/nss3/ssl.h */ public static native int ConfigServerCert(SSLFDProxy fd, PK11Cert cert, PK11PrivKey key); /** * Configure the server's session cache. * * See also: SSL_ConfigServerSessionIDCache in /usr/include/nss3/ssl.h */ public static native int ConfigServerSessionIDCache(int maxCacheEntries, long timeout, long ssl3_timeout, String directory); /** * Introspect the peer's certificate. * * See also: SSL_PeerCertificate in /usr/include/nss3/ssl.h */ public static native PK11Cert PeerCertificate(SSLFDProxy fd); /** * Introspect the peer's certificate chain. * * See also: SSL_PeerCertificateChain in /usr/include/nss3/ssl.h */ public static native PK11Cert[] PeerCertificateChain(SSLFDProxy fd) throws Exception; /** * Use client authentication; set client certificate from SSLFDProxy. * * See also: SSL_GetClientAuthDataHook in /usr/include/nss3/ssl.h, * org.mozilla.jss.nss.SSLFDProxy.SetClientCert(...) */ public static native int AttachClientCertCallback(SSLFDProxy fd); /** * Enable recording of alerts in the SSLFDProxy object. * * See also: SSL_AlertReceivedCallback in /usr/include/nss3/ssl.h, * SSL_AlertSentCallback in /usr/include/nss3/ssl.h */ public static int EnableAlertLogging(SSLFDProxy fd) { fd.inboundAlerts = new ArrayList(); fd.inboundOffset = 0; fd.outboundAlerts = new ArrayList(); fd.outboundOffset = 0; return EnableAlertLoggingNative(fd); } /* Internal helper for EnableAlertLogging method. */ private static native int EnableAlertLoggingNative(SSLFDProxy fd); /** * Use the default JSS certificate checking handler (which understands CryptoManager * OCSP status). * * See also: SSL_AuthCertificateHook in /usr/include/nss3/ssl.h and * JSSL_DefaultCertAuthCallback in jss/ssl/callbacks.c */ public static native int ConfigJSSDefaultCertAuthCallback(SSLFDProxy fd); /* Internal methods for querying constants. */ private static native int getSSLRequestCertificate(); private static native int getSSLRequireCertificate(); private static native int getSSLSECSuccess(); private static native int getSSLSECFailure(); private static native int getSSLSECWouldBlock(); } jss-4.6.3/org/mozilla/jss/nss/SSLFDProxy.c000066400000000000000000000215231362106420000202410ustar00rootroot00000000000000#include #include #include #include #include #include "java_ids.h" #include "jssutil.h" #include "pk11util.h" #include "SSLFDProxy.h" #include "GlobalRefProxy.h" PRStatus JSS_NSS_getSSLClientCert(JNIEnv *env, jobject sslfd_proxy, CERTCertificate **cert) { jclass sslfdProxyClass; jfieldID certField; jobject certProxy; PR_ASSERT(env != NULL && sslfd_proxy != NULL && cert != NULL); /* Resolve the clientCert field on a SSLFDProxy object. */ sslfdProxyClass = (*env)->GetObjectClass(env, sslfd_proxy); if (sslfdProxyClass == NULL) { return PR_FAILURE; } certField = (*env)->GetFieldID(env, sslfdProxyClass, SSLFD_PROXY_CLIENT_CERT_FIELD, SSLFD_PROXY_CLIENT_CERT_SIG); if (certField == NULL) { return PR_FAILURE; } certProxy = (*env)->GetObjectField(env, sslfd_proxy, certField); if (certProxy == NULL) { *cert = NULL; return PR_SUCCESS; } /* Get the underlying CERTCertificate pointer from the clientCert * (of type PK11Cert) object. */ return JSS_PK11_getCertPtr(env, certProxy, cert); } static PRStatus JSS_NSS_getEventArrayList(JNIEnv *env, jobject sslfd_proxy, const char *which, jobject *list) { jclass sslfdProxyClass; jfieldID eventArrayListField; PR_ASSERT(env != NULL && sslfd_proxy != NULL && list != NULL); sslfdProxyClass = (*env)->GetObjectClass(env, sslfd_proxy); if (sslfdProxyClass == NULL) { return PR_FAILURE; } eventArrayListField = (*env)->GetFieldID(env, sslfdProxyClass, which, SSLFD_PROXY_EVENT_LIST_SIG); if (eventArrayListField == NULL) { /* Unlike JSS_NSS_getSSLClientCert above, this is a failure to process * the event. We expect the */ return PR_FAILURE; } *list = (*env)->GetObjectField(env, sslfd_proxy, eventArrayListField); if (*list == NULL) { return PR_FAILURE; } return PR_SUCCESS; } PRStatus JSS_NSS_getSSLAlertReceivedList(JNIEnv *env, jobject sslfd_proxy, jobject *list) { return JSS_NSS_getEventArrayList(env, sslfd_proxy, "inboundAlerts", list); } PRStatus JSS_NSS_getSSLAlertSentList(JNIEnv *env, jobject sslfd_proxy, jobject *list) { return JSS_NSS_getEventArrayList(env, sslfd_proxy, "outboundAlerts", list); } PRStatus JSS_NSS_addGlobalRef(JNIEnv *env, jobject sslfd_proxy, jobject *global_ref) { jclass sslfdProxyClass; jfieldID globalRefField; jobject globalRefElem; if (JSS_getPtrFromProxyOwner(env, sslfd_proxy, "globalRef", "L" GLOBAL_REF_PROXY_CLASS_NAME ";", (void **)global_ref) == PR_FAILURE || *global_ref == NULL) { /* We assume we failed because we don't yet have a global reference * to this SSLFDProxy object. Create one. */ (*env)->ExceptionClear(env); sslfdProxyClass = (*env)->GetObjectClass(env, sslfd_proxy); if (sslfdProxyClass == NULL) { return PR_FAILURE; } globalRefField = (*env)->GetFieldID(env, sslfdProxyClass, "globalRef", "L" GLOBAL_REF_PROXY_CLASS_NAME ";"); if (globalRefField == NULL) { return PR_FAILURE; } *global_ref = (*env)->NewGlobalRef(env, sslfd_proxy); if (*global_ref == NULL) { return PR_FAILURE; } globalRefElem = JSS_PR_wrapGlobalRef(env, global_ref); if (globalRefElem == NULL) { (*env)->ExceptionDescribe(env); return PR_FAILURE; } (*env)->SetObjectField(env, sslfd_proxy, globalRefField, globalRefElem); } return PR_SUCCESS; } void JSS_NSS_removeGlobalRef(JNIEnv *env, jobject sslfd_proxy) { jclass sslfdProxyClass; jfieldID globalRefField; jobject globalRefElem; jclass globalRefClass; jmethodID globalRefClose; sslfdProxyClass = (*env)->GetObjectClass(env, sslfd_proxy); if (sslfdProxyClass == NULL) { return; } globalRefField = (*env)->GetFieldID(env, sslfdProxyClass, "globalRef", NATIVE_PROXY_CLASS_NAME); if (globalRefField == NULL) { return; } globalRefElem = (*env)->GetObjectField(env, sslfd_proxy, globalRefField); if (globalRefElem == NULL) { return; } globalRefClass = (*env)->GetObjectClass(env, globalRefElem); if (globalRefClass == NULL) { return; } globalRefClose = (*env)->GetMethodID(env, globalRefClass, "close", "()V"); if (globalRefClose == NULL) { return; } (*env)->CallVoidMethod(env, globalRefElem, globalRefClose); } PRStatus JSS_NSS_addSSLAlert(JNIEnv *env, jobject sslfd_proxy, jobject list, const SSLAlert *alert) { jclass eventClass; jmethodID eventConstructor; jobject event; jclass eventListClass; jmethodID arrayListAdd; PR_ASSERT(env != NULL && sslfd_proxy != NULL && list != NULL && alert != NULL); /* Build the new alert event object (org.mozilla.jss.ssl.SSLAlertEvent). */ eventClass = (*env)->FindClass(env, SSL_ALERT_EVENT_CLASS); if (eventClass == NULL) { return PR_FAILURE; } eventConstructor = (*env)->GetMethodID(env, eventClass, "", "(L" SSLFD_PROXY_CLASS_NAME ";II)V"); if (eventConstructor == NULL) { return PR_FAILURE; } event = (*env)->NewObject(env, eventClass, eventConstructor, sslfd_proxy, (int)alert->level, (int)alert->description); if (event == NULL) { return PR_FAILURE; } /* Add it to the event list. */ eventListClass = (*env)->GetObjectClass(env, list); if (eventListClass == NULL) { return PR_FAILURE; } arrayListAdd = (*env)->GetMethodID(env, eventListClass, "add", "(Ljava/lang/Object;)Z"); if (arrayListAdd == NULL) { return PR_FAILURE; } // We ignore the return code: ArrayList.add() always returns true. (void)(*env)->CallBooleanMethod(env, list, arrayListAdd, event); return PR_SUCCESS; } void JSSL_SSLFDAlertReceivedCallback(const PRFileDesc *fd, void *arg, const SSLAlert *alert) { JNIEnv *env; jobject sslfd_proxy = (jobject)arg; jobject list; if (fd == NULL || arg == NULL || alert == NULL || JSS_javaVM == NULL) { return; } if ((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != JNI_OK || env == NULL) { return; } if (JSS_NSS_getSSLAlertReceivedList(env, sslfd_proxy, &list) != PR_SUCCESS) { return; } if (JSS_NSS_addSSLAlert(env, sslfd_proxy, list, alert) != PR_SUCCESS) { return; } } void JSSL_SSLFDAlertSentCallback(const PRFileDesc *fd, void *arg, const SSLAlert *alert) { JNIEnv *env; jobject sslfd_proxy = (jobject)arg; jobject list; if (fd == NULL || arg == NULL || alert == NULL || JSS_javaVM == NULL) { return; } if ((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != JNI_OK || env == NULL) { return; } if (JSS_NSS_getSSLAlertSentList(env, sslfd_proxy, &list) != PR_SUCCESS) { return; } if (JSS_NSS_addSSLAlert(env, sslfd_proxy, list, alert) != PR_SUCCESS) { return; } } SECStatus JSSL_SSLFDCertSelectionCallback(void *arg, PRFileDesc *fd, CERTDistNames *caNames, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey) { CERTCertificate *cert = arg; PK11SlotList *slotList; PK11SlotListElement *slotElement; SECKEYPrivateKey *privkey = NULL; /* Certificate selection for client auth requires that we pass both the * certificate (in *pRetCert) and its key (in *pRetKey). We iterate over * all slots that the certificate is in, looking for a private key in * any of them. Once found, we return the private key. */ slotList = PK11_GetAllSlotsForCert(cert, NULL /* unused arg */); if (slotList == NULL) { return SECFailure; } for (slotElement = slotList->head; slotElement; slotElement = slotElement->next) { privkey = PK11_FindPrivateKeyFromCert(slotElement->slot, cert, NULL /* pinarg */); if (privkey != NULL) { break; } } /* Always free the slot list. */ PK11_FreeSlotList(slotList); /* If the certificate isn't found, return SECFailure. */ if (privkey == NULL) { return SECFailure; } *pRetCert = cert; *pRetKey = privkey; return SECSuccess; } JNIEXPORT void JNICALL Java_org_mozilla_jss_nss_SSLFDProxy_releaseNativeResources (JNIEnv *env, jobject this) { JSS_NSS_removeGlobalRef(env, this); } jss-4.6.3/org/mozilla/jss/nss/SSLFDProxy.h000066400000000000000000000020431362106420000202420ustar00rootroot00000000000000#include #include #include #pragma once PRStatus JSS_NSS_getSSLClientCert(JNIEnv *env, jobject sslfd_proxy, CERTCertificate **cert); PRStatus JSS_NSS_getSSLAlertSentList(JNIEnv *env, jobject sslfd_proxy, jobject *list); PRStatus JSS_NSS_getSSLAlertReceivedList(JNIEnv *env, jobject sslfd_proxy, jobject *list); PRStatus JSS_NSS_addSSLAlert(JNIEnv *env, jobject sslfd_proxy, jobject list, const SSLAlert *alert); PRStatus JSS_NSS_addGlobalRef(JNIEnv *env, jobject sslfd_proxy, jobject *global_ref); void JSS_NSS_removeGlobalRef(JNIEnv *env, jobject sslfd_proxy); void JSSL_SSLFDAlertReceivedCallback(const PRFileDesc *fd, void *arg, const SSLAlert *alert); void JSSL_SSLFDAlertSentCallback(const PRFileDesc *fd, void *arg, const SSLAlert *alert); SECStatus JSSL_SSLFDCertSelectionCallback(void *arg, PRFileDesc *fd, CERTDistNames *caNames, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey); jss-4.6.3/org/mozilla/jss/nss/SSLFDProxy.java000066400000000000000000000020611362106420000207340ustar00rootroot00000000000000package org.mozilla.jss.nss; import java.lang.IllegalArgumentException; import java.util.ArrayList; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.pkcs11.PK11Cert; import org.mozilla.jss.ssl.SSLAlertEvent; import org.mozilla.jss.util.GlobalRefProxy; public class SSLFDProxy extends PRFDProxy { public PK11Cert clientCert; public GlobalRefProxy globalRef; public ArrayList inboundAlerts; public int inboundOffset; public ArrayList outboundAlerts; public int outboundOffset; public SSLFDProxy(byte[] pointer) { super(pointer); } public void SetClientCert(X509Certificate cert) throws IllegalArgumentException { if (!(cert instanceof PK11Cert)) { throw new IllegalArgumentException("Unable to cast given certificate to PK11Cert: " + cert.getClass().getName()); } clientCert = (PK11Cert)cert; } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); } } jss-4.6.3/org/mozilla/jss/nss/SecurityStatusResult.java000066400000000000000000000035471362106420000232430ustar00rootroot00000000000000package org.mozilla.jss.nss; import java.lang.StringBuilder; /** * The fields in a SecurityStatusResult indicate whether a given SSL-enabled * PRFileDesc has completed its handshake and the resulting handshake-specific * information. * * These object is returned by org.mozilla.jss.nss.SSL.SecurityStatus(fd). */ public class SecurityStatusResult { /* Whether or not the handshake has completed successfully. */ public int on; /* The current ciphersuite used. */ public byte[] cipher; /* Size of the negotiated peer key. */ public int keySize; /* Size of the session secret key. */ public int secretKeySize; /* Issuer of the peer's certificate. */ public byte[] issuer; /* Subject of the peer's certificate. */ public byte[] subject; public SecurityStatusResult(int _on, byte[] _cipher, int _keySize, int _secretKeySize, byte[] _issuer, byte[] _subject) { this.on = _on; this.cipher = _cipher; this.keySize = _keySize; this.secretKeySize = _secretKeySize; this.issuer = _issuer; this.subject = _subject; } public String toString() { StringBuilder result = new StringBuilder("SecurityStatusResult:"); result.append("\n- on: " + on); if (cipher != null && cipher.length > 0) { result.append("\n- cipher: "); result.append(new String(cipher)); } result.append("\n- keySize: " + keySize); result.append("\n- secretKeySize: " + secretKeySize); if (issuer != null && issuer.length > 0) { result.append("\n- issuer: "); result.append(new String(issuer)); } if (subject != null && subject.length > 0) { result.append("\n- subject: "); result.append(new String(subject)); } return result.toString(); } } jss-4.6.3/org/mozilla/jss/package.html000066400000000000000000000004541362106420000176360ustar00rootroot00000000000000 Configuration and top-level operations of the JSS system. jss-4.6.3/org/mozilla/jss/pkcs10/000077500000000000000000000000001362106420000164535ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkcs10/CertificationRequest.java000066400000000000000000000271011362106420000234530ustar00rootroot00000000000000/* 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.pkcs10; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.SignatureException; import java.security.cert.CertificateException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.InvalidKeyFormatException; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.KeyPairGenerator; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.Signature; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.pkix.primitive.Name; /** * A pkcs10 signed CertificationRequest. */ public class CertificationRequest implements ASN1Value { private CertificationRequestInfo info; private byte[] infoEncoding; private byte[] signature; private AlgorithmIdentifier algId; SEQUENCE sequence; CertificationRequest(CertificationRequestInfo info, //byte[] infoEncoding, AlgorithmIdentifier algId, byte[] signature) throws IOException { this.info = info; //this.infoEncoding = infoEncoding; this.algId = algId; this.signature = signature; // bundle everything into a SEQUENCE sequence = new SEQUENCE(); sequence.addElement( info ); sequence.addElement( algId ); sequence.addElement( new BIT_STRING( signature, 0 ) ); } /** * Creates and signs an X.509 CertificationRequest. * @param info A CertificationRequestInfo (TBSCertificationRequest), * which specifies * the actual information of the CertificationRequest. * @param privKey The private key with which to sign the certificate. * @param signingAlg The algorithm to use to sign the CertificationRequest. * It must match the algorithm specified in the CertificationRequestInfo. * @exception IOException If an error occurred while encoding the * CertificationRequest. * @exception NotInitializedException Because this * operation involves cryptography (signing), CryptoManager must * be initialized before calling it. * @exception TokenException If an error occurs on a PKCS #11 token. * @exception NoSuchAlgorithmException If the OID for the signing algorithm * cannot be located. * @exception CertificateException If the signing algorithm specified * as a parameter does not match the one in the CertificationRequest info. * @exception InvalidKeyException If the key does not match the signing * algorithm. * @exception SignatureException If an error occurs while signing the * CertificationRequest. */ public CertificationRequest(CertificationRequestInfo info, java.security.PrivateKey privKey, SignatureAlgorithm signingAlg) throws IOException, NotInitializedException, TokenException, NoSuchAlgorithmException, CertificateException, InvalidKeyException, SignatureException { // make sure key is a Ninja private key if( !(privKey instanceof PrivateKey) ) { throw new InvalidKeyException("Private Key is does not belong to"+ " this provider"); } PrivateKey priv = (PrivateKey)privKey; // create algId if(signingAlg.getSigningAlg() == SignatureAlgorithm.RSASignature) { algId = new AlgorithmIdentifier( signingAlg.toOID(), null ); } else { algId = new AlgorithmIdentifier( signingAlg.toOID() ); } // encode the cert info this.info = info; infoEncoding = ASN1Util.encode(info); // sign the info encoding CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = priv.getOwningToken(); Signature sig = token.getSignatureContext(signingAlg); sig.initSign(priv); sig.update(infoEncoding); signature = sig.sign(); // bundle everything into a SEQUENCE sequence = new SEQUENCE(); sequence.addElement( info ); sequence.addElement( algId ); sequence.addElement( new BIT_STRING( signature, 0 ) ); } /** * Verifies the signature on this CertificationRequest. Does not indicate * that the CertificationRequest is valid at any specific time. */ public void verify() throws InvalidKeyException, NotInitializedException, NoSuchAlgorithmException, CertificateException, TokenException, SignatureException, InvalidKeyFormatException { verify( info.getSubjectPublicKeyInfo().toPublicKey() ); } /** * Verifies the signature on this CertificationRequest, using the given public key. * Does not indicate the CertificationRequest is valid at any specific time. */ public void verify(PublicKey key) throws InvalidKeyException, NotInitializedException, NoSuchAlgorithmException, CertificateException, TokenException, SignatureException { CryptoManager cm = CryptoManager.getInstance(); verify(key, cm.getInternalCryptoToken()); } /** * Verifies the signature on this CertificationRequest, using the given public * key and CryptoToken. Does not indicate the CertificationRequest is valid at * any specific time. */ public void verify(PublicKey key, CryptoToken token) throws NoSuchAlgorithmException, CertificateException, TokenException, SignatureException, InvalidKeyException { Signature sig = token.getSignatureContext( SignatureAlgorithm.fromOID( algId.getOID() ) ); sig.initVerify(key); sig.update(infoEncoding); if( ! sig.verify(signature) ) { throw new CertificateException("Signature is invalid"); } } /** * Returns the information (TBSCertificationRequest) contained in this CertificationRequest. */ public CertificationRequestInfo getInfo() { return info; } private 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.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( CertificationRequestInfo.getTemplate() ); //seqt.addElement( new ANY.Template() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( BIT_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); //ANY infoAny = (ANY)seq.elementAt(0); //byte[] infoEncoding = infoAny.getEncoded(); /*CertificationRequestInfo info = (CertificationRequestInfo) infoAny.decodeWith( CertificationRequestInfo.getTemplate() ); */ CertificationRequestInfo info = (CertificationRequestInfo) seq.elementAt(0); // although signature is a bit string, all algorithms we use // will produce an octet string. BIT_STRING bs = (BIT_STRING) seq.elementAt(2); if( bs.getPadCount() != 0 ) { throw new InvalidBERException("signature does not fall into"+ " an integral number of bytes"); } byte[] signature = bs.getBits(); return new CertificationRequest( info, //infoEncoding, (AlgorithmIdentifier) seq.elementAt(1), signature ); } } public static void main(String argv[]) { try { if(argv.length > 2 || argv.length < 1) { System.out.println("Usage: CertificationRequest []"); System.exit(0); } CryptoManager.initialize( argv[0] ); CryptoManager cm = CryptoManager.getInstance(); CertificationRequest cert; // read in a cert FileInputStream fis = new FileInputStream(argv[1]); try (BufferedInputStream bis = new BufferedInputStream(fis)) { cert = (CertificationRequest) CertificationRequest.getTemplate().decode(bis); } CertificationRequestInfo info = cert.getInfo(); info.print(System.out); //X509CertificationRequest hardcore = cm.findCertByNickname("Hardcore"); //PublicKey key = hardcore.getPublicKey(); cert.verify(); System.out.println("verified"); FileOutputStream fos = new FileOutputStream("certinfo.der"); info.encode(fos); fos.close(); // make a new public key CryptoToken token = cm.getInternalKeyStorageToken(); KeyPairGenerator kpg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA); kpg.initialize(512); System.out.println("Generating a new key pair..."); KeyPair kp = kpg.genKeyPair(); System.out.println("Generated key pair"); // set the CertificationRequest's public key info.setSubjectPublicKeyInfo(kp.getPublic()); // make new Name Name name = new Name(); name.addCommonName("asldkj"); name.addCountryName("US"); name.addOrganizationName("Some Corp"); name.addOrganizationalUnitName("Some Org Unit"); name.addLocalityName("Silicon Valley"); name.addStateOrProvinceName("California"); info.setSubject(name); System.out.println("About to create a new cert request..."); // create a new cert requestfrom this certReqinfo CertificationRequest genCert = new CertificationRequest(info, kp.getPrivate(), SignatureAlgorithm.RSASignatureWithMD5Digest); System.out.println("Created new cert request"); genCert.verify(); System.out.println("Cert verifies!"); fos = new FileOutputStream("gencert.der"); genCert.encode(fos); fos.close(); } catch( Exception e ) { e.printStackTrace(); } } } jss-4.6.3/org/mozilla/jss/pkcs10/CertificationRequestInfo.java000066400000000000000000000120101362106420000242600ustar00rootroot00000000000000/* 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.pkcs10; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.security.PublicKey; import java.io.InputStream; import java.io.PrintStream; import java.io.OutputStream; import java.io.IOException; /** * A TBSCertificationRequest (to-be-signed CertificationRequest), * the actual information in * a CertificationRequest apart from the signature. */ public class CertificationRequestInfo implements ASN1Value { private INTEGER version = new INTEGER(0); private Name subject; private SubjectPublicKeyInfo subjectPublicKeyInfo; private SET attributes; /** * Creates a CertificationRequestInfo with the required fields. */ public CertificationRequestInfo(INTEGER version, Name subject, SubjectPublicKeyInfo subjectPublicKeyInfo, SET attributes) { setVersion(version); setSubject(subject); setSubjectPublicKeyInfo(subjectPublicKeyInfo); setAttributes(attributes); } public void setVersion(INTEGER version) { verifyNotNull(version); this.version = version; } public INTEGER getVersion() { return version; } public void setSubject(Name subject) { verifyNotNull(subject); this.subject = subject; } public Name getSubject() { return subject; } public void setSubjectPublicKeyInfo( SubjectPublicKeyInfo subjectPublicKeyInfo) { verifyNotNull(subjectPublicKeyInfo); this.subjectPublicKeyInfo = subjectPublicKeyInfo; } /** * Extracts the SubjectPublicKeyInfo from the given public key and * stores it in the CertificationRequestInfo. * * @exception InvalidBERException If an error occurs decoding the * the information extracted from the public key. */ public void setSubjectPublicKeyInfo( PublicKey pubk ) throws InvalidBERException, IOException { verifyNotNull(pubk); setSubjectPublicKeyInfo( new SubjectPublicKeyInfo(pubk) ); } public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return subjectPublicKeyInfo; } public void setAttributes(SET attributes) { //verifyNotNull(attributes); this.attributes = attributes; } public SET getAttributes() { return attributes; } private void verifyNotNull(Object obj) { if( obj == null ) { throw new NullPointerException(); } } 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(version ); seq.addElement(subject); seq.addElement(subjectPublicKeyInfo); seq.addElement(new Tag(0), attributes); seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public void print(PrintStream ps) throws IOException, InvalidBERException { ps.println("CertificationRequestInfo:"); ps.println("Version: "+version); ps.println("Subject: "+subject.getRFC1485()); } /** * Template class for decoding a CertificationRequestInfo. */ public static class Template implements ASN1Template { SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(INTEGER.getTemplate()); //version seqt.addElement(Name.getTemplate()); //subject seqt.addElement(SubjectPublicKeyInfo.getTemplate()); seqt.addElement(Tag.get(0), new SET.OF_Template(Attribute.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 { try { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); CertificationRequestInfo cinfo = new CertificationRequestInfo( (INTEGER) seq.elementAt(0), // version (Name) seq.elementAt(1), // subject (SubjectPublicKeyInfo) seq.elementAt(2), (SET) seq.elementAt(3) ); return cinfo; } catch( Exception e ) { throw new InvalidBERException(e.getMessage()); } } } } jss-4.6.3/org/mozilla/jss/pkcs10/package.html000066400000000000000000000004271362106420000207370ustar00rootroot00000000000000 Encoding and decoding pkcs10 request jss-4.6.3/org/mozilla/jss/pkcs11/000077500000000000000000000000001362106420000164545ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkcs11/CipherContextProxy.java000066400000000000000000000010431362106420000231360ustar00rootroot00000000000000/* 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.pkcs11; import org.mozilla.jss.util.NativeProxy; final class CipherContextProxy extends NativeProxy { public CipherContextProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); } } jss-4.6.3/org/mozilla/jss/pkcs11/KeyProxy.java000066400000000000000000000007151362106420000211140ustar00rootroot00000000000000/* 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.pkcs11; abstract class KeyProxy extends org.mozilla.jss.util.NativeProxy { protected KeyProxy(byte[] pointer) { super(pointer); } protected void finalize() throws Throwable { super.finalize(); } } jss-4.6.3/org/mozilla/jss/pkcs11/KeyType.java000066400000000000000000000230411362106420000207110ustar00rootroot00000000000000/* 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.pkcs11; import java.security.NoSuchAlgorithmException; import java.util.Hashtable; import org.mozilla.jss.crypto.Algorithm; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.CMACAlgorithm; import org.mozilla.jss.crypto.HMACAlgorithm; import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.util.Assert; /** * PKCS #11 Key Types * These are the possible types for keys in the * wrapper library. * Key types are implemented as flyweights. * * Although the KeyType class is public, it should * be considered private. We made the KeyType class * public so that we can force it to load during * CryptoManager.initialize(), before we install JSS * as a provider. **/ public final class KeyType { protected KeyType() {} protected KeyType(Algorithm[] algs, String name) { int i; assert(algs!=null); algorithms = algs.clone(); // Register this key as the key type for each of its algorithms for(i=0; i < algorithms.length; i++) { assert(! algHash.containsKey(algorithms[i]) ); algHash.put(algorithms[i], this); } this.name = name; } /** * Returns an array of algorithms supported by this key type. */ public Algorithm[] supportedAlgorithms() { return algorithms; } /** * Returns the KeyType corresponding to the given Algorithm. If there * is no KeyType registered for this algorithm, a NoSuchAlgorithmException * is thrown. */ static public KeyType getKeyTypeFromAlgorithm(Algorithm alg) throws NoSuchAlgorithmException { assert(alg!=null); Object obj = algHash.get(alg); if(obj == null) { throw new NoSuchAlgorithmException(); } assert( obj instanceof KeyType ); return (KeyType) obj; } public String toString() { return name; } ////////////////////////////////////////////////////////////// // Instance Data ////////////////////////////////////////////////////////////// // An array of algorithms supported by this key type protected Algorithm[] algorithms; protected String name; ////////////////////////////////////////////////////////////// // Class Data ////////////////////////////////////////////////////////////// // A hash table associating a key type with each algorithm static protected Hashtable algHash; static { algHash = new Hashtable<>(); } ////////////////////////////////////////////////////////////// // Key Types ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// static public final KeyType NULL = new KeyType(new Algorithm[0], "NULL"); ////////////////////////////////////////////////////////////// static public final KeyType RSA = new KeyType (new Algorithm[] { SignatureAlgorithm.RSASignature, SignatureAlgorithm.RSASignatureWithMD2Digest, SignatureAlgorithm.RSASignatureWithMD5Digest, SignatureAlgorithm.RSASignatureWithSHA1Digest, SignatureAlgorithm.RSASignatureWithSHA256Digest, SignatureAlgorithm.RSASignatureWithSHA384Digest, SignatureAlgorithm.RSASignatureWithSHA512Digest, KeyWrapAlgorithm.RSA }, "RSA" ); ////////////////////////////////////////////////////////////// static public final KeyType DSA = new KeyType(new Algorithm[] { SignatureAlgorithm.DSASignature, SignatureAlgorithm.DSASignatureWithSHA1Digest }, "DSA" ); ////////////////////////////////////////////////////////////// static public final KeyType EC = new KeyType(new Algorithm[] { SignatureAlgorithm.ECSignature, SignatureAlgorithm.ECSignatureWithSHA1Digest, SignatureAlgorithm.ECSignatureWithSHA256Digest, SignatureAlgorithm.ECSignatureWithSHA384Digest, SignatureAlgorithm.ECSignatureWithSHA512Digest }, "EC" ); ////////////////////////////////////////////////////////////// /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. * This is just a placeholder for backward compatibility. */ @Deprecated static public final KeyType FORTEZZA = new KeyType(new Algorithm[0], "FORTEZZA"); ////////////////////////////////////////////////////////////// static public final KeyType DH = new KeyType(new Algorithm[0], "DH"); ////////////////////////////////////////////////////////////// static public final KeyType KEA = new KeyType(new Algorithm[0], "KEA"); ////////////////////////////////////////////////////////////// static public final KeyType DES = new KeyType(new Algorithm[] { KeyWrapAlgorithm.DES_ECB, KeyWrapAlgorithm.DES_CBC, KeyWrapAlgorithm.DES_CBC_PAD, EncryptionAlgorithm.DES_ECB, EncryptionAlgorithm.DES_CBC, EncryptionAlgorithm.DES_CBC_PAD }, "DES" ); ////////////////////////////////////////////////////////////// static public final KeyType DES3 = new KeyType(new Algorithm[] { KeyWrapAlgorithm.DES3_ECB, KeyWrapAlgorithm.DES3_CBC, KeyWrapAlgorithm.DES3_CBC_PAD, EncryptionAlgorithm.DES3_ECB, EncryptionAlgorithm.DES3_CBC, EncryptionAlgorithm.DES3_CBC_PAD }, "DESede" ); ////////////////////////////////////////////////////////////// static public final KeyType AES = new KeyType(new Algorithm[] { KeyWrapAlgorithm.AES_ECB, KeyWrapAlgorithm.AES_CBC, KeyWrapAlgorithm.AES_CBC_PAD, KeyWrapAlgorithm.AES_KEY_WRAP, KeyWrapAlgorithm.AES_KEY_WRAP_PAD, EncryptionAlgorithm.AES_128_ECB, EncryptionAlgorithm.AES_128_CBC, EncryptionAlgorithm.AES_192_ECB, EncryptionAlgorithm.AES_192_CBC, EncryptionAlgorithm.AES_256_ECB, EncryptionAlgorithm.AES_256_CBC, EncryptionAlgorithm.AES_CBC_PAD, EncryptionAlgorithm.AES_128_CBC_PAD, EncryptionAlgorithm.AES_192_CBC_PAD, EncryptionAlgorithm.AES_256_CBC_PAD, CMACAlgorithm.AES }, "AES" ); ////////////////////////////////////////////////////////////// static public final KeyType RC4 = new KeyType(new Algorithm[] { EncryptionAlgorithm.RC4 }, "RC4" ); ////////////////////////////////////////////////////////////// static public final KeyType RC2 = new KeyType(new Algorithm[] { EncryptionAlgorithm.RC2_CBC, EncryptionAlgorithm.RC2_CBC_PAD }, "RC2" ); ////////////////////////////////////////////////////////////// static public final KeyType SHA1_HMAC = new KeyType(new Algorithm[] { HMACAlgorithm.SHA1 }, "SHA1_HMAC" ); static public final KeyType SHA256_HMAC = new KeyType(new Algorithm[] { HMACAlgorithm.SHA256 }, "SHA256_HMAC" ); static public final KeyType SHA384_HMAC = new KeyType(new Algorithm[] { HMACAlgorithm.SHA384 }, "SHA384_HMAC" ); static public final KeyType SHA512_HMAC = new KeyType(new Algorithm[] { HMACAlgorithm.SHA512 }, "SHA512_HMAC" ); static public final KeyType GENERIC_SECRET = new KeyType(new Algorithm[] { }, "GENERIC_SECRET"); } jss-4.6.3/org/mozilla/jss/pkcs11/ModuleProxy.java000066400000000000000000000010061362106420000216030ustar00rootroot00000000000000/* 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.pkcs11; import org.mozilla.jss.util.*; final class ModuleProxy extends NativeProxy { ModuleProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Cert.c000066400000000000000000000507601362106420000201220ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_CertProxy.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pk11util.h" #include /* * Class: org_mozilla_jss_pkcs11_PK11Cert * Method: getEncoded * Signature: ()[B */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getEncoded (JNIEnv *env, jobject this) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread; CERTCertificate *cert; SECItem *derCert; jbyteArray derArray=NULL; pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); PR_ASSERT(env!=NULL && this!=NULL); /* * extract the DER cert from the CERTCertificate* */ if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(cert != NULL); derCert = &cert->derCert; /* the SECItem type does not have to be siDERCertBuffer */ if(derCert->data==NULL || derCert->len<1) { JSS_throw(env, CERTIFICATE_ENCODING_EXCEPTION); goto finish; } /* * Copy the DER data to a new Java byte array */ derArray = JSS_ToByteArray(env, derCert->data, derCert->len); if (derArray == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } finish: PR_DetachThread(); return derArray; } /* * Class: org_mozilla_jss_pkcs11_PK11Cert * Method: getVersion * Signature: ()I */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getVersion (JNIEnv *env, jobject this) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread; CERTCertificate *cert; long lVersion = 0; pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); PR_ASSERT(env!=NULL && this!=NULL); /* * Get the version from the CERTCertificate * */ if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(cert!=NULL); if(cert->version.data==NULL || cert->version.len<=0) { /* default value is 0 */ lVersion = 0; goto finish; } lVersion = DER_GetInteger(&cert->version); /* jint is 2s complement 32 bits. The max value is 0111...111. */ PR_ASSERT( (lVersion >= 0L) && (lVersion < (long)0x7fffffff) ); finish: PR_DetachThread(); return (jint) lVersion; } /****************************************************************** * * C e r t P r o x y . g e t P u b l i c K e y * * Extracts the SECKEYPublicKey from the CERTCertificate, wraps it * in a Java wrapper, and returns it. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getPublicKey (JNIEnv *env, jobject this) { CERTCertificate *cert; SECKEYPublicKey *pubk=NULL; PRThread * VARIABLE_MAY_NOT_BE_USED pThread; jobject pubKey=NULL; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } pubk = CERT_ExtractPublicKey(cert); if(pubk==NULL) { PR_ASSERT( PR_GetError() == SEC_ERROR_NO_MEMORY); JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } pubKey = JSS_PK11_wrapPubKey(env, &pubk); if(pubKey == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } finish: if(pubk!=NULL) { SECKEY_DestroyPublicKey(pubk); } PR_DetachThread(); return pubKey; } /****************************************************************** * * C e r t P r o x y . r e l e a s e N a t i v e R e s o u r c e s * * Calls CERT_DestroyCertificate on the underlying CERTCertificate. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_CertProxy_releaseNativeResources (JNIEnv *env, jobject this) { CERTCertificate *cert; PRThread * VARIABLE_MAY_NOT_BE_USED pThread; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); /* Get the CERTCertificate structure */ if(JSS_getPtrFromProxy(env, this, (void**)&cert) != PR_SUCCESS) { PR_ASSERT( PR_FALSE ); goto finish; } PR_ASSERT(cert != NULL); CERT_DestroyCertificate(cert); finish: PR_DetachThread(); } /****************************************************************** * * J S S _ P K 1 1 _ g e t C e r t P t r * * Given a Certificate object, extracts the CERTCertificate* and * stores it at the given address. * * certObject: A JNI reference to a JSS Certificate object. * ptr: Address of a CERTCertificate* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCertPtr(JNIEnv *env, jobject certObject, CERTCertificate **ptr) { PR_ASSERT(env!=NULL && certObject!=NULL && ptr!=NULL); /* Get the pointer from the cert proxy */ return JSS_getPtrFromProxyOwner(env, certObject, CERT_PROXY_FIELD, CERT_PROXY_SIG, (void**)ptr); } /****************************************************************** * * J S S _ P K 1 1 _ g e t C e r t S l o t P t r * * Given a Certificate object, extracts the PK11SlotInfo* and * stores it at the given address. * * certObject: A JNI reference to a JSS Certificate object. * ptr: Address of a PK11SlotInfo* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCertSlotPtr(JNIEnv *env, jobject certObject, PK11SlotInfo **ptr) { PR_ASSERT(env!=NULL && certObject!=NULL && ptr!=NULL); /* Get the pointer from the token proxy */ return JSS_getPtrFromProxyOwner(env, certObject, PK11TOKEN_PROXY_FIELD, PK11TOKEN_PROXY_SIG, (void**)ptr); } /* * This is a shady way of deciding if the cert is a user cert. * Hopefully it will work. What we used to do was check for cert->slot. */ #define isUserCert(cert) \ ( ((cert)->trust->sslFlags & CERTDB_USER) || \ ((cert)->trust->emailFlags & CERTDB_USER) || \ ((cert)->trust->objectSigningFlags & CERTDB_USER) ) /**************************************************************** * * f i n d S l o t B y T o k e n N a m e A n d C e r t * * Find the slot containing the token with the given name * and cert. */ static PK11SlotInfo * findSlotByTokenNameAndCert(char *name, CERTCertificate *cert) { PK11SlotList *list; PK11SlotListElement *le; PK11SlotInfo *slot = NULL; list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL); if(list == NULL) { return NULL; } for(le = list->head; le; le = le->next) { if( (PORT_Strcmp(PK11_GetTokenName(le->slot),name) == 0) && (PK11_FindCertInSlot(le->slot,cert,NULL) != CK_INVALID_HANDLE)) { slot = PK11_ReferenceSlot(le->slot); break; } } PK11_FreeSlotList(list); if(slot == NULL) { PORT_SetError(SEC_ERROR_NO_TOKEN); } return slot; } /************************************************************************* * * J S S _ P K 1 1 _ f i n d C e r t A n d S l o t F r o m N i c k n a m e * * A variant of NSS's PK11_FindCertFromNickname function that also * returns a PK11SlotInfo* in *ppSlot. * * If nickname is of the format "token:nickname", the slot that * contains the specified token is returned. Otherwise the internal * key slot (which contains the permanent database token) is returned. */ CERTCertificate * JSS_PK11_findCertAndSlotFromNickname(const char *nickname, void *wincx, PK11SlotInfo **ppSlot) { CERTCertificate *cert; cert = PK11_FindCertFromNickname(nickname, wincx); if(cert == NULL) { return NULL; } if( PORT_Strchr(nickname, ':')) { char* tokenname = PORT_Strdup(nickname); char* colon = PORT_Strchr(tokenname, ':'); *colon = '\0'; *ppSlot = findSlotByTokenNameAndCert(tokenname, cert); PORT_Free(tokenname); if(*ppSlot == NULL) { /* The token containing the cert was just removed. */ CERT_DestroyCertificate(cert); return NULL; } } else { *ppSlot = PK11_GetInternalKeySlot(); } return cert; } /*************************************************************************** * * J S S _ P K 1 1 _ f i n d C e r t s A n d S l o t F r o m N i c k n a m e * * A variant of NSS's PK11_FindCertsFromNickname function that also * returns a PK11SlotInfo* in *ppSlot. * * If nickname is of the format "token:nickname", the slot that * contains the specified token is returned. Otherwise the internal * key slot (which contains the permanent database token) is returned. */ CERTCertList * JSS_PK11_findCertsAndSlotFromNickname(char *nickname, void *wincx, PK11SlotInfo **ppSlot) { CERTCertList *certList; certList = PK11_FindCertsFromNickname(nickname, wincx); if(certList == NULL) { return NULL; } if( PORT_Strchr(nickname, ':')) { char* tokenname = PORT_Strdup(nickname); char* colon = PORT_Strchr(tokenname, ':'); CERTCertListNode *head = CERT_LIST_HEAD(certList); *colon = '\0'; *ppSlot = findSlotByTokenNameAndCert(tokenname, head->cert); PORT_Free(tokenname); if(*ppSlot == NULL) { /* The token containing the certs was just removed. */ CERT_DestroyCertList(certList); return NULL; } } else { *ppSlot = PK11_GetInternalKeySlot(); } return certList; } /*********************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t A n d S l o t A n d N i c k n a m e * * Builds a Certificate wrapper around a CERTCertificate, a * PK11SlotInfo, and a nickname. * cert: Will be eaten and erased whether the wrap was successful or not. * slot: Will be eaten and erased whether the wrap was successful or not. * nickname: the cert instance's nickname * returns: a new PK11Cert wrapping the CERTCertificate, PK11SlotInfo, * and nickname, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCertAndSlotAndNickname(JNIEnv *env, CERTCertificate **cert, PK11SlotInfo **slot, const char *nickname) { jclass certClass; jmethodID constructor; jbyteArray certPtr; jbyteArray slotPtr; jstring jnickname = NULL; jobject Cert=NULL; PR_ASSERT(env!=NULL && cert!=NULL && *cert!=NULL && slot!=NULL); certPtr = JSS_ptrToByteArray(env, *cert); slotPtr = JSS_ptrToByteArray(env, *slot); if (nickname) { jnickname = (*env)->NewStringUTF(env, nickname); } certClass = (*env)->FindClass(env, INTERNAL_TOKEN_CERT_CLASS_NAME); if(certClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, certClass, PLAIN_CONSTRUCTOR, CERT_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* Call the constructor */ Cert = (*env)->NewObject(env, certClass, constructor, certPtr, slotPtr, jnickname); if(Cert==NULL) { goto finish; } finish: if(Cert==NULL) { CERT_DestroyCertificate(*cert); if(*slot!=NULL) { PK11_FreeSlot(*slot); } } *cert = NULL; *slot = NULL; return Cert; } /**************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t A n d S l o t * * Builds a Certificate wrapper around a CERTCertificate and a * PK11SlotInfo. * cert: Will be eaten and erased whether the wrap was successful or not. * slot: Will be eaten and erased whether the wrap was successful or not. * returns: a new PK11Cert wrapping the CERTCertificate and PK11SlotInfo, * or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCertAndSlot(JNIEnv *env, CERTCertificate **cert, PK11SlotInfo **slot) { return JSS_PK11_wrapCertAndSlotAndNickname(env, cert, slot, (*cert)->nickname); } /**************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t * * Builds a Certificate wrapper around a CERTCertificate. * cert: Will be eaten and erased whether the wrap was successful or not. * returns: a new PK11Cert wrapping the CERTCertificate, or NULL if an * exception was thrown. * * Use JSS_PK11_wrapCertAndSlot instead if it is important for the PK11Cert * object to have the correct slot pointer or the slot pointer is readily * available. */ jobject JSS_PK11_wrapCert(JNIEnv *env, CERTCertificate **cert) { PK11SlotInfo *slot = (*cert)->slot; if(slot != NULL) { slot = PK11_ReferenceSlot(slot); } return JSS_PK11_wrapCertAndSlot(env, cert, &slot); } static ssize_t CERT_LIST_COUNT(CERTCertList *chain) { ssize_t count = -1; CERTCertListNode *node = NULL; if (chain == NULL) { return count; } for (node = CERT_LIST_HEAD(chain); !CERT_LIST_END(node, chain); node = CERT_LIST_NEXT(node)) { count += 1; } return count + 1; } /**************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t C h a i n * * Builds an array of PK11Cert objects from a CERTCertList. * ppChain: Pointer to pointer to CERTCertList. The CERTCertList * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this CERTCertList again. To enforce this, *ppChain * will be set to NULL whether the functions fails or succeeds. * Returns: a new Java PK11Cert[] object, or NULL if an exception was thrown. */ jobjectArray JSS_PK11_wrapCertChain(JNIEnv *env, CERTCertList **chain) { jobjectArray result = NULL; jobject wrappedCert = NULL; CERTCertListNode *node = NULL; ssize_t count = 0; if (chain == NULL || *chain == NULL) { goto done; } // Since we can't easily resize our jobjectArray once created, walk the // chain and count its length. count = CERT_LIST_COUNT(*chain); if (count <= 0) { goto done; } // Allocate our result structure. result = (*env)->NewObjectArray(env, count, (*env)->FindClass(env, CERT_CLASS_NAME), NULL); count = 0; for (node = CERT_LIST_HEAD((*chain)); !CERT_LIST_END(node, (*chain)); node = CERT_LIST_NEXT(node)) { // Wrap the certificate and insert it into the array. wrappedCert = JSS_PK11_wrapCert(env, &node->cert); (*env)->SetObjectArrayElement(env, result, count, wrappedCert); count += 1; } done: if (chain) { CERT_DestroyCertList(*chain); *chain = NULL; } return result; } /********************************************************************** * PK11Cert.getOwningToken */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getOwningToken (JNIEnv *env, jobject this) { PK11SlotInfo *slot; jobject token = NULL; PR_ASSERT(env!=NULL && this!=NULL); /* get the C PK11SlotInfo structure */ if( JSS_PK11_getCertSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot != NULL); /* wrap the slot in a Java PK11Token */ token = JSS_PK11_wrapPK11Token(env, &slot); if(token == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } finish: return token; } /* * workaround for bug 100791: misspelled function prototypes in pk11func.h */ SECItem* PK11_GetLowLevelKeyIDForCert(PK11SlotInfo*,CERTCertificate*,void*); /********************************************************************** * PK11Cert.getUniqueID */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getUniqueID (JNIEnv *env, jobject this) { CERTCertificate *cert; SECItem *id = NULL; jbyteArray byteArray=NULL; PR_ASSERT(env!=NULL && this!=NULL); /************************************************** * Get the CERTCertificate structure **************************************************/ if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { goto finish; } /*************************************************** * Get the id ***************************************************/ id = PK11_GetLowLevelKeyIDForCert(NULL /*slot*/, cert, NULL/*pinarg*/); if( id == NULL ) { PR_ASSERT(PR_FALSE); goto finish; } /*************************************************** * Write the id to a new byte array ***************************************************/ byteArray = JSS_ToByteArray(env, id->data, id->len); if (byteArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: if( id != NULL ) { SECITEM_FreeItem(id, PR_TRUE /*freeit*/); } return byteArray; } /********************************************************************** * This is what used to be PK11Cert.getNickname. Kept merely to * satisfy the symbol export file jss.def. */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getNickname (JNIEnv *env, jobject this) { PR_NOT_REACHED("a stub function"); return NULL; } /********************************************************************** * PK11Cert.setTrust */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_setTrust (JNIEnv *env, jobject this, jint type, jint newTrust) { CERTCertificate *cert; CERTCertTrust trust; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { return; } if( CERT_GetCertTrust( cert, &trust ) != SECSuccess) { /* cert doesn't have any trust yet, so initialize to 0 */ memset(&trust, 0, sizeof(trust)); } switch(type) { case 0: /* SSL */ trust.sslFlags = newTrust; break; case 1: /* email */ trust.emailFlags = newTrust; break; case 2: /* object signing */ trust.objectSigningFlags = newTrust; break; default: PR_ASSERT(PR_FALSE); return; } if( CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust) != SECSuccess) { PR_ASSERT(PR_FALSE); return; } return; } /********************************************************************** * PK11Cert.getTrust */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getTrust (JNIEnv *env, jobject this, jint type) { CERTCertificate *cert; CERTCertTrust trust; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { return 0; } if( CERT_GetCertTrust( cert, &trust ) != SECSuccess) { PR_ASSERT(PR_FALSE); return 0; } switch(type) { case 0: /* SSL */ return trust.sslFlags; case 1: /* email */ return trust.emailFlags; case 2: /* object signing */ return trust.objectSigningFlags; default: PR_ASSERT(PR_FALSE); return 0; } } /********************************************************************** * PK11Cert.getSerialNumberByteArray */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getSerialNumberByteArray (JNIEnv *env, jobject this) { CERTCertificate *cert; if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { return NULL; } PR_ASSERT(cert->serialNumber.len > 0); PR_ASSERT(cert->serialNumber.data != NULL); return JSS_OctetStringToByteArray(env, &cert->serialNumber); } /********************************************************************** * PK11Cert.getSubjectDNString */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getSubjectDNString (JNIEnv *env, jobject this) { CERTCertificate *cert; char *ascii; if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { return NULL; } ascii = CERT_NameToAscii(&cert->subject); if( ascii ) { return (*env)->NewStringUTF(env, ascii); } else { return NULL; } } /********************************************************************** * PK11Cert.getIssuerDNString */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getIssuerDNString (JNIEnv *env, jobject this) { CERTCertificate *cert; char *ascii; if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { return NULL; } ascii = CERT_NameToAscii(&cert->issuer); if( ascii ) { return (*env)->NewStringUTF(env, ascii); } else { return NULL; } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Cert.java000066400000000000000000000276631362106420000206270ustar00rootroot00000000000000/* 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.pkcs11; import java.util.*; import java.math.BigInteger; import java.security.*; import java.security.cert.*; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.util.Assert; import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PK11Cert extends java.security.cert.X509Certificate implements org.mozilla.jss.crypto.X509Certificate { public static Logger logger = LoggerFactory.getLogger(PK11Cert.class); // Internal X509CertImpl to handle java.security.cert.X509Certificate // methods. private X509CertImpl x509 = null; @Override public native byte[] getEncoded() throws CertificateEncodingException; //public native byte[] getUniqueID(); public String getNickname() { return nickname; } /** * A class that implements Principal with a String. */ protected static class StringPrincipal implements Principal { public StringPrincipal(String str) { this.str = str; } public boolean equals(Object other) { if( ! (other instanceof StringPrincipal) ) { return false; } return getName().equals( ((StringPrincipal)other).getName() ); } public String getName() { return str; } public int hashCode() { return str.hashCode(); } public String toString() { return str; } protected String str; } public Principal getSubjectDN() { return new StringPrincipal( getSubjectDNString() ); } public Principal getIssuerDN() { return new StringPrincipal( getIssuerDNString() ); } public BigInteger getSerialNumber() { return new BigInteger( getSerialNumberByteArray() ); } protected native byte[] getSerialNumberByteArray(); protected native String getSubjectDNString(); protected native String getIssuerDNString(); public native java.security.PublicKey getPublicKey(); public native int getVersion(); /* Begin methods necessary for java.security.cert.X509Certificate */ public int getBasicConstraints() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getBasicConstraints(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public boolean[] getKeyUsage() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getKeyUsage(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public boolean[] getSubjectUniqueID() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getSubjectUniqueID(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public boolean[] getIssuerUniqueID() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getIssuerUniqueID(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public byte[] getSigAlgParams() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getSigAlgParams(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public String getSigAlgName() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getSigAlgName(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public String getSigAlgOID() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getSigAlgOID(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public byte[] getSignature() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getSignature(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public byte[] getTBSCertificate() throws CertificateEncodingException { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getTBSCertificate(); } catch (CertificateEncodingException cee) { throw cee; } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public Date getNotAfter() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getNotAfter(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public Date getNotBefore() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getNotBefore(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } x509.checkValidity(); } catch (CertificateExpiredException cee) { throw cee; } catch (CertificateNotYetValidException cnyve) { throw cnyve; } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } x509.checkValidity(date); } catch (CertificateExpiredException cee) { throw cee; } catch (CertificateNotYetValidException cnyve) { throw cnyve; } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public String toString() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.toString(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } x509.verify(key); } catch (NoSuchAlgorithmException nsae) { throw nsae; } catch (InvalidKeyException ike) { throw ike; } catch (NoSuchProviderException nspe) { throw nspe; } catch (SignatureException se) { throw se; } catch (CertificateException ce) { throw ce; } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } x509.verify(key, sigProvider); } catch (NoSuchAlgorithmException nsae) { throw nsae; } catch (InvalidKeyException ike) { throw ike; } catch (NoSuchProviderException nspe) { throw nspe; } catch (SignatureException se) { throw se; } catch (CertificateException ce) { throw ce; } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public byte[] getExtensionValue(String oid) { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getExtensionValue(oid); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public Set getCriticalExtensionOIDs() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getCriticalExtensionOIDs(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public Set getNonCriticalExtensionOIDs() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.getNonCriticalExtensionOIDs(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public boolean hasUnsupportedCriticalExtension() { try { if (x509 == null) { x509 = new X509CertImpl(getEncoded()); } return x509.hasUnsupportedCriticalExtension(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } /////////////////////////////////////////////////////////////////////// // PKCS #11 Cert stuff. Must only be called on certs that have // an associated slot. /////////////////////////////////////////////////////////////////////// protected native byte[] getUniqueID(); protected native CryptoToken getOwningToken(); /////////////////////////////////////////////////////////////////////// // Trust Management. Must only be called on certs that live in the // internal database. /////////////////////////////////////////////////////////////////////// /** * Sets the trust flags for this cert. * * @param type SSL, EMAIL, or OBJECT_SIGNING. * @param trust The trust flags for this type of trust. */ protected native void setTrust(int type, int trust); /** * Gets the trust flags for this cert. * * @param type SSL, EMAIL, or OBJECT_SIGNING. * @return The trust flags for this type of trust. */ protected native int getTrust(int type); ///////////////////////////////////////////////////////////// // Construction ///////////////////////////////////////////////////////////// //PK11Cert(CertProxy proxy) { // assert(proxy!=null); // this.certProxy = proxy; //} PK11Cert(byte[] certPtr, byte[] slotPtr, String nickname) { assert(certPtr!=null); assert(slotPtr!=null); certProxy = new CertProxy(certPtr); tokenProxy = new TokenProxy(slotPtr); this.nickname = nickname; } ///////////////////////////////////////////////////////////// // private data ///////////////////////////////////////////////////////////// protected CertProxy certProxy; protected TokenProxy tokenProxy; protected String nickname; } class CertProxy extends org.mozilla.jss.util.NativeProxy { public static Logger logger = LoggerFactory.getLogger(CertProxy.class); public CertProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Cipher.c000066400000000000000000000217441362106420000204370ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11Cipher.h" #include #include #include #include #include /* JSS includes */ #include #include #include #include #include /*********************************************************************** * * PK11Cipher.initContext */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11Cipher_initContext (JNIEnv *env, jclass clazz, jboolean encrypt, jobject keyObj, jobject algObj, jbyteArray ivBA, jboolean padded) { return Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits ( env, clazz, encrypt, keyObj, algObj, ivBA, 0, padded); } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits (JNIEnv *env, jclass clazz, jboolean encrypt, jobject keyObj, jobject algObj, jbyteArray ivBA, jint keyBits, jboolean padded) { CK_MECHANISM_TYPE mech; PK11SymKey *key=NULL; SECItem *param=NULL; SECItem *iv=NULL; PK11Context *context=NULL; CK_ATTRIBUTE_TYPE op; jobject contextObj = NULL; PR_ASSERT(env!=NULL && clazz!=NULL && keyObj!=NULL && algObj!=NULL); /* get mechanism */ mech = JSS_getPK11MechFromAlg(env, algObj); if(mech == CKM_INVALID_MECHANISM) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to resolve algorithm to" " PKCS #11 mechanism"); goto finish; } if (padded) mech = PK11_GetPadMechanism(mech); /* get operation type */ if( encrypt ) { op = CKA_ENCRYPT; } else { op = CKA_DECRYPT; } /* get key */ if( JSS_PK11_getSymKeyPtr(env, keyObj, &key) != PR_SUCCESS) { goto finish; } /* get param, if there is one */ if( ivBA != NULL ) { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { /* exception was thrown */ goto finish; } } param = PK11_ParamFromIV(mech, iv); /* * Set RC2 effective key length. */ if( mech == CKM_RC2_CBC || mech == CKM_RC2_CBC_PAD ) { ((CK_RC2_CBC_PARAMS*)param->data)->ulEffectiveBits = keyBits; } /* create crypto context */ context = PK11_CreateContextBySymKey(mech, op, key, param); if(context == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to generate crypto context"); goto finish; } /* wrap crypto context. This sets context to NULL. */ contextObj = JSS_PK11_wrapCipherContextProxy(env, &context); finish: if( param != NULL ) { SECITEM_FreeItem(param, PR_TRUE /*freeit*/); } if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*freeit*/); } if(context != NULL) { /* if the function succeeded, context would be NULL */ PK11_DestroyContext(context, PR_TRUE /*freeit*/); } PR_ASSERT( contextObj || (*env)->ExceptionOccurred(env) ); return contextObj; } /*********************************************************************** * * PK11Cipher.updateContext */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Cipher_updateContext (JNIEnv *env, jclass clazz, jobject contextObj, jbyteArray inputBA, jint blockSize) { PK11Context *context=NULL; jbyte *inbuf=NULL; unsigned int inlen; unsigned char *outbuf=NULL; unsigned int outlen; jbyteArray outArray=NULL; PR_ASSERT(env!=NULL && clazz!=NULL && contextObj!=NULL && inputBA!=NULL); /* get the context */ if( JSS_PK11_getCipherContext(env, contextObj, &context) != PR_SUCCESS) { goto finish; } /* extract input from byte array */ inlen = (*env)->GetArrayLength(env, inputBA); inbuf = (*env)->GetByteArrayElements(env, inputBA, NULL); if(inbuf == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* create output buffer */ outlen = inlen + blockSize; /* this will hold the output */ outbuf = PR_Malloc(outlen); if(outbuf == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* do the operation */ if( PK11_CipherOp(context, outbuf, (int*)&outlen, outlen, (unsigned char*)inbuf, inlen) != SECSuccess) { JSS_throwMsgPrErrArg( env, TOKEN_EXCEPTION, "Cipher context update failed", PR_GetError()); goto finish; } /* convert output buffer to byte array */ outArray = JSS_ToByteArray(env, outbuf, outlen); if (outArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: if(outbuf) { PR_Free(outbuf); } if (inbuf) { (*env)->ReleaseByteArrayElements(env, inputBA, inbuf, JNI_ABORT); } return outArray; } /*********************************************************************** * * PK11Cipher.finalizeContext * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Cipher_finalizeContext (JNIEnv *env, jclass clazz, jobject contextObj, jint blockSize, jboolean padded) { PK11Context *context=NULL; unsigned char *outBuf = NULL; unsigned int outLen, newOutLen; jobject outBA=NULL; SECStatus status; PR_ASSERT(env!=NULL && contextObj!=NULL); /* get context */ if( JSS_PK11_getCipherContext(env, contextObj, &context) != PR_SUCCESS) { goto finish; } /* create output buffer */ outLen = blockSize; /* maximum amount needed */ outBuf = PR_Malloc(outLen); if(outBuf == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* perform the finalization */ status = PK11_DigestFinal(context, outBuf, &newOutLen, outLen); if( (status != SECSuccess) ) { JSS_throwMsgPrErrArg( env, TOKEN_EXCEPTION, "Cipher context finalization failed", PR_GetError()); goto finish; } /* convert output buffer to byte array */ outBA = JSS_ToByteArray(env, outBuf, newOutLen); if(outBA == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: if(outBuf) { PR_Free(outBuf); } PR_ASSERT( outBA || (*env)->ExceptionOccurred(env) ); return outBA; } /*********************************************************************** * * J S S _ P K 1 1 _ g e t C i p h e r C o n t e x t * * Extracts the PK11Context from a CipherContextProxy. * * proxy * A CipherContextProxy. * * pContext * Address of a PK11Context*, which will be filled with the pointer * extracted from the CipherContextProxy. * * RETURNS * PR_SUCCESS for success, or PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCipherContext(JNIEnv *env, jobject proxy, PK11Context **pContext) { PR_ASSERT(env!=NULL && proxy!=NULL && pContext!=NULL); return JSS_getPtrFromProxy(env, proxy, (void**)pContext); } /*********************************************************************** * * J S S _ P K 1 1 _ m a k e C i p h e r C o n t e x t P r o x y * * Wraps a PK11Context in a CipherContextProxy. * * context * address of a pointer to a PK11Context, which must not be NULL. * It will be eaten by the wrapper and set to NULL, even if the * function returns NULL. * * RETURNS * A new CipherContextProxy, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCipherContextProxy(JNIEnv *env, PK11Context **context) { jbyteArray pointer=NULL; jclass proxyClass; jmethodID constructor; jobject contextObj=NULL; PR_ASSERT( env!=NULL && context!=NULL && *context!=NULL ); /* convert pointer to byte array */ pointer = JSS_ptrToByteArray(env, *context); /* * Lookup the class and constructor */ proxyClass = (*env)->FindClass(env, CIPHER_CONTEXT_PROXY_CLASS_NAME); if(proxyClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID(env, proxyClass, PLAIN_CONSTRUCTOR, CIPHER_CONTEXT_PROXY_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* call the constructor */ contextObj = (*env)->NewObject(env, proxyClass, constructor, pointer); finish: if(contextObj == NULL) { /* didn't work, so free resources */ PK11_DestroyContext( (PK11Context*)*context, PR_TRUE /*freeit*/ ); } *context=NULL; PR_ASSERT( contextObj || (*env)->ExceptionOccurred(env) ); return contextObj; } /*********************************************************************** * * CipherContextProxy.releaseNativeResources */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_CipherContextProxy_releaseNativeResources (JNIEnv *env, jobject this) { PK11Context *context; if( JSS_PK11_getCipherContext(env, this, &context) == PR_SUCCESS ) { PK11_DestroyContext(context, PR_TRUE /*freeit*/); } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Cipher.java000066400000000000000000000216621362106420000211350ustar00rootroot00000000000000/* 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.pkcs11; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.IVParameterSpec; import org.mozilla.jss.crypto.IllegalBlockSizeException; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; final class PK11Cipher extends org.mozilla.jss.crypto.Cipher { // set once in the constructor private PK11Token token; // set once in the constructor private EncryptionAlgorithm algorithm; // set with initXXX() private AlgorithmParameterSpec parameters=null; // set with initXXX() private SymmetricKey key=null; // set with initXXX() private byte[] IV=null; // set with initXXX() private CipherContextProxy contextProxy = null; // modified by various operations private int state=UNINITIALIZED; // States private static final int UNINITIALIZED=0; private static final int ENCRYPT=1; private static final int DECRYPT=2; private PK11Cipher() { } PK11Cipher(PK11Token token, EncryptionAlgorithm algorithm) { this.token = token; this.algorithm = algorithm; } public void initEncrypt(SymmetricKey key) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException { initEncrypt(key, null); } public void initDecrypt(SymmetricKey key) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException { initDecrypt(key, null); } private static byte[] getIVFromParams(AlgorithmParameterSpec params) { byte[] IV = null; if( params instanceof IVParameterSpec ) { IV = ((IVParameterSpec)params).getIV(); } else if( params instanceof IvParameterSpec ) { IV = ((IvParameterSpec)params).getIV(); } else if( params instanceof RC2ParameterSpec ) { IV = ((RC2ParameterSpec)params).getIV(); } return IV; } /** * @deprecated isPadded() in EncryptionAlgorithm has been deprecated */ @Deprecated public void initEncrypt(SymmetricKey key, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException { reset(); checkKey(key); checkParams(parameters); IV = getIVFromParams(parameters); this.key = key; this.parameters = parameters; state = ENCRYPT; if( parameters instanceof RC2ParameterSpec ) { contextProxy = initContextWithKeyBits( true, key, algorithm, IV, ((RC2ParameterSpec)parameters).getEffectiveKeyBits(), algorithm.isPadded()); } else { contextProxy = initContext( true, key, algorithm, IV, algorithm.isPadded()); } } /** * @deprecated isPadded() in EncryptionAlgorithm has been deprecated */ @Deprecated public void initDecrypt(SymmetricKey key, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException { reset(); checkKey(key); checkParams(parameters); IV = getIVFromParams(parameters); this.key = key; this.parameters = parameters; state = DECRYPT; if( parameters instanceof RC2ParameterSpec ) { contextProxy = initContextWithKeyBits( false, key, algorithm, IV, ((RC2ParameterSpec)parameters).getEffectiveKeyBits(), algorithm.isPadded()); } else { contextProxy = initContext( false, key, algorithm, IV, algorithm.isPadded()); } } public byte[] update(byte[] bytes) throws IllegalStateException, TokenException { if( state == UNINITIALIZED ) { throw new IllegalStateException(); } return updateContext( contextProxy, bytes, algorithm.getBlockSize()); } public byte[] update(byte[] bytes, int offset, int length) throws IllegalStateException, TokenException { byte[] sub = new byte[length]; System.arraycopy( bytes, offset, sub, 0, length ); return update(sub); } /** * @deprecated isPadded() in EncryptionAlgorithm has been deprecated */ @Deprecated public byte[] doFinal(byte[] bytes) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException { if( state == UNINITIALIZED ) { throw new IllegalStateException(); } byte[] first = update(bytes); byte[] last = finalizeContext(contextProxy, algorithm.getBlockSize(), algorithm.isPadded() ); byte[] combined = new byte[ first.length+last.length ]; System.arraycopy(first, 0, combined, 0, first.length); System.arraycopy(last, 0, combined, first.length, last.length); return combined; } public byte[] doFinal(byte[] bytes, int offset, int length) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException { byte[] sub = new byte[length]; System.arraycopy(bytes, offset, sub, 0, length); return doFinal(sub); } /** * @deprecated isPadded() in EncryptionAlgorithm has been deprecated */ @Deprecated public byte[] doFinal() throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException { if( state == UNINITIALIZED ) { throw new IllegalStateException(); } return finalizeContext(contextProxy, algorithm.getBlockSize(), algorithm.isPadded() ); } private static native CipherContextProxy initContext(boolean encrypt, SymmetricKey key, EncryptionAlgorithm alg, byte[] IV, boolean padded) throws TokenException; // This version accepts the number of effective key bits for RC2 CBC. private static native CipherContextProxy initContextWithKeyBits(boolean encrypt, SymmetricKey key, EncryptionAlgorithm alg, byte[] IV, int keyBits, boolean padded) throws TokenException; private static native byte[] updateContext( CipherContextProxy context, byte[] input, int blocksize ) throws TokenException; private static native byte[] finalizeContext( CipherContextProxy context, int blocksize, boolean padded) throws TokenException, IllegalBlockSizeException, BadPaddingException; private void reset() { parameters = null; key = null; IV = null; state = UNINITIALIZED; contextProxy = null; } /** * Matches the params against those expected by the algorithm. */ private void checkParams(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { if( ! algorithm.isValidParameterObject(params) ) { String name = "null"; if( params != null ) { name = params.getClass().getName(); } throw new InvalidAlgorithmParameterException(algorithm + " cannot use a " + name + " parameter"); } } /** * Checks for null, makes sure the key lives on the correct token, * makes sure it is a PKCS #11 key, makes sure it's the right type * for this algorithm. */ private void checkKey(SymmetricKey key) throws InvalidKeyException { if( key==null ) { throw new InvalidKeyException("Key is null"); } if( ! key.getOwningToken().equals(token) ) { throw new InvalidKeyException("Key does not reside on the "+ "current token"); } if( ! (key instanceof PK11SymKey) ) { throw new InvalidKeyException("Key is not a PKCS #11 key"); } try { KeyType keyType = ((PK11SymKey) key).getKeyType(); if ( keyType != KeyType.GENERIC_SECRET && keyType != KeyType.getKeyTypeFromAlgorithm(algorithm) ) { throw new InvalidKeyException("Key is not the right type for"+ " this algorithm. Got: " + ((PK11SymKey)key).getKeyType() + " Expected: " + KeyType.getKeyTypeFromAlgorithm(algorithm)); } } catch( NoSuchAlgorithmException e ) { throw new RuntimeException("Unknown algorithm: " + algorithm, e); } } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11DSAPrivateKey.java000066400000000000000000000017471362106420000223400ustar00rootroot00000000000000package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.TokenException; import java.math.BigInteger; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPrivateKey; class PK11DSAPrivateKey extends PK11PrivKey implements DSAPrivateKey { private static final long serialVersionUID = 1L; private PK11DSAPrivateKey() { super(null); } protected PK11DSAPrivateKey(byte[] pointer) { super(pointer); } public PrivateKey.Type getType() { return PrivateKey.Type.DSA; } /** * If this fails, we just return null, since no exceptions are allowed. */ public DSAParams getParams() { try { return getDSAParams(); } catch(TokenException te) { return null; } } /** * Not implemented. NSS doesn't support extracting private key material * like this. */ public BigInteger getX() { return null; } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11DSAPublicKey.java000066400000000000000000000026601362106420000221370ustar00rootroot00000000000000/* 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.pkcs11; import java.math.BigInteger; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAParameterSpec; public final class PK11DSAPublicKey extends PK11PubKey implements DSAPublicKey { private static final long serialVersionUID = 1L; public PK11DSAPublicKey(byte[] pointer) { super(pointer); } public DSAParams getParams() { try { BigInteger P = new BigInteger( getPByteArray() ); BigInteger Q = new BigInteger( getQByteArray() ); BigInteger G = new BigInteger( getGByteArray() ); return new DSAParameterSpec(P, Q, G); } catch(NumberFormatException e) { throw new RuntimeException("Unable to decode DSA parameters: " + e.getMessage(), e); } } public BigInteger getY() { try { return new BigInteger( getYByteArray() ); } catch(NumberFormatException e) { throw new RuntimeException("Unable to decode DSA public value: " + e.getMessage(), e); } } private native byte[] getPByteArray(); private native byte[] getQByteArray(); private native byte[] getGByteArray(); private native byte[] getYByteArray(); } jss-4.6.3/org/mozilla/jss/pkcs11/PK11ECPrivateKey.java000066400000000000000000000021741362106420000222130ustar00rootroot00000000000000package org.mozilla.jss.pkcs11; import java.security.interfaces.ECPrivateKey; import java.security.spec.ECParameterSpec; import java.math.BigInteger; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.util.EC; class PK11ECPrivateKey extends PK11PrivKey implements ECPrivateKey { private static final long serialVersionUID = 1L; private PK11ECPrivateKey() { super(null); } protected PK11ECPrivateKey(byte[] pointer) { super(pointer); } public PrivateKey.Type getType() { return PrivateKey.Type.EC; } public ECParameterSpec getParams() { PK11PubKey publicKey = getPublicKey(); if (!(publicKey instanceof PK11ECPublicKey)) { throw new RuntimeException("Unknown key type: expected the public key of an EC key to be an PK11ECPublicKey; got: " + publicKey); } PK11ECPublicKey ecPublicKey = (PK11ECPublicKey)publicKey; return ecPublicKey.getParams(); } /** * Not implemented. NSS doesn't support extracting private key material * like this. */ public BigInteger getS() { return null; } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11ECPublicKey.java000066400000000000000000000021351362106420000220140ustar00rootroot00000000000000/* 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.pkcs11; import java.security.interfaces.ECPublicKey; import java.security.spec.ECPoint; import java.security.spec.ECParameterSpec; import java.math.BigInteger; import org.mozilla.jss.netscape.security.util.Utils; import org.mozilla.jss.util.EC; public final class PK11ECPublicKey extends PK11PubKey implements ECPublicKey { private static final long serialVersionUID = 1L; public PK11ECPublicKey(byte[] pointer) { super(pointer); } public ECParameterSpec getParams() { byte[] curveData = getCurveByteArray(); return EC.decodeNSSOID(curveData); } public byte[] getCurveBA() { return getCurveByteArray(); } public ECPoint getW() { byte[] pointData = getWByteArray(); return EC.decodeNSSPoint(pointData); } private native byte[] getCurveByteArray(); public native byte[] getWByteArray(); } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Exception.java000066400000000000000000000015251362106420000216550ustar00rootroot00000000000000/* 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.pkcs11; /** * This is a generic PKCS #11 exception. */ public class PK11Exception extends RuntimeException { private static final long serialVersionUID = 1L; public PK11Exception() { } public PK11Exception(String mesg) { super(mesg); } public PK11Exception(Throwable cause) { super(cause); } public PK11Exception(String mesg, Throwable cause) { super(mesg, cause); } public PK11Exception(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11InternalCert.java000066400000000000000000000054741362106420000223200ustar00rootroot00000000000000/* 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.pkcs11; import org.mozilla.jss.crypto.*; /** * A certificate that lives in the internal cert database. */ public class PK11InternalCert extends PK11Cert implements InternalCertificate { /////////////////////////////////////////////////////////////////////// // Trust Management. This is all package stuff because it can only // be called from PK11InternalCert. /////////////////////////////////////////////////////////////////////// public static final int SSL = 0; public static final int EMAIL = 1; public static final int OBJECT_SIGNING=2; /** * Set the SSL trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public void setSSLTrust(int trust) { super.setTrust(SSL, trust); } /** * Set the email (S/MIME) trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public void setEmailTrust(int trust) { super.setTrust(EMAIL, trust); } /** * Set the object signing trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public void setObjectSigningTrust(int trust) { super.setTrust(OBJECT_SIGNING, trust); } /** * Get the SSL trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public int getSSLTrust() { return super.getTrust(SSL); } /** * Get the email (S/MIME) trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public int getEmailTrust() { return super.getTrust(EMAIL); } /** * Get the object signing trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public int getObjectSigningTrust() { return super.getTrust(OBJECT_SIGNING); } ///////////////////////////////////////////////////////////// // Construction ///////////////////////////////////////////////////////////// PK11InternalCert(byte[] certPtr, byte[] slotPtr, String nickname) { super(certPtr, slotPtr, nickname); } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11InternalTokenCert.java000066400000000000000000000014701362106420000233110ustar00rootroot00000000000000/* 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.pkcs11; import org.mozilla.jss.crypto.*; /** * A certificate that lives on the internal token. It has database information * (like trust flags) but also PKCS #11 information (like unique ID). */ public final class PK11InternalTokenCert extends PK11InternalCert implements TokenCertificate { public byte[] getUniqueID() { return super.getUniqueID(); } public CryptoToken getOwningToken() { return super.getOwningToken(); } PK11InternalTokenCert(byte[] certPtr, byte[] slotPtr, String nickname) { super(certPtr, slotPtr, nickname); } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Key.java000066400000000000000000000036401362106420000204470ustar00rootroot00000000000000/* 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.pkcs11; import org.mozilla.jss.util.*; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.IOException; import org.mozilla.jss.util.AssertionException; abstract class PK11Key implements java.security.Key { ////////////////////////////////////////////////////////// // Public Interface /////////////////////////////////////////////////////////// /** * Subclasses that support encoding can overload this method. */ public byte[] getEncoded() { return null; } /** * Subclasses that support encoding can overload this method. */ public String getFormat() { return null; } ///////////////////////////////////////////////////////////// // Construction ///////////////////////////////////////////////////////////// protected PK11Key() {} ///////////////////////////////////////////////////////////// // Implementation ///////////////////////////////////////////////////////////// // **HACK** // Override serialization methods so that we don't get serialized, // even though we are supposed to support it as an implementation of Key. private void writeObject(ObjectOutputStream out) throws IOException { throw new AssertionException("PKCS#11 Key is not really serializable"); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { throw new AssertionException("PKCS#11 Key is not really serializable"); } ///////////////////////////////////////////////////////////// // Members ///////////////////////////////////////////////////////////// protected KeyProxy keyProxy; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11KeyGenerator.c000066400000000000000000000352211362106420000216170ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11KeyGenerator.h" #include #include #include #include #include #include /* for hand-generating SHA-1 PBA HMAC key */ #include #include "jssutil.h" #include "pk11util.h" #include "StaticVoidPointer.h" #include #include #include #include #include /*********************************************************************** * * PK11KeyGenerator.generateNormal * * Generates a non-PBE symmetric key on a token. * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generateNormal (JNIEnv *env, jclass clazz, jobject token, jobject alg, jint strength, jint opFlags, jboolean temporary, jint sensitive) { PK11SlotInfo *slot=NULL; PK11SymKey *skey=NULL; CK_MECHANISM_TYPE mech; PK11AttrFlags attrFlags=0; jobject keyObj=NULL; PR_ASSERT( env!=NULL && clazz!=NULL && token!=NULL && alg!=NULL ); /* Get the slot */ if( JSS_PK11_getTokenSlotPtr(env, token, &slot) != PR_SUCCESS ) { goto finish; } /* Get the algorithm info */ mech = JSS_getPK11MechFromAlg(env, alg); PR_ASSERT(mech != CKM_INVALID_MECHANISM); if(!temporary) { attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE); } if(sensitive==1) { attrFlags |= PK11_ATTR_SENSITIVE; } else if(sensitive==0) { attrFlags |= PK11_ATTR_INSENSITIVE; } /* generate the key */ skey = PK11_TokenKeyGenWithFlags(slot, mech, NULL /*param*/, strength/8 /*in bytes*/, NULL /*keyid*/, opFlags, attrFlags, NULL /*wincx*/ ); if(skey==NULL) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "KeyGen failed on token"); goto finish; } /* wrap the key. This sets skey to NULL. */ keyObj = JSS_PK11_wrapSymKey(env, &skey); finish: if(skey!=NULL) { /* will only be non-NULL if keygen succeeded but wrapSymKey failed */ PK11_FreeSymKey(skey); } return keyObj; } /* We do the translation in Java now, but I'll leave this here just in case */ #if 0 /*********************************************************************** * * C o p y P a s s w o r d T o S E C I t e m * * pass * A Java Password object. * * RETURNS * A new SECItem containing a copy of the bytes in the password, * or NULL iff an exception occurred. Be sure to zero it when * you free it. */ static SECItem* CopyPasswordToSECItem(JNIEnv *env, jobject pass) { jclass passClass=NULL; jmethodID byteCopyMethod=NULL; jbyteArray pwArray=NULL; jbyte *bytes=NULL; SECItem *item=NULL; int numBytes=0; PR_ASSERT(env!=NULL && pass!=NULL); /* get password class and method */ passClass = (*env)->GetObjectClass(env, pass); if(passClass == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find Password class"); ASSERT_OUTOFMEM(env); goto finish; } byteCopyMethod = (*env)->GetMethodID( env, passClass, PW_GET_BYTE_COPY_NAME, PW_GET_BYTE_COPY_SIG); if(byteCopyMethod==NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find Password manipulation" " methods from native implementation"); ASSERT_OUTOFMEM(env); goto finish; } /* copy to a byte array */ pwArray = (*env)->CallObjectMethod(env, pass, byteCopyMethod); if(pwArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } numBytes = (*env)->GetArrayLength(env, pwArray); /* copy from the byte array to a jbyte array */ bytes = (*env)->GetByteArrayElements(env, pwArray, NULL); if(bytes == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* copy from the jbyte array to a new SECItem */ item = PR_NEW(SECItem); /* last byte is null termination */ PR_ASSERT( bytes[numBytes-1] == 0 ); item->len = numBytes - 1; item->data = PR_Malloc(item->len); if(item->data==NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } memcpy(item->data, bytes, item->len); finish: if(bytes!=NULL) { /* clear the password */ PR_ASSERT(numBytes > 0); memset(bytes, 0, numBytes); (*env)->ReleaseByteArrayElements(env, pwArray, bytes, 0); } else { PR_ASSERT(pwArray!=NULL); } return item; } #endif static void FUNCTION_MAY_NOT_BE_USED print_secitem(SECItem *item) { unsigned int i; unsigned int online; if(item==NULL) { return; } for(i=0, online=0; i < item->len; i++, online++) { if(online > 25) { printf("\n"); online = 0; } printf("%.2x ", item->data[i]); } } /*********************************************************************** * * c o n s t r u c t S H A 1 P B A K e y * * Constructs a PBE key using CKM_PBA_SHA1_WITH_SHA1_HMAC. This should * be supported by NSS automatically, but isn't (bug #336587). * * RETURNS * A symmetric key from the given password, salt, and iteration count, * or NULL if an exception was thrown. * THROWS * TokenException if an error occurs. */ static PK11SymKey* constructSHA1PBAKey(JNIEnv *env, PK11SlotInfo *slot, SECItem *pwitem, SECItem *salt, int iterationCount) { PK11SymKey *key=NULL; unsigned char ivData[8]; SECItem mechItem; CK_PBE_PARAMS pbe_params; if( pwitem == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "constructSHA1PAKey:" " pwitem NULL"); goto finish; } if( salt == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "constructSHA1PAKey:" " salt NULL"); goto finish; } pbe_params.pInitVector = ivData; pbe_params.pPassword = pwitem->data; pbe_params.ulPasswordLen = pwitem->len; pbe_params.pSalt = salt->data; pbe_params.ulSaltLen = salt->len; pbe_params.ulIteration = iterationCount; mechItem.data = (unsigned char *) &pbe_params; mechItem.len = sizeof(pbe_params); key = PK11_RawPBEKeyGen(slot, CKM_PBA_SHA1_WITH_SHA1_HMAC, &mechItem, pwitem, PR_FALSE, NULL); if( key == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "PK11_RawPBEKeyGen:" " failed to generate key"); goto finish; } finish: return key; } /*********************************************************************** * * PK11KeyGenerator.generatePBE * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE( JNIEnv *env, jclass clazz, jobject token, jobject alg, jobject encAlg, jbyteArray passBA, jbyteArray saltBA, jint iterationCount) { PK11SlotInfo *slot=NULL; PK11SymKey *skey=NULL; SECOidTag oidTag; SECAlgorithmID *algid=NULL; SECItem *salt=NULL; SECItem *pwitem=NULL; jobject keyObj=NULL; CK_MECHANISM_TYPE mech=CKM_INVALID_MECHANISM; PR_ASSERT(env!=NULL && clazz!=NULL && token!=NULL && alg!=NULL && passBA!=NULL && saltBA!=NULL); /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, token, &slot) != PR_SUCCESS) { goto finish; } /* convert salt to SECItem */ salt = JSS_ByteArrayToSECItem(env, saltBA); if(salt == NULL) { goto finish; } /* convert password to SECItem */ pwitem = JSS_ByteArrayToSECItem(env, passBA); if(pwitem==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* print_secitem(pwitem); */ mech = JSS_getPK11MechFromAlg(env, alg); if( mech == CKM_PBA_SHA1_WITH_SHA1_HMAC ) { /* special case, construct key by hand. Bug #336587 */ skey = constructSHA1PBAKey(env, slot, pwitem, salt, iterationCount); if( skey==NULL ) { /* exception was thrown */ goto finish; } } else { /* get the algorithm info */ oidTag = JSS_getOidTagFromAlg(env, alg); PR_ASSERT(oidTag != SEC_OID_UNKNOWN); SECOidTag encAlgOidTag = JSS_getOidTagFromAlg(env, encAlg); PR_ASSERT(encAlgOidTag != SEC_OID_UNKNOWN); /* create algid */ algid = PK11_CreatePBEV2AlgorithmID( oidTag, encAlgOidTag, SEC_OID_HMAC_SHA1, 0, iterationCount, salt); if( algid == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to process PBE parameters"); goto finish; } /* generate the key */ skey = PK11_PBEKeyGen(slot, algid, pwitem, PR_FALSE /*faulty3DES*/, NULL /*wincx*/); if( skey == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to generate PBE key"); goto finish; } } /* wrap the key. This sets skey to NULL. */ keyObj = JSS_PK11_wrapSymKey(env, &skey); finish: if(algid) { SECOID_DestroyAlgorithmID(algid, PR_TRUE /*freeit*/); } if(salt) { SECITEM_FreeItem(salt, PR_TRUE /*freeit*/); } if(pwitem) { SECITEM_ZfreeItem(pwitem, PR_TRUE /*freeit*/); } if(skey) { /* skey will be NULL if everything worked */ PK11_FreeSymKey(skey); } return keyObj; } /*********************************************************************** * * PK11KeyGenerator.generatePBE_IV * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE_1IV (JNIEnv *env, jclass clazz, jobject alg, jbyteArray passBA, jbyteArray saltBA, jint iterationCount) { SECOidTag oidTag; SECAlgorithmID *algid=NULL; SECItem *salt=NULL; SECItem *pwitem=NULL; SECItem *ivItem=NULL; jbyteArray ivBA=NULL; PR_ASSERT(env!=NULL && clazz!=NULL && alg!=NULL && passBA!=NULL && saltBA!=NULL); /* get the algorithm info */ oidTag = JSS_getOidTagFromAlg(env, alg); PR_ASSERT(oidTag != SEC_OID_UNKNOWN); /* convert salt to SECItem */ salt = JSS_ByteArrayToSECItem(env, saltBA); if(salt == NULL) { goto finish; } /* create algid */ algid = PK11_CreatePBEAlgorithmID(oidTag, iterationCount, salt); if( algid == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to process PBE parameters"); goto finish; } /* convert password to SECItem */ pwitem = JSS_ByteArrayToSECItem(env, passBA); if(pwitem==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* generate the IV */ ivItem = SEC_PKCS5GetIV(algid, pwitem, PR_FALSE /*faulty3DES*/); if(ivItem==NULL) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to generate PBE " "initialization vector"); goto finish; } /* convert IV to byte array */ ivBA = JSS_SECItemToByteArray(env, ivItem); finish: if(algid) { SECOID_DestroyAlgorithmID(algid, PR_TRUE /*freeit*/); } if(salt) { SECITEM_FreeItem(salt, PR_TRUE /*freeit*/); } if(pwitem) { SECITEM_ZfreeItem(pwitem, PR_TRUE /*freeit*/); } if(ivItem) { SECITEM_FreeItem(ivItem, PR_TRUE /*freeit*/); } return ivBA; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_nativeClone (JNIEnv *env, jclass clazz, jobject tokenObj, jobject toBeClonedObj) { PK11SlotInfo *slot=NULL; PK11SymKey *toBeCloned=NULL; PK11SymKey *clone=NULL; SECStatus rv; jobject cloneObj=NULL; PR_ASSERT(env!=NULL && tokenObj!=NULL && toBeClonedObj!=NULL); /* get slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get toBeCloned */ if( JSS_PK11_getSymKeyPtr(env, toBeClonedObj, &toBeCloned) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* extract the key value */ rv = PK11_ExtractKeyValue(toBeCloned); if( rv != SECSuccess ) { JSS_throw(env, NOT_EXTRACTABLE_EXCEPTION); goto finish; } clone = PK11_ImportSymKey( slot, PK11_GetMechanism(toBeCloned), PK11_OriginGenerated, /* we don't know this, but it doesn't matter */ CKA_ENCRYPT, /* !!! Actually we want to enable all operations */ PK11_GetKeyData(toBeCloned), NULL /* wincx */ ); if( clone == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to create new symmetric" " key object"); goto finish; } /* wrap the new key in a Java object */ cloneObj = JSS_PK11_wrapSymKey(env, &clone); finish: if( clone!=NULL ) { /* clone would be NULL if we completed successfully */ PK11_FreeSymKey(clone); } return cloneObj; } /*********************************************************************** * * PK11KeyGenerator.generateKBKDF * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generateKBKDF(JNIEnv *env, jclass clazz, jobject tokenObj, jobject baseKeyObj, jlong alg, jobject paramsObj, jlong params_size, jlong derivedKeyAlgorithm, jint strength, jint opFlags, jboolean temporary, jint sensitive) { PK11SlotInfo *slot = NULL; PK11SymKey *baseKey = NULL; PK11SymKey *result = NULL; jobject resultObj = NULL; SECItem param_item = { 0 }; void *param_ptr = NULL; PRBool isPerm = PR_FALSE; PR_ASSERT(env != NULL && tokenObj != NULL); /* get slot */ if (JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get base key */ if (JSS_PK11_getSymKeyPtr(env, baseKeyObj, &baseKey) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get params */ if (JSS_PR_getStaticVoidRef(env, paramsObj, ¶m_ptr) != PR_SUCCESS) { /* exception was thrown */ goto finish; } param_item.type = siBuffer; param_item.data = (unsigned char *)(param_ptr); param_item.len = (unsigned int) params_size; isPerm = (temporary == JNI_FALSE) ? PR_TRUE : PR_FALSE; result = PK11_DeriveWithFlagsPerm(baseKey, alg, ¶m_item, derivedKeyAlgorithm, CKA_ENCRYPT, strength, opFlags, isPerm); if (result == NULL) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to create derived symmetric key object"); goto finish; } resultObj = JSS_PK11_wrapSymKey(env, &result); finish: PK11_FreeSymKey(result); return resultObj; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11KeyGenerator.java000066400000000000000000000307461362106420000223250ustar00rootroot00000000000000/* 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.pkcs11; import java.io.CharConversionException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.spec.AlgorithmParameterSpec; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.KBKDFParameterSpec; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.PBEKeyGenParams; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.util.NativeProxy; import org.mozilla.jss.util.Password; import org.mozilla.jss.util.UTF8Converter; public final class PK11KeyGenerator implements KeyGenerator { // opFlag constants: each of these flags specifies a crypto operation // the key will support. Their values must match the same-named C // preprocessor macros defined in the PKCS #11 header pkcs11t.h. private static final int CKF_ENCRYPT = 0x00000100; private static final int CKF_DECRYPT = 0x00000200; private static final int CKF_SIGN = 0x00000800; private static final int CKF_VERIFY = 0x00002000; private static final int CKF_WRAP = 0x00020000; private static final int CKF_UNWRAP = 0x00040000; // A table for mapping SymmetricKey.Usage to opFlag. This must be // synchronized with SymmetricKey.Usage. private static final int opFlagForUsage[] = { CKF_ENCRYPT, /* 0 */ CKF_DECRYPT, /* 1 */ CKF_WRAP, /* 2 */ CKF_UNWRAP, /* 3 */ CKF_SIGN, /* 4 */ CKF_VERIFY /* 5 */ }; // The token this key will be generated on. private PK11Token token; // The algorithm to use to generate the key private KeyGenAlgorithm algorithm; // The strength of the key to be generated in bits. A value of 0 means // that the strength has not been set. This is OK for most algorithms. private int strength=0; // The parameters for this algorithm. May be null for some algorithms. private AlgorithmParameterSpec parameters; // The crypto operations the key will support. It is the logical OR // of the opFlag constants, each specifying a supported operation. private int opFlags = CKF_SIGN | CKF_ENCRYPT; // Whether the key will be temporary or permanent private boolean temporaryKeyMode = true; // Whether the key will be sensitive or insensitive // 1: sensitive // 0: insensitive // -1: unspecified (token dependent) private int sensitiveKeyMode = -1; // Used to convert Java Password into a byte[]. private KeyGenerator.CharToByteConverter charToByte; private PK11KeyGenerator() { } // package private constructor PK11KeyGenerator(PK11Token token, KeyGenAlgorithm algorithm) { if( token==null || algorithm==null ) { throw new NullPointerException(); } this.token = token; this.algorithm = algorithm; charToByte = new KeyGenerator.CharToByteConverter() { public byte[] convert(char[] chars) throws CharConversionException { return UTF8Converter.UnicodeToUTF8(chars); } }; } /** * Sets the character to byte converter for passwords. The default * conversion is UTF8 with no null termination. */ public void setCharToByteConverter( KeyGenerator.CharToByteConverter charToByte) { if( charToByte==null ) { throw new IllegalArgumentException("CharToByteConverter is null"); } this.charToByte = charToByte; } /** * @param strength Key size in bits. Must be evenly divisible by 8. */ public void initialize(int strength) throws InvalidAlgorithmParameterException { // if this algorithm only accepts PBE key gen params, it can't // use a strength Class[] paramClasses = algorithm.getParameterClasses(); if( paramClasses.length == 1 && paramClasses[0].equals(PBEKeyGenParams.class) ) { throw new InvalidAlgorithmParameterException("PBE keygen "+ "algorithms require PBEKeyGenParams "); } // validate the strength for our algorithm if( ! algorithm.isValidStrength(strength) ) { throw new InvalidAlgorithmParameterException(strength+ " is not a valid strength for "+algorithm); } if( strength % 8 != 0 ) { throw new InvalidAlgorithmParameterException( "Key strength must be divisible by 8"); } this.strength = strength; } public void initialize(AlgorithmParameterSpec parameters) throws InvalidAlgorithmParameterException { if( ! algorithm.isValidParameterObject(parameters) ) { String name = "null"; if( parameters != null ) { name = parameters.getClass().getName(); } throw new InvalidAlgorithmParameterException( algorithm + " cannot use a " + name + " parameter"); } this.parameters = parameters; } public void setKeyUsages(SymmetricKey.Usage[] usages) { this.opFlags = 0; for( int i = 0; i < usages.length; i++ ) { if( usages[i] != null ) { this.opFlags |= opFlagForUsage[usages[i].getVal()]; } } } public void temporaryKeys(boolean temp) { this.temporaryKeyMode = temp; } public void sensitiveKeys(boolean sensitive) { this.sensitiveKeyMode = sensitive ? 1 : 0; } /** * Generates the key. This is the public interface, the actual * work is done by native methods. */ public SymmetricKey generate() throws IllegalStateException, TokenException, CharConversionException { Class[] paramClasses = algorithm.getParameterClasses(); boolean is_pbe = paramClasses.length == 1 && paramClasses[0].equals(PBEKeyGenParams.class); boolean is_kbkdf = paramClasses.length == 1 && parameters instanceof KBKDFParameterSpec; if (is_pbe) { if(parameters==null || !(parameters instanceof PBEKeyGenParams)) { throw new IllegalStateException( "PBE keygen algorithms require PBEKeyGenParams"); } PBEKeyGenParams kgp = (PBEKeyGenParams)parameters; byte[] pwbytes=null; try { pwbytes = charToByte.convert( kgp.getPassword().getChars() ); return generatePBE( token, algorithm, kgp.getEncryptionAlgorithm(), pwbytes, kgp.getSalt(), kgp.getIterations()); } finally { if( pwbytes!=null ) { Password.wipeBytes(pwbytes); } } } else if (is_kbkdf) { KBKDFParameterSpec kps = (KBKDFParameterSpec) parameters; SymmetricKey result = null; try { try { kps.open(); long pkcs11_alg = algorithm.getEnum().getValue(); result = generateKBKDF(token, kps.prfKey, pkcs11_alg, kps.mPointer, kps.mPointerSize, kps.derivedKeyAlgorithm, kps.keySize, opFlags, temporaryKeyMode, sensitiveKeyMode); } finally { kps.close(); } } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } return result; } else { return generateNormal(token, algorithm, strength, opFlags, temporaryKeyMode, sensitiveKeyMode); } } /** * Generates an Initialization Vector using a PBE algorithm. * In order to call this method, the algorithm must be a PBE algorithm, * and the KeyGenerator must have been initialized with an instance * of PBEKeyGenParams. * * @return The initialization vector derived from the password and salt * using the PBE algorithm. */ public byte[] generatePBE_IV() throws TokenException, CharConversionException { Class[] paramClasses = algorithm.getParameterClasses(); boolean is_pbe = paramClasses.length == 1 && paramClasses[0].equals(PBEKeyGenParams.class); if (is_pbe) { if(parameters==null || !(parameters instanceof PBEKeyGenParams)) { throw new IllegalStateException( "PBE keygen algorithms require PBEKeyGenParams"); } PBEKeyGenParams kgp = (PBEKeyGenParams)parameters; byte[] pwbytes=null; try { pwbytes = charToByte.convert(kgp.getPassword().getChars()); return generatePBE_IV(algorithm, pwbytes, kgp.getSalt(), kgp.getIterations() ); } finally { if(pwbytes!=null) { Password.wipeBytes(pwbytes); } } } else { throw new IllegalStateException( "IV generation can only be performed by PBE algorithms"); } } /** * A native method to generate an IV using a PBE algorithm. * None of the parameters should be NULL. */ private static native byte[] generatePBE_IV(KeyGenAlgorithm alg, byte[] password, byte[] salt, int iterations) throws TokenException; /** * Allows a SymmetricKey to be cloned on a different token. * * @exception SymmetricKey.NotExtractableException If the key material * cannot be extracted from the current token. * @exception InvalidKeyException If the owning token cannot process * the key to be cloned. */ public SymmetricKey clone(SymmetricKey key) throws SymmetricKey.NotExtractableException, InvalidKeyException, TokenException { return clone(key, token); } /** * Allows a SymmetricKey to be cloned on a different token. * * @param key The key to clone. * @param token The token on which to clone the key. * @exception SymmetricKey.NotExtractableException If the key material * cannot be extracted from the current token. * @exception InvalidKeyException If the owning token cannot process * the key to be cloned. */ public static SymmetricKey clone(SymmetricKey key, PK11Token token) throws SymmetricKey.NotExtractableException, InvalidKeyException, TokenException { if( ! (key instanceof PK11SymKey) ) { throw new InvalidKeyException("Key is not a PKCS #11 key"); } return nativeClone(token, key); } private static native SymmetricKey nativeClone(PK11Token token, SymmetricKey toBeCloned) throws SymmetricKey.NotExtractableException, TokenException; /** * A native method to generate a non-PBE key. * @param token The token where the key generation happens * @param algorithm The algorithm to use * @param strength The key size in bits, should be 0 for fixed-length * key algorithms. * @param opFlags The crypto operations the key will support * @param temporary Whether the key will be temporary or permanent */ private static native SymmetricKey generateNormal(PK11Token token, KeyGenAlgorithm algorithm, int strength, int opFlags, boolean temporary, int sensitive) throws TokenException; /** * A native method to generate a PBE key. None of the parameters should * be null. */ private static native SymmetricKey generatePBE( PK11Token token, KeyGenAlgorithm algorithm, EncryptionAlgorithm encAlg, byte[] pass, byte[] salt, int iterationCount) throws TokenException; /** * A native method to generate a key using KBKDF. None of the parameters * should be null. */ private static native SymmetricKey generateKBKDF(PK11Token token, PK11SymKey baseKeyObj, long algorithm, NativeProxy pointer, long pointer_size, long derivedKeyAlgorithm, int strength, int opFlags, boolean temporary, int sensitive) throws TokenException; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.c000066400000000000000000000363351362106420000224420ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11KeyPairGenerator.h" #include #include #include #include #include #include #include #include #include #include /*********************************************************************** * * k e y s T o K e y P a i r * * Turns a SECKEYPrivateKey and a SECKEYPublicKey into a Java KeyPair * object. * * INPUTS * pPrivk * Address of a SECKEYPrivateKey* which will be consumed by the * KeyPair. The pointer will be set to NULL. It is not necessary * to free this private key if the function exits successfully. * pPubk * Address of a SECKEYPublicKey* which will be consumed by this * KeyPair. The pointer will be set to NULL. It is not necessary * to free this public key if the function exits successfully. */ static jobject keysToKeyPair(JNIEnv *env, SECKEYPrivateKey **pPrivk, SECKEYPublicKey **pPubk) { jobject privateKey; jobject publicKey; jobject keyPair=NULL; jclass keyPairClass; jmethodID keyPairConstructor; /************************************************** * wrap the keys in Java objects *************************************************/ publicKey = JSS_PK11_wrapPubKey(env, pPubk); privateKey = JSS_PK11_wrapPrivKey(env, pPrivk); if(publicKey==NULL || privateKey==NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /************************************************** * encapsulate the keys in a keypair *************************************************/ keyPairClass = (*env)->FindClass(env, KEY_PAIR_CLASS_NAME); if(keyPairClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyPairConstructor = (*env)->GetMethodID( env, keyPairClass, KEY_PAIR_CONSTRUCTOR_NAME, KEY_PAIR_CONSTRUCTOR_SIG); if(keyPairConstructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyPair = (*env)->NewObject(env, keyPairClass, keyPairConstructor, publicKey, privateKey); if(keyPair == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: return keyPair; } int PK11_NumberObjectsFor(PK11SlotInfo*, CK_ATTRIBUTE*, int); SECStatus JSS_PK11_generateKeyPairWithOpFlags(JNIEnv *env, CK_MECHANISM_TYPE mechanism, PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privk, void *params, PRBool temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask) { PK11AttrFlags attrFlags = 0; *privk=NULL; *pubk=NULL; PR_ASSERT(env!=NULL && slot!=NULL); /************************************************** * login to the token if necessary *************************************************/ if( PK11_Authenticate(slot, PR_TRUE /*loadcerts*/, NULL) != SECSuccess) { JSS_throwMsg(env, TOKEN_EXCEPTION, "unable to login to token"); goto finish; } /************************************************** * generate the key pair on the token *************************************************/ if( temporary ) { attrFlags |= PK11_ATTR_SESSION; } else { attrFlags |= PK11_ATTR_TOKEN; } if( extractable == 1 ) { attrFlags |= PK11_ATTR_EXTRACTABLE; } else if( extractable == 0 ) { attrFlags |= PK11_ATTR_UNEXTRACTABLE; } /* * The default of sensitive is set this way to be backward * compatible. */ if( sensitive == -1 ) { sensitive = !temporary; } /* * The PRIVATE/PUBLIC attributes are set this way to be backward * compatible with the original PK11_GenerateKeyPair call. */ if( sensitive ) { attrFlags |= (PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE); } else { attrFlags |= (PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC); } *privk = PK11_GenerateKeyPairWithOpFlags(slot, mechanism, params, pubk, attrFlags, (CK_FLAGS) op_flags, (CK_FLAGS) op_flags_mask /* the ones we don't want*/, NULL /* default PW callback */ ); if( *privk == NULL ) { int errLength; char *errBuf; char *msgBuf; errLength = PR_GetErrorTextLength(); if(errLength > 0) { errBuf = PR_Malloc(errLength); if(errBuf == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } PR_GetErrorText(errBuf); } msgBuf = PR_smprintf("Keypair Generation failed on token with error: %d : %s", PR_GetError(), errLength>0? errBuf : ""); if(errLength>0) { PR_Free(errBuf); } JSS_throwMsg(env, TOKEN_EXCEPTION, msgBuf); PR_Free(msgBuf); goto finish; } return SECSuccess; finish: if(*privk!=NULL) { SECKEY_DestroyPrivateKey(*privk); *privk = NULL; } if(*pubk!=NULL) { SECKEY_DestroyPublicKey(*pubk); *pubk = NULL; } return SECFailure; } /* * make a common key gen function for both this file and PK11Token.c */ SECStatus JSS_PK11_generateKeyPair(JNIEnv *env, CK_MECHANISM_TYPE mechanism, PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privk, void *params, PRBool temporary, jint sensitive, jint extractable) { return JSS_PK11_generateKeyPairWithOpFlags(env, mechanism, slot, pubk, privk, params, temporary, sensitive, extractable, 0, 0); } /********************************************************************** * Local generic helpers */ static jobject PK11KeyPairGeneratorWithOpFlags(JNIEnv *env, jobject this, jobject token, CK_MECHANISM_TYPE mechanism, void *params, jboolean temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask) { PK11SlotInfo* slot; SECKEYPrivateKey *privk=NULL; SECKEYPublicKey *pubk=NULL; jobject keyPair=NULL; SECStatus rv; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL); /************************************************** * get the slot pointer *************************************************/ if( JSS_PK11_getTokenSlotPtr(env, token, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot != NULL); rv = JSS_PK11_generateKeyPairWithOpFlags(env, mechanism, slot, &pubk, &privk, params, temporary, sensitive, extractable, op_flags, op_flags_mask); if (rv != SECSuccess) { goto finish; } /************************************************** * wrap in a Java KeyPair object *************************************************/ keyPair = keysToKeyPair(env, &privk, &pubk); if(keyPair == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } finish: if(privk!=NULL) { SECKEY_DestroyPrivateKey(privk); } if(pubk!=NULL) { SECKEY_DestroyPublicKey(pubk); } return keyPair; } static jobject PK11KeyPairGenerator(JNIEnv *env, jobject this, jobject token, CK_MECHANISM_TYPE mechanism, void *params, jboolean temporary, jint sensitive, jint extractable) { return PK11KeyPairGeneratorWithOpFlags(env, this, token, mechanism, params, temporary, sensitive, extractable, 0, 0); } /********************************************************************** * PK11KeyPairGenerator.generateRSAKeyPair */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPair (JNIEnv *env, jobject this, jobject token, jint keySize, jlong publicExponent, jboolean temporary, jint sensitive, jint extractable) { PK11RSAGenParams params; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL); /************************************************** * setup parameters *************************************************/ params.keySizeInBits = keySize; params.pe = publicExponent; return PK11KeyPairGenerator(env, this, token, CKM_RSA_PKCS_KEY_PAIR_GEN, ¶ms, temporary, sensitive, extractable); } /********************************************************************** * PK11KeyPairGenerator.generateRSAKeyPairWithOpFlags */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPairWithOpFlags (JNIEnv *env, jobject this, jobject token, jint keySize, jlong publicExponent, jboolean temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask) { PK11RSAGenParams params; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL); /************************************************** * setup parameters *************************************************/ params.keySizeInBits = keySize; params.pe = publicExponent; return PK11KeyPairGeneratorWithOpFlags(env, this, token, CKM_RSA_PKCS_KEY_PAIR_GEN, ¶ms, temporary, sensitive, extractable, op_flags, op_flags_mask); } #define ZERO_SECITEM(item) {(item).len=0; (item).data=NULL;} /********************************************************************** * * PK11KeyPairGenerator.generateDSAKeyPair * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPair (JNIEnv *env, jobject this, jobject token, jbyteArray P, jbyteArray Q, jbyteArray G, jboolean temporary, jint sensitive, jint extractable) { SECItem p, q, g; PQGParams *params=NULL; jobject keyPair=NULL; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL && P!=NULL && Q!=NULL && G!=NULL); /* zero these so we can free them indiscriminately later */ ZERO_SECITEM(p); ZERO_SECITEM(q); ZERO_SECITEM(g); /************************************************** * Setup the parameters *************************************************/ if( JSS_ByteArrayToOctetString(env, P, &p) || JSS_ByteArrayToOctetString(env, Q, &q) || JSS_ByteArrayToOctetString(env, G, &g) ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } params = PK11_PQG_NewParams(&p, &q, &g); if(params == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } keyPair = PK11KeyPairGenerator(env, this, token, CKM_DSA_KEY_PAIR_GEN, params, temporary, sensitive, extractable); finish: SECITEM_FreeItem(&p, PR_FALSE); SECITEM_FreeItem(&q, PR_FALSE); SECITEM_FreeItem(&g, PR_FALSE); PK11_PQG_DestroyParams(params); return keyPair; } /********************************************************************** * * PK11KeyPairGenerator.generateDSAKeyPair * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPairWithOpFlags (JNIEnv *env, jobject this, jobject token, jbyteArray P, jbyteArray Q, jbyteArray G, jboolean temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask) { SECItem p, q, g; PQGParams *params=NULL; jobject keyPair=NULL; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL && P!=NULL && Q!=NULL && G!=NULL); /* zero these so we can free them indiscriminately later */ ZERO_SECITEM(p); ZERO_SECITEM(q); ZERO_SECITEM(g); /************************************************** * Setup the parameters *************************************************/ if( JSS_ByteArrayToOctetString(env, P, &p) || JSS_ByteArrayToOctetString(env, Q, &q) || JSS_ByteArrayToOctetString(env, G, &g) ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } params = PK11_PQG_NewParams(&p, &q, &g); if(params == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } keyPair = PK11KeyPairGeneratorWithOpFlags(env, this, token, CKM_DSA_KEY_PAIR_GEN, params, temporary, sensitive, extractable, op_flags, op_flags_mask); finish: SECITEM_FreeItem(&p, PR_FALSE); SECITEM_FreeItem(&q, PR_FALSE); SECITEM_FreeItem(&g, PR_FALSE); PK11_PQG_DestroyParams(params); return keyPair; } void DumpItem(SECItem *item) { unsigned char *data = item->data; unsigned int i; for (i=0; i < item->len; i++) { printf(" %02x",data[i]); } printf(" : %8p %d\n", data, item->len); } /********************************************************************** * * PK11KeyPairGenerator.generateECKeyPair * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPair (JNIEnv *env, jobject this, jobject token, jbyteArray Curve, jboolean temporary, jint sensitive, jint extractable) { SECItem curve; jobject keyPair=NULL; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL && Curve!=NULL ); /* zero these so we can free them indiscriminately later */ ZERO_SECITEM(curve); /************************************************** * Setup the parameters *************************************************/ if( JSS_ByteArrayToOctetString(env, Curve, &curve)) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } keyPair = PK11KeyPairGenerator(env, this, token, CKM_EC_KEY_PAIR_GEN, &curve, temporary, sensitive, extractable); finish: SECITEM_FreeItem(&curve, PR_FALSE); return keyPair; } /********************************************************************** * * PK11KeyPairGenerator.generateECKeyPairWithOpFlags * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPairWithOpFlags (JNIEnv *env, jobject this, jobject token, jbyteArray Curve, jboolean temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask) { SECItem curve; jobject keyPair=NULL; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL && Curve!=NULL ); /* zero these so we can free them indiscriminately later */ ZERO_SECITEM(curve); /************************************************** * Setup the parameters *************************************************/ if( JSS_ByteArrayToOctetString(env, Curve, &curve)) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } keyPair = PK11KeyPairGeneratorWithOpFlags(env, this, token, CKM_EC_KEY_PAIR_GEN, &curve, temporary, sensitive, extractable, op_flags, op_flags_mask); finish: SECITEM_FreeItem(&curve, PR_FALSE); return keyPair; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.java000066400000000000000000001454711362106420000231430ustar00rootroot00000000000000/* 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.pkcs11; import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.RSAKeyGenParameterSpec; import java.util.Hashtable; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.Policy; import org.mozilla.jss.crypto.PQGParams; import org.mozilla.jss.crypto.RSAParameterSpec; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.util.Assert; import org.mozilla.jss.util.ECCurve; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A Key Pair Generator implemented using PKCS #11. * * @see org.mozilla.jss.crypto.PQGParams */ public final class PK11KeyPairGenerator extends org.mozilla.jss.crypto.KeyPairGeneratorSpi { public static Logger logger = LoggerFactory.getLogger(PK11KeyPairGenerator.class); // curve code for getting the actual EC curve private enum ECCurve_Code { // NIST, SEC2 Prime curves secp521r1 , // == nistp521 nistp521 , secp384r1 , // == nistp384 nistp384 , secp256r1 , // == nistp256 nistp256 , secp256k1 , secp224r1 , // == nistp224 nistp224 , secp224k1 , secp192r1 , // == nistp192 nistp192 , secp192k1 , secp160r2 , secp160r1 , secp160k1 , secp128r2 , secp128r1 , secp112r2 , secp112r1 , // NIST, SEC2 Binary curves sect571r1 , // == nistb571 nistb571 , sect571k1 , // == nistk571 nistk571 , sect409r1 , // == nistb409 nistb409 , sect409k1 , // == nistk409 nistk409 , sect283r1 , // == nistb283 nistb283 , sect283k1 , // == nistk283 nistk283 , sect239k1 , sect233r1 , // == nistb233 nistb233 , sect233k1 , // == nistk233 nistk233 , sect193r2 , sect193r1 , nistb163 , sect163r2 , // == nistb163 sect163r1 , sect163k1 , // == nistk163 nistk163 , sect131r2 , sect131r1 , sect113r2 , sect113r1 , // ANSI X9.62 Prime curves prime239v3 , prime239v2 , prime239v1 , prime192v3 , prime192v2 , prime192v1 , // == nistp192 // prime256v1 == nistp256 // ANSI X9.62 Binary curves c2pnb163v1 , c2pnb163v2 , c2pnb163v3 , c2pnb176v1 , c2tnb191v1 , c2tnb191v2 , c2tnb191v3 , //c2onb191v4 , //c2onb191v5 , c2pnb208w1 , c2tnb239v1 , c2tnb239v2 , c2tnb239v3 , //c2onb239v4 , //c2onb239v5 , c2pnb272w1 , c2pnb304w1 , c2tnb359v1 , c2pnb368w1 , c2tnb431r1 // no WTLS curves fo now }; private static Hashtable ECCurve_NameToCode = new Hashtable<>(); static { // NIST, SEC2 Prime curves ECCurve_NameToCode.put( "secp521r1", ECCurve_Code.secp521r1); ECCurve_NameToCode.put( "nistp521", ECCurve_Code.nistp521); ECCurve_NameToCode.put( "secp384r1", ECCurve_Code.secp384r1); ECCurve_NameToCode.put( "nistp384", ECCurve_Code.nistp384); ECCurve_NameToCode.put( "secp256r1", ECCurve_Code.secp256r1); ECCurve_NameToCode.put( "nistp256", ECCurve_Code.nistp256); ECCurve_NameToCode.put( "secp256k1", ECCurve_Code.secp256k1); ECCurve_NameToCode.put( "secp224r1", ECCurve_Code.secp224r1); ECCurve_NameToCode.put( "nistp224", ECCurve_Code.nistp224); ECCurve_NameToCode.put( "secp224k1", ECCurve_Code.secp224k1); ECCurve_NameToCode.put( "secp192r1", ECCurve_Code.secp192r1); ECCurve_NameToCode.put( "nistp192", ECCurve_Code.nistp192); ECCurve_NameToCode.put( "secp192k1", ECCurve_Code.secp192k1); ECCurve_NameToCode.put( "secp160r2", ECCurve_Code.secp160r2); ECCurve_NameToCode.put( "secp160r1", ECCurve_Code.secp160r1); ECCurve_NameToCode.put( "secp160k1", ECCurve_Code.secp160k1); ECCurve_NameToCode.put( "secp128r2", ECCurve_Code.secp128r2); ECCurve_NameToCode.put( "secp128r1", ECCurve_Code.secp128r1); ECCurve_NameToCode.put( "secp112r2", ECCurve_Code.secp112r2); ECCurve_NameToCode.put( "secp112r1", ECCurve_Code.secp112r1); // NIST, SEC2 Binary curves ECCurve_NameToCode.put( "sect571r1", ECCurve_Code.sect571r1); ECCurve_NameToCode.put( "nistb571", ECCurve_Code.nistb571); ECCurve_NameToCode.put( "sect571k1", ECCurve_Code.sect571k1); ECCurve_NameToCode.put( "nistk571", ECCurve_Code.nistk571); ECCurve_NameToCode.put( "sect409r1", ECCurve_Code.sect409r1); ECCurve_NameToCode.put( "nistb409", ECCurve_Code.nistb409); ECCurve_NameToCode.put( "sect409k1", ECCurve_Code.sect409k1); ECCurve_NameToCode.put( "nistk409", ECCurve_Code.nistk409); ECCurve_NameToCode.put( "sect283r1", ECCurve_Code.sect283r1); ECCurve_NameToCode.put( "nistb283", ECCurve_Code.nistb283); ECCurve_NameToCode.put( "sect283k1", ECCurve_Code.sect283k1); ECCurve_NameToCode.put( "nistk283", ECCurve_Code.nistk283); ECCurve_NameToCode.put( "sect239k1", ECCurve_Code.sect239k1); ECCurve_NameToCode.put( "sect233r1", ECCurve_Code.sect233r1); ECCurve_NameToCode.put( "nistb233", ECCurve_Code.nistb233); ECCurve_NameToCode.put( "sect233k1", ECCurve_Code.sect233k1); ECCurve_NameToCode.put( "nistk233", ECCurve_Code.nistk233); ECCurve_NameToCode.put( "sect193r2", ECCurve_Code.sect193r2); ECCurve_NameToCode.put( "sect193r1", ECCurve_Code.sect193r1); ECCurve_NameToCode.put( "nistb163", ECCurve_Code.nistb163); ECCurve_NameToCode.put( "sect163r2", ECCurve_Code.sect163r2); ECCurve_NameToCode.put( "sect163r1", ECCurve_Code.sect163r1); ECCurve_NameToCode.put( "sect163k1", ECCurve_Code.sect163k1); ECCurve_NameToCode.put( "nistk163", ECCurve_Code.nistk163); ECCurve_NameToCode.put( "sect131r2", ECCurve_Code.sect131r2); ECCurve_NameToCode.put( "sect131r1", ECCurve_Code.sect131r1); ECCurve_NameToCode.put( "sect113r2", ECCurve_Code.sect113r2); ECCurve_NameToCode.put( "sect113r1", ECCurve_Code.sect113r1); // ANSI Prime curves ECCurve_NameToCode.put( "prime239v3", ECCurve_Code.prime239v3); ECCurve_NameToCode.put( "prime239v2", ECCurve_Code.prime239v2); ECCurve_NameToCode.put( "prime239v1", ECCurve_Code.prime239v1); ECCurve_NameToCode.put( "prime192v3", ECCurve_Code.prime192v3); ECCurve_NameToCode.put( "prime192v2", ECCurve_Code.prime192v2); ECCurve_NameToCode.put( "prime192v1", ECCurve_Code.prime192v1); // ANSI Binary curves ECCurve_NameToCode.put( "c2pnb163v1", ECCurve_Code.c2pnb163v1); ECCurve_NameToCode.put( "c2pnb163v2", ECCurve_Code.c2pnb163v2); ECCurve_NameToCode.put( "c2pnb163v3", ECCurve_Code.c2pnb163v3); ECCurve_NameToCode.put( "c2pnb176v1", ECCurve_Code.c2pnb176v1); ECCurve_NameToCode.put( "c2tnb191v1", ECCurve_Code.c2tnb191v1); ECCurve_NameToCode.put( "c2tnb191v2", ECCurve_Code.c2tnb191v2); ECCurve_NameToCode.put( "c2tnb191v3", ECCurve_Code.c2tnb191v3); //ECCurve_NameToCode.put( // "c2onb191v4", ECCurve_Code.c2onb191v4); //ECCurve_NameToCode.put( // "c2onb191v5", ECCurve_Code.c2onb191v5); ECCurve_NameToCode.put( "c2pnb208w1", ECCurve_Code.c2pnb208w1); ECCurve_NameToCode.put( "c2tnb239v1", ECCurve_Code.c2tnb239v1); ECCurve_NameToCode.put( "c2tnb239v2", ECCurve_Code.c2tnb239v2); ECCurve_NameToCode.put( "c2tnb239v3", ECCurve_Code.c2tnb239v3); //ECCurve_NameToCode.put( // "c2onb239v4", ECCurve_Code.c2onb239v4); //ECCurve_NameToCode.put( // "c2onb239v5", ECCurve_Code.c2onb239v5); ECCurve_NameToCode.put( "c2pnb272w1", ECCurve_Code.c2pnb272w1); ECCurve_NameToCode.put( "c2pnb304w1", ECCurve_Code.c2pnb304w1); ECCurve_NameToCode.put( "c2tnb359v1", ECCurve_Code.c2tnb359v1); ECCurve_NameToCode.put( "c2pnb368w1", ECCurve_Code.c2pnb368w1); ECCurve_NameToCode.put( "c2tnb431r1", ECCurve_Code.c2tnb431r1); } // opFlag constants: each of these flags specifies a crypto operation // the key will support. Their values must match the same-named C // preprocessor macros defined in the PKCS #11 header pkcs11t.h. private static final int CKF_ENCRYPT = 0x00000100; private static final int CKF_DECRYPT = 0x00000200; private static final int CKF_SIGN = 0x00000800; private static final int CKF_SIGN_RECOVER = 0x00001000; private static final int CKF_VERIFY = 0x00002000; private static final int CKF_VERIFY_RECOVER = 0x00004000; private static final int CKF_WRAP = 0x00020000; private static final int CKF_UNWRAP = 0x00040000; private static final int CKF_DERIVE = 0x00080000; // A table for mapping SymmetricKey.Usage to opFlag. This must be // synchronized with SymmetricKey.Usage. private static final int opFlagForUsage[] = { CKF_ENCRYPT, /* 0 */ CKF_DECRYPT, /* 1 */ CKF_SIGN, /* 2 */ CKF_SIGN_RECOVER, /* 3 */ CKF_VERIFY, /* 4 */ CKF_VERIFY_RECOVER, /* 5 */ CKF_WRAP, /* 6 */ CKF_UNWRAP, /* 7 */ CKF_DERIVE /* 8 */ }; // The crypto operations the key will support. It is the logical OR // of the opFlag constants, each specifying a supported operation. private int opFlags = 0; private int opFlagsMask = 0; /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Constructor for PK11KeyPairGenerator. * @param token The PKCS #11 token that the keypair will be generated on. * @param algorithm The type of key that will be generated. Currently, * KeyPairAlgorithm.RSA , * KeyPairAlgorithm.DSA and * KeyPairAlgorithm.EC are supported. * @throws NoSuchAlgorithmException * @throws TokenException */ public PK11KeyPairGenerator(PK11Token token, KeyPairAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { assert(token!=null && algorithm!=null); mKeygenOnInternalToken = false; // Make sure we can do this kind of keygen if( ! token.doesAlgorithm(algorithm) ) { if( token.doesAlgorithm( algorithm.getAlgFamily() ) && token.isWritable() ) { // NSS will do the keygen on the internal module // and move the key to the token. We'll say this is // OK for now. mKeygenOnInternalToken = true; } else { throw new NoSuchAlgorithmException(); } } this.token = token; this.algorithm = algorithm; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Public Methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Initializes this KeyPairGenerator with the given key strength. * *

For DSA key generation, pre-cooked PQG values will be used * be used if the key size is 512, 768, or 1024. Otherwise, an * InvalidParameterException will be thrown. * * @param strength The strength (size) of the keys that will be generated. * @param random Ignored * @exception InvalidParameterException If the key strength is not * supported by the algorithm or this implementation. */ public void initialize(int strength, SecureRandom random) throws InvalidParameterException { if(algorithm == KeyPairAlgorithm.RSA) { params = new RSAParameterSpec(strength, DEFAULT_RSA_PUBLIC_EXPONENT); } else if(algorithm == KeyPairAlgorithm.DSA) { if(strength==512) { params = PQG512; } else if(strength==768) { params = PQG768; } else if(strength==1024) { params = PQG1024; } else { throw new InvalidParameterException( "In order to use pre-cooked PQG values, key strength must"+ "be 512, 768, or 1024."); } } else { assert( algorithm == KeyPairAlgorithm.EC ); if (strength < 112) { // for EC, "strength" is actually a code for curves defined in // ECCurve_Code params = getECCurve(strength); } else { // this is the old method of strength to curve mapping, // which is somewhat defective params = getCurve(strength); } } } /** * Initializes this KeyPairGenerator with the given algorithm-specific * parameters. * * @param params The algorithm-specific parameters that will govern * key pair generation. * @param random Ignored * @throws InvalidAlgorithmParameterException If the parameters * are inappropriate for the key type or are not supported by * this implementation. */ public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if(params == null) { throw new InvalidAlgorithmParameterException("Null parameters"); } if(algorithm == KeyPairAlgorithm.RSA) { if (!(params instanceof RSAKeyGenParameterSpec)) { throw new InvalidAlgorithmParameterException(); } // Security library stores public exponent in an unsigned long if (((RSAKeyGenParameterSpec)params).getPublicExponent().bitLength() > 31) { throw new InvalidAlgorithmParameterException( "RSA Public Exponent must fit in 31 or fewer bits."); } } else if ( algorithm == KeyPairAlgorithm.DSA ){ if(! (params instanceof DSAParameterSpec) ) { throw new InvalidAlgorithmParameterException(); } } else { assert(algorithm == KeyPairAlgorithm.EC); if (params instanceof ECGenParameterSpec) { ECGenParameterSpec standard_params = (ECGenParameterSpec)params; String curve_name = standard_params.getName(); ECCurve curve = ECCurve.fromName(curve_name); if (curve == null) { throw new InvalidAlgorithmParameterException("Unable to find curve with the given name: " + curve_name); } OBJECT_IDENTIFIER[] oid = curve.getOIDs(); assert(oid.length >= 1); byte[] encoded_oid = ASN1Util.encode(oid[0]); params = new PK11ParameterSpec(encoded_oid); } if (!(params instanceof PK11ParameterSpec)) { throw new InvalidAlgorithmParameterException("Expected params to either be an instance of ECGenParameterSpec or PK11ParameterSpec!"); } } // future add support for X509EncodedSpec this.params = params; } /** * Generates a key pair on a token. Uses parameters if they were passed * in through a call to initialize, otherwise uses defaults. * @return * @throws TokenException */ public KeyPair generateKeyPair() throws TokenException { if(algorithm == KeyPairAlgorithm.RSA) { if(params != null) { RSAKeyGenParameterSpec rsaparams = (RSAKeyGenParameterSpec)params; if (rsaparams.getKeysize() < Policy.RSA_MINIMUM_KEY_SIZE) { String msg = "unsafe RSA key size of "; msg += rsaparams.getKeysize() + ". Policy.RSA_MINIMUM_KEY_SIZE "; msg += "dictates a minimum of " + Policy.RSA_MINIMUM_KEY_SIZE; if (Policy.ENFORCING_KEY_SIZES) { throw new TokenException("Disallowing " + msg); } else { logger.warn("Ignored jss.crypto.Policy violation: " + msg); } } if (rsaparams.getPublicExponent().longValue() < Policy.RSA_MINIMUM_PUBLIC_EXPONENT.longValue()) { String msg = "unsafe RSA exponent of "; msg += rsaparams.getPublicExponent().longValue() + ". "; msg += "Policy.RSA_MINIMUM_PUBLIC_EXPONENT dictates a minimum of "; msg += Policy.RSA_MINIMUM_PUBLIC_EXPONENT.longValue(); if (Policy.ENFORCING_KEY_SIZES) { throw new TokenException("Disallowing " + msg); } else { logger.warn("Ignored jss.crypto.Policy violation: " + msg); } } return generateRSAKeyPairWithOpFlags( token, rsaparams.getKeysize(), rsaparams.getPublicExponent().longValue(), temporaryPairMode, sensitivePairMode, extractablePairMode, opFlags, opFlagsMask); } else { return generateRSAKeyPairWithOpFlags( token, DEFAULT_RSA_KEY_SIZE, DEFAULT_RSA_PUBLIC_EXPONENT.longValue(), temporaryPairMode, sensitivePairMode, extractablePairMode, opFlags, opFlagsMask); } } else if(algorithm == KeyPairAlgorithm.DSA ) { if(params==null) { params = PQG1024; } DSAParameterSpec dsaParams = (DSAParameterSpec)params; return generateDSAKeyPairWithOpFlags( token, PQGParams.BigIntegerToUnsignedByteArray(dsaParams.getP()), PQGParams.BigIntegerToUnsignedByteArray(dsaParams.getQ()), PQGParams.BigIntegerToUnsignedByteArray(dsaParams.getG()), temporaryPairMode, sensitivePairMode, extractablePairMode, opFlags, opFlagsMask); } else { assert( algorithm == KeyPairAlgorithm.EC ); // requires JAVA 1.5 for ECParameters. // //AlgorithmParameters ecParams = // AlgorithmParameters.getInstance("ECParameters"); // ecParams.init(params); PK11ParameterSpec ecParams = (PK11ParameterSpec) params; return generateECKeyPairWithOpFlags( token, ecParams.getEncoded(), /* curve */ temporaryPairMode, sensitivePairMode, extractablePairMode, opFlags, opFlagsMask); } } /** * @return true if the keypair generation will be done on the * internal token and then moved to this token. */ public boolean keygenOnInternalToken() { return mKeygenOnInternalToken; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Native Implementation Methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Generates an RSA key pair with the given size and public exponent. */ private native KeyPair generateRSAKeyPair(PK11Token token, int keySize, long publicExponent, boolean temporary, int sensitive, int extractable) throws TokenException; /** * Generates an RSA key pair with the given size and public exponent. * Adds the ability to specify a set of flags and masks * to control how NSS generates the key pair. */ private native KeyPair generateRSAKeyPairWithOpFlags(PK11Token token, int keySize, long publicExponent, boolean temporary, int sensitive, int extractable, int op_flags, int op_flags_mask) throws TokenException; /** * Generates a DSA key pair with the given P, Q, and G values. * P, Q, and G are stored as big-endian twos-complement octet strings. */ private native KeyPair generateDSAKeyPair(PK11Token token, byte[] P, byte[] Q, byte[] G, boolean temporary, int sensitive, int extractable) throws TokenException; /** * Generates a DSA key pair with the given P, Q, and G values. * P, Q, and G are stored as big-endian twos-complement octet strings. * Adds the ability to specify a set of flags and masks * to control how NSS generates the key pair. */ private native KeyPair generateDSAKeyPairWithOpFlags(PK11Token token, byte[] P, byte[] Q, byte[] G, boolean temporary, int sensitive, int extractable, int op_flags, int op_flags_mask) throws TokenException; /** * Generates a EC key pair with the given a curve. * Curves are stored as DER Encoded Parameters. */ private native KeyPair generateECKeyPair(PK11Token token, byte[] Curve, boolean temporary, int sensitive, int extractable) throws TokenException; /** * Generates a EC key pair with the given a curve. * Curves are stored as DER Encoded Parameters. * Adds the ability to specify a set of flags and masks * to control how NSS generates the key pair. */ private native KeyPair generateECKeyPairWithOpFlags(PK11Token token, byte[] Curve, boolean temporary, int sensitive, int extractable, int op_flags, int op_flags_mask) throws TokenException; /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Defaults /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private static final int DEFAULT_RSA_KEY_SIZE = 2048; private static final BigInteger DEFAULT_RSA_PUBLIC_EXPONENT = BigInteger.valueOf(65537); ////////////////////////////////////////////////////////////////////// // 1024-bit PQG parameters // These were generated and verified using the // org.mozilla.jss.crypto.PQGParams class. ////////////////////////////////////////////////////////////////////// private static final String p1024= "135839652435190934085800139191680301864221874900900696919010316554114342871389066526982023513828891845682496590926522957486592076092819515303251959435284578074745022943475516750500021440278782993316814165831392449756706958779266394680687474113495272524355075654433600922751920548192539119568200162784715902571"; private static final String q1024= "1289225024022202541601051225376429063716419728261"; private static final String g1024= "9365079229044517973775853147905914670746128595481021901304748201231245287028018351117994470223961367498481071639148009750748608477086914440940765659773400233006204556380834403997210445996745757996115285802608489502160956380238739417382954486304730446079375880915926936667959108637040861595671319957190194969"; private static final String h1024= "52442921523337940900621893014039829709890959980326720828933601226740749524581606283131306291278616835323956710592993182613544059214633911716533418368425327413628234095671352084418677611348898811691107611640282098605730539089258655659910952545940615065321018163879856499128636989240131903260975031351698627473"; private static final String seed1024= "99294487279227522120410987308721952265545668206337642687581596155167227884587528576179879564731162765515189527566190299324927751299864501359105446993895763527646668003992063667962831489586752303126546478655915858883436326503676798267446073013163508014466163441488290854738816489359449082537210762470653355837"; private static final int counter1024 = 159; /** * Pre-cooked PQG values for 1024-bit keypairs, along with the seed, * counter, and H values needed to verify them. */ public static final PQGParams PQG1024 = new PQGParams( new BigInteger(p1024), new BigInteger(q1024), new BigInteger(g1024), new BigInteger(seed1024), counter1024, new BigInteger(h1024)); ////////////////////////////////////////////////////////////////////// // 768-bit PQG parameters // These were generated and verified using the // org.mozilla.jss.crypto.PQGParams class. ////////////////////////////////////////////////////////////////////// private static final String p768 = "1334591549939035619289567230283054603122655003980178118026955029363553392594293499178687789871628588392413078786977899109276604404053531960657701920766542891720144660923735290663050045086516783083489369477138289683344192203747015183"; private static final String q768 = "1356132865877303155992130272917916166541739006871"; private static final String g768 = "1024617924160404238802957719732914916383807485923819254303813897112921288261546213295904612554364830820266594592843780972915270096284099079324418834215265083315386166747220804977600828688227714319518802565604893756612386174125343163"; private static final String seed768 = "818335465751997015393064637168438154352349887221925302425470688493624428407506863871577128315308555744979456856342994235252156194662586703244255741598129996211081771019031721876068721218509213355334043303099174315838637885951947797"; private static final int counter768 = 80; private static final String h768 = "640382699969409389484886950168366372251172224987648937408021020040753785108834000620831523080773231719549705102680417704245010958792653770817759388668805215557594892534053348624875390588773257372677159854630106242075665177245698591"; /** * Pre-cooked PQG values for 768-bit keypairs, along with the seed, * counter, and H values needed to verify them. */ public static final PQGParams PQG768 = new PQGParams( new BigInteger(p768), new BigInteger(q768), new BigInteger(g768), new BigInteger(seed768), counter768, new BigInteger(h768)); ////////////////////////////////////////////////////////////////////// // 512-bit PQG parameters // These were generated and verified using the // org.mozilla.jss.crypto.PQGParams class. ////////////////////////////////////////////////////////////////////// private static final String p512 = "6966483207285155416780416172202915863379050665227482416115451434656043093992853756903066653962454938528584622842487778598918381346739078775480034378802841"; private static final String q512 = "1310301134281640075932276656367326462518739803527"; private static final String g512 = "1765808308320938820731237312304158486199455718816858489736043318496656574508696475222741642343469219895005992985361010111736160340009944528784078083324884"; private static final String h512 = "1166033533097555931825481846268490827226947692615252570752313574243187654088977281409544725210974913958636100321681636002587474728477655589742540645702652"; private static final String seed512 = "1823071686803672528716836609217295942310764795778335243232708299998660956064222751939859670873282519585591423918449571513004815205037154878988595168291600"; private static final int counter512 = 186; /** * Pre-cooked PQG values for 512-bit keypairs, along with the seed, * counter, and H values needed to verify them. */ public static final PQGParams PQG512 = new PQGParams( new BigInteger(p512), new BigInteger(q512), new BigInteger(g512), new BigInteger(seed512), counter512, new BigInteger(h512)); /////////////////////////////////////////////////////////////////////// // Test the PQG parameters /////////////////////////////////////////////////////////////////////// private static boolean defaultsTested = false; private static synchronized void testDefaults() { if(!defaultsTested) { assert(PQG1024.paramsAreValid()); assert(PQG768.paramsAreValid()); assert(PQG512.paramsAreValid()); defaultsTested = true; } } public void temporaryPairs(boolean temp) { temporaryPairMode = temp; } public void sensitivePairs(boolean sensitive) { sensitivePairMode = sensitive ? 1 : 0; } public void extractablePairs(boolean extractable) { extractablePairMode = extractable ? 1 : 0; } /** * Sets the requested key usages desired for the * generated key pair. * This allows the caller to suggest how NSS generates the key pair. * @param usages List of desired key usages. * @param usages_mask Corresponding mask for the key usages. * if a usages is desired, make sure it is in the mask as well. */ public void setKeyPairUsages(org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usages, org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usages_mask) { this.opFlags = 0; this.opFlagsMask = 0; if(usages != null) { for( int i = 0; i < usages.length; i++ ) { if( usages[i] != null ) { this.opFlags |= opFlagForUsage[usages[i].getVal()]; } } } if(usages_mask != null) { for( int i = 0; i < usages_mask.length; i++ ) { if( usages_mask[i] != null ) { this.opFlagsMask |= opFlagForUsage[usages_mask[i].getVal()]; } } } } // // requires JAVA 1.5 // //private AlgorithmParameterSpec getCurve(int strength) { //} private static final OBJECT_IDENTIFIER ANSI_X962_PRIME_CURVE = new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10045, 3, 1 } ); private static final OBJECT_IDENTIFIER ANSI_X962_BINARY_CURVE = new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10045, 3, 0 } ); private static final OBJECT_IDENTIFIER SECG_EC_CURVE = new OBJECT_IDENTIFIER( new long[] { 1, 3, 132, 0 } ); // ANSI Prime curves static final OBJECT_IDENTIFIER CURVE_ANSI_P192V1 = ANSI_X962_PRIME_CURVE.subBranch(1); static final OBJECT_IDENTIFIER CURVE_ANSI_P192V2 = ANSI_X962_PRIME_CURVE.subBranch(2); static final OBJECT_IDENTIFIER CURVE_ANSI_P192V3 = ANSI_X962_PRIME_CURVE.subBranch(3); static final OBJECT_IDENTIFIER CURVE_ANSI_P239V1 = ANSI_X962_PRIME_CURVE.subBranch(4); static final OBJECT_IDENTIFIER CURVE_ANSI_P239V2 = ANSI_X962_PRIME_CURVE.subBranch(5); static final OBJECT_IDENTIFIER CURVE_ANSI_P239V3 = ANSI_X962_PRIME_CURVE.subBranch(6); static final OBJECT_IDENTIFIER CURVE_ANSI_P256V1 = ANSI_X962_PRIME_CURVE.subBranch(7); // ANSI Binary curves static final OBJECT_IDENTIFIER CURVE_ANSI_PNB163V1 =ANSI_X962_BINARY_CURVE.subBranch(1); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB163V2 =ANSI_X962_BINARY_CURVE.subBranch(2); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB163V3 =ANSI_X962_BINARY_CURVE.subBranch(3); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB176V1 =ANSI_X962_BINARY_CURVE.subBranch(4); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB191V1 =ANSI_X962_BINARY_CURVE.subBranch(5); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB191V2 =ANSI_X962_BINARY_CURVE.subBranch(6); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB191V3 =ANSI_X962_BINARY_CURVE.subBranch(7); static final OBJECT_IDENTIFIER CURVE_ANSI_ONB191V4 =ANSI_X962_BINARY_CURVE.subBranch(8); static final OBJECT_IDENTIFIER CURVE_ANSI_ONB191V5 =ANSI_X962_BINARY_CURVE.subBranch(9); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB208W1 =ANSI_X962_BINARY_CURVE.subBranch(10); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB239V1 =ANSI_X962_BINARY_CURVE.subBranch(11); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB239V2 =ANSI_X962_BINARY_CURVE.subBranch(12); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB239V3 =ANSI_X962_BINARY_CURVE.subBranch(13); static final OBJECT_IDENTIFIER CURVE_ANSI_ONB239V4 =ANSI_X962_BINARY_CURVE.subBranch(14); static final OBJECT_IDENTIFIER CURVE_ANSI_ONB239V5 =ANSI_X962_BINARY_CURVE.subBranch(15); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB272W1 =ANSI_X962_BINARY_CURVE.subBranch(16); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB304W1 =ANSI_X962_BINARY_CURVE.subBranch(17); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB359V1 =ANSI_X962_BINARY_CURVE.subBranch(18); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB368W1 =ANSI_X962_BINARY_CURVE.subBranch(19); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB431R1 =ANSI_X962_BINARY_CURVE.subBranch(20); // SEG Prime curves static final OBJECT_IDENTIFIER CURVE_SECG_P112R1 = SECG_EC_CURVE.subBranch(6); static final OBJECT_IDENTIFIER CURVE_SECG_P112R2 = SECG_EC_CURVE.subBranch(7); static final OBJECT_IDENTIFIER CURVE_SECG_P128R1 = SECG_EC_CURVE.subBranch(28); static final OBJECT_IDENTIFIER CURVE_SECG_P128R2 = SECG_EC_CURVE.subBranch(29); static final OBJECT_IDENTIFIER CURVE_SECG_P160K1 = SECG_EC_CURVE.subBranch(9); static final OBJECT_IDENTIFIER CURVE_SECG_P160R1 = SECG_EC_CURVE.subBranch(8); static final OBJECT_IDENTIFIER CURVE_SECG_P160R2 = SECG_EC_CURVE.subBranch(30); static final OBJECT_IDENTIFIER CURVE_SECG_P192K1 = SECG_EC_CURVE.subBranch(31); static final OBJECT_IDENTIFIER CURVE_SECG_P224K1 = SECG_EC_CURVE.subBranch(32); static final OBJECT_IDENTIFIER CURVE_SECG_P224R1 = SECG_EC_CURVE.subBranch(33); static final OBJECT_IDENTIFIER CURVE_SECG_P256K1 = SECG_EC_CURVE.subBranch(10); static final OBJECT_IDENTIFIER CURVE_SECG_P384R1 = SECG_EC_CURVE.subBranch(34); static final OBJECT_IDENTIFIER CURVE_SECG_P521R1 = SECG_EC_CURVE.subBranch(35); // SEG Binary curves static final OBJECT_IDENTIFIER CURVE_SECG_T113R1 = SECG_EC_CURVE.subBranch(4); static final OBJECT_IDENTIFIER CURVE_SECG_T113R2 = SECG_EC_CURVE.subBranch(5); static final OBJECT_IDENTIFIER CURVE_SECG_T131R1 = SECG_EC_CURVE.subBranch(22); static final OBJECT_IDENTIFIER CURVE_SECG_T131R2 = SECG_EC_CURVE.subBranch(23); static final OBJECT_IDENTIFIER CURVE_SECG_T163K1 = SECG_EC_CURVE.subBranch(1); static final OBJECT_IDENTIFIER CURVE_SECG_T163R1 = SECG_EC_CURVE.subBranch(2); static final OBJECT_IDENTIFIER CURVE_SECG_T163R2 = SECG_EC_CURVE.subBranch(15); static final OBJECT_IDENTIFIER CURVE_SECG_T193R1 = SECG_EC_CURVE.subBranch(24); static final OBJECT_IDENTIFIER CURVE_SECG_T193R2 = SECG_EC_CURVE.subBranch(25); static final OBJECT_IDENTIFIER CURVE_SECG_T233K1 = SECG_EC_CURVE.subBranch(26); static final OBJECT_IDENTIFIER CURVE_SECG_T233R1 = SECG_EC_CURVE.subBranch(27); static final OBJECT_IDENTIFIER CURVE_SECG_T239K1 = SECG_EC_CURVE.subBranch(3); static final OBJECT_IDENTIFIER CURVE_SECG_T283K1 = SECG_EC_CURVE.subBranch(16); static final OBJECT_IDENTIFIER CURVE_SECG_T283R1 = SECG_EC_CURVE.subBranch(17); static final OBJECT_IDENTIFIER CURVE_SECG_T409K1 = SECG_EC_CURVE.subBranch(36); static final OBJECT_IDENTIFIER CURVE_SECG_T409R1 = SECG_EC_CURVE.subBranch(37); static final OBJECT_IDENTIFIER CURVE_SECG_T571K1 = SECG_EC_CURVE.subBranch(38); static final OBJECT_IDENTIFIER CURVE_SECG_T571R1 = SECG_EC_CURVE.subBranch(39); // the EC curvecode to oid hash table private static Hashtable mECCurve_CodeToCurve = new Hashtable<>(); static { // SEG Prime curves mECCurve_CodeToCurve.put( ECCurve_Code.secp521r1.ordinal(), CURVE_SECG_P521R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistp521.ordinal(), CURVE_SECG_P521R1); mECCurve_CodeToCurve.put( ECCurve_Code.secp384r1.ordinal(), CURVE_SECG_P384R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistp384.ordinal(), CURVE_SECG_P384R1); mECCurve_CodeToCurve.put( ECCurve_Code.secp256r1.ordinal(), CURVE_ANSI_P256V1); mECCurve_CodeToCurve.put( ECCurve_Code.nistp256.ordinal(), CURVE_ANSI_P256V1); mECCurve_CodeToCurve.put( ECCurve_Code.secp256k1.ordinal(), CURVE_SECG_P256K1); mECCurve_CodeToCurve.put( ECCurve_Code.secp224r1.ordinal(), CURVE_SECG_P224R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistp224.ordinal(), CURVE_SECG_P224R1); mECCurve_CodeToCurve.put( ECCurve_Code.secp224k1.ordinal(), CURVE_SECG_P224K1); mECCurve_CodeToCurve.put( ECCurve_Code.secp192r1.ordinal(), CURVE_ANSI_P192V1); mECCurve_CodeToCurve.put( ECCurve_Code.nistp192.ordinal(), CURVE_ANSI_P192V1); mECCurve_CodeToCurve.put( ECCurve_Code.secp192k1.ordinal(), CURVE_SECG_P192K1); mECCurve_CodeToCurve.put( ECCurve_Code.secp160r2.ordinal(), CURVE_SECG_P160R2); mECCurve_CodeToCurve.put( ECCurve_Code.secp160r1.ordinal(), CURVE_SECG_P160R1); mECCurve_CodeToCurve.put( ECCurve_Code.secp160k1.ordinal(), CURVE_SECG_P160K1); mECCurve_CodeToCurve.put( ECCurve_Code.secp128r2.ordinal(), CURVE_SECG_P128R2); mECCurve_CodeToCurve.put( ECCurve_Code.secp128r1.ordinal(), CURVE_SECG_P128R1); mECCurve_CodeToCurve.put( ECCurve_Code.secp112r2.ordinal(), CURVE_SECG_P112R2); mECCurve_CodeToCurve.put( ECCurve_Code.secp112r1.ordinal(), CURVE_SECG_P112R1); // SEG Binary curves mECCurve_CodeToCurve.put( ECCurve_Code.sect571r1.ordinal(), CURVE_SECG_T571R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistb571.ordinal(), CURVE_SECG_T571R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect571k1.ordinal(), CURVE_SECG_T571K1); mECCurve_CodeToCurve.put( ECCurve_Code.nistk571.ordinal(), CURVE_SECG_T571K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect409r1.ordinal(), CURVE_SECG_T409R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistb409.ordinal(), CURVE_SECG_T409R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect409k1.ordinal(), CURVE_SECG_T409K1); mECCurve_CodeToCurve.put( ECCurve_Code.nistk409.ordinal(), CURVE_SECG_T409K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect283r1.ordinal(), CURVE_SECG_T283R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistb283.ordinal(), CURVE_SECG_T283R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect283k1.ordinal(), CURVE_SECG_T283K1); mECCurve_CodeToCurve.put( ECCurve_Code.nistk283.ordinal(), CURVE_SECG_T283K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect239k1.ordinal(), CURVE_SECG_T239K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect233r1.ordinal(), CURVE_SECG_T233R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistb233.ordinal(), CURVE_SECG_T233R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect233k1.ordinal(), CURVE_SECG_T233K1); mECCurve_CodeToCurve.put( ECCurve_Code.nistk233.ordinal(), CURVE_SECG_T233K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect193r2.ordinal(), CURVE_SECG_T193R2); mECCurve_CodeToCurve.put( ECCurve_Code.sect193r1.ordinal(), CURVE_SECG_T193R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistb163.ordinal(), CURVE_SECG_T163K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect163r2.ordinal(), CURVE_SECG_T163R2); mECCurve_CodeToCurve.put( ECCurve_Code.sect163r1.ordinal(), CURVE_SECG_T163R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect163k1.ordinal(), CURVE_SECG_T163K1); mECCurve_CodeToCurve.put( ECCurve_Code.nistk163.ordinal(), CURVE_SECG_T163K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect131r2.ordinal(), CURVE_SECG_T131R2); mECCurve_CodeToCurve.put( ECCurve_Code.sect131r1.ordinal(), CURVE_SECG_T131R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect113r2.ordinal(), CURVE_SECG_T113R2); mECCurve_CodeToCurve.put( ECCurve_Code.sect113r1.ordinal(), CURVE_SECG_T113R1); // ANSI Prime curves mECCurve_CodeToCurve.put( ECCurve_Code.prime239v3.ordinal(), CURVE_ANSI_P239V3); mECCurve_CodeToCurve.put( ECCurve_Code.prime239v2.ordinal(), CURVE_ANSI_P239V2); mECCurve_CodeToCurve.put( ECCurve_Code.prime239v1.ordinal(), CURVE_ANSI_P239V1); mECCurve_CodeToCurve.put( ECCurve_Code.prime192v3.ordinal(), CURVE_ANSI_P192V3); mECCurve_CodeToCurve.put( ECCurve_Code.prime192v2.ordinal(), CURVE_ANSI_P192V2); mECCurve_CodeToCurve.put( ECCurve_Code.prime192v1.ordinal(), CURVE_ANSI_P192V1); // ANSI Binary curves mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb163v1.ordinal(), CURVE_ANSI_PNB163V1); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb163v2.ordinal(), CURVE_ANSI_PNB163V2); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb163v3.ordinal(), CURVE_ANSI_PNB163V3); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb176v1.ordinal(), CURVE_ANSI_PNB176V1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb191v1.ordinal(), CURVE_ANSI_TNB191V1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb191v2.ordinal(), CURVE_ANSI_TNB191V2); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb191v3.ordinal(), CURVE_ANSI_TNB191V3); //mECCurve_CodeToCurve.put( // ECCurve_Code.c2onb191v4.ordinal(), (Object) CURVE_ANSI_ONB191V4); //mECCurve_CodeToCurve.put( // ECCurve_Code.c2onb191v5.ordinal(), (Object) CURVE_ANSI_ONB191V5); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb208w1.ordinal(), CURVE_ANSI_PNB208W1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb239v1.ordinal(), CURVE_ANSI_TNB239V1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb239v2.ordinal(), CURVE_ANSI_TNB239V2); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb239v3.ordinal(), CURVE_ANSI_TNB239V3); //mECCurve_CodeToCurve.put( // ECCurve_Code.c2onb239v4.ordinal(), (Object) CURVE_ANSI_ONB239V4); //mECCurve_CodeToCurve.put( // ECCurve_Code.c2onb239v5.ordinal(), (Object) CURVE_ANSI_ONB239V5); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb272w1.ordinal(), CURVE_ANSI_PNB272W1); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb304w1.ordinal(), CURVE_ANSI_PNB304W1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb359v1.ordinal(), CURVE_ANSI_TNB359V1); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb368w1.ordinal(), CURVE_ANSI_PNB368W1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb431r1.ordinal(), CURVE_ANSI_TNB431R1); } public int getCurveCodeByName(String curveName) throws InvalidParameterException { if (curveName == null) throw new InvalidParameterException(); ECCurve_Code c = ECCurve_NameToCode.get(curveName); if (c == null) throw new InvalidParameterException(curveName); return c.ordinal(); } /* * getECCurve * maps curvecode to the actual oid of the curve and * returns the PK11ParameterSpec */ private AlgorithmParameterSpec getECCurve(int curvecode) throws InvalidParameterException { OBJECT_IDENTIFIER oid; oid = mECCurve_CodeToCurve.get(curvecode); if (oid == null) throw new IllegalArgumentException("curvecode ="+curvecode); return new PK11ParameterSpec(ASN1Util.encode(oid)); } private AlgorithmParameterSpec getCurve(int strength) throws InvalidParameterException { OBJECT_IDENTIFIER oid; switch (strength) { case 112: oid = CURVE_SECG_P112R1; // == WTLS-6 // Can't get to curve SECG P-112R2 // Can't get to curve WTLS-8 (No oid for WTLS-8) break; case 113: oid = CURVE_SECG_T113R1; // == WTLS-4 // Can't get to curve SECG T-113R2 // Can't get to curve WTLS-1 (No oid for WTLS-1) break; case 128: oid = CURVE_SECG_P128R1; // Can't get to curve SECG P-128R2 break; case 131: oid = CURVE_SECG_T131R1; // Can't get to curve SECG T-131R2 break; case 160: oid = CURVE_SECG_P160R1; // == WTLS-7 (TLS-16) // Can't get to curve SECG P-160K1 (TLS-15) // Can't get to curve SECG P-160R2 (TLS-17) // Can't get to curve WTLS-9 (No oid for WTLS-9) break; case 163: oid = CURVE_SECG_T163K1; // == NIST K-163 == WTLS-3 (TLS-1) // Can't get to curve ANSI C2-PNB163V1 == WTLS-5 // Can't get to curve ANSI C2-PNB163V2 // Can't get to curve ANSI C2-PNB163V3 // Can't get to curve SECG T-163R1 (TLS-2) // Can't get to curve SECG T-163R2 == NIST B-163 (TLS-3) break; case 176: oid = CURVE_ANSI_PNB176V1; break; case 191: oid = CURVE_ANSI_TNB191V1; // Can't get to curve ANSI C2-TNB191V2 // Can't get to curve ANSI C2-TNB191V3 // Can't get to curve ANSI C2-ONB191V4 // Can't get to curve ANSI C2-ONB191V5 break; case 192: oid = CURVE_ANSI_P192V1; // == NIST P-192 == SECG P-192R1 (TLS-19) // Can't get to curve ANSI P-192V2 // Can't get to curve ANSI P-192V3 // Can't get to curve SECG P-192K1 (TLS-18) break; case 193: oid = CURVE_SECG_T193R1; // (TLS-4) // Can't get to curve SECG T-193R2 // (TLS-5) break; case 208: oid = CURVE_ANSI_PNB208W1; break; case 224: oid = CURVE_SECG_P224R1; // == NIST P-224 == WTLS-12 (TLS-21) // Can't get to curve SECG P-224K1 (TLS-20) break; case 233: oid = CURVE_SECG_T233R1; // == NIST B-233 == WTLS-11 (TLS-7) // Can't get to curve SECG T-233K1 == NIST K-233 == WTLS-10 (TLS-6) break; case 239: oid = CURVE_SECG_T239K1; // (TLS8) // Can't get to curve ANSI P-239V1 // Can't get to curve ANSI P-239V2 // Can't get to curve ANSI P-239V3 // Can't get to curve ANSI C2-TNB239V1 // Can't get to curve ANSI C2-TNB239V2 // Can't get to curve ANSI C2-TNB239V3 // Can't get to curve ANSI C2-ONB239V4 // Can't get to curve ANSI C2-ONB239V5 break; case 256: oid = CURVE_ANSI_P256V1; // == NIST P-256 == SECG P-256R1 (TLS-23) // Can't get to curve SECG P-256K1 (TLS-22) break; case 272: oid = CURVE_ANSI_PNB272W1; break; case 283: oid = CURVE_SECG_T283R1; // == NIST B-283 (TLS-10) // Can't get to curve SECG T-283K1 == NIST K-283 (TLS-9) break; case 304: oid = CURVE_ANSI_PNB304W1; break; case 359: oid = CURVE_ANSI_TNB359V1; break; case 368: oid = CURVE_ANSI_PNB368W1; break; case 384: oid = CURVE_SECG_P384R1; // == NIST P-384 (TLS-24) break; case 409: oid = CURVE_SECG_T409R1; // == NIST B-409 (TLS-12) // Can't get to curve SECG T-409K1 == NIST K-409 (TLS-11) break; case 431: oid = CURVE_ANSI_TNB431R1; break; case 521: oid = CURVE_SECG_P521R1; // == NIST P-521 (TLS-25) break; case 571: oid = CURVE_SECG_T571R1; // == NIST B-571 (TLS-14) // Can't get to curve SECG T-571K1 == NIST K-571 (TLS-13) break; default: throw new InvalidParameterException(); } return new PK11ParameterSpec(ASN1Util.encode(oid)); } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Private members /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private PK11Token token; private AlgorithmParameterSpec params; private KeyPairAlgorithm algorithm; private boolean mKeygenOnInternalToken; private boolean temporaryPairMode = false; // 1: sensitive // 0: insensitive // -1: sensitive if temporaryPairMode is false, // insensitive if temporaryPairMode is true // (the default depends on temporaryPairMode for backward // compatibility) private int sensitivePairMode = -1; // 1: extractable // 0: unextractable // -1: unspecified (token dependent) private int extractablePairMode = -1; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11KeyWrapper.c000066400000000000000000000635301362106420000213150ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11KeyWrapper.h" #include #include #include #include #include #include /* JSS includes */ #include #include #include #include #include #define MAX_PRIVATE_KEY_LEN MAX_RSA_MODULUS_LEN /* * This is bytes, not bits. A 2048-bit wrapped RSA private key takes up around * 1200 bytes, because lots of "helper" values are stored along with the * modulus and exponent. 4096 bytes will hold at least a 4096-bit RSA key. */ #define MAX_WRAPPED_KEY_LEN 4096 /*********************************************************************** * * PK11KeyWrapper.nativeWrapSymWithSym */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapSymWithSym (JNIEnv *env, jobject this, jobject tokenObj, jobject toBeWrappedObj, jobject wrappingKeyObj, jobject algObj, jbyteArray ivBA) { PK11SymKey *wrapping = NULL; PK11SymKey *toBeWrapped = NULL; CK_MECHANISM_TYPE mech; SECItem wrapped; jbyteArray wrappedBA=NULL; SECItem *iv=NULL, *param=NULL; SECStatus status; /* initialize so we can goto finish */ wrapped.data = NULL; wrapped.len = 0; /* get wrapping key */ if( JSS_PK11_getSymKeyPtr(env, wrappingKeyObj, &wrapping)!= PR_SUCCESS) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract symmetric " "wrapping key"); return NULL; } /* get toBeWrapped key */ if( JSS_PK11_getSymKeyPtr(env, toBeWrappedObj, &toBeWrapped) != PR_SUCCESS){ JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract symmetric " "to be wrapped key"); return NULL; } /* get the mechanism */ mech = JSS_getPK11MechFromAlg(env, algObj); if(mech == CKM_INVALID_MECHANISM) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized algorithm"); goto finish; } /* get the parameter */ if( ivBA ) { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { goto finish; /* exception was thrown */ } param = PK11_ParamFromIV(mech, iv); if( param == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to create mechanism" " parameter from initialization vector"); goto finish; } } /* setup space for wrapped key */ wrapped.len = MAX_WRAPPED_KEY_LEN; /* yuk! */ wrapped.data = PR_Malloc(wrapped.len); if(wrapped.data == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* perform the wrap */ status = PK11_WrapSymKey(mech, param, wrapping, toBeWrapped, &wrapped); if( status != SECSuccess ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Wrap operation failed on token"); goto finish; } /* package the wrapped data into a byte array */ wrappedBA = JSS_SECItemToByteArray(env, &wrapped); finish: if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*freeit*/); } if(param) { SECITEM_FreeItem(param, PR_TRUE /*freeit*/); } SECITEM_FreeItem(&wrapped, PR_FALSE /*freeit*/); return wrappedBA; } /*********************************************************************** * * PK11KeyWrapper.nativeWrapSymWithPub */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapSymWithPub (JNIEnv *env, jobject this, jobject tokenObj, jobject toBeWrappedObj, jobject wrappingKeyObj, jobject algObj, jbyteArray ivBA) { SECKEYPublicKey *wrapping = NULL; PK11SymKey *toBeWrapped = NULL; CK_MECHANISM_TYPE mech; SECItem wrapped; jbyteArray wrappedBA=NULL; SECStatus status; /* initialize so we can goto finish */ wrapped.data = NULL; wrapped.len = 0; /* get wrapping key */ if( JSS_PK11_getPubKeyPtr(env, wrappingKeyObj, &wrapping)!= PR_SUCCESS) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract public " "wrapping key"); return NULL; } /* get toBeWrapped key */ if( JSS_PK11_getSymKeyPtr(env, toBeWrappedObj, &toBeWrapped) != PR_SUCCESS){ JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract symmetric " "to be wrapped key"); return NULL; } /* get the mechanism */ mech = JSS_getPK11MechFromAlg(env, algObj); if(mech == CKM_INVALID_MECHANISM) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized algorithm"); goto finish; } /* setup space for wrapped key */ wrapped.len = MAX_WRAPPED_KEY_LEN; /* yuk! */ wrapped.data = PR_Malloc(wrapped.len); if(wrapped.data == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* perform the wrap */ status = PK11_PubWrapSymKey(mech, wrapping, toBeWrapped, &wrapped); if( status != SECSuccess ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Wrap operation failed on token"); goto finish; } /* package the wrapped data into a byte array */ wrappedBA = JSS_SECItemToByteArray(env, &wrapped); finish: SECITEM_FreeItem(&wrapped, PR_FALSE /*freeit*/); return wrappedBA; } /*********************************************************************** * * PK11KeyWrapper.nativeWrapPrivWithSym */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapPrivWithSym (JNIEnv *env, jobject this, jobject tokenObj, jobject toBeWrappedObj, jobject wrappingKeyObj, jobject algObj, jbyteArray ivBA) { PK11SymKey *wrapping = NULL; SECKEYPrivateKey *toBeWrapped= NULL; CK_MECHANISM_TYPE mech; SECStatus status; SECItem wrapped; PK11SlotInfo *slot=NULL; jbyteArray wrappedBA=NULL; SECItem *iv=NULL, *param=NULL; /* setup space for wrapped key */ wrapped.len = MAX_WRAPPED_KEY_LEN; wrapped.data = PR_Malloc(wrapped.len); if(wrapped.data == NULL) { wrapped.len = 0; JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* get wrapping key */ if( JSS_PK11_getSymKeyPtr(env, wrappingKeyObj, &wrapping) != PR_SUCCESS) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract symmetric " "wrapping key"); return NULL; } /* get toBeWrapped key */ if( JSS_PK11_getPrivKeyPtr(env, toBeWrappedObj, &toBeWrapped) !=PR_SUCCESS){ JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract private " "to be wrapped key"); return NULL; } /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* Get the wrapping mechanism */ mech = getSupportedWrappingMechanism(env, algObj, slot); if(mech == CKM_INVALID_MECHANISM) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized algorithm"); goto finish; } /* get the mechanism parameter (IV) */ if( ivBA ) { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { goto finish; /* exception was thrown */ } param = PK11_ParamFromIV(mech, iv); if( param == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to convert initialization vector to parameter"); goto finish; } } /* perform the wrap operation */ status = PK11_WrapPrivKey(slot, wrapping, toBeWrapped, mech, param, &wrapped, NULL /* wincx */ ); if(status != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Wrapping operation failed on token"); goto finish; } PR_ASSERT(wrapped.len>0 && wrapped.data!=NULL); /* package the wrapped data into a byte array */ wrappedBA = JSS_SECItemToByteArray(env, &wrapped); /* fall through if an exception occurs */ finish: if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*freeit*/); } if(param) { SECITEM_FreeItem(param, PR_TRUE /*freeit*/); } SECITEM_FreeItem(&wrapped, PR_FALSE /*freeit*/); return wrappedBA; } /*********************************************************************** * * PK11KeyWrapper.nativeUnwrapPrivWithSym */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapPrivWithSym (JNIEnv *env, jclass clazz, jobject tokenObj, jobject unwrapperObj, jbyteArray wrappedBA, jobject wrapAlgObj, jobject typeAlgObj, jbyteArray publicValueBA, jbyteArray ivBA, jboolean temporary) { PK11SlotInfo *slot; PK11SymKey *unwrappingKey; SECKEYPrivateKey *privk=NULL; jobject privkObj=NULL; CK_MECHANISM_TYPE wrapType, keyTypeMech; CK_KEY_TYPE keyType; SECItem *wrapped=NULL, *iv=NULL, *param=NULL, *pubValue=NULL; SECItem label; /* empty secitem, doesn't need to be freed */ PRBool token; CK_ATTRIBUTE_TYPE attribs[4] = {0, 0, 0, 0}; int numAttribs = 0; CK_TOKEN_INFO tokenInfo; /* ideal defaults */ PRBool isSensitive = PR_TRUE; PRBool isExtractable = PR_FALSE; /* special case nethsm and lunasa*/ const int numManufacturerIDchars = 7; CK_UTF8CHAR nethsmManufacturerID[] = {'n','C','i','p','h','e','r'}; CK_UTF8CHAR lunasaManufacturerID[] = {'S','a','f','e','n','e','t'}; PRBool isNethsm = PR_TRUE; PRBool isLunasa = PR_TRUE; tokenInfo.manufacturerID[0] = 0; if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { /* exception was thrown */ goto finish; } if ( (PK11_GetTokenInfo(slot, &tokenInfo) == SECSuccess) && (tokenInfo.manufacturerID[0] != 0)) { int ix = 0; for(ix=0; ix < numManufacturerIDchars; ix++) { if (tokenInfo.manufacturerID[ix] != nethsmManufacturerID[ix]) { isNethsm = PR_FALSE; break; } } for(ix=0; ix < numManufacturerIDchars; ix++) { if (tokenInfo.manufacturerID[ix] != lunasaManufacturerID[ix]) { isLunasa = PR_FALSE; break; } } } else { isNethsm = PR_FALSE; isLunasa = PR_FALSE; } /* get unwrapping key */ if( JSS_PK11_getSymKeyPtr(env, unwrapperObj, &unwrappingKey) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* Get the wrapping mechanism */ wrapType = getSupportedWrappingMechanism(env, wrapAlgObj, slot); if(wrapType == CKM_INVALID_MECHANISM) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unknown algorithm"); goto finish; } /* get the mechanism parameter (IV) */ if( ivBA ) { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { goto finish; /* exception was thrown */ } param = PK11_ParamFromIV(wrapType, iv); if( param == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to convert initialization vector to parameter"); goto finish; } } /* get wrapped key from byte array */ wrapped = JSS_ByteArrayToSECItem(env, wrappedBA); if( wrapped == NULL ) { /* exception was thrown */ goto finish; } /* initialize the label to be empty */ label.len = 0; label.data = NULL; /* get the public value */ pubValue = JSS_ByteArrayToSECItem(env, publicValueBA); if(pubValue == NULL ) { /* exception was thrown */ goto finish; } if( temporary ) { token = PR_FALSE; } else { token = PR_TRUE; } /* get key type */ keyTypeMech = JSS_getPK11MechFromAlg(env, typeAlgObj); if( keyTypeMech == CKM_INVALID_MECHANISM ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized key type algorithm"); goto finish; } keyType = PK11_GetKeyType(keyTypeMech, 0); /* special case nethsm and lunasa*/ if( isNethsm ) { isSensitive = PR_FALSE; isExtractable = PR_FALSE; } else if ( isLunasa) { isSensitive = PR_FALSE; isExtractable = PR_TRUE; } /* figure out which operations to enable for this key */ switch (keyType) { case CKK_RSA: numAttribs = 3; attribs[0] = CKA_SIGN; attribs[1] = CKA_SIGN_RECOVER; attribs[2] = CKA_UNWRAP; if (isExtractable) { attribs[3] = CKA_EXTRACTABLE; numAttribs = 4; } break; case CKK_EC: numAttribs = 1; attribs[0] = CKA_SIGN; if (isExtractable) { attribs[1] = CKA_EXTRACTABLE; numAttribs = 2; } break; case CKK_DSA: attribs[0] = CKA_SIGN; numAttribs = 1; break; case CKK_KEA: case CKK_DH: case CKK_X9_42_DH: attribs[0] = CKA_DERIVE; numAttribs = 1; break; default: /* unknown key type */ PR_ASSERT(PR_FALSE); attribs[0] = CKA_SIGN; numAttribs = 1; break; } /* perform the unwrap */ privk = PK11_UnwrapPrivKey(slot, unwrappingKey, wrapType, param, wrapped, &label, pubValue, token, isSensitive /*sensitive*/, keyType, attribs, numAttribs, NULL /*wincx*/); if( privk == NULL ) { char err[256] = {0}; PR_snprintf(err, 256, "Key Unwrap failed on token; keyType=%d", keyType); JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, err); goto finish; } /* stuff the privk into a Java private key object. This sets privk to * NULL */ privkObj = JSS_PK11_wrapPrivKey(env, &privk); finish: if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*free iv*/); } if(param) { SECITEM_FreeItem(param, PR_TRUE /*free param*/); } if(wrapped) { SECITEM_FreeItem(wrapped, PR_TRUE /*free wrapped*/); } if(pubValue) { SECITEM_FreeItem(pubValue, PR_TRUE /*free pubValue*/); } PR_ASSERT(privk==NULL); PR_ASSERT( privkObj!=NULL || (*env)->ExceptionOccurred(env) ); return privkObj; } #define ALL_SYMKEY_OPS (CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP) /*********************************************************************** * * PK11KeyWrapper.nativeUnwrapSymWithSym */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymWithSym (JNIEnv *env, jclass clazz, jobject tokenObj, jobject unwrapperObj, jbyteArray wrappedBA, jobject wrapAlgObj, jobject typeAlgObj, jint keyLen, jbyteArray ivBA, jint usageEnum, jboolean temporary) { PK11SymKey *symKey=NULL, *wrappingKey=NULL; CK_MECHANISM_TYPE wrappingMech, keyTypeMech; SECItem *wrappedKey=NULL, *iv=NULL, *param=NULL; jobject keyObj = NULL; CK_ULONG operation; CK_FLAGS flags; PRBool isPermanent = PR_FALSE; /* get key type */ keyTypeMech = JSS_getPK11MechFromAlg(env, typeAlgObj); if( keyTypeMech == CKM_INVALID_MECHANISM ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized key type algorithm"); goto finish; } /* get wrapping key */ if( JSS_PK11_getSymKeyPtr(env, unwrapperObj, &wrappingKey) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get wrapping mechanism */ wrappingMech = JSS_getPK11MechFromAlg(env, wrapAlgObj); if( wrappingMech == CKM_INVALID_MECHANISM ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized wrapping algorithm"); goto finish; } /* get the mechanism parameter (IV) */ if (ivBA == NULL) { param = PK11_ParamFromIV(wrappingMech,NULL); } else { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { goto finish; /* exception was thrown */ } param = PK11_ParamFromIV(wrappingMech, iv); if( param == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to convert initialization vector to parameter"); goto finish; } } /* get the wrapped key */ wrappedKey = JSS_ByteArrayToSECItem(env, wrappedBA); if( wrappedKey == NULL ) { /* exception was thrown */ goto finish; } if( usageEnum == -1 ) { operation = CKA_ENCRYPT; /* doesn't matter, flags will override */ flags = ALL_SYMKEY_OPS; } else { operation = JSS_symkeyUsage[usageEnum]; flags = 0; } if( temporary ) { isPermanent = PR_FALSE; } else { isPermanent = PR_TRUE; } if( isPermanent == PR_FALSE) { symKey = PK11_UnwrapSymKeyWithFlags(wrappingKey, wrappingMech, param, wrappedKey, keyTypeMech, operation, keyLen, flags); } else { symKey = PK11_UnwrapSymKeyWithFlagsPerm(wrappingKey, wrappingMech, param, wrappedKey, keyTypeMech, operation, keyLen, flags,isPermanent); } if( symKey == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to unwrap key"); goto finish; } /* wrap the symmetric key in a Java object. This will clear symKey */ keyObj = JSS_PK11_wrapSymKey(env, &symKey); finish: if(wrappedKey) { SECITEM_FreeItem(wrappedKey, PR_TRUE /*free wrappedKey*/); } if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*free iv*/); } if(param) { SECITEM_FreeItem(param, PR_TRUE /*free param*/); } if( symKey ) { PK11_FreeSymKey(symKey); } return keyObj; } /*********************************************************************** * * PK11KeyWrapper.nativeUnwrapSymWithPriv */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymWithPriv (JNIEnv *env, jclass clazz, jobject tokenObj, jobject unwrapperObj, jbyteArray wrappedBA, jobject wrapAlgObj, jobject typeAlgObj, jint keyLen, jbyteArray ivBA, jint usageEnum) { PK11SymKey *symKey=NULL; CK_MECHANISM_TYPE wrappingMech=0, keyTypeMech=0; SECItem *wrappedKey=NULL, *iv=NULL, *param=NULL; jobject keyObj=NULL; SECKEYPrivateKey *wrappingKey=NULL; CK_ULONG operation; /* get key type */ keyTypeMech = JSS_getPK11MechFromAlg(env, typeAlgObj); if( keyTypeMech == CKM_INVALID_MECHANISM ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized key type algorithm"); goto finish; } /* get wrapping key */ if( JSS_PK11_getPrivKeyPtr(env, unwrapperObj, &wrappingKey) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get the mechanism parameter (IV) */ if (ivBA == NULL) { param = PK11_ParamFromIV(wrappingMech, NULL); } else { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { goto finish; /* exception was thrown */ } param = PK11_ParamFromIV(wrappingMech, iv); if( param == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to convert initialization vector to parameter"); goto finish; } } /* get the wrapped key */ wrappedKey = JSS_ByteArrayToSECItem(env, wrappedBA); if( wrappedKey == NULL ) { /* exception was thrown */ goto finish; } if( usageEnum == -1 ) { /* !!!XXX If they didn't specify a usage, we'll assume decrypt because that's the most common case, and we can't specify more than one. See bug 135255. */ operation = CKA_DECRYPT; } else { operation = JSS_symkeyUsage[usageEnum]; } symKey = PK11_PubUnwrapSymKey(wrappingKey, wrappedKey, keyTypeMech, operation, keyLen); if( symKey == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to unwrap key"); goto finish; } /* Put the symmetric key into a Java object. This will clear symKey */ keyObj = JSS_PK11_wrapSymKey(env, &symKey); finish: if(wrappedKey) { SECITEM_FreeItem(wrappedKey, PR_TRUE /*free wrappedKey*/); } if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*free iv*/); } if(param) { SECITEM_FreeItem(param, PR_TRUE /*free param*/); } if( symKey ) { PK11_FreeSymKey(symKey); } return keyObj; } /*********************************************************************** * * PK11KeyWrapper.nativeUnwrapSymPlaintext */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymPlaintext (JNIEnv *env, jclass clazz, jobject tokenObj, jbyteArray wrappedBA, jobject typeAlgObj, jint usageEnum, jboolean temporary) { PK11SymKey *symKey=NULL; CK_MECHANISM_TYPE keyTypeMech; SECItem *wrappedKey=NULL; jobject keyObj = NULL; PK11SlotInfo *slot = NULL; CK_ULONG operation; CK_FLAGS flags; PRBool isPerm = PR_FALSE; /* get key type */ keyTypeMech = JSS_getPK11MechFromAlg(env, typeAlgObj); if( keyTypeMech == CKM_INVALID_MECHANISM ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized key type algorithm"); goto finish; } if( temporary ) { isPerm = PR_FALSE; } else { isPerm = PR_TRUE; } /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get the wrapped key */ wrappedKey = JSS_ByteArrayToSECItem(env, wrappedBA); if( wrappedKey == NULL ) { /* exception was thrown */ goto finish; } if( usageEnum == -1 ) { operation = CKA_ENCRYPT; flags = ALL_SYMKEY_OPS; } else { operation = JSS_symkeyUsage[usageEnum]; flags = 0; } /* pull in the key */ symKey = PK11_ImportSymKeyWithFlags(slot, keyTypeMech, PK11_OriginUnwrap, operation, wrappedKey, flags, isPerm, NULL); if( symKey == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to unwrap key"); goto finish; } /* wrap the symmetric key in a Java object. This will clear symKey */ keyObj = JSS_PK11_wrapSymKey(env, &symKey); finish: if(wrappedKey) { SECITEM_FreeItem(wrappedKey, PR_TRUE /*free wrappedKey*/); } if( symKey ) { PK11_FreeSymKey(symKey); } return keyObj; } /*********************************************************************** * * J S S _ P K 1 1 _ g e t E r r o r S t r i n g * * Returns a simple error string for a given PKCS #11 error. */ char* JSS_PK11_getErrorString(CK_RV crv) { switch(crv) { case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY"; case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID"; case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID"; case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL"; case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED"; case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR"; case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY"; case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED"; case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED"; case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED"; case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR"; case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY"; case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID"; case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE"; case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE"; case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE"; case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID"; case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID"; case CKR_OK: return "CKR_OK"; case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE"; case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED"; case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID"; case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY"; case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE"; case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT"; case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED"; case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID"; case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE"; case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"; case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN"; case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID"; case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE"; case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID"; case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE"; case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT"; default: return "PKCS #11 error"; } } /* * Get the wrapping mechanism */ CK_MECHANISM_TYPE getSupportedWrappingMechanism(JNIEnv *env, jobject algObj, PK11SlotInfo *slot) { CK_MECHANISM_TYPE mech = JSS_getPK11MechFromAlg(env, algObj); /* * Currently, NSS has different definitions for the AES KeyWrap * mechanisms from the PKCS11 standard. * Below, we first check for support of the PKCS11 standard; * If supported, we go with that, if not, we try the NSS ones */ if ( mech == CKM_AES_KEY_WRAP || mech == CKM_NSS_AES_KEY_WRAP) { if (!PK11_DoesMechanism(slot, CKM_AES_KEY_WRAP)) { mech = CKM_NSS_AES_KEY_WRAP; } else { mech = CKM_AES_KEY_WRAP; } } else if ( mech == CKM_AES_KEY_WRAP_PAD || mech == CKM_NSS_AES_KEY_WRAP_PAD) { if (!PK11_DoesMechanism(slot, CKM_AES_KEY_WRAP_PAD)) { mech = CKM_NSS_AES_KEY_WRAP_PAD; } else { mech = CKM_AES_KEY_WRAP_PAD; } } return mech; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11KeyWrapper.java000066400000000000000000000572121362106420000220140ustar00rootroot00000000000000/* 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.pkcs11; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; import javax.crypto.spec.RC2ParameterSpec; import org.mozilla.jss.crypto.Algorithm; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.HMACAlgorithm; import org.mozilla.jss.crypto.IVParameterSpec; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.KeyWrapper; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.util.Assert; final class PK11KeyWrapper implements KeyWrapper { private PK11Token token; private KeyWrapAlgorithm algorithm; private int state=UNINITIALIZED; private AlgorithmParameterSpec parameters=null; private SymmetricKey symKey=null; private PrivateKey privKey=null; private PublicKey pubKey=null; private byte[] IV=null; // states private static final int UNINITIALIZED=0; private static final int WRAP=1; private static final int UNWRAP=2; private PK11KeyWrapper() { } PK11KeyWrapper(PK11Token token, KeyWrapAlgorithm algorithm) { this.token = token; this.algorithm = algorithm; } public void initWrap(SymmetricKey wrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException { initWrap(parameters); checkWrapper(wrappingKey); this.symKey = wrappingKey; } public void initWrap(PublicKey wrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException { initWrap(parameters); checkWrapper(wrappingKey); this.pubKey = wrappingKey; } public void initWrap() throws InvalidKeyException, InvalidAlgorithmParameterException { if( algorithm != KeyWrapAlgorithm.PLAINTEXT ) { throw new InvalidKeyException(algorithm + " requires a key"); } reset(); state = WRAP; } /** * Does everything that is key-independent for initializing a wrap. */ private void initWrap(AlgorithmParameterSpec parameters) throws InvalidAlgorithmParameterException { reset(); checkParams(parameters); this.parameters = parameters; state = WRAP; } public void initUnwrap(PrivateKey unwrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException { initUnwrap(parameters); checkWrapper(unwrappingKey); this.privKey = unwrappingKey; } public void initUnwrap(SymmetricKey unwrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException { initUnwrap(parameters); checkWrapper(unwrappingKey); this.symKey = unwrappingKey; } public void initUnwrap() throws InvalidKeyException, InvalidAlgorithmParameterException { if( algorithm != KeyWrapAlgorithm.PLAINTEXT ) { throw new InvalidKeyException(algorithm + " requires a key"); } reset(); state = UNWRAP; } /** * Does the key-independent parts of initializing an unwrap. */ private void initUnwrap(AlgorithmParameterSpec parameters) throws InvalidAlgorithmParameterException { reset(); checkParams(parameters); this.parameters = parameters; state = UNWRAP; } /** * Makes sure the key is right for the algorithm. */ private void checkWrapper(PublicKey key) throws InvalidKeyException { if( key==null ) { throw new InvalidKeyException("Key is null"); } if( ! (key instanceof PK11PubKey) ) { throw new InvalidKeyException("Key is not a PKCS #11 key"); } try { KeyType type = KeyType.getKeyTypeFromAlgorithm(algorithm); if( (type == KeyType.RSA && !(key instanceof RSAPublicKey)) || // requires JAVA 1.5 // (type == KeyType.EC && !(key instanceof ECPublicKey)) || (type == KeyType.DSA && !(key instanceof DSAPublicKey)) ) { throw new InvalidKeyException("Key is not the right type for "+ "this algorithm"); } } catch( NoSuchAlgorithmException e ) { throw new RuntimeException("Unable to find algorithm from key type: " + e.getMessage(), e); } } /** * Makes sure the key lives on the token and is right for the algorithm. */ private void checkWrapper(SymmetricKey key) throws InvalidKeyException { if( key==null ) { throw new InvalidKeyException("Key is null"); } try { if( ! key.getOwningToken().equals(token) ) { throw new InvalidKeyException("Key does not reside on the current token: key owning token="+ key.getOwningToken().getName()); } if( ! (key instanceof PK11SymKey) ) { throw new InvalidKeyException("Key is not a PKCS #11 key"); } if( ((PK11SymKey)key).getKeyType() != KeyType.getKeyTypeFromAlgorithm(algorithm) ) { throw new InvalidKeyException("Key is not the right type for"+ " this algorithm"); } } catch( NoSuchAlgorithmException e ) { throw new RuntimeException("Unknown algorithm: " + e.getMessage(), e); } catch (Exception e) { throw new RuntimeException("Unable to check wrapper: " + e.getMessage(), e); } } /** * Makes sure the key is on the token and is right for the algorithm. */ private void checkWrapper(PrivateKey key) throws InvalidKeyException { if( key==null ) { throw new InvalidKeyException("Key is null"); } if( ! key.getOwningToken().equals(token) ) { throw new InvalidKeyException("Key does not reside on the "+ "current token"); } if( ! (key instanceof PK11PrivKey) ) { throw new InvalidKeyException("Key is not a PKCS #11 key"); } try { if( ((PK11PrivKey)key).getKeyType() != KeyType.getKeyTypeFromAlgorithm(algorithm) ) { throw new InvalidKeyException("Key is not the right type for"+ " this algorithm"); } } catch( NoSuchAlgorithmException e ) { throw new RuntimeException("Unknown algorithm: " + e.getMessage(), e); } } private void checkParams(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { if( ! algorithm.isValidParameterObject(params) ) { String name = "null"; if( params != null ) { name = params.getClass().getName(); } throw new InvalidAlgorithmParameterException( algorithm + " cannot use a " + name + " parameter"); } if( params instanceof IVParameterSpec ) { IV = ((IVParameterSpec)params).getIV(); } else if( params instanceof javax.crypto.spec.IvParameterSpec ) { IV = ((javax.crypto.spec.IvParameterSpec)params).getIV(); } else if( params instanceof RC2ParameterSpec ) { IV = ((RC2ParameterSpec)params).getIV(); } } public byte[] wrap(PrivateKey toBeWrapped) throws InvalidKeyException, IllegalStateException, TokenException { if( state != WRAP ) { throw new IllegalStateException(); } if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { throw new InvalidKeyException( "plaintext wrapping not supported"); } checkWrappee(toBeWrapped); if( symKey != null ) { assert( privKey==null && pubKey==null ); return nativeWrapPrivWithSym(token, toBeWrapped, symKey, algorithm, IV); } else { throw new InvalidKeyException( "Wrapping a private key with a public key is not supported"); /* assert( pubKey!=null && privKey==null && symKey==null ); return nativeWrapPrivWithPub(token, toBeWrapped, pubKey, algorithm, IV); */ } } public byte[] wrap(SymmetricKey toBeWrapped) throws InvalidKeyException, IllegalStateException, TokenException { if( state != WRAP ) { throw new IllegalStateException(); } if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { throw new InvalidKeyException("plaintext wrapping not supported"); } checkWrappee(toBeWrapped); if( symKey != null ) { assert( privKey==null && pubKey==null ); return nativeWrapSymWithSym(token, toBeWrapped, symKey, algorithm, IV); } else { assert( pubKey!=null && privKey==null && symKey==null ); return nativeWrapSymWithPub(token, toBeWrapped, pubKey, algorithm, IV); } } /** * Makes sure the key lives on the right token. */ private void checkWrappee(SymmetricKey symKey) throws InvalidKeyException { if( symKey == null ) { throw new InvalidKeyException("key to be wrapped is null"); } if( ! (symKey instanceof PK11SymKey) ) { throw new InvalidKeyException("key to be wrapped is not a "+ "PKCS #11 key"); } /* NSS is capable of moving keys appropriately, so this call is prematurely bailing if( ! symKey.getOwningToken().equals(token) ) { throw new InvalidKeyException("key to be wrapped does not live"+ " on the same token as the wrapping key"); } */ } /** * Makes sure the key lives on the right token. */ private void checkWrappee(PrivateKey privKey) throws InvalidKeyException { if( privKey == null ) { throw new InvalidKeyException("key to be wrapped is null"); } if( ! (privKey instanceof PK11PrivKey) ) { throw new InvalidKeyException("key to be wrapped is not a "+ "PKCS #11 key"); } /* NSS is capable of moving keys appropriately, so this call is prematurely bailing if( ! privKey.getOwningToken().equals(token) ) { throw new InvalidKeyException("key to be wrapped does not live"+ " on the same token as the wrapping key"); } */ } /** * Wrap a symmetric with a symmetric */ private static native byte[] nativeWrapSymWithSym(PK11Token token, SymmetricKey toBeWrapped, SymmetricKey wrappingKey, KeyWrapAlgorithm alg, byte[] IV) throws TokenException; /** * Wrap a symmetric with a public */ private static native byte[] nativeWrapSymWithPub(PK11Token token, SymmetricKey toBeWrapped, PublicKey wrappingKey, KeyWrapAlgorithm alg, byte[] IV) throws TokenException; /** * Wrap a private with a symmetric */ private static native byte[] nativeWrapPrivWithSym(PK11Token token, PrivateKey toBeWrapped, SymmetricKey wrappingKey, KeyWrapAlgorithm alg, byte[] IV) throws TokenException; /** * Wrap a private with a public. * NOTE: This operation is not supported by the security library. private static native byte[] nativeWrapPrivWithPub(PK11Token token, PrivateKey toBeWrapped, PublicKey wrappingKey, KeyWrapAlgorithm alg, byte[] IV) throws TokenException; */ /** * Unwraps a private key, creating a permanent private key object. * A permanent private key object resides on a token until it is * explicitly deleted from the token. */ public PrivateKey unwrapPrivate(byte[] wrapped, PrivateKey.Type type, PublicKey publicKey) throws TokenException, InvalidKeyException, IllegalStateException { return baseUnwrapPrivate(wrapped, type, publicKey, false); } /** * Unwraps a private key, creating a temporary private key object. * A temporary * private key is one that does not permanently reside on a token. * As soon as it is garbage-collected, it is gone forever. */ public PrivateKey unwrapTemporaryPrivate(byte[] wrapped, PrivateKey.Type type, PublicKey publicKey) throws TokenException, InvalidKeyException, IllegalStateException { return baseUnwrapPrivate(wrapped, type, publicKey, true); } private PrivateKey baseUnwrapPrivate(byte[] wrapped, PrivateKey.Type type, PublicKey publicKey, boolean temporary) throws TokenException, InvalidKeyException, IllegalStateException { if( state != UNWRAP ) { throw new IllegalStateException(); } if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { throw new TokenException("plaintext unwrapping of private keys " + "is not supported"); } byte[] publicValue = extractPublicValue(publicKey, type); /* If first byte is null, omit it. * It can be null due to how BigInteger.toByteArray() is specified. */ if (publicValue.length > 0 && publicValue[0] == 0) { publicValue = Arrays.copyOfRange(publicValue, 1, publicValue.length); } if( symKey != null ) { assert(pubKey==null && privKey==null); PrivateKey importedKey = nativeUnwrapPrivWithSym( token, symKey, wrapped, algorithm, algFromType(type), publicValue, IV, temporary); if (!temporary && publicKey instanceof org.mozilla.jss.pkcs11.PK11PubKey) { try { token.importPublicKey( publicKey, true /* permanent */ ); } catch (Exception e) { // squash all exceptions // (some tokens cannot store the public key) } } return importedKey; } else { throw new InvalidKeyException("Unwrapping a private key with" + " a private key is not supported"); /* assert(privKey!=null && pubKey==null && symKey==null); return nativeUnwrapPrivWithPriv(token, privKey, wrapped, algorithm, algFromType(type), publicValue, IV, temporary ); */ } } /** * Extracts the "public value" from a public key. The public value is * used to construct the key identifier (CKA_ID). Also, the internal token * stores the EC DSA and EC public value along with the private key. */ private static byte[] extractPublicValue(PublicKey publicKey, PrivateKey.Type type) throws InvalidKeyException { /* this code should call a generic function which returns the * proper public value. */ if( publicKey == null ) { throw new InvalidKeyException("publicKey is null"); } if( type == PrivateKey.RSA ) { if( !(publicKey instanceof RSAPublicKey)) { throw new InvalidKeyException("Type of public key does not "+ "match type of private key which is RSA"); } return ((RSAPublicKey)publicKey).getModulus().toByteArray(); } else if(type == PrivateKey.EC) { if( !(publicKey instanceof PK11ECPublicKey) ) { throw new InvalidKeyException("Type of public key does not "+ "match type of private key which is EC"); } return ((PK11ECPublicKey)publicKey).getWByteArray(); } else if(type == PrivateKey.DSA) { if( !(publicKey instanceof DSAPublicKey) ) { throw new InvalidKeyException("Type of public key does not "+ "match type of private key which is DSA"); } return ((DSAPublicKey)publicKey).getY().toByteArray(); } else { throw new InvalidKeyException("Unknown private key type: " + type); } } public SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, SymmetricKey.Usage usage, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { return unwrapSymmetric(wrapped, type, usage.getVal(), keyLen); } public SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { return unwrapSymmetric(wrapped, type, -1, keyLen); } public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, SymmetricKey.Usage usage, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { return unwrapSymmetricPerm(wrapped, type, usage.getVal(), keyLen); } public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { return unwrapSymmetricPerm(wrapped, type, -1, keyLen); } private SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, int usageEnum, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { if( state != UNWRAP ) { throw new IllegalStateException(); } /* Since we want permanent,make the temporary arg false */ boolean temporary = false; if( (! algorithm.isPadded()) && (type == SymmetricKey.RC4) ) { if( keyLen <= 0 ) { throw new InvalidAlgorithmParameterException( "RC4 keys wrapped in unpadded algorithms need key length"+ " specified when unwrapping"); } } else { // Don't use the key length keyLen = 0; } if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { return nativeUnwrapSymPlaintext(token, wrapped, algFromType(type), usageEnum,temporary ); } else { if( symKey != null ) { assert(pubKey==null && privKey==null); return nativeUnwrapSymWithSym(token, symKey, wrapped, algorithm, algFromType(type), keyLen, IV, usageEnum,temporary); } else { assert(privKey!=null && pubKey==null && symKey==null); throw new TokenException("We do not support permnament unwrapping with private key."); } } } private SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, int usageEnum, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { if( state != UNWRAP ) { throw new IllegalStateException(); } if( (! algorithm.isPadded()) && (type == SymmetricKey.RC4) ) { if( keyLen <= 0 ) { throw new InvalidAlgorithmParameterException( "RC4 keys wrapped in unpadded algorithms need key length"+ " specified when unwrapping"); } } else { // Don't use the key length //keyLen = 0; } /* Since we DONT want permanent,make the temporary arg true */ boolean temporary = true; if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { return nativeUnwrapSymPlaintext(token, wrapped, algFromType(type), usageEnum, temporary ); } else { if( symKey != null ) { assert(pubKey==null && privKey==null); return nativeUnwrapSymWithSym(token, symKey, wrapped, algorithm, algFromType(type), keyLen, IV, usageEnum,temporary); } else { assert(privKey!=null && pubKey==null && symKey==null); return nativeUnwrapSymWithPriv(token, privKey, wrapped, algorithm, algFromType(type), keyLen, IV, usageEnum ); } } } private static Algorithm algFromType(PrivateKey.Type type) { if (type == PrivateKey.RSA) { return KeyPairAlgorithm.RSAFamily; } else if (type == PrivateKey.DSA) { return KeyPairAlgorithm.DSAFamily; } else { assert( type == PrivateKey.EC); return KeyPairAlgorithm.ECFamily; } } private static Algorithm algFromType(SymmetricKey.Type type) { if( type == SymmetricKey.DES ) { return EncryptionAlgorithm.DES_ECB; } else if( type == SymmetricKey.DES3 ) { return EncryptionAlgorithm.DES3_ECB; } else if( type == SymmetricKey.AES ) { return EncryptionAlgorithm.AES_128_ECB; }else if( type == SymmetricKey.RC4 ) { return EncryptionAlgorithm.RC4; } else if( type == SymmetricKey.AES ) { return EncryptionAlgorithm.AES_128_ECB; } else if( type == SymmetricKey.SHA1_HMAC) { return HMACAlgorithm.SHA1; } else { assert( type == SymmetricKey.RC2 ); return EncryptionAlgorithm.RC2_CBC; } } /** * Unwrap a private with a symmetric. */ private static native PrivateKey nativeUnwrapPrivWithSym(PK11Token token, SymmetricKey unwrappingKey, byte[] wrappedKey, KeyWrapAlgorithm alg, Algorithm type, byte[] publicValue, byte[] IV, boolean temporary) throws TokenException; /** * Unwrap a private with a private. * NOTE: this is not supported by the security library. private static native PrivateKey nativeUnwrapPrivWithPriv(PK11Token token, PrivateKey unwrappingKey, byte[] wrappedKey, KeyWrapAlgorithm alg, Algorithm type, byte[] publicValue, byte[] IV, boolean temporary) throws TokenException; */ /** * Unwrap a symmetric with a symmetric. */ private static native SymmetricKey nativeUnwrapSymWithSym(PK11Token token, SymmetricKey unwrappingKey, byte[] wrappedKey, KeyWrapAlgorithm alg, Algorithm type, int keyLen, byte[] IV, int usageEnum, boolean temporary) throws TokenException; /** * Unwrap a symmetric with a private. */ private static native SymmetricKey nativeUnwrapSymWithPriv(PK11Token token, PrivateKey unwrappingKey, byte[] wrappedKey, KeyWrapAlgorithm alg, Algorithm type, int keyLen, byte[] IV, int usageEnum) throws TokenException; private static native SymmetricKey nativeUnwrapSymPlaintext(PK11Token token, byte[] wrappedKey, Algorithm type, int usageEnum, boolean temporary); private void reset() { state = UNINITIALIZED; symKey = null; privKey = null; pubKey = null; parameters = null; IV = null; } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11MessageDigest.c000066400000000000000000000110621362106420000217410ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11MessageDigest.h" #include #include #include #include #include /* JSS includes */ #include #include #include #include #include /*********************************************************************** * * PK11MessageDigest.initDigest * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11MessageDigest_initDigest (JNIEnv *env, jclass clazz, jobject algObj) { SECOidTag alg; PK11Context *context=NULL; alg = JSS_getOidTagFromAlg(env, algObj); PR_ASSERT( alg != SEC_OID_UNKNOWN ); /* we checked already in Java */ context = PK11_CreateDigestContext(alg); if( context == NULL ) { JSS_throwMsg(env, DIGEST_EXCEPTION, "Unable to create digest context"); return NULL; } return JSS_PK11_wrapCipherContextProxy(env, &context); } /*********************************************************************** * * PK11MessageDigest.initHMAC * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11MessageDigest_initHMAC (JNIEnv *env, jclass clazz, jobject tokenObj, jobject algObj, jobject keyObj) { PK11SymKey *origKey = NULL, *newKey=NULL; PK11Context *context = NULL; CK_MECHANISM_TYPE mech; SECItem param; jobject contextObj=NULL; mech = JSS_getPK11MechFromAlg(env, algObj); PR_ASSERT( mech != CKM_INVALID_MECHANISM ); /* we checked already in Java */ if( JSS_PK11_getSymKeyPtr(env, keyObj, &origKey) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } /* copy the key, setting the CKA_SIGN attribute */ newKey = PK11_CopySymKeyForSigning(origKey, mech); /* For some key on the hsm, this call could fail, but the key may work anyway */ if( newKey == NULL ) { newKey = origKey; } param.data = NULL; param.len = 0; context = PK11_CreateContextBySymKey(mech, CKA_SIGN, newKey, ¶m); if( context == NULL ) { JSS_throwMsg(env, DIGEST_EXCEPTION, "Unable to initialize digest context"); goto finish; } contextObj = JSS_PK11_wrapCipherContextProxy(env, &context); finish: if(newKey && (newKey != origKey)) { /* SymKeys are ref counted, and the context will free it's ref * when it is destroyed */ PK11_FreeSymKey(newKey); } return contextObj; } /*********************************************************************** * * PK11MessageDigest.update * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11MessageDigest_update (JNIEnv *env, jclass clazz, jobject proxyObj, jbyteArray inbufBA, jint offset, jint len) { PK11Context *context = NULL; jbyte* bytes = NULL; jsize length = 0; if( JSS_PK11_getCipherContext(env, proxyObj, &context) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } if (!JSS_RefByteArray(env, inbufBA, &bytes, &length) || length < offset+len) { goto finish; } if( PK11_DigestOp(context, (unsigned char*)(bytes+offset), len) != SECSuccess ) { JSS_throwMsg(env, DIGEST_EXCEPTION, "Digest operation failed"); goto finish; } finish: JSS_DerefByteArray(env, inbufBA, bytes, JNI_ABORT); } /*********************************************************************** * * PK11MessageDigest.digest * */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11MessageDigest_digest (JNIEnv *env, jclass clazz, jobject proxyObj, jbyteArray outbuf, jint offset, jint len) { PK11Context *context=NULL; jbyte *bytes=NULL; jsize length = 0; SECStatus status; unsigned int outLen = 0; if( JSS_PK11_getCipherContext(env, proxyObj, &context) != PR_SUCCESS) { /* exception was thrown */ goto finish; } if (!JSS_RefByteArray(env, outbuf, &bytes, &length) || length < offset+len) { ASSERT_OUTOFMEM(env); goto finish; } status = PK11_DigestFinal(context, (unsigned char*)(bytes+offset), &outLen, len); if( status != SECSuccess ) { JSS_throwMsg(env, DIGEST_EXCEPTION, "Error occurred while performing" " digest operation"); goto finish; } finish: JSS_DerefByteArray(env, outbuf, bytes, 0); return outLen; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11MessageDigest.java000066400000000000000000000073741362106420000224530ustar00rootroot00000000000000/* 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.pkcs11; import org.mozilla.jss.crypto.*; import java.security.DigestException; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; /** * Message Digesting with PKCS #11. */ public final class PK11MessageDigest extends JSSMessageDigest { private PK11Token token; private CipherContextProxy digestProxy; private PK11SymKey hmacKey; private DigestAlgorithm alg; PK11MessageDigest(PK11Token token, DigestAlgorithm alg) throws NoSuchAlgorithmException, DigestException { this.token = token; this.alg = alg; if( ! token.doesAlgorithm(alg) ) { throw new NoSuchAlgorithmException(); } reset(); } public void initHMAC(SymmetricKey key) throws DigestException, InvalidKeyException { if( ! (alg instanceof HMACAlgorithm || alg instanceof CMACAlgorithm) ) { throw new DigestException("Digest is not an HMAC or CMAC digest"); } reset(); if( ! (key instanceof PK11SymKey) ) { throw new InvalidKeyException("HMAC key is not a PKCS #11 key"); } hmacKey = (PK11SymKey) key; if( ! key.getOwningToken().equals(token) ) { hmacKey = null; throw new InvalidKeyException( "HMAC key does not live on the same token as this digest"); } this.digestProxy = initHMAC(token, alg, hmacKey); } public void update(byte[] input, int offset, int len) throws DigestException { if( digestProxy == null ) { throw new DigestException("Digest not correctly initialized"); } if( input.length < offset+len ) { throw new IllegalArgumentException( "Input buffer is not large enough for offset and length"); } update(digestProxy, input, offset, len); } public int digest(byte[] outbuf, int offset, int len) throws DigestException { if( digestProxy == null ) { throw new DigestException("Digest not correctly initialized"); } if( outbuf.length < offset+len ) { throw new IllegalArgumentException( "Output buffer is not large enough for offset and length"); } int retval = digest(digestProxy, outbuf, offset, len); reset(); return retval; } public void reset() throws DigestException { if( ! (alg instanceof HMACAlgorithm || alg instanceof CMACAlgorithm) ) { // This is a regular digest, so we have enough information // to initialize the context this.digestProxy = initDigest(alg); } else if( hmacKey != null ) { // This is an HMAC digest, and we have a key this.digestProxy = initHMAC(token, alg, hmacKey); } else { // this is an HMAC digest for which we don't have the key yet, // we have to wait to construct the context this.digestProxy = null; } } public DigestAlgorithm getAlgorithm() { return alg; } private static native CipherContextProxy initDigest(DigestAlgorithm alg) throws DigestException; private static native CipherContextProxy initHMAC(PK11Token token, DigestAlgorithm alg, PK11SymKey key) throws DigestException; private static native void update(CipherContextProxy proxy, byte[] inbuf, int offset, int len); private static native int digest(CipherContextProxy proxy, byte[] outbuf, int offset, int len); } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Module.c000066400000000000000000000150101362106420000204370ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11Module.h" #include #include #include #include #include #include "pk11util.h" #include #include #include "jss_exceptions.h" /*********************************************************************** * Class: org_mozilla_jss_pkcs11_PK11Module * Method: getName * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Module_getName (JNIEnv *env, jobject this) { SECMODModule *module; jstring nameString=NULL; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getModulePtr(env, this, &module) != PR_SUCCESS) { goto finish; } PR_ASSERT(module->commonName != NULL); nameString = (*env)->NewStringUTF(env, module->commonName); finish: PR_ASSERT( nameString || (*env)->ExceptionOccurred(env) ); return nameString; } /*********************************************************************** * Class: org_mozilla_jss_pkcs11_PK11Module * Method: getLibraryName * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Module_getLibraryName (JNIEnv *env, jobject this) { SECMODModule *module; jstring libName = NULL; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getModulePtr(env, this, &module) != PR_SUCCESS) { goto finish; } PR_ASSERT(module->dllName != NULL); libName = (*env)->NewStringUTF(env, module->dllName); finish: PR_ASSERT( libName || (*env)->ExceptionOccurred(env) ); return libName; } /*********************************************************************** * Class: org_mozilla_jss_pkcs11_PK11Module * Method: putTokensInVector * Signature: (Ljava/util/Vector;)V */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Module_putTokensInVector (JNIEnv *env, jobject this, jobject vector) { SECMODModule *module; jclass vectorClass; jmethodID addElement; jobject token; PK11SlotInfo *slot; int i; PR_ASSERT(env!=NULL && this!=NULL && vector!=NULL); /*************************** * Get Vector JNI ids ***************************/ vectorClass = (*env)->GetObjectClass(env, vector); if(vectorClass==NULL) goto finish; addElement = (*env)->GetMethodID(env, vectorClass, VECTOR_ADD_ELEMENT_NAME, VECTOR_ADD_ELEMENT_SIG); if(addElement==NULL) goto finish; /*************************** * Get the PKCS #11 module ***************************/ if( JSS_PK11_getModulePtr(env, this, &module) != PR_SUCCESS) goto finish; /************************** * Loop over slots **************************/ for(i=0; i < module->slotCount; i++) { if (PK11_IsPresent(module->slots[i])) { char *tokenname; tokenname = PK11_GetTokenName(module->slots[i]); /* ignore if the token has no name */ if( tokenname!=NULL && tokenname[0]!='\0' ) { /* turn the slot into a PK11Token */ slot = PK11_ReferenceSlot(module->slots[i]); PR_ASSERT(slot!=NULL); token = JSS_PK11_wrapPK11Token(env, &slot); /* stick the PK11Token in the Vector */ (*env)->CallVoidMethod(env, vector, addElement, token); } } } finish: return; } /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P K 1 1 M o d u l e * * Turns a SECMODModule* C structure into a PK11Module Java object. * * INPUTS * ptr * Address of a SECMODModule *. This pointer will be copied * into the new Java object, then set to NULL. * RETURNS * A new Java PK11Module object, or NULL if an exception was thrown. * In any case, the ptr parameter is eaten. */ jobject JSS_PK11_wrapPK11Module(JNIEnv *env, SECMODModule **module) { jclass moduleClass; jmethodID constructor; jobject newModule=NULL; jbyteArray pointer; PR_ASSERT(env!=NULL && module!=NULL && *module!=NULL); pointer = JSS_ptrToByteArray(env, (void*)*module); /* * Lookup the class and constructor */ moduleClass = (*env)->FindClass(env, PK11MODULE_CLASS_NAME); if(moduleClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, moduleClass, PLAIN_CONSTRUCTOR, PK11MODULE_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * Call the constructor */ newModule = (*env)->NewObject(env, moduleClass, constructor, pointer); finish: if(newModule==NULL) { SECMOD_DestroyModule(*module); } *module = NULL; return newModule; } /*********************************************************************** * * J S S _ P K 1 1 _ g e t M o d u l e P t r * * Retrieve the SECMODModule pointer of the given PK11Module. * * INPUTS * module * A reference to a Java PK11Module. * ptr * Address of a SECMODModule * that will be loaded with the * SECMODModule pointer of the given PK11Module. * RETURNS * PR_FAILURE if an exception was thrown, or PR_SUCCESS if the * peration succeeded. */ PRStatus JSS_PK11_getModulePtr(JNIEnv *env, jobject module, SECMODModule **ptr) { PR_ASSERT(env!=NULL && module!=NULL && ptr!=NULL); return JSS_getPtrFromProxyOwner(env, module, PK11MODULE_PROXY_FIELD, PK11MODULE_PROXY_SIG, (void**)ptr); } /********************************************************************** * ModuleProxy.releaseNativeResources */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_ModuleProxy_releaseNativeResources (JNIEnv *env, jobject this) { SECMODModule *module; if (JSS_getPtrFromProxy(env, this, (void **)&module) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(module != NULL); SECMOD_DestroyModule(module); finish: return; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Module.java000066400000000000000000000031311362106420000211370ustar00rootroot00000000000000/* 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.pkcs11; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.util.Assert; public final class PK11Module { private PK11Module() { throw new RuntimeException("PK11Module default constructor"); } /** * This constructor should only be called from native code. */ private PK11Module(byte[] pointer) { assert(pointer!=null); moduleProxy = new ModuleProxy(pointer); reloadTokens(); } /** * Returns the common name of this module. */ public native String getName(); /** * Returns the name of the shared library implementing this module. */ public native String getLibraryName(); /** * Get the CryptoTokens provided by this module. * * @return An enumeration of CryptoTokens that come from this module. */ public synchronized Enumeration getTokens() { return tokenVector.elements(); } /** * Re-load the list of this module's tokens. This function is private * to JSS. */ public synchronized void reloadTokens() { tokenVector = new Vector<>(); putTokensInVector(tokenVector); } private native void putTokensInVector(Vector tokens); private Vector tokenVector; private ModuleProxy moduleProxy; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11ParameterSpec.java000066400000000000000000000010201362106420000224400ustar00rootroot00000000000000/* 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.pkcs11; import java.security.spec.AlgorithmParameterSpec; public final class PK11ParameterSpec implements AlgorithmParameterSpec { public PK11ParameterSpec(byte [] derBlob) { blob = derBlob; } public byte [] getEncoded() { return blob; } private byte [] blob; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11PrivKey.c000066400000000000000000000465311362106420000206170ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_PrivateKeyProxy.h" #include #include #include #include #include #include #include #include #include #include #include #include "pk11util.h" #include "java_ids.h" /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P r i v K e y * privk: will be stored in a Java wrapper. * Returns: a new PK11PrivKey, or NULL if an exception occurred. */ jobject JSS_PK11_wrapPrivKey(JNIEnv *env, SECKEYPrivateKey **privk) { jclass keyClass; jmethodID constructor; jbyteArray ptrArray; jobject Key=NULL; const char *className = NULL; PR_ASSERT(env!=NULL && privk!=NULL && *privk!=NULL); /* Find the class */ switch( (*privk)->keyType ) { case rsaKey: className = "org/mozilla/jss/pkcs11/PK11RSAPrivateKey"; break; case dsaKey: className = "org/mozilla/jss/pkcs11/PK11DSAPrivateKey"; break; case ecKey: className = "org/mozilla/jss/pkcs11/PK11ECPrivateKey"; break; default: className = "org/mozilla/jss/pkcs11/PK11PrivKey"; break; } keyClass = (*env)->FindClass(env, className); if(keyClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* find the constructor */ constructor = (*env)->GetMethodID(env, keyClass, "", "([B)V"); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* convert the pointer to a byte array */ ptrArray = JSS_ptrToByteArray(env, (void*)*privk); if(ptrArray == NULL) { goto finish; } /* call the constructor */ Key = (*env)->NewObject(env, keyClass, constructor, ptrArray); finish: if(Key == NULL) { SECKEY_DestroyPrivateKey(*privk); } *privk = NULL; return Key; } /*********************************************************************** * PK11PrivKey.verifyKeyIsOnToken */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_verifyKeyIsOnToken (JNIEnv *env, jobject this, jobject token) { SECKEYPrivateKey *key = NULL; PK11SlotInfo *slot = NULL; PK11SlotInfo *keySlot = NULL; PK11SlotInfo *dbSlot = NULL; PK11SlotInfo *cryptoSlot = NULL; if( JSS_PK11_getPrivKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } if( JSS_PK11_getTokenSlotPtr(env, token, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } keySlot = PK11_GetSlotFromPrivateKey(key); dbSlot = PK11_GetInternalKeySlot(); if(keySlot == dbSlot) { cryptoSlot = PK11_GetInternalSlot(); /* hack for internal module */ if(slot != keySlot && slot != cryptoSlot) { JSS_throwMsg(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION, "Key is not present on this token"); goto finish; } } else if(keySlot != slot) { JSS_throwMsg(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION, "Key is not present on this token"); goto finish; } finish: if(keySlot != NULL) { PK11_FreeSlot(keySlot); } if(dbSlot != NULL) { PK11_FreeSlot(dbSlot); } if(cryptoSlot != NULL) { PK11_FreeSlot(cryptoSlot); } } /* * PK11PrivKey.getKeyType * * Returns: The KeyType of this key. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_getKeyType (JNIEnv *env, jobject this) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread; SECKEYPrivateKey *privk; KeyType keyType; char* keyTypeFieldName; jclass keyTypeClass; jfieldID keyTypeField; jobject keyTypeObject = NULL; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); if(JSS_PK11_getPrivKeyPtr(env, this, &privk) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL ); goto finish; } PR_ASSERT(privk!=NULL); keyType = SECKEY_GetPrivateKeyType(privk); switch(keyType) { case nullKey: keyTypeFieldName = NULL_KEYTYPE_FIELD; break; case rsaKey: keyTypeFieldName = RSA_KEYTYPE_FIELD; break; case dsaKey: keyTypeFieldName = DSA_KEYTYPE_FIELD; break; case fortezzaKey: keyTypeFieldName = FORTEZZA_KEYTYPE_FIELD; break; case dhKey: keyTypeFieldName = DH_KEYTYPE_FIELD; break; case keaKey: keyTypeFieldName = KEA_KEYTYPE_FIELD; break; case ecKey: keyTypeFieldName = EC_KEYTYPE_FIELD; break; default: PR_ASSERT(PR_FALSE); keyTypeFieldName = NULL_KEYTYPE_FIELD; break; } keyTypeClass = (*env)->FindClass(env, KEYTYPE_CLASS_NAME); if(keyTypeClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyTypeField = (*env)->GetStaticFieldID(env, keyTypeClass, keyTypeFieldName, KEYTYPE_FIELD_SIG); if(keyTypeField==NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyTypeObject = (*env)->GetStaticObjectField( env, keyTypeClass, keyTypeField); if(keyTypeObject == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: PR_DetachThread(); return keyTypeObject; } /* * PrivateKeyProxy.releaseNativeResources */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PrivateKeyProxy_releaseNativeResources (JNIEnv *env, jobject this) { SECKEYPrivateKey *privk; PRThread * VARIABLE_MAY_NOT_BE_USED pThread; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); /* Get the SECKEYPrivateKey structure */ if(JSS_getPtrFromProxy(env, this, (void**) &privk) != PR_SUCCESS) { PR_ASSERT( PR_FALSE ); goto finish; } PR_ASSERT(privk != NULL); SECKEY_DestroyPrivateKey(privk); finish: PR_DetachThread(); return; } /* * Given a PrivateKey object, extracts the SECKEYPrivateKey* and stores it * at the given address. * * privkObject: A JNI reference to a PrivateKey object. * ptr: Address of a SECKEYPrivateKey* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getPrivKeyPtr(JNIEnv *env, jobject privkObject, SECKEYPrivateKey** ptr) { PR_ASSERT(env!=NULL && privkObject!=NULL); /* Get the pointer from the key proxy */ PR_ASSERT(sizeof(SECKEYPrivateKey*) == sizeof(void*)); return JSS_getPtrFromProxyOwner(env, privkObject, KEY_PROXY_FIELD, KEY_PROXY_SIG, (void**)ptr); } /*********************************************************************** * * PK11PrivKey.getPK11Token * * Figures out which slot this key lives on and wraps it in a PK11Token, * * RETURNS * NULL if an exception occurred, otherwise a new PK11Token object. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_getOwningToken (JNIEnv *env, jobject this) { SECKEYPrivateKey *key = NULL; PK11SlotInfo *keySlot = NULL; jobject token = NULL; PR_ASSERT(env!=NULL && this!=NULL); /* Get the C key structure */ if( JSS_PK11_getPrivKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /* Get the slot that this key lives on */ keySlot = PK11_GetSlotFromPrivateKey(key); PR_ASSERT(keySlot != NULL); /* Turn the slot into a Java PK11Token */ token = JSS_PK11_wrapPK11Token(env, &keySlot); if(token == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } finish: if(keySlot != NULL) { PK11_FreeSlot(keySlot); } return token; } /* * workaround for bug 100791: misspelled function prototypes in pk11func.h */ SECItem* PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey*); /********************************************************************** * PK11PrivKey.getUniqueID */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_getUniqueID (JNIEnv *env, jobject this) { SECKEYPrivateKey *key = NULL; SECItem *idItem = NULL; jbyteArray byteArray = NULL; PR_ASSERT(env!=NULL && this!=NULL); /*************************************************** * Get the private key structure ***************************************************/ if( JSS_PK11_getPrivKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /*************************************************** * Get the key id ***************************************************/ idItem = PK11_GetLowLevelKeyIDForPrivateKey(key); if(idItem == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to get key id"); goto finish; } /*************************************************** * Write the key id to a new byte array ***************************************************/ PR_ASSERT(idItem->len > 0); byteArray = JSS_ToByteArray(env, idItem->data, idItem->len); if (byteArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: if(idItem != NULL) { SECITEM_FreeItem(idItem, PR_TRUE /*freeit*/); } return byteArray; } /********************************************************************** * PK11PrivKey.getStrength */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_getStrength (JNIEnv *env, jobject this) { SECKEYPrivateKey *key = NULL; PK11SlotInfo *slot = NULL; int strength; PR_ASSERT(env!=NULL && this!=NULL); /*************************************************** * Get the private key and slot C structures ***************************************************/ if( JSS_PK11_getPrivKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return -1; } slot = PK11_GetSlotFromPrivateKey(key); PR_ASSERT(slot!=NULL); /*************************************************** * Try to login to the token if necessary ***************************************************/ PK11_Authenticate(slot, PR_TRUE /*readCerts*/, NULL /*wincx*/); /*************************************************** * Get the strength ( in bytes ) ***************************************************/ strength = PK11_GetPrivateModulusLen(key); if( strength > 0 ) { /* convert to bits */ return strength * 8; } else { return strength; } } /*********************************************************************** * JSS_PK11_getKeyType * * Converts a PrivateKey.KeyType object to a PKCS #11 key type. * * INPUTS * keyTypeObj * A org.mozilla.jss.crypto.PrivateKey.KeyType object. * RETURNS * The key type, or nullKey if an exception occurred. */ KeyType JSS_PK11_getKeyType(JNIEnv *env, jobject keyTypeObj) { jclass keyTypeClass; jfieldID fieldID; char *fieldNames[] = { RSA_PRIVKEYTYPE_FIELD, DSA_PRIVKEYTYPE_FIELD, FORTEZZA_KEYTYPE_FIELD, DH_KEYTYPE_FIELD, KEA_KEYTYPE_FIELD, EC_KEYTYPE_FIELD }; int numTypes = 6; KeyType keyTypes[] = { rsaKey, dsaKey, fortezzaKey, dhKey, keaKey, ecKey }; jobject field; int i; PR_ASSERT(env!=NULL && keyTypeObj!=NULL); keyTypeClass = (*env)->FindClass(env, PRIVKEYTYPE_CLASS_NAME); if( keyTypeClass == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } for(i=0; i < numTypes; i++) { fieldID = (*env)->GetStaticFieldID(env, keyTypeClass, fieldNames[i], PRIVKEYTYPE_SIG); if( fieldID == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } field = (*env)->GetStaticObjectField(env, keyTypeClass, fieldID); if( field == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } if( (*env)->IsSameObject(env, keyTypeObj, field) ) { return keyTypes[i]; } } /* unrecognized type? */ PR_ASSERT( PR_FALSE ); finish: return nullKey; } /*********************************************************************** * importPrivateKey */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_fromPrivateKeyInfo ( JNIEnv *env, jclass clazz, jbyteArray keyArray, jobject tokenObj, jbyteArray publicValueArray ) { SECItem *derPK = NULL; jthrowable excep; SECStatus status; SECItem nickname; jobject keyObj = NULL; SECKEYPrivateKey* privk = NULL; PK11SlotInfo *slot = NULL; unsigned int keyUsage; SECItem *publicValue = NULL; PR_ASSERT(env!=NULL && clazz!=NULL); if(keyArray == NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } /* * copy the java byte arrays into local copies */ derPK = JSS_ByteArrayToSECItem(env, keyArray); if( derPK == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } if( publicValueArray != NULL ) { publicValue = JSS_ByteArrayToSECItem(env, publicValueArray); if( publicValue == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } } /* * get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } nickname.len = 0; nickname.data = NULL; /* * enable the key for as many operations as possible */ keyUsage = KU_ALL; status = PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPK, &nickname, publicValue, PR_FALSE /*isPerm*/, PR_TRUE /*isPrivate*/, keyUsage, &privk, NULL /*wincx*/); if(status != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to import private key info"); goto finish; } PR_ASSERT(privk != NULL); keyObj = JSS_PK11_wrapPrivKey(env, &privk); finish: /* Save any exceptions */ if( (excep=(*env)->ExceptionOccurred(env)) != NULL ) { (*env)->ExceptionClear(env); } if( derPK != NULL ) { SECITEM_FreeItem(derPK, PR_TRUE /*freeit*/); } if( publicValue != NULL ) { SECITEM_FreeItem(publicValue, PR_TRUE /*freeit*/); } /* now re-throw the exception */ if( excep ) { (*env)->Throw(env, excep); } return keyObj; } #define ZERO_SECITEM(item) (item).data=NULL; (item).len=0; /*********************************************************************** * getDSAParamsNative * * Returns a 3-element array of byte[]. The elements are P, Q, and G. */ JNIEXPORT jobjectArray JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_getDSAParamsNative (JNIEnv *env, jobject this) { SECKEYPrivateKey *key = NULL; PQGParams *pqgParams = NULL; /*----PQG parameters and friends----*/ SECItem P; /* prime */ SECItem Q; /* subPrime */ SECItem G; /* base */ /*----Java versions of the PQG parameters----*/ jobject jP = NULL; jobject jQ = NULL; jobject jG = NULL; jobjectArray pqgArray = NULL; PR_ASSERT(env!=NULL && this!=NULL); /* clear the SECItems so we can free them indiscriminately at the end */ ZERO_SECITEM(P); ZERO_SECITEM(Q); ZERO_SECITEM(G); /* * Get the private key C structure */ if( JSS_PK11_getPrivKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /* * Get the PQG params from the private key */ pqgParams = (PQGParams*)PK11_GetPQGParamsFromPrivateKey(key); if( pqgParams == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract PQG parameters from private key"); goto finish; } if( PK11_PQG_GetPrimeFromParams( pqgParams, &P) || PK11_PQG_GetSubPrimeFromParams( pqgParams, &Q) || PK11_PQG_GetBaseFromParams( pqgParams, &G) ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract PQG parameters from private key"); goto finish; } /* * Now turn them into byte arrays */ if( !(jP = JSS_OctetStringToByteArray(env, &P)) || !(jQ = JSS_OctetStringToByteArray(env, &Q)) || !(jG = JSS_OctetStringToByteArray(env, &G)) ) { goto finish; } /* * Stash the byte arrays into an array of arrays. */ pqgArray = (*env)->NewObjectArray( env, 3, (*env)->GetObjectClass(env, jP), NULL); if( pqgArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } (*env)->SetObjectArrayElement(env, pqgArray, 0, jP); (*env)->SetObjectArrayElement(env, pqgArray, 1, jQ); (*env)->SetObjectArrayElement(env, pqgArray, 2, jG); finish: if(pqgParams!=NULL) { PK11_PQG_DestroyParams(pqgParams); } SECITEM_FreeItem(&P, PR_FALSE /*don't free P itself*/); SECITEM_FreeItem(&Q, PR_FALSE); SECITEM_FreeItem(&G, PR_FALSE); return pqgArray; } /********************************************************************** * PK11RSAPrivateKey.getModulusByteArray */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11RSAPrivateKey_getModulusByteArray (JNIEnv *env, jobject this) { SECKEYPrivateKey *privateKey = NULL; SECKEYPublicKey *publicKey = NULL; PK11SlotInfo *slot = NULL; int rv; jbyte *value = NULL; jint length; jbyteArray array = NULL; PR_ASSERT(env!=NULL && this!=NULL); // get private key rv = JSS_PK11_getPrivKeyPtr(env, this, &privateKey); // check return code if (rv != PR_SUCCESS) { char *message = PR_smprintf("Unable to get RSA private key (rc: %d)", rv); JSS_throwMsg(env, PK11_EXCEPTION, message); PR_smprintf_free(message); goto finish; } // get slot from private key slot = PK11_GetSlotFromPrivateKey(privateKey); PR_ASSERT(slot!=NULL); // login to token if necessary PK11_Authenticate(slot, PR_TRUE, NULL); // convert private key to public key publicKey = SECKEY_ConvertToPublicKey(privateKey); // get modulus from public key value = (jbyte*)publicKey->u.rsa.modulus.data; length = (jint)publicKey->u.rsa.modulus.len; // create byte array array = JSS_ToByteArray(env, value, length); // check byte array creation if (array == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } finish: if (publicKey) { SECKEY_DestroyPublicKey(publicKey); } if (slot) { PK11_FreeSlot(slot); } return array; } /********************************************************************** * PK11PrivKey.getPublicKey() * * Returns an instance of the public key from the private key. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_getPublicKey (JNIEnv *env, jobject this) { SECKEYPrivateKey *privKey; SECKEYPublicKey *pubKey; if (JSS_PK11_getPrivKeyPtr(env, this, &privKey) != PR_SUCCESS) { return NULL; } pubKey = SECKEY_ConvertToPublicKey(privKey); if (pubKey == NULL) { return NULL; } return JSS_PK11_wrapPubKey(env, &pubKey); } jss-4.6.3/org/mozilla/jss/pkcs11/PK11PrivKey.java000066400000000000000000000101371362106420000213070ustar00rootroot00000000000000/* 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.pkcs11; import java.math.BigInteger; import java.security.spec.DSAParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.util.Assert; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PK11PrivKey extends org.mozilla.jss.pkcs11.PK11Key implements PrivateKey { private static final long serialVersionUID = 1L; private PK11PrivKey() { } protected PK11PrivKey(byte[] pointer) { assert(pointer!=null); keyProxy = new PrivateKeyProxy(pointer); } /** * Make sure this key lives on the given token. */ public native void verifyKeyIsOnToken(PK11Token token) throws org.mozilla.jss.crypto.NoSuchItemOnTokenException; /** * Returns a new CryptoToken where this key resides. * * @return The PK11Token that owns this key. */ public native CryptoToken getOwningToken(); public native byte[] getUniqueID() throws TokenException; public native KeyType getKeyType(); public PrivateKey.Type getType() { KeyType kt = getKeyType(); if( kt == KeyType.RSA ) { return PrivateKey.Type.RSA; } else if (kt == KeyType.DSA) { return PrivateKey.Type.DSA; } else { assert(kt == KeyType.EC); return PrivateKey.Type.EC; } } public String getAlgorithm() { return getType().toString(); } /** * Returns the size in bits of the modulus of an RSA Private key. * Returns -1 for other types of keys. */ public native int getStrength(); /** * Returns the corresponding public key from a private key instance. */ public native PK11PubKey getPublicKey(); /** * Imports a PrivateKeyInfo, storing it as a temporary PrivateKey * on the given token. * The key will be a temporary (session) key until it is imported * into a KeyStore, at which point it will be made a permanent (token) * object. */ public static PK11PrivKey fromPrivateKeyInfo(PKCS8EncodedKeySpec spec, CryptoToken token) throws TokenException { return fromPrivateKeyInfo(spec.getEncoded(), token); } /** * Imports a PrivateKeyInfo, storing it as a temporary PrivateKey * on the given token. * The key will be a temporary (session) key until it is imported * into a KeyStore, at which point it will be made a permanent (token) * object. */ public static PK11PrivKey fromPrivateKeyInfo(byte[] pki, CryptoToken token) throws TokenException { return fromPrivateKeyInfo(pki, token, null); } /** * Imports a PrivateKeyInfo, storing it as a temporary PrivateKey * on the given token. * The key will be a temporary (session) key until it is imported * into a KeyStore, at which point it will be made a permanent (token) * object. * @param publicValue An encoding of the public key, as used by the NSS * pk11wrap code. Don't use this unless you know what you're doing. */ public static native PK11PrivKey fromPrivateKeyInfo(byte[] pki, CryptoToken token, byte[] publicValue) throws TokenException; protected DSAParameterSpec getDSAParams() throws TokenException { byte[][] pqgArray = getDSAParamsNative(); return new DSAParameterSpec( new BigInteger(1, pqgArray[0]), new BigInteger(1, pqgArray[1]), new BigInteger(1, pqgArray[2]) ); } private native byte[][] getDSAParamsNative() throws TokenException; } class PrivateKeyProxy extends KeyProxy { public static Logger logger = LoggerFactory.getLogger(PrivateKeyProxy.class); public PrivateKeyProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); } jss-4.6.3/org/mozilla/jss/pkcs11/PK11PubKey.c000066400000000000000000000426021362106420000204200ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_PublicKeyProxy.h" #include "_jni/org_mozilla_jss_pkcs11_PK11RSAPublicKey.h" #include "_jni/org_mozilla_jss_pkcs11_PK11DSAPublicKey.h" #include "_jni/org_mozilla_jss_pkcs11_PK11ECPublicKey.h" #include #include #include #include #include #include #include #include #include #include "pk11util.h" #include "java_ids.h" #include #include /*********************************************************************** * PublicKeyProxy.releaseNativeResources */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PublicKeyProxy_releaseNativeResources (JNIEnv *env, jobject this) { SECKEYPublicKey *pubk; PRThread * VARIABLE_MAY_NOT_BE_USED pThread; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); /* Get the SECKEYPublicKey structure */ if(JSS_getPtrFromProxy(env, this, (void**) &pubk) != PR_SUCCESS) { PR_ASSERT( PR_FALSE ); goto finish; } PR_ASSERT(pubk != NULL); SECKEY_DestroyPublicKey(pubk); finish: PR_DetachThread(); return; } /*********************************************************************** ** JSS_PK11_wrapPubKey */ jobject JSS_PK11_wrapPubKey(JNIEnv *env, SECKEYPublicKey **pKey) { jobject pubKey=NULL; jclass keyClass; KeyType keyType; jmethodID constructor; jbyteArray ptr; char *keyClassName; PR_ASSERT(env!=NULL && pKey!=NULL); /* What kind of public key? */ keyType = (*pKey)->keyType; switch(keyType) { case rsaKey: keyClassName = PK11_RSA_PUBKEY_CLASS_NAME; break; case dsaKey: keyClassName = PK11_DSA_PUBKEY_CLASS_NAME; break; case ecKey: keyClassName = PK11_EC_PUBKEY_CLASS_NAME; break; default: keyClassName = PK11PUBKEY_CLASS_NAME; break; } keyClass = (*env)->FindClass(env, keyClassName); if(keyClass==NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, keyClass, PK11PUBKEY_CONSTRUCTOR_NAME, PK11PUBKEY_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } ptr = JSS_ptrToByteArray(env, (void*)*pKey); if(ptr == NULL) { ASSERT_OUTOFMEM(env); goto finish; } pubKey = (*env)->NewObject(env, keyClass, constructor, ptr); if(pubKey == NULL) { ASSERT_OUTOFMEM(env); goto finish; } *pKey = NULL; finish: if(pubKey==NULL && *pKey!=NULL) { SECKEY_DestroyPublicKey(*pKey); *pKey = NULL; } PR_DetachThread(); return pubKey; } /*********************************************************************** * Given a PublicKey object, extracts the SECKEYPublicKey* and stores it * at the given address. * * pubkObject: A JNI reference to a PublicKey object. * ptr: Address of a SECKEYPublicKey* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getPubKeyPtr(JNIEnv *env, jobject pubkObject, SECKEYPublicKey** ptr) { PR_ASSERT(env!=NULL && pubkObject!=NULL); /* Get the pointer from the key proxy */ PR_ASSERT(sizeof(SECKEYPublicKey*) == sizeof(void*)); return JSS_getPtrFromProxyOwner(env, pubkObject, KEY_PROXY_FIELD, KEY_PROXY_SIG, (void**)ptr); } /*********************************************************************** * PK11PubKey.verifyKeyIsOnToken */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_verifyKeyIsOnToken (JNIEnv *env, jobject this, jobject token) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread; SECKEYPublicKey *key = NULL; PK11SlotInfo *slot = NULL; PK11SlotInfo *keySlot = NULL; pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); if( JSS_PK11_getPubKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } if( JSS_PK11_getTokenSlotPtr(env, token, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } #if 0 keySlot = PK11_GetSlotFromPublicKey(key); #else keySlot = PK11_ReferenceSlot(key->pkcs11Slot); #endif if(keySlot == PK11_GetInternalKeySlot()) { /* hack for internal module */ if(slot != keySlot && slot != PK11_GetInternalSlot()) { JSS_throwMsg(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION, "Key is not present on this token"); goto finish; } } else if(keySlot != slot) { JSS_throwMsg(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION, "Key is not present on this token"); goto finish; } finish: if(keySlot != NULL) { PK11_FreeSlot(keySlot); } PR_DetachThread(); } /*********************************************************************** * PK11PubKey.getKeyType * * Returns: The KeyType of this key. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_getKeyType (JNIEnv *env, jobject this) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread; SECKEYPublicKey *pubk; KeyType keyType; char* keyTypeFieldName; jclass keyTypeClass; jfieldID keyTypeField; jobject keyTypeObject = NULL; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); if(JSS_PK11_getPubKeyPtr(env, this, &pubk) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL ); goto finish; } PR_ASSERT(pubk!=NULL); keyType = pubk->keyType; switch(keyType) { case nullKey: keyTypeFieldName = NULL_KEYTYPE_FIELD; break; case rsaKey: keyTypeFieldName = RSA_KEYTYPE_FIELD; break; case dsaKey: keyTypeFieldName = DSA_KEYTYPE_FIELD; break; case ecKey: keyTypeFieldName = EC_KEYTYPE_FIELD; break; case fortezzaKey: keyTypeFieldName = FORTEZZA_KEYTYPE_FIELD; break; case dhKey: keyTypeFieldName = DH_KEYTYPE_FIELD; break; case keaKey: keyTypeFieldName = KEA_KEYTYPE_FIELD; break; default: PR_ASSERT(PR_FALSE); keyTypeFieldName = NULL_KEYTYPE_FIELD; break; } keyTypeClass = (*env)->FindClass(env, KEYTYPE_CLASS_NAME); if(keyTypeClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyTypeField = (*env)->GetStaticFieldID(env, keyTypeClass, keyTypeFieldName, KEYTYPE_FIELD_SIG); if(keyTypeField==NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyTypeObject = (*env)->GetStaticObjectField( env, keyTypeClass, keyTypeField); if(keyTypeObject == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: PR_DetachThread(); return keyTypeObject; } typedef enum { DSA_P, DSA_Q, DSA_G, DSA_PUBLIC, RSA_MODULUS, RSA_PUBLIC_EXPONENT, EC_CURVE, EC_W } PublicKeyField; static jbyteArray get_public_key_info(JNIEnv *env, jobject this, PublicKeyField field); /********************************************************************** * * PK11RSAPublicKey.getModulusByteArray * * Returns the modulus of this RSA Public Key. The format is a big-endian * octet string in a byte array, suitable for importing into a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11RSAPublicKey_getModulusByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, RSA_MODULUS); } /********************************************************************** * * PK11RSAPublicKey.getPublicExponentByteArray * * Returns the modulus of this RSA Public Key. The format is a big-endian * octet string in a byte array, suitable for importing into a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11RSAPublicKey_getPublicExponentByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, RSA_PUBLIC_EXPONENT); } /********************************************************************** * * PK11DSAPublicKey.getPByteArray * * Returns the prime of this DSA Public Key. The format is a big-endian * octet string in a byte array, suitable for importing into a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getPByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, DSA_P); } /********************************************************************** * * PK11DSAPublicKey.getQByteArray * * Returns the subprime of this DSA Public Key. The format is a big-endian * octet string in a byte array, suitable for importing into a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getQByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, DSA_Q); } /********************************************************************** * * PK11DSAPublicKey.getGByteArray * * Returns the base of this DSA Public Key. The format is a big-endian * octet string in a byte array, suitable for importing into a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getGByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, DSA_G); } /********************************************************************** * * PK11DSAPublicKey.getYByteArray * * Returns the public value (Y) of this DSA Public Key. The format is a * big-endian octet string in a byte array, suitable for importing into * a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getYByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, DSA_PUBLIC); } /********************************************************************** * * PK11ECPublicKey.getParamByteArray * * Returns the curve of this EC Public Key. The format is a DER encoded * octet string in a byte array. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11ECPublicKey_getCurveByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, EC_CURVE); } /********************************************************************** * * PK11ECPublicKey.getWByteArray * * Returns the public value (W) of this EC Public Key. * The format is a 1 byte to indicate compression followed by points * Wx and Wy unsigned and concatenated. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11ECPublicKey_getWByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, EC_W); } /********************************************************************** * g e t _ p u b l i c _ k e y _ i n f o * * Looks up a field in a PK11PubKey and converts it to a Java byte array. * The field is assumed to be a SECItem big-endian octet string. The byte * array is suitable for feeding to a BigInteger constructor. */ static jbyteArray get_public_key_info (JNIEnv *env, jobject this, PublicKeyField field) { SECKEYPublicKey *pubk; jbyteArray byteArray=NULL; SECItem *item=NULL; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getPubKeyPtr(env, this, &pubk) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } switch( field ) { case DSA_P: PR_ASSERT(pubk->keyType == dsaKey); item = &pubk->u.dsa.params.prime; break; case DSA_Q: PR_ASSERT(pubk->keyType == dsaKey); item = &pubk->u.dsa.params.subPrime; break; case DSA_G: PR_ASSERT(pubk->keyType == dsaKey); item = &pubk->u.dsa.params.base; break; case DSA_PUBLIC: PR_ASSERT(pubk->keyType == dsaKey); item = &pubk->u.dsa.publicValue; break; case RSA_MODULUS: PR_ASSERT(pubk->keyType == rsaKey); item = &pubk->u.rsa.modulus; break; case RSA_PUBLIC_EXPONENT: PR_ASSERT(pubk->keyType == rsaKey); item = &pubk->u.rsa.publicExponent; break; case EC_CURVE: PR_ASSERT(pubk->keyType == ecKey); item = &pubk->u.ec.DEREncodedParams; break; case EC_W: PR_ASSERT(pubk->keyType == ecKey); item = &pubk->u.ec.publicValue; break; default: PR_ASSERT(PR_FALSE); break; } PR_ASSERT(item != NULL); byteArray = JSS_OctetStringToByteArray(env, item); if(byteArray == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } finish: return byteArray; } /*********************************************************************** * * p u b k F r o m R a w * * Creates a PK11PubKey from its raw form. The raw form is a DER encoding * of the public key. For example, this is what is stored in a * SubjectPublicKeyInfo. */ static jobject pubkFromRaw(JNIEnv *env, CK_KEY_TYPE type, jbyteArray rawBA) { jobject pubkObj=NULL; SECKEYPublicKey *pubk=NULL; SECItem *pubkDER=NULL; /* validate args */ PR_ASSERT(env!=NULL); if( rawBA == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } pubkDER = JSS_ByteArrayToSECItem(env, rawBA); if( pubkDER == NULL ) { /* exception was thrown */ goto finish; } pubk = SECKEY_ImportDERPublicKey(pubkDER, type); if( pubk == NULL ) { JSS_throw(env, INVALID_KEY_FORMAT_EXCEPTION); goto finish; } /* this clears pubk */ pubkObj = JSS_PK11_wrapPubKey(env, &pubk); if( pubkObj == NULL ) { /* exception was thrown */ goto finish; } finish: if(pubkDER!=NULL) { SECITEM_FreeItem(pubkDER, PR_TRUE /*freeit*/); } return pubkObj; } /*********************************************************************** * * PK11PubKey.fromRawNative */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_fromRawNative (JNIEnv *env, jclass clazz, jint type, jbyteArray rawBA) { return pubkFromRaw(env, type, rawBA); } /*********************************************************************** * * PK11PubKey.RSAfromRaw * Deprecated: call fromRawNative instead. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_RSAFromRaw (JNIEnv *env, jclass clazz, jbyteArray rawBA) { return pubkFromRaw(env, CKK_RSA, rawBA); } /*********************************************************************** * * PK11PubKey.DSAfromRaw * Deprecated: call fromRawNative instead. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_DSAFromRaw (JNIEnv *env, jclass clazz, jbyteArray rawBA) { return pubkFromRaw(env, CKK_DSA, rawBA); } /*********************************************************************** * * PK11PubKey.getEncoded * * Converts the public key to a SubjectPublicKeyInfo, and returns its * DER-encoding. */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_getEncoded (JNIEnv *env, jobject this) { SECKEYPublicKey *pubk; jbyteArray encodedBA=NULL; SECItem *spkiDER=NULL; /* get the public key */ if( JSS_PK11_getPubKeyPtr(env, this, &pubk) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } spkiDER = PK11_DEREncodePublicKey(pubk); if( spkiDER == NULL ) { JSS_trace(env, JSS_TRACE_ERROR, "unable to DER-encode" " SubjectPublicKeyInfo"); JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* convert the der-encoding to a Java byte array */ encodedBA = JSS_SECItemToByteArray(env, spkiDER); finish: if(spkiDER!=NULL) { SECITEM_FreeItem(spkiDER, PR_TRUE /*freeit*/); } return encodedBA; } /*********************************************************************** * * PK11PubKey.fromSPKI * * Generates a PK11PubKey from a DER-encoded SubjectPublicKeyInfo. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_fromSPKI (JNIEnv *env, jobject this, jbyteArray spkiBA) { jobject pubkObj = NULL; SECItem *spkiItem = NULL; CERTSubjectPublicKeyInfo *spki = NULL; SECKEYPublicKey *pubk = NULL; /* * convert byte array to SECItem */ spkiItem = JSS_ByteArrayToSECItem(env, spkiBA); if( spkiItem == NULL ) { /* exception was thrown */ goto finish; } /* * convert SECItem to SECKEYPublicKey */ spki = SECKEY_DecodeDERSubjectPublicKeyInfo(spkiItem); if( spki == NULL ) { JSS_throwMsg(env, INVALID_KEY_FORMAT_EXCEPTION, "Unable to decode DER-encoded SubjectPublicKeyInfo: " "invalid DER encoding"); goto finish; } pubk = SECKEY_ExtractPublicKey(spki); if( pubk == NULL ) { JSS_throwMsg(env, INVALID_KEY_FORMAT_EXCEPTION, "Unable to decode SubjectPublicKeyInfo: DER encoding problem, or" " unrecognized key type "); goto finish; } /* * put a Java wrapper around it */ pubkObj = JSS_PK11_wrapPubKey(env, &pubk); /* this clears pubk */ if( pubkObj == NULL ) { /* exception was thrown */ goto finish; } finish: if( spkiItem != NULL ) { SECITEM_FreeItem(spkiItem, PR_TRUE /*freeit*/); } if( spki != NULL ) { SECKEY_DestroySubjectPublicKeyInfo(spki); } if( pubk != NULL ) { SECKEY_DestroyPublicKey(pubk); } return pubkObj; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11PubKey.java000066400000000000000000000064141362106420000211200ustar00rootroot00000000000000/* 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.pkcs11; import org.mozilla.jss.crypto.InvalidKeyFormatException; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.util.Assert; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PK11PubKey extends org.mozilla.jss.pkcs11.PK11Key implements java.security.PublicKey { private static final long serialVersionUID = 1L; protected PK11PubKey(byte[] pointer) { assert(pointer!=null); keyProxy = new PublicKeyProxy(pointer); } /** * Make sure this key lives on the given token. */ public native void verifyKeyIsOnToken(PK11Token token) throws org.mozilla.jss.crypto.NoSuchItemOnTokenException; public native KeyType getKeyType(); public String getAlgorithm() { return getKeyType().toString(); } /** * Creates a PK11PubKey from its raw form. The raw form is a DER encoding * of the public key. For example, this is what is stored in a * SubjectPublicKeyInfo. * * @param type The type of private key to be decoded. * @param rawKey The bytes of the raw key. * @exception InvalidKeyFormatException If the raw key could not be * decoded. * @deprecated This method works for RSA keys but not DSA or EC keys. Use * fromSPKI() instead. * @see #fromSPKI(byte[]) */ @Deprecated public static PK11PubKey fromRaw(PrivateKey.Type type, byte[] rawKey) throws InvalidKeyFormatException { if( type != PrivateKey.Type.RSA ) { throw new InvalidKeyFormatException( "fromRaw() is broken for DSA keys. Use fromSPKI() instead."); } return fromRawNative( type.getPKCS11Type(), rawKey ); } /** * param type The PKCS #11 type of the key (CKK_). */ private static native PK11PubKey fromRawNative(int type, byte[] rawKey) throws InvalidKeyFormatException; /** * Creates a PK11PubKey from a SubjectPublicKeyInfo. * * @param spki The BER-encoded SubjectPublicKeyInfo. * @exception InvalidKeyFormatException If the SPKI could not be * decoded. */ public static native PK11PubKey fromSPKI(byte[] spki) throws InvalidKeyFormatException; /** * deprecated Use fromRawNative instead. */ private static native PK11PubKey RSAFromRaw(byte[] rawKey); /** * deprecated Use fromRawNative instead. */ private static native PK11PubKey DSAFromRaw(byte[] rawKey); /** * Returns a DER-encoded SubjectPublicKeyInfo representing this key. */ public native byte[] getEncoded(); /** * The name of the primary encoding format of this key. The primary * encoding format is X.509 SubjectPublicKeyInfo, and the name * is "X.509". */ public String getFormat() { return "X.509"; } } class PublicKeyProxy extends KeyProxy { public static Logger logger = LoggerFactory.getLogger(PublicKeyProxy.class); public PublicKeyProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); } jss-4.6.3/org/mozilla/jss/pkcs11/PK11RSAPrivateKey.java000066400000000000000000000016101362106420000223430ustar00rootroot00000000000000package org.mozilla.jss.pkcs11; import java.math.BigInteger; import org.mozilla.jss.crypto.PrivateKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; class PK11RSAPrivateKey extends PK11PrivKey implements java.security.interfaces.RSAPrivateKey { public static Logger logger = LoggerFactory.getLogger(PK11RSAPrivateKey.class); private static final long serialVersionUID = 1L; private PK11RSAPrivateKey() { super(null); } protected PK11RSAPrivateKey(byte[] pointer) { super(pointer); } public PrivateKey.Type getType() { return PrivateKey.Type.RSA; } public BigInteger getModulus() { logger.debug("PK11RSAPrivateKey: getModulus()"); return new BigInteger(1, getModulusByteArray()); } native byte[] getModulusByteArray(); public BigInteger getPrivateExponent() { // !!! return null; } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11RSAPublicKey.java000066400000000000000000000017651362106420000221620ustar00rootroot00000000000000/* 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.pkcs11; import java.security.interfaces.RSAPublicKey; import java.math.BigInteger; public class PK11RSAPublicKey extends PK11PubKey implements RSAPublicKey { private static final long serialVersionUID = 1L; public PK11RSAPublicKey(byte[] pointer) { super(pointer); } public BigInteger getModulus() { try { return new BigInteger(1, getModulusByteArray()); } catch( NumberFormatException e) { return null; } } private native byte[] getModulusByteArray(); public BigInteger getPublicExponent() { try { return new BigInteger(1, getPublicExponentByteArray()); } catch( NumberFormatException e) { return null; } } private native byte[] getPublicExponentByteArray(); } jss-4.6.3/org/mozilla/jss/pkcs11/PK11SecureRandom.c000066400000000000000000000116441362106420000216120ustar00rootroot00000000000000/* 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/. */ /* * NSS and NSPR header files */ #include #include /* * JNI header files */ #include "_jni/org_mozilla_jss_pkcs11_PK11SecureRandom.h" /* * JSS header files */ #include /* * JNI FUNCTION: PK11SecureRandom.setSeed * * JNI FUNCTION TYPE: protected * * JNI INPUTS: * * env * The JNI object through which all JNI functions are referenced * * this * A JNI reference to the class which defines this native method * * INPUTS: * * N/A * * OUTPUTS: * * jseed * A JNI array for storage of the random byte seed sequence * * ERRORS: * * N/A * * RETURN: * * Upon success, this method returns a byte array * containing a random byte sequence * * NOTES: * * This routine is called to seed the pseudo-random number generator. * * JNI NOTES: * * Class: org_mozilla_jss_pkcs11_PK11SecureRandom * Method: setSeed * Signature: ([B)V */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11SecureRandom_setSeed ( JNIEnv* env, jobject this, jbyteArray jseed ) { /* * "JNI" data members */ jbyte* jdata = NULL; jsize jlen = 0; /* * "C" data members */ PRThread* VARIABLE_MAY_NOT_BE_USED pThread = NULL; SECStatus status = PR_FALSE; PK11SlotInfo* slot = NULL; /* * Perform initial assertions */ PR_ASSERT( env != NULL && this != NULL ); /* * Attach to the external java thread */ pThread = PR_AttachThread( PR_SYSTEM_THREAD, 0, NULL ); PR_ASSERT( pThread != NULL ); /* * Obtain the appropriate "slot" */ slot = PK11_GetBestSlot( CKM_FAKE_RANDOM, NULL ); if( slot == NULL ) { PR_ASSERT( PR_FALSE ); goto finish; } /* * Convert "JNI jbyteArray" into "JNI jbyte*" so * that it can be cast into a "C unsigned char*"; * also get its length. */ JSS_RefByteArray(env, jseed, &jdata, &jlen); /* * Seed the pseudo-random number generator; * currently, failures from this routine are ignored */ status = PK11_SeedRandom( slot, ( unsigned char* ) jdata, ( int ) jlen ); if( status != SECSuccess ) { PR_ASSERT( PR_FALSE ); goto finish; } finish: /* * Copy back the contents of the "JNI jbyte*" and * free any resources associated with it */ JSS_DerefByteArray(env, jseed, jdata, 0); /* * Free any "C" resources */ if( slot != NULL ) { PK11_FreeSlot( slot ); } slot = NULL; /* * Detach from the external java thread and return */ PR_DetachThread(); return; } /* * JNI FUNCTION: PK11SecureRandom.nextBytes * * JNI FUNCTION TYPE: protected * * JNI INPUTS: * * env * The JNI object through which all JNI functions are referenced * * this * A JNI reference to the class which defines this native method * * INPUTS: * * N/A * * OUTPUTS: * * jbytes * A JNI array for storage of the random byte sequence * * ERRORS: * * N/A * * RETURN: * * Upon success, this method returns a byte array * containing a random byte sequence * * NOTES: * * This routine is called to generate a pseudo-random number. * * JNI NOTES: * * Class: org_mozilla_jss_pkcs11_PK11SecureRandom * Method: nextBytes * Signature: ([B)V */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11SecureRandom_nextBytes ( JNIEnv* env, jobject this, jbyteArray jbytes ) { /* * "JNI" data members */ jbyte* jdata = NULL; jsize jlen = 0; /* * "C" data members */ PRThread* VARIABLE_MAY_NOT_BE_USED pThread = NULL; SECStatus status = PR_FALSE; /* * Perform initial assertions */ PR_ASSERT( env != NULL && this != NULL ); /* * Attach to the external java thread */ pThread = PR_AttachThread( PR_SYSTEM_THREAD, 0, NULL ); PR_ASSERT( pThread != NULL ); /* * Convert "JNI jbyteArray" into "JNI jbyte*" so * that it can be cast into a "C unsigned char*"; * also get its length. */ JSS_RefByteArray(env, jbytes, &jdata, &jlen); /* * Generate a pseudo-random number; currently, * failures from this routine are ignored */ status = PK11_GenerateRandom( ( unsigned char* ) jdata, ( int ) jlen ); if( status != SECSuccess ) { goto finish; } finish: /* * Copy back the contents of the "JNI jbyte*" and * free any resources associated with it */ JSS_DerefByteArray(env, jbytes, jdata, 0); /* * Detach from the external java thread and return */ PR_DetachThread(); return; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11SecureRandom.java000066400000000000000000000021761362106420000223110ustar00rootroot00000000000000/* 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.pkcs11; /** * A random number generator for PKCS #11. * * @see org.mozilla.jss.CryptoManager */ public final class PK11SecureRandom implements org.mozilla.jss.crypto.JSSSecureRandom { //////////////////////////////////////////////////// // construction and finalization //////////////////////////////////////////////////// public PK11SecureRandom() {} //////////////////////////////////////////////////// // public routines //////////////////////////////////////////////////// public synchronized native void setSeed( byte[] seed ); public void setSeed( long seed ) { byte[] data = new byte[8]; // convert long into 8-byte byte array for( int i = 0; i < 8; i++ ) { data[i] = ( byte ) ( seed >> ( 8 * i ) ); } setSeed( data ); } public synchronized native void nextBytes( byte bytes[] ); } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Signature.c000066400000000000000000000467261362106420000211750ustar00rootroot00000000000000/* 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/. */ #include #include #include #include #include #include "_jni/org_mozilla_jss_pkcs11_PK11Signature.h" #include "_jni/org_mozilla_jss_pkcs11_SigContextProxy.h" #include #include #include #include #include #include #include #include "pk11util.h" static PRStatus getPrivateKey(JNIEnv *env, jobject sig, SECKEYPrivateKey**key); static PRStatus getPublicKey(JNIEnv *env, jobject sig, SECKEYPublicKey**key); static PRStatus getSomeKey(JNIEnv *env, jobject sig, void **key, short type); static SECOidTag getAlgorithm(JNIEnv *env, jobject sig); static void setSigContext(JNIEnv *env, jobject sig, jobject context); static PRStatus getSigContext(JNIEnv *env, jobject sig, void**pContext, SigContextType* pType); /*********************************************************************** * * PK11Signature.initSigContext */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_initSigContext (JNIEnv *env, jobject this) { SGNContext *ctxt=NULL; jobject contextProxy=NULL; SECKEYPrivateKey *privk; /* Extract the private key from the PK11Signature */ if( getPrivateKey(env, this, &privk) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /* Start the signing operation */ ctxt = SGN_NewContext(getAlgorithm(env, this), privk); if(ctxt == NULL) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to create signing context"); goto finish; } if( SGN_Begin(ctxt) != SECSuccess ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to begin signing context"); goto finish; } /* Create a contextProxy and stick it in the PK11Signature object */ contextProxy = JSS_PK11_wrapSigContextProxy(env, (void**)&ctxt, SGN_CONTEXT); if(contextProxy == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } setSigContext(env, this, contextProxy); finish: if(contextProxy==NULL && ctxt!=NULL) { /* we created a context but not the Java wrapper, so we need to * delete the context here. */ SGN_DestroyContext(ctxt, PR_TRUE /*freeit*/); } } JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_initVfyContext (JNIEnv *env, jobject this) { VFYContext *ctxt=NULL; jobject contextProxy=NULL; SECKEYPublicKey *pubk; if( getPublicKey(env, this, &pubk) != PR_SUCCESS ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } ctxt = VFY_CreateContext(pubk, NULL /*sig*/, getAlgorithm(env, this), NULL /*wincx*/); if( ctxt == NULL) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to create verification context"); goto finish; } if( VFY_Begin(ctxt) != SECSuccess) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to begin verification context"); goto finish; } /* create a ContextProxy and stick it in the PK11Signature object */ contextProxy = JSS_PK11_wrapSigContextProxy(env, (void**)&ctxt, VFY_CONTEXT); if(contextProxy == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } setSigContext(env, this, contextProxy); finish: if(contextProxy==NULL && ctxt!=NULL) { /* we created a context but not the Java wrapper, so we need to * delete the context here */ VFY_DestroyContext(ctxt, PR_TRUE /*freeit*/); } } /********************************************************************** * * PK11Signature.engineUpdateNative * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_engineUpdateNative (JNIEnv *env, jobject this, jbyteArray bArray, jint offset, jint length) { SigContextType type; void *ctxt; jbyte *bytes=NULL; jint numBytes; /* Extract the signature context */ if( getSigContext(env, this, &ctxt, &type) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(ctxt != NULL); /* Get the bytes to be updated */ if (!JSS_RefByteArray(env, bArray, &bytes, &numBytes)) { ASSERT_OUTOFMEM(env); goto finish; } if( offset < 0 || offset >= numBytes || length < 0 || (offset+length) > numBytes || (offset+length) < 0 ) { JSS_throw(env, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION); goto finish; } /* Update the context */ if(type == SGN_CONTEXT) { if( SGN_Update( (SGNContext*)ctxt, (unsigned char*)bytes + offset, (unsigned)length ) != SECSuccess) { JSS_throwMsg(env, SIGNATURE_EXCEPTION, "update failed"); goto finish; } } else { PR_ASSERT( type == VFY_CONTEXT ); if( VFY_Update( (VFYContext*)ctxt, (unsigned char*)bytes + offset, (unsigned) length ) != SECSuccess) { JSS_throwMsg(env, SIGNATURE_EXCEPTION, "update failed"); goto finish; } } finish: JSS_DerefByteArray(env, bArray, bytes, JNI_ABORT); } /********************************************************************** * * PK11Signature.engineSignNative * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_engineSignNative (JNIEnv *env, jobject this) { SGNContext *ctxt; SigContextType type; SECItem signature; jbyteArray sigArray=NULL; PR_ASSERT(env!=NULL && this!=NULL); signature.data = NULL; /* * Extract the signature context from the Java wrapper */ if( getSigContext(env, this, (void**)&ctxt, &type) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(ctxt!=NULL && type==SGN_CONTEXT); /* * Finish the signing operation. */ if( SGN_End(ctxt, &signature) != SECSuccess) { JSS_throwMsgPrErr(env, SIGNATURE_EXCEPTION, "Signing operation failed"); goto finish; } /* * Convert SECItem signature to Java byte array */ sigArray = JSS_ToByteArray(env, signature.data, signature.len); if (sigArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: if( signature.data != NULL ) { PR_Free(signature.data); } return sigArray; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_engineVerifyNative (JNIEnv *env, jobject this, jbyteArray sigArray) { jboolean verified = JNI_FALSE; VFYContext *ctxt; SigContextType type; SECItem sigItem = {siBuffer, NULL, 0}; PR_ASSERT( env!=NULL && this!=NULL && sigArray!=NULL); /* * Lookup the context */ if( getSigContext(env, this, (void**)&ctxt, &type) != PR_SUCCESS) { PR_ASSERT(PR_FALSE); JSS_throwMsg(env, SIGNATURE_EXCEPTION, "Unable to retrieve verification context"); goto finish; } if(type != VFY_CONTEXT) { PR_ASSERT(PR_FALSE); JSS_throwMsg(env, SIGNATURE_EXCEPTION, "Verification engine has signature context"); goto finish; } /* * Convert signature to SECItem */ if (!JSS_RefByteArray(env, sigArray, (jbyte **) &sigItem.data, (jsize *) &sigItem.len)) { ASSERT_OUTOFMEM(env); goto finish; } /* * Finish the verification operation */ if( VFY_EndWithSignature(ctxt, &sigItem) == SECSuccess) { verified = JNI_TRUE; } else if( PR_GetError() != SEC_ERROR_BAD_SIGNATURE) { PR_ASSERT(PR_FALSE); JSS_throwMsg(env, SIGNATURE_EXCEPTION, "Failed to complete verification operation"); goto finish; } finish: JSS_DerefByteArray(env, sigArray, sigItem.data, JNI_ABORT); return verified; } /* * Extract the algorithm from a PK11Signature. * * sig: a PK11Signature. * Returns: the algorithm of this signature, or SEC_OID_UNKNOWN if an * error occurs. */ static SECOidTag getAlgorithm(JNIEnv *env, jobject sig) { jclass sigClass; jfieldID algField; jobject alg; SECOidTag retval=SEC_OID_UNKNOWN; PR_ASSERT(env!=NULL && sig!=NULL); sigClass = (*env)->GetObjectClass(env, sig); PR_ASSERT(sigClass != NULL); algField = (*env)->GetFieldID( env, sigClass, SIG_ALGORITHM_FIELD, SIG_ALGORITHM_SIG); if(algField == NULL) { ASSERT_OUTOFMEM(env); goto finish; } alg = (*env)->GetObjectField(env, sig, algField); if(alg == NULL) { ASSERT_OUTOFMEM(env); goto finish; } retval = JSS_getOidTagFromAlg(env, alg); finish: return retval; } /* * Set the contextProxy member of a PK11Signature. * * sig: the PK11Signature whose contextProxy we are setting. * context: the ContextProxy we are setting in the signature. It may be NULL. **/ static void setSigContext(JNIEnv *env, jobject sig, jobject context) { jclass sigClass; jfieldID contextField; PR_ASSERT(env!=NULL && sig!=NULL); sigClass = (*env)->GetObjectClass(env, sig); PR_ASSERT(sigClass!=NULL); contextField = (*env)->GetFieldID( env, sigClass, SIG_CONTEXT_PROXY_FIELD, SIG_CONTEXT_PROXY_SIG); if(contextField == NULL) { ASSERT_OUTOFMEM(env); /* This function doesn't advertise that it can throw exceptions, * so we shouldn't throw one */ (*env)->ExceptionClear(env); return; } (*env)->SetObjectField(env, sig, contextField, context); } /* * Don't call this if there is no context. */ static PRStatus getSigContext(JNIEnv *env, jobject sig, void**pContext, SigContextType* pType) { jfieldID contextField; jclass sigClass; jobject proxy; PR_ASSERT(env!=NULL && sig!=NULL && pContext!=NULL && pType!=NULL); sigClass = (*env)->GetObjectClass(env, sig); #ifdef DEBUG { jclass realSigClass = (*env)->FindClass(env, PK11SIGNATURE_CLASS_NAME); PR_ASSERT( (*env)->IsInstanceOf(env, sig, realSigClass) ); } #endif contextField = (*env)->GetFieldID(env, sigClass, SIG_CONTEXT_PROXY_FIELD, SIG_CONTEXT_PROXY_SIG); if(contextField == NULL) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } proxy = (*env)->GetObjectField(env, sig, contextField); if(proxy == NULL) { PR_ASSERT(PR_FALSE); JSS_throw(env, TOKEN_EXCEPTION); return PR_FAILURE; } if( JSS_PK11_getSigContext(env, proxy, pContext, pType) != PR_SUCCESS ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return PR_FAILURE; } PR_ASSERT(*pContext != NULL); return PR_SUCCESS; } #define PUBLICKEYTYPE 0 #define PRIVATEKEYTYPE 1 /********************************************************************** * * g e t P r i v a t e K e y */ static PRStatus getPrivateKey(JNIEnv *env, jobject sig, SECKEYPrivateKey**key) { return getSomeKey(env, sig, (void**)key, PRIVATEKEYTYPE); } /********************************************************************** * * g e t P u b l i c K e y */ static PRStatus getPublicKey(JNIEnv *env, jobject sig, SECKEYPublicKey**key) { return getSomeKey(env, sig, (void**)key, PUBLICKEYTYPE); } static PRStatus getSomeKey(JNIEnv *env, jobject sig, void **key, short type) { jfieldID keyField; jclass sigClass; jobject keyProxy; PR_ASSERT(env!=NULL && sig!=NULL && key!=NULL); sigClass = (*env)->GetObjectClass(env, sig); #ifdef DEBUG { jclass realSigClass = (*env)->FindClass(env, PK11SIGNATURE_CLASS_NAME); PR_ASSERT( (*env)->IsInstanceOf(env, sig, realSigClass) ); } #endif keyField = (*env)->GetFieldID(env, sigClass, SIG_KEY_FIELD, SIG_KEY_SIG); if(keyField == NULL) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } keyProxy = (*env)->GetObjectField(env, sig, keyField); if(keyProxy == NULL) { PR_ASSERT(PR_FALSE); JSS_throw(env, TOKEN_EXCEPTION); return PR_FAILURE; } if(type == PRIVATEKEYTYPE) { if( JSS_PK11_getPrivKeyPtr(env, keyProxy, (SECKEYPrivateKey**)key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return PR_FAILURE; } } else { if( JSS_PK11_getPubKeyPtr(env, keyProxy, (SECKEYPublicKey**)key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return PR_FAILURE; } } PR_ASSERT(*key != NULL); return PR_SUCCESS; } struct SigContextProxyStr { void *ctxt; SigContextType type; }; /*********************************************************************** * J S S _ P K 1 1 _ g e t S i g C o n t e x t * * Extracts the context pointer from a SigContextProxy. * proxy: a non-NULL SigContextProxy object. * pContext: address of a SGNContext* or VFYContext* where the pointer will be * stored. * pType: address of a SigContextType where will be stored the type * of the context either SGN_CONTEXT or VFY_CONTEXT. * Returns: PR_SUCCESS, unless an exception was thrown. */ PRStatus JSS_PK11_getSigContext(JNIEnv *env, jobject proxy, void**pContext, SigContextType *pType) { SigContextProxy *ctxtProxy; PR_ASSERT(env!=NULL && proxy!=NULL && pContext!=NULL && pType!=NULL); if( JSS_getPtrFromProxy(env, proxy, (void**)&ctxtProxy) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } /* Make sure the pointers are OK */ if(ctxtProxy==NULL || ctxtProxy->ctxt==NULL) { PR_ASSERT(PR_FALSE); JSS_throw(env, SIGNATURE_EXCEPTION); return PR_FAILURE; } /* Everything looks good, return the pointer */ *pContext = ctxtProxy->ctxt; *pType = ctxtProxy->type; return PR_SUCCESS; } /********************************************************************** * * J S S _ P K 1 1 _ w r a p S i g C o n t e x t P r o x y * * Wraps a SGNContext in a SigContextProxy. * * ctxt: address of ptr to a SGNContext or VfyContext, which must not be NULL. * It will be eaten by the wrapper and set to NULL. * * type: type of context, either SGN_CONTEXT or VFY_CONTEXT * Returns: a new SigContextProxy object wrapping the given SGNContext, or * NULL if an exception was thrown. */ jobject JSS_PK11_wrapSigContextProxy(JNIEnv *env, void **ctxt, SigContextType type) { jclass proxyClass; jmethodID constructor; jbyteArray byteArray; SigContextProxy *proxy=NULL; jobject Context=NULL; PR_ASSERT(env!=NULL && ctxt!=NULL && *ctxt!=NULL); /* Create the proxy structure */ proxy = (SigContextProxy*) PR_Malloc(sizeof(SigContextProxy)); if(proxy == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } proxy->ctxt = *ctxt; proxy->type = type; byteArray = JSS_ptrToByteArray(env, (void*)proxy); /* * Lookup the class and constructor */ proxyClass = (*env)->FindClass(env, SIG_CONTEXT_PROXY_CLASS_NAME); if( proxyClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, proxyClass, SIG_CONTEXT_PROXY_CONSTRUCTOR_NAME, SIG_CONTEXT_PROXY_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* call the constructor */ Context = (*env)->NewObject(env, proxyClass, constructor, byteArray); finish: if(Context==NULL) { /* didn't work, so free resources */ if(proxy!=NULL) { PR_Free(proxy); } if(type==SGN_CONTEXT) { SGN_DestroyContext( (SGNContext*)*ctxt, PR_TRUE /*freeit*/); } else { PR_ASSERT(type == VFY_CONTEXT); VFY_DestroyContext( (VFYContext*)*ctxt, PR_TRUE /*freeit*/); } } *ctxt = NULL; return Context; } /*********************************************************************** * * SigContextProxy.releaseNativeResources * * Deletes the SGNContext wrapped by this SigContextProxy object. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_SigContextProxy_releaseNativeResources (JNIEnv *env, jobject this) { SigContextProxy *proxy; /* Retrieve the proxy pointer */ if( JSS_getPtrFromProxy(env, this, (void**)&proxy) != PR_SUCCESS) { #ifdef DEBUG PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); PR_fprintf(PR_STDERR, "ERROR: native signature context was not released\n"); #endif goto finish; } PR_ASSERT(proxy!=NULL); /* Free the context and the proxy */ if(proxy->type == SGN_CONTEXT) { SGN_DestroyContext( (SGNContext*)proxy->ctxt, PR_TRUE /*freeit*/); } else { PR_ASSERT(proxy->type == VFY_CONTEXT); VFY_DestroyContext( (VFYContext*)proxy->ctxt, PR_TRUE /*freeit*/); } PR_Free(proxy); finish: ; } /*********************************************************************** * PK11Signature.engineRawSignNative */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_engineRawSignNative (JNIEnv *env, jclass clazz, jobject tokenObj, jobject keyObj, jbyteArray hashBA) { SECKEYPrivateKey *key = NULL; SECItem *sig = NULL; SECItem *hash = NULL; jbyteArray sigBA = NULL; PR_ASSERT(env!=NULL && tokenObj!=NULL && keyObj!=NULL && hashBA!=NULL); /* Get the private key */ if( JSS_PK11_getPrivKeyPtr(env, keyObj, &key) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } /* get the hash */ hash = JSS_ByteArrayToSECItem(env, hashBA); /* prepare space for the sig */ sig = PR_NEW(SECItem); sig->len = PK11_SignatureLen(key); sig->data = PR_Malloc(sig->len); /* perform the signature operation */ if( PK11_Sign(key, sig, hash) != SECSuccess ) { JSS_throwMsg(env, SIGNATURE_EXCEPTION, "Signature operation failed" " on token"); goto finish; } /* convert signature to byte array */ sigBA = JSS_SECItemToByteArray(env, sig); finish: if(sig) { SECITEM_FreeItem(sig, PR_TRUE /*freeit*/); } if(hash) { SECITEM_FreeItem(hash, PR_TRUE /*freeit*/); } return sigBA; } /*********************************************************************** * PK11Signature.engineRawVerifyNative */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_engineRawVerifyNative (JNIEnv *env, jclass clazz, jobject tokenObj, jobject keyObj, jbyteArray hashBA, jbyteArray sigBA) { SECItem *sig=NULL; SECItem *hash=NULL; SECKEYPublicKey *key=NULL; jboolean verified=JNI_FALSE; SECStatus status; PR_ASSERT(env!=NULL && tokenObj!=NULL && keyObj!=NULL && hashBA!=NULL && sigBA!=NULL); sig = JSS_ByteArrayToSECItem(env, sigBA); if(sig==NULL) { goto finish; } hash = JSS_ByteArrayToSECItem(env, hashBA); if(hash==NULL) { goto finish; } if( JSS_PK11_getPubKeyPtr(env, keyObj, &key) != PR_SUCCESS ) { goto finish; } /* perform the operation */ status = PK11_Verify(key, sig, hash, NULL /*wincx*/); if( status == SECSuccess ) { verified = JNI_TRUE; } else if( PR_GetError() != SEC_ERROR_BAD_SIGNATURE ) { JSS_throwMsg(env, SIGNATURE_EXCEPTION, "Verification operation" " failed on token"); goto finish; } finish: if(sig) { SECITEM_FreeItem(sig, PR_TRUE /*freeit*/); } if(hash) { SECITEM_FreeItem(hash, PR_TRUE /*freeit*/); } return verified; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Signature.java000066400000000000000000000244721362106420000216660ustar00rootroot00000000000000/* 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.pkcs11; import java.io.ByteArrayOutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import org.mozilla.jss.crypto.Algorithm; import org.mozilla.jss.crypto.NoSuchItemOnTokenException; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.util.Assert; import org.mozilla.jss.util.NativeProxy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; final class PK11Signature extends org.mozilla.jss.crypto.SignatureSpi { public PK11Signature(PK11Token token, SignatureAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { assert(token!=null && algorithm!=null); // Make sure this token supports this algorithm. It's OK if // it only supports the signing part; the hashing can be done // on the internal module. if( ! token.doesAlgorithm(algorithm) && ! token.doesAlgorithm(algorithm.getSigningAlg()) ) { throw new NoSuchAlgorithmException(); } this.tokenProxy = token.getProxy(); this.token = token; this.algorithm = algorithm; if( algorithm.getRawAlg() == algorithm ) { raw = true; rawInput = new ByteArrayOutputStream(); } this.state = UNINITIALIZED; } public void engineInitSign(org.mozilla.jss.crypto.PrivateKey privateKey) throws InvalidKeyException, TokenException { PK11PrivKey privKey; assert(privateKey!=null); // // Scrutinize the key. Make sure it: // -is a PKCS #11 key // -lives on this token // -is the right type for the algorithm // if( privateKey == null ) { throw new InvalidKeyException("private key is null"); } if( ! (privateKey instanceof PK11PrivKey) ) { throw new InvalidKeyException("privateKey is not a PKCS #11 "+ "private key"); } privKey = (PK11PrivKey) privateKey; try { privKey.verifyKeyIsOnToken(token); } catch(NoSuchItemOnTokenException e) { throw new InvalidKeyException(e.toString()); } try { if( KeyType.getKeyTypeFromAlgorithm(algorithm) != privKey.getKeyType()) { throw new InvalidKeyException( "Key type is inconsistent with algorithm"); } } catch( NoSuchAlgorithmException e ) { throw new InvalidKeyException("Unknown algorithm: " + algorithm, e); } // Finally, the key is OK key = privKey; // Now initialize the signature context if( ! raw ) { sigContext = null; initSigContext(); } // Don't set state until we know everything worked state = SIGN; } /************************************************************* ** This is just here for JCA compliance, we don't take randoms this way. */ public void engineInitSign(org.mozilla.jss.crypto.PrivateKey privateKey, SecureRandom random) throws InvalidKeyException, TokenException { throw new RuntimeException("PK11Signature.engineInitSign() is not supported"); // engineInitSign(privateKey); } /************************************************************* ** Creates a signing context, initializes it, ** and sets the sigContext field. */ protected native void initSigContext() throws TokenException; public void engineInitVerify(PublicKey publicKey) throws InvalidKeyException, TokenException { PK11PubKey pubKey; assert(publicKey!=null); // // Scrutinize the key. Make sure it: // -is a PKCS #11 key // -lives on this token // -is the right type for the algorithm // if( ! (publicKey instanceof PK11PubKey) ) { throw new InvalidKeyException("publicKey is not a PKCS #11 "+ "public key"); } pubKey = (PK11PubKey) publicKey; //try { // pubKey.verifyKeyIsOnToken(token); //} catch( NoSuchItemOnTokenException e) { // throw new InvalidKeyException(e.toString()); //} try { if( KeyType.getKeyTypeFromAlgorithm(algorithm) != pubKey.getKeyType()) { throw new InvalidKeyException( "Key type is inconsistent with algorithm"); } } catch( NoSuchAlgorithmException e ) { throw new InvalidKeyException("Unknown algorithm: " + algorithm, e); } key = pubKey; if( ! raw ) { sigContext = null; initVfyContext(); } // Don't set state until we know everything worked. state = VERIFY; } protected native void initVfyContext() throws TokenException; public void engineUpdate(byte b) throws SignatureException, TokenException { engineUpdate(new byte[] {b}, 0, 1); } public void engineUpdate(byte[] b, int off, int len) throws SignatureException, TokenException { assert(b != null); if( (state==SIGN || state==VERIFY) ) { if(!raw && sigContext==null) { throw new SignatureException("Signature has no context"); } else if( raw && rawInput==null) { throw new SignatureException("Raw signature has no input stream"); } } else { assert(state == UNINITIALIZED); throw new SignatureException("Signature is not initialized"); } assert(token!=null); assert(tokenProxy!=null); assert(algorithm!=null); assert(key!=null); if( raw ) { rawInput.write(b, off, len); } else { engineUpdateNative( b, off, len); } } protected native void engineUpdateNative(byte[] b, int off, int len) throws TokenException; public byte[] engineSign() throws SignatureException, TokenException { if(state != SIGN) { throw new SignatureException("Signature is not initialized"); } if(!raw && sigContext==null) { throw new SignatureException("Signature has no context"); } else if(raw && rawInput==null) { throw new SignatureException("Signature has no input"); } assert(token!=null); assert(tokenProxy!=null); assert(algorithm!=null); assert(key!=null); byte[] result; if( raw ) { result = engineRawSignNative(token, (PK11PrivKey)key, rawInput.toByteArray()); rawInput.reset(); } else { result = engineSignNative(); } state = UNINITIALIZED; sigContext = null; return result; } public int engineSign(byte[] outbuf, int offset, int len) throws SignatureException, TokenException { assert(outbuf!=null); byte[] sig; if( raw ) { sig = engineRawSignNative(token, (PK11PrivKey)key, rawInput.toByteArray()); rawInput.reset(); } else { sig = engineSign(); } if( (outbuf==null) || (outbuf.length <= offset) || (len < sig.length) || (offset+len > outbuf.length)) { throw new SignatureException( "outbuf is not sufficient to hold signature"); } System.arraycopy( sig, 0, outbuf, offset, sig.length); return sig.length; } /** * Performs raw signing of the given hash with the given private key. */ private static native byte[] engineRawSignNative(PK11Token token, PrivateKey key, byte[] hash) throws SignatureException, TokenException; private native byte[] engineSignNative() throws SignatureException, TokenException; public boolean engineVerify(byte[] sigBytes) throws SignatureException, TokenException { assert(sigBytes!=null); if(state != VERIFY) { throw new SignatureException( "Signature is not initialized properly"); } if(!raw && sigContext==null) { throw new SignatureException("Signature has no context"); } if(raw && rawInput==null) { throw new SignatureException("Signature has no input"); } assert(token!=null); assert(tokenProxy!=null); assert(algorithm!=null); assert(key!=null); if(sigBytes==null) { return false; } boolean result; if( raw ) { result = engineRawVerifyNative(token, (PK11PubKey)key, rawInput.toByteArray(), sigBytes); rawInput.reset(); } else { result = engineVerifyNative(sigBytes); } state = UNINITIALIZED; sigContext = null; return result; } /** * Performs raw verification of the signature of a hash using the * given public key, on the given token. */ protected static native boolean engineRawVerifyNative(PK11Token token, PublicKey key, byte[] hash, byte[] signature) throws SignatureException, TokenException; native protected boolean engineVerifyNative(byte[] sigBytes) throws SignatureException, TokenException; public void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException, TokenException { throw new RuntimeException("PK11Signature.engineSetParameter() is not yet implemented"); } protected PK11Token token; protected TokenProxy tokenProxy; protected Algorithm algorithm; protected PK11Key key; protected int state; protected SigContextProxy sigContext; protected boolean raw=false; // raw signing only, no hashing protected ByteArrayOutputStream rawInput; // states static public final int UNINITIALIZED = 0; static public final int SIGN = 1; static public final int VERIFY = 2; } class SigContextProxy extends NativeProxy { public static Logger logger = LoggerFactory.getLogger(SigContextProxy.class); public SigContextProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Store.c000066400000000000000000000635001362106420000203150ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11Store.h" #include #include #include #include #include #include #include #include #include #include #include "pk11util.h" #include #include typedef struct { enum { PW_NONE = 0, PW_FROMFILE = 1, PW_PLAINTEXT = 2, PW_EXTERNAL = 3 } source; char *data; } secuPWData; SECItem *preparePassword(JNIEnv *env, jobject conv, jobject pwObj); /********************************************************************** * PK11Store.putSymKeysInVector */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_putSymKeysInVector (JNIEnv *env, jobject this, jobject keyVector) { PK11SlotInfo *slot; jobject object = NULL; jclass vectorClass; jmethodID addElement; PK11SymKey *firstSymKey= NULL; PK11SymKey *sk = NULL; PK11SymKey *nextSymKey = NULL; secuPWData pwdata; pwdata.source = PW_NONE; pwdata.data = (char *) NULL; PR_ASSERT(env!=NULL && this!=NULL && keyVector!=NULL); if( JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(slot!=NULL); vectorClass = (*env)->GetObjectClass(env, keyVector); if(vectorClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } addElement = (*env)->GetMethodID(env, vectorClass, VECTOR_ADD_ELEMENT_NAME, VECTOR_ADD_ELEMENT_SIG); if(addElement == NULL) { ASSERT_OUTOFMEM(env); goto finish; } PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/); /* Obtain the symmetric key list. */ firstSymKey = PK11_ListFixedKeysInSlot( slot , NULL, ( void *) &pwdata ); sk = firstSymKey; while(( sk != NULL )) { if( sk ) { nextSymKey = sk; object = JSS_PK11_wrapSymKey(env, &sk); if(object == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } /*************************************************** * Insert the key into the vector ***************************************************/ (*env)->CallVoidMethod(env, keyVector, addElement, object); } sk = PK11_GetNextSymKey( nextSymKey ); } finish: return; } /********************************************************************** * PK11Store.loadPrivateKeys */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_loadPrivateKeys (JNIEnv *env, jobject this, jobject collection) { PK11SlotInfo *slot; SECKEYPrivateKeyList *list = NULL; SECKEYPrivateKeyListNode *node = NULL; SECKEYPrivateKey* key = NULL; jobject privateKey = NULL; jclass collectionClass; jmethodID collectionAdd; PR_ASSERT(env!=NULL && this!=NULL && collection!=NULL); if (JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(slot!=NULL); /* * Most, if not all, tokens have to be logged in before they allow * access to their private keys, so try to log in here. If we're already * logged in, this is a no-op. * If the login fails, go ahead and try to get the keys anyway, in case * this is an exceptionally promiscuous token. */ PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/); // get the list of keys on this token list = PK11_ListPrivateKeysInSlot(slot); if (list == NULL) { JSS_throwMsg(env, TOKEN_EXCEPTION, "PK11_ListPrivateKeysInSlot " "returned an error"); goto finish; } // get Collection class collectionClass = (*env)->FindClass(env, COLLECTION_CLASS_NAME); if (collectionClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } // get Collection.add() method collectionAdd = (*env)->GetMethodID(env, collectionClass, COLLECTION_ADD_NAME, COLLECTION_ADD_SIG); if (collectionAdd == NULL) { ASSERT_OUTOFMEM(env); goto finish; } for( node = PRIVKEY_LIST_HEAD(list); !PRIVKEY_LIST_END(node, list); node = PRIVKEY_LIST_NEXT(node) ) { // wrap private key key = SECKEY_CopyPrivateKey(node->key); privateKey = JSS_PK11_wrapPrivKey(env, &key); if (privateKey == NULL) { PR_ASSERT((*env)->ExceptionOccurred(env)); goto finish; } // add private key into collection (*env)->CallBooleanMethod(env, collection, collectionAdd, privateKey); } finish: if (list != NULL) { SECKEY_DestroyPrivateKeyList(list); } return; } /********************************************************************** * PK11Store.loadPublicKeys */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_loadPublicKeys (JNIEnv *env, jobject this, jobject collection) { PK11SlotInfo *slot; SECKEYPublicKeyList *list = NULL; SECKEYPublicKeyListNode *node = NULL; SECKEYPublicKey* key = NULL; jobject publicKey = NULL; jclass collectionClass; jmethodID collectionAdd; PR_ASSERT(env!=NULL && this!=NULL && collection!=NULL); if (JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(slot!=NULL); /* * Most, if not all, tokens have to be logged in before they allow * access to their public keys, so try to log in here. If we're already * logged in, this is a no-op. * If the login fails, go ahead and try to get the keys anyway, in case * this is an exceptionally promiscuous token. */ PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/); // get the list of keys on this token list = PK11_ListPublicKeysInSlot(slot, NULL /*nickname*/); if (list == NULL) { JSS_throwMsg(env, TOKEN_EXCEPTION, "PK11_ListPublicKeysInSlot " "returned an error"); goto finish; } // get Collection class collectionClass = (*env)->FindClass(env, COLLECTION_CLASS_NAME); if (collectionClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } // get Collection.add() method collectionAdd = (*env)->GetMethodID(env, collectionClass, COLLECTION_ADD_NAME, COLLECTION_ADD_SIG); if (collectionAdd == NULL) { ASSERT_OUTOFMEM(env); goto finish; } for( node = PUBKEY_LIST_HEAD(list); !PUBKEY_LIST_END(node, list); node = PUBKEY_LIST_NEXT(node) ) { // wrap public key key = SECKEY_CopyPublicKey(node->key); publicKey = JSS_PK11_wrapPubKey(env, &key); if (publicKey == NULL) { PR_ASSERT((*env)->ExceptionOccurred(env)); goto finish; } // add public key into collection (*env)->CallBooleanMethod(env, collection, collectionAdd, publicKey); } finish: if (list != NULL) { SECKEY_DestroyPublicKeyList(list); } return; } /********************************************************************** * PK11Store.putCertsInVector */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_putCertsInVector (JNIEnv *env, jobject this, jobject certVector) { PK11SlotInfo *slot; PK11SlotInfo *slotCopy; jclass vectorClass; jmethodID addElement; CERTCertList *certList = NULL; CERTCertificate *certCopy; CERTCertListNode *node = NULL; jobject object; PR_ASSERT(env!=NULL && this!=NULL && certVector!=NULL); if( JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(slot!=NULL); /* * log in if the slot does not have publicly readable certs */ if( !PK11_IsFriendly(slot) ) { PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/); } certList = PK11_ListCertsInSlot(slot); if( certList == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "PK11_ListCertsInSlot " "returned an error"); goto finish; } /************************************************** * Get JNI ids **************************************************/ vectorClass = (*env)->GetObjectClass(env, certVector); if(vectorClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } addElement = (*env)->GetMethodID(env, vectorClass, VECTOR_ADD_ELEMENT_NAME, VECTOR_ADD_ELEMENT_SIG); if(addElement == NULL) { ASSERT_OUTOFMEM(env); goto finish; } for( node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node) ) { /*************************************************** * Wrap the object ***************************************************/ certCopy = CERT_DupCertificate(node->cert); slotCopy = PK11_ReferenceSlot(slot); object = JSS_PK11_wrapCertAndSlotAndNickname(env, &certCopy, &slotCopy, node->appData); if(object == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } /*************************************************** * Insert the cert into the vector ***************************************************/ (*env)->CallVoidMethod(env, certVector, addElement, object); } finish: if( certList != NULL ) { CERT_DestroyCertList(certList); } return; } /************************************************************************ * * J S S _ g e t S t o r e S l o t P t r * * Retrieve the PK11SlotInfo pointer of the given PK11Store. * * INPUTS * store * A reference to a Java PK11Store * slot * address of a PK11SlotInfo* that will be loaded with * the PK11SlotInfo pointer of the given token. * RETURNS * PR_SUCCESS if the operation was successful, PR_FAILURE if an * exception was thrown. */ PRStatus JSS_PK11_getStoreSlotPtr(JNIEnv *env, jobject store, PK11SlotInfo **slot) { PR_ASSERT(env!=NULL && store!=NULL && slot!=NULL); return JSS_getPtrFromProxyOwner(env, store, PK11STORE_PROXY_FIELD, PK11STORE_PROXY_SIG, (void**)slot); } /********************************************************************** * PK11Store.deletePrivateKey */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_deletePrivateKey (JNIEnv *env, jobject this, jobject privateKeyObj) { PK11SlotInfo *slot; SECKEYPrivateKey *privateKey; PR_ASSERT(env!=NULL && this!=NULL); if (privateKeyObj == NULL) { JSS_throw(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION); goto finish; } if (JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT((*env)->ExceptionOccurred(env) != NULL); goto finish; } if (JSS_PK11_getPrivKeyPtr(env, privateKeyObj, &privateKey) != PR_SUCCESS) { PR_ASSERT((*env)->ExceptionOccurred(env) != NULL); goto finish; } /* A private key may be temporary, but you can't use this function * to delete it. Instead, just let it be garbage collected */ if (privateKey->pkcs11IsTemp) { PR_ASSERT(PR_FALSE); JSS_throwMsg(env, TOKEN_EXCEPTION, "Private Key is not a permanent PKCS #11 object"); goto finish; } if (slot != privateKey->pkcs11Slot) { JSS_throw(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION); goto finish; } if (PK11_DestroyTokenObject(privateKey->pkcs11Slot, privateKey->pkcs11ID) != SECSuccess) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to remove private key"); goto finish; } finish: return; } /********************************************************************** * PK11Store.deletePublicKey */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_deletePublicKey (JNIEnv *env, jobject this, jobject publicKeyObj) { PK11SlotInfo *slot; SECKEYPublicKey *publicKey; PR_ASSERT(env != NULL && this != NULL); if (publicKeyObj == NULL) { JSS_throw(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION); goto finish; } if (JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT((*env)->ExceptionOccurred(env) != NULL); goto finish; } if (JSS_PK11_getPubKeyPtr(env, publicKeyObj, &publicKey) != PR_SUCCESS) { PR_ASSERT((*env)->ExceptionOccurred(env) != NULL); goto finish; } if (slot != publicKey->pkcs11Slot) { JSS_throw(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION); goto finish; } if (PK11_DestroyTokenObject(publicKey->pkcs11Slot, publicKey->pkcs11ID) != SECSuccess) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to remove public key"); goto finish; } finish: return; } /********************************************************************** * PK11Store.deleteCert * * This function deletes the specified certificate and its associated * private key. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_deleteCert (JNIEnv *env, jobject this, jobject certObject) { CERTCertificate *cert; SECStatus VARIABLE_MAY_NOT_BE_USED status; PR_ASSERT(env!=NULL && this!=NULL); if(certObject == NULL) { JSS_throw(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION); goto finish; } if( JSS_PK11_getCertPtr(env, certObject, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } status = PK11_DeleteTokenCertAndKey(cert, NULL); status = SEC_DeletePermCertificate(cert); finish: return; } /********************************************************************** * PK11Store.deleteCertOnly * * This function deletes the specified certificate only. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_deleteCertOnly (JNIEnv *env, jobject this, jobject certObject) { CERTCertificate *cert; SECStatus VARIABLE_MAY_NOT_BE_USED status; PR_ASSERT(env!=NULL && this!=NULL); if(certObject == NULL) { JSS_throw(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION); goto finish; } if( JSS_PK11_getCertPtr(env, certObject, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } status = SEC_DeletePermCertificate(cert); finish: return; } #define DER_DEFAULT_CHUNKSIZE (2048) int PK11_NumberObjectsFor(PK11SlotInfo*, CK_ATTRIBUTE*, int); /*********************************************************************** * PK11Store.importdPrivateKey */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_importPrivateKey ( JNIEnv *env, jobject this, jbyteArray keyArray, jobject keyTypeObj, jboolean temporary ) { SECItem derPK; PK11SlotInfo *slot; jthrowable excep; SECStatus status; SECItem nickname; jobject privkObj = NULL; /* * initialize so we can goto finish */ derPK.data = NULL; derPK.len = 0; PR_ASSERT(env!=NULL && this!=NULL); if(keyArray == NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } /* * copy the java byte array into a local copy */ if (!JSS_RefByteArray(env, keyArray, (jbyte **) &derPK.data, (jsize *) &derPK.len)) { if (derPK.len == 0) { JSS_throwMsg(env, INVALID_KEY_FORMAT_EXCEPTION, "Key array is empty"); } else { ASSERT_OUTOFMEM(env); } goto finish; } /* * Get the PKCS #11 slot */ if( JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } nickname.len = 0; nickname.data = NULL; SECKEYPrivateKey *privk = NULL; status = PK11_ImportDERPrivateKeyInfoAndReturnKey( slot, &derPK, &nickname, NULL /*public value*/, !temporary /*isPerm*/, PR_TRUE /*isPrivate*/, 0 /*keyUsage*/, &privk, NULL /*wincx*/); if(status != SECSuccess) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to import private key info"); goto finish; } privkObj = JSS_PK11_wrapPrivKey(env, &privk); if (privkObj == NULL) { goto finish; } finish: /* Save any exceptions */ if( (excep=(*env)->ExceptionOccurred(env)) ) { (*env)->ExceptionClear(env); } JSS_DerefByteArray(env, keyArray, derPK.data, JNI_ABORT); /* now re-throw the exception */ if( excep ) { (*env)->Throw(env, excep); } return privkObj; } extern const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[]; JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_getEncryptedPrivateKeyInfo( JNIEnv *env, jobject this, jobject conv, jobject pwObj, jobject algObj, jint iterations, jobject key) { // initialisations so we can goto finish SECItem *pwItem = NULL; SECKEYEncryptedPrivateKeyInfo *epki = NULL; SECItem epkiItem; epkiItem.data = NULL; epkiItem.len = 0; jbyteArray encodedEpki = NULL; PR_ASSERT(env != NULL && this != NULL); if (pwObj == NULL || algObj == NULL || key == NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } if (iterations <= 0) { iterations = 2000; // set default iterations } // get slot PK11SlotInfo *slot = NULL; if( JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(slot!=NULL); // get algorithm SECOidTag algTag = JSS_getOidTagFromAlg(env, algObj); if (algTag == SEC_OID_UNKNOWN) { JSS_throwMsg(env, NO_SUCH_ALG_EXCEPTION, "Unrecognized algorithm"); goto finish; } pwItem = preparePassword(env, conv, pwObj); if (pwItem == NULL) { ASSERT_OUTOFMEM(env); goto finish; } // get key SECKEYPrivateKey *privk; if (JSS_PK11_getPrivKeyPtr(env, key, &privk) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } // export the epki epki = PK11_ExportEncryptedPrivKeyInfo( slot, algTag, pwItem, privk, iterations, NULL /*wincx*/); if (epki == NULL) { JSS_throwMsgPrErr( env, TOKEN_EXCEPTION, "Failed to export EncryptedPrivateKeyInfo"); goto finish; } // DER-encode the epki if (SEC_ASN1EncodeItem(NULL, &epkiItem, epki, SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate)) == NULL) { JSS_throwMsg( env, TOKEN_EXCEPTION, "Failed to ASN1-encode EncryptedPrivateKeyInfo"); goto finish; } // convert to Java byte array encodedEpki = JSS_SECItemToByteArray(env, &epkiItem); finish: if (epki != NULL) { SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE /*freeit*/); } if (epkiItem.data != NULL) { SECITEM_FreeItem(&epkiItem, PR_FALSE /*freeit*/); } if (pwItem != NULL) { SECITEM_FreeItem(pwItem, PR_TRUE /*freeit*/); } return encodedEpki; } JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_importEncryptedPrivateKeyInfo( JNIEnv *env, jobject this, jobject conv, jobject pwObj, jstring nickname, jobject pubKeyObj, jbyteArray epkiBytes) { // initialisations so we can goto finish SECItem *epkiItem = NULL; SECKEYEncryptedPrivateKeyInfo *epki = NULL; SECItem *pwItem = NULL; SECItem *spkiItem = NULL; CERTSubjectPublicKeyInfo *spki = NULL; SECKEYPublicKey *pubKey = NULL; const char *nicknameChars = NULL; PR_ASSERT(env != NULL && this != NULL); if (pwObj == NULL || nickname == NULL || pubKeyObj == NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } // get slot PK11SlotInfo *slot = NULL; if (JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(slot != NULL); // decode EncryptedPrivateKeyInfo epkiItem = JSS_ByteArrayToSECItem(env, epkiBytes); epki = PR_Calloc(1, sizeof(SECKEYEncryptedPrivateKeyInfo)); if (SEC_ASN1DecodeItem( NULL, epki, SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate), epkiItem ) != SECSuccess) { JSS_throwMsg(env, INVALID_DER_EXCEPTION, "Failed to decode EncryptedPrivateKeyInfo"); goto finish; } pwItem = preparePassword(env, conv, pwObj); if (pwItem == NULL) { ASSERT_OUTOFMEM(env); goto finish; } // get public key value jclass pubKeyClass = (*env)->GetObjectClass(env, pubKeyObj); if (pubKeyClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } jmethodID getEncoded = (*env)->GetMethodID( env, pubKeyClass, "getEncoded", "()[B"); if (getEncoded == NULL) { ASSERT_OUTOFMEM(env); goto finish; } jbyteArray spkiBytes = (*env)->CallObjectMethod( env, pubKeyObj, getEncoded); spkiItem = JSS_ByteArrayToSECItem(env, spkiBytes); spki = PR_Calloc(1, sizeof(CERTSubjectPublicKeyInfo)); if (SEC_ASN1DecodeItem( NULL, spki, SEC_ASN1_GET(CERT_SubjectPublicKeyInfoTemplate), spkiItem ) != SECSuccess) { JSS_throwMsg(env, INVALID_DER_EXCEPTION, "Failed to decode SubjectPublicKeyInfo"); goto finish; } pubKey = SECKEY_ExtractPublicKey(spki); if (pubKey == NULL) { JSS_throwMsgPrErr(env, INVALID_DER_EXCEPTION, "Failed to extract public key from SubjectPublicKeyInfo"); goto finish; } SECItem *pubValue; switch (pubKey->keyType) { case dsaKey: pubValue = &pubKey->u.dsa.publicValue; break; case dhKey: pubValue = &pubKey->u.dh.publicValue; break; case rsaKey: pubValue = &pubKey->u.rsa.modulus; break; case ecKey: pubValue = &pubKey->u.ec.publicValue; break; default: pubValue = NULL; } // prepare nickname nicknameChars = JSS_RefJString(env, nickname); if (nicknameChars == NULL) { ASSERT_OUTOFMEM(env); goto finish; } SECItem nickItem; nickItem.data = (unsigned char *) nicknameChars; nickItem.len = (*env)->GetStringUTFLength(env, nickname); // if keyUsage = 0, defaults to signing and encryption/key agreement. // see pk11akey.c in NSS int keyUsage = 0; // perform import SECStatus result = PK11_ImportEncryptedPrivateKeyInfo( slot, epki, pwItem, &nickItem, pubValue, PR_TRUE /* isperm */, PR_TRUE /* isprivate */, pubKey->keyType, keyUsage, NULL /* wincx */); if (result != SECSuccess) { JSS_throwMsgPrErr( env, TOKEN_EXCEPTION, "Failed to import EncryptedPrivateKeyInfo to token"); goto finish; } // Attempt to store the public key in the token. // Failure is non-fatal (some tokens cannot store the public key). PK11_ImportPublicKey(slot, pubKey, PR_TRUE /* isToken (permanent) */); finish: if (epkiItem != NULL) { SECITEM_FreeItem(epkiItem, PR_TRUE /*freeit*/); } if (epki != NULL) { SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE /*freeit*/); } if (spkiItem != NULL) { SECITEM_FreeItem(spkiItem, PR_TRUE /*freeit*/); } if (spki != NULL) { SECKEY_DestroySubjectPublicKeyInfo(spki); } if (pwItem != NULL) { SECITEM_FreeItem(pwItem, PR_TRUE /*freeit*/); } if (pubKey != NULL) { SECKEY_DestroyPublicKey(pubKey); } JSS_DerefJString(env, nickname, nicknameChars); } /* Process the given password through the given PasswordConverter, * returning a new SECItem* on success. * * After use, the caller should free the SECItem: * * SECITEM_FreeItem(pwItem, PR_TRUE). */ SECItem *preparePassword(JNIEnv *env, jobject conv, jobject pwObj) { jclass passwordClass = (*env)->GetObjectClass(env, pwObj); if (passwordClass == NULL) { ASSERT_OUTOFMEM(env); return NULL; } jbyteArray pwBytes; if (conv == NULL) { jmethodID getByteCopy = (*env)->GetMethodID( env, passwordClass, PW_GET_BYTE_COPY_NAME, PW_GET_BYTE_COPY_SIG); if (getByteCopy == NULL) { ASSERT_OUTOFMEM(env); return NULL; } pwBytes = (*env)->CallObjectMethod(env, pwObj, getByteCopy); } else { jmethodID getChars = (*env)->GetMethodID( env, passwordClass, "getChars", "()[C"); if (getChars == NULL) { ASSERT_OUTOFMEM(env); return NULL; } jcharArray pwChars = (*env)->CallObjectMethod(env, pwObj, getChars); jclass convClass = (*env)->GetObjectClass(env, conv); if (conv == NULL) { ASSERT_OUTOFMEM(env); return NULL; } jmethodID convert = (*env)->GetMethodID( env, convClass, "convert", "([C)[B"); if (convert == NULL) { ASSERT_OUTOFMEM(env); return NULL; } pwBytes = (*env)->CallObjectMethod(env, conv, convert, pwChars); } return JSS_ByteArrayToSECItem(env, pwBytes); } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Store.java000066400000000000000000000166271362106420000210240ustar00rootroot00000000000000/* 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.pkcs11; import java.math.BigInteger; import java.security.PublicKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; import java.util.Collection; import java.util.Vector; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.crypto.Algorithm; import org.mozilla.jss.crypto.CryptoStore; import org.mozilla.jss.crypto.KeyAlreadyImportedException; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.NoSuchItemOnTokenException; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.util.Assert; import org.mozilla.jss.util.Password; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class PK11Store implements CryptoStore { public static Logger logger = LoggerFactory.getLogger(PK11Store.class); //////////////////////////////////////////////////////////// // Private Keys //////////////////////////////////////////////////////////// /** * Imports a raw private key into this token. * * @param key The private key. * @exception TokenException If the key cannot be imported to this token. * @exception KeyAlreadyImportedException If the key already on this token. */ public PrivateKey importPrivateKey(byte[] key, PrivateKey.Type type) throws TokenException,KeyAlreadyImportedException { return importPrivateKey(key, type, false); } public native PrivateKey importPrivateKey( byte[] key, PrivateKey.Type type, boolean temporary) throws TokenException,KeyAlreadyImportedException; public synchronized PrivateKey[] getPrivateKeys() throws TokenException { ArrayList list = new ArrayList<>(); loadPrivateKeys(list); PrivateKey[] array = new PrivateKey[list.size()]; list.toArray(array); return array; } protected native void loadPrivateKeys(Collection privateKeys) throws TokenException; public synchronized PublicKey[] getPublicKeys() throws TokenException { ArrayList list = new ArrayList<>(); loadPublicKeys(list); PublicKey[] array = new PublicKey[list.size()]; list.toArray(array); return array; } protected native void loadPublicKeys(Collection privateKeys) throws TokenException; public PublicKey findPublicKey(PrivateKey privateKey) throws TokenException, ObjectNotFoundException { // NSS does not provide a function to find the public key of a private key, // so it has to be done manually. if (privateKey instanceof RSAPrivateKey) { logger.debug("PKCS11Store: searching for RSA public key"); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey; BigInteger modulus = rsaPrivateKey.getModulus(); // Find the RSA public key by comparing the modulus. for (PublicKey publicKey : getPublicKeys()) { if (!(publicKey instanceof RSAPublicKey)) { // not an RSA public key continue; } RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey; if (!modulus.equals(rsaPublicKey.getModulus())) { // modulus doesn't match continue; } logger.debug("PKCS11Store: found RSA public key"); return publicKey; } } else { // TODO: add support for non-RSA keys } throw new ObjectNotFoundException("Unable to find public key"); } public synchronized SymmetricKey[] getSymmetricKeys() throws TokenException { Vector keys = new Vector<>(); putSymKeysInVector(keys); SymmetricKey[] array = new SymmetricKey[keys.size()]; keys.copyInto( array); return array; } protected native void putSymKeysInVector(Vector symKeys) throws TokenException; public native void deletePrivateKey(PrivateKey privateKey) throws NoSuchItemOnTokenException, TokenException; public native void deletePublicKey(PublicKey publicKey) throws NoSuchItemOnTokenException, TokenException; public byte[] getEncryptedPrivateKeyInfo( X509Certificate cert, PBEAlgorithm pbeAlg, Password pw, int iteration) throws NotInitializedException, ObjectNotFoundException, TokenException { return getEncryptedPrivateKeyInfo( null, pw, pbeAlg, iteration, CryptoManager.getInstance().findPrivKeyByCert(cert) ); } public native byte[] getEncryptedPrivateKeyInfo( KeyGenerator.CharToByteConverter conv, Password pw, Algorithm alg, int n, PrivateKey k); public native void importEncryptedPrivateKeyInfo( KeyGenerator.CharToByteConverter conv, Password pw, String nickname, PublicKey pubKey, byte[] epkiBytes); //////////////////////////////////////////////////////////// // Certs //////////////////////////////////////////////////////////// public X509Certificate[] getCertificates() throws TokenException { Vector certs = new Vector<>(); putCertsInVector(certs); X509Certificate[] array = new X509Certificate[certs.size()]; certs.copyInto( array ); return array; } protected native void putCertsInVector(Vector certs) throws TokenException; /** * Deletes the specified certificate and its associated private * key from the store. * * @param cert certificate to be deleted * @exception NoSuchItemOnTokenException If the certificate not found * @exception TokenException General token error */ // Currently have to use PK11_DeleteTokenObject + PK11_FindObjectForCert // or maybe SEC_DeletePermCertificate. public native void deleteCert(X509Certificate cert) throws NoSuchItemOnTokenException, TokenException; /** * Deletes the specified certificate from the store. * * @param cert certificate to be deleted * @exception NoSuchItemOnTokenException If the certificate not found * @exception TokenException General token error */ public native void deleteCertOnly(X509Certificate cert) throws NoSuchItemOnTokenException, TokenException; //////////////////////////////////////////////////////////// // Construction //////////////////////////////////////////////////////////// protected boolean updated; public PK11Store(TokenProxy proxy) { assert(proxy!=null); this.storeProxy = proxy; } protected PK11Store() { } //////////////////////////////////////////////////////////// // Private data //////////////////////////////////////////////////////////// protected TokenProxy storeProxy; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11SymKey.c000066400000000000000000000232311362106420000204370ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_SymKeyProxy.h" #include #include #include #include #include #include #include #include "pk11util.h" /*********************************************************************** * * J S S _ P K 1 1 _ w r a p S y m K e y * Puts a Symmetric Key into a Java object. * (Does NOT perform a cryptographic "wrap" operation.) * symKey: will be stored in a Java wrapper. * Returns: a new PK11SymKey, or NULL if an exception occurred. */ jobject JSS_PK11_wrapSymKey(JNIEnv *env, PK11SymKey **symKey) { jclass keyClass; jmethodID constructor; jbyteArray ptrArray; jobject Key=NULL; char *nickname = NULL; jstring jnickname = NULL; PR_ASSERT(env!=NULL && symKey!=NULL && *symKey!=NULL); /* find the class */ keyClass = (*env)->FindClass(env, PK11SYMKEY_CLASS_NAME); if( keyClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } nickname = PK11_GetSymKeyNickname( *symKey ); if (nickname) { jnickname = (*env)->NewStringUTF(env, nickname); } /* find the constructor */ constructor = (*env)->GetMethodID(env, keyClass, PLAIN_CONSTRUCTOR, PK11SYMKEY_CONSTRUCTOR_1_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* convert the pointer to a byte array */ ptrArray = JSS_ptrToByteArray(env, (void*)*symKey); if( ptrArray == NULL ) { goto finish; } /* call the constructor */ Key = (*env)->NewObject(env, keyClass, constructor, ptrArray, jnickname); finish: if(Key == NULL) { PK11_FreeSymKey(*symKey); } if(nickname != NULL) { PORT_Free(nickname); nickname = NULL; } *symKey = NULL; return Key; } /*********************************************************************** * * PK11SymKey.getOwningToken */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_getOwningToken (JNIEnv *env, jobject this) { PK11SymKey *key = NULL; PK11SlotInfo *slot = NULL; jobject token = NULL; PR_ASSERT(env!=NULL && this!=NULL); /* Get the C key structure */ if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /* Get the slot this key lives on */ slot = PK11_GetSlotFromKey(key); PR_ASSERT(slot != NULL); /* Turn the slot into a Java PK11Token */ token = JSS_PK11_wrapPK11Token(env, &slot); if(token == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } finish: if(slot != NULL) { PK11_FreeSlot(slot); } return token; } /*********************************************************************** * * PK11SymKey.getStrength */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_getStrength (JNIEnv *env, jobject this) { PK11SymKey *key=NULL; int strength = 0; /* get the key pointer */ if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS) { goto finish; } strength = PK11_GetKeyStrength(key, NULL /*algid*/); finish: return strength; } /*********************************************************************** * * PK11SymKey.getLength */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_getLength (JNIEnv *env, jobject this) { PK11SymKey *key=NULL; unsigned int strength = 0; /* get the key pointer */ if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS) { goto finish; } strength = PK11_GetKeyLength(key); finish: return (jint) strength; } /*********************************************************************** * * PK11SymKey.setNickNameNative */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_setNickNameNative (JNIEnv *env, jobject this,jstring nickname) { PK11SymKey *key=NULL; const char *keyname = NULL; SECStatus status; /* If no nickname provided, we are done */ if( nickname == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Nickname is NULL, will not be set"); goto finish; } /* get the key pointer */ if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS) { goto finish; } /* convert the Java String into a native "C" string */ keyname = JSS_RefJString(env, nickname); /* name the key */ status = PK11_SetSymKeyNickname( key, keyname ); if( status != SECSuccess ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to name symmetric key"); } finish: /* free the native "C" string */ JSS_DerefJString(env, nickname, keyname); } /*********************************************************************** * * PK11SymKey.getKeyData */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_getKeyData (JNIEnv *env, jobject this) { PK11SymKey *key=NULL; SECItem *keyData; /* a reference to the key data */ jbyteArray dataArray=NULL; /* get the key pointer */ if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS) { goto finish; } /* Extract the key data */ if( PK11_ExtractKeyValue(key) != SECSuccess ) { /* key is not extractable */ JSS_throwMsg(env, NOT_EXTRACTABLE_EXCEPTION, "Unable to extract " "symmetric key data"); goto finish; } keyData = PK11_GetKeyData(key); /* PK11_ExtractKeyValue should have failed if keyData is NULL */ PR_ASSERT(keyData != NULL); /* copy the key data into a Java byte array */ dataArray = JSS_SECItemToByteArray(env, keyData); finish: /* keyData is just a reference, nothing to free */ if( dataArray == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); } return dataArray; } /*********************************************************************** * * PK11SymKey.getKeyType */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_getKeyType (JNIEnv *env, jobject this) { PK11SymKey *key=NULL; CK_MECHANISM_TYPE keyMech; char *typeFieldName=NULL; jclass typeClass=NULL; jfieldID typeField=NULL; jobject typeObject=NULL; if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS ) { ASSERT_OUTOFMEM(env); goto finish; } /* Look up the key type from the key */ keyMech = PK11_GetMechanism(key); switch(keyMech) { /* PBE mechanisms have to be handled by hand */ case CKM_PBE_MD2_DES_CBC: case CKM_PBE_MD5_DES_CBC: case CKM_NETSCAPE_PBE_SHA1_DES_CBC: typeFieldName = DES_KEYTYPE_FIELD; break; case CKM_PBE_SHA1_RC4_128: case CKM_PBE_SHA1_RC4_40: typeFieldName = RC4_KEYTYPE_FIELD; break; case CKM_PBE_SHA1_RC2_128_CBC: case CKM_PBE_SHA1_RC2_40_CBC: typeFieldName = RC2_KEYTYPE_FIELD; break; case CKM_PBE_SHA1_DES3_EDE_CBC: typeFieldName = DES3_KEYTYPE_FIELD; break; case CKM_PBA_SHA1_WITH_SHA1_HMAC: typeFieldName = SHA1_HMAC_KEYTYPE_FIELD; break; default: keyMech = PK11_GetKeyType( keyMech, 0 ); switch(keyMech) { case CKK_DES: typeFieldName = DES_KEYTYPE_FIELD; break; case CKK_DES3: typeFieldName = DES3_KEYTYPE_FIELD; break; case CKK_RC4: typeFieldName = RC4_KEYTYPE_FIELD; break; case CKK_RC2: typeFieldName = RC2_KEYTYPE_FIELD; break; case CKK_AES: typeFieldName = AES_KEYTYPE_FIELD; break; case CKK_DES2: typeFieldName = DES3_KEYTYPE_FIELD; break; case CKK_GENERIC_SECRET: typeFieldName = GENERIC_SECRET_KEYTYPE_FIELD; break; default: PR_ASSERT(PR_FALSE); typeFieldName = DES_KEYTYPE_FIELD; break; } break; } /* convert to a Java key type */ typeClass = (*env)->FindClass(env, KEYTYPE_CLASS_NAME); if(typeClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } typeField = (*env)->GetStaticFieldID(env, typeClass, typeFieldName, KEYTYPE_FIELD_SIG); if(typeField == NULL) { ASSERT_OUTOFMEM(env); goto finish; } typeObject = (*env)->GetStaticObjectField(env, typeClass, typeField); if(typeObject == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: return typeObject; } /*********************************************************************** * * J S S _ P K 1 1 _ g e t S y m K e y P t r * */ PRStatus JSS_PK11_getSymKeyPtr(JNIEnv *env, jobject symKeyObject, PK11SymKey **ptr) { PR_ASSERT(env!=NULL && symKeyObject!=NULL); /* Get the pointer from the key proxy */ return JSS_getPtrFromProxyOwner(env, symKeyObject, SYM_KEY_PROXY_FIELD, SYM_KEY_PROXY_SIG, (void**)ptr); } /*********************************************************************** * * SymKeyProxy.releaseNativeResources */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_SymKeyProxy_releaseNativeResources (JNIEnv *env, jobject this) { PK11SymKey *key=NULL; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_getPtrFromProxy(env, this, (void**)&key) == PR_SUCCESS) { PK11_FreeSymKey(key); } else { /* can't really throw an exception from a destructor */ PR_ASSERT(PR_FALSE); } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11SymKey.java000066400000000000000000000056371362106420000211500ustar00rootroot00000000000000/* 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.pkcs11; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.util.Assert; // We've updated jss.crypto.SymmetricKey to extend javax.crypto.SecretKey, so // PK11SymKey implements that interface as well. public final class PK11SymKey implements SymmetricKey { protected PK11SymKey(byte[] pointer) { assert(pointer!=null); keyProxy = new SymKeyProxy(pointer); nickName = null; } protected PK11SymKey(byte[] pointer,String nickName) { assert(pointer!=null); keyProxy = new SymKeyProxy(pointer); this.nickName = nickName; } private SymKeyProxy keyProxy; private String nickName; public SymmetricKey.Type getType() { KeyType kt = getKeyType(); SymmetricKey.Type result = SymmetricKey.Type.fromKeyType(kt); if (result == null) { throw new RuntimeException("Unrecognized key type: " + kt); } return result; } public native CryptoToken getOwningToken(); /** * Returns key strength, measured as the number of bits of secret material. * NOTE: Due to a bug in the security library (333440), this * may return a wrong answer for PBE keys that have embedded parity * (like DES). A DES key is 56 bits of information plus * 8 bits of parity, so it takes up 64 bits. For a normal DES key, * this method will correctly return 56, but for a PBE-generated DES key, * the security library bug causes it to return 64. */ public native int getStrength(); /** * Returns the length of the key in bytes, as returned by * PK11_GetKeyLength(). */ public native int getLength(); public native byte[] getKeyData() throws SymmetricKey.NotExtractableException; public native KeyType getKeyType(); public String getAlgorithm() { return getKeyType().toString(); } public byte[] getEncoded() { try { return getKeyData(); } catch(SymmetricKey.NotExtractableException nee) { return null; } } public String getFormat() { return "RAW"; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; if( nickName != null) { setNickNameNative(nickName); } } public native void setNickNameNative(String nickName); } class SymKeyProxy extends KeyProxy { public SymKeyProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.c000066400000000000000000000235471362106420000231760ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11SymmetricKeyDeriver.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "java_ids.h" #include "pk11util.h" #include /*********************************************************************** * Expose the NSS functionality at low level, one should know what to do * at the Java level. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11SymmetricKeyDeriver_nativeDeriveSymKey (JNIEnv * env, jobject this,jobject tokenObj, jobject baseKeyObj, jobject secondaryKeyObj, jlong deriveMechanism, jbyteArray param, jbyteArray iv, jlong targetMechanism, jlong operation, jlong keySize) { jobject keyObj = NULL; PK11SlotInfo *slot=NULL; PK11SlotInfo *bestSlot = NULL; PK11SlotInfo *slotForKey = NULL; PK11SlotInfo *slotForSecondaryKey = NULL; PK11SlotInfo *finalSlot = NULL; PK11SlotInfo *finalSecondarySlot = NULL; PK11SlotInfo *finalBaseKeySlot = NULL; PK11SymKey *baseKey = NULL; PK11SymKey *bestBaseKey = NULL; PK11SymKey *finalBaseKey = NULL; PK11SymKey *newKey = NULL; PK11SymKey *secondaryKey = NULL; PK11SymKey *bestSecondaryKey = NULL; PK11SymKey *finalSecondaryKey = NULL; PK11SymKey *derivedKey = NULL; jbyte *paramValue = NULL; int paramLength = 0; jbyte *ivValue = NULL; int ivLength = 0; CK_OBJECT_HANDLE keyhandle = 0; CK_AES_CBC_ENCRYPT_DATA_PARAMS aes; CK_DES_CBC_ENCRYPT_DATA_PARAMS des; CK_KEY_DERIVATION_STRING_DATA string; SECItem paramsItem = { siBuffer, NULL, 0 }; PR_ASSERT(env!=NULL && this!=NULL); if( baseKeyObj == 0) { PR_fprintf(PR_STDOUT,"baseKeyObj can not be null!\n"); goto finish; } if( param != NULL) { JSS_RefByteArray(env, param, ¶mValue, ¶mLength); } if( iv != NULL) { JSS_RefByteArray(env, iv, &ivValue, &ivLength); } /* Set up the params data for the PK11_Derive family */ switch ( deriveMechanism ) { case CKM_DES_ECB_ENCRYPT_DATA: case CKM_DES3_ECB_ENCRYPT_DATA: case CKM_AES_ECB_ENCRYPT_DATA: case CKM_CAMELLIA_ECB_ENCRYPT_DATA: case CKM_SEED_ECB_ENCRYPT_DATA: /* Use CK_KEY_DERIVATION_STRING_DATA */ string.pData = (unsigned char *) paramValue; string.ulLen = paramLength; paramsItem.data = (void *) &string; paramsItem.len = sizeof(string); break; case CKM_DES_CBC_ENCRYPT_DATA: case CKM_DES3_CBC_ENCRYPT_DATA: /* Use CK_DES_CBC_ENCRYPT_DATA_PARAMS */ if( ivValue == NULL) { PR_fprintf(PR_STDOUT, "Need iv param for CKM_DES_CBC_ENCRYPT_DATA or CKM_DES3_CBC_ENCRYPT_DATA. \n"); goto finish; } if( ivLength != 8) { PR_fprintf(PR_STDOUT, "Need iv param for CKM_DES_CBC_ENCRYPT_DATA structure to be 8 bytes!. \n"); goto finish; } des.pData = (unsigned char *) paramValue; des.length = paramLength; PORT_Memcpy(des.iv,ivValue,ivLength); paramsItem.data = (void *) &des; paramsItem.len = sizeof(des); break; case CKM_AES_CBC_ENCRYPT_DATA: case CKM_CAMELLIA_CBC_ENCRYPT_DATA: case CKM_SEED_CBC_ENCRYPT_DATA: /* Use CK_AES_CBC_ENCRYPT_DATA_PARAMS */ if ( ivValue == NULL ) { PR_fprintf(PR_STDOUT, "Need iv param for CBC encrypt derive for AES, or CAMELLIA or SEED. \n"); goto finish; } if( ivLength != 16) { PR_fprintf(PR_STDOUT, "Need iv param for CK_AES_CBC_ENCRYPT_DATA_PARAMS structure to be 16 bytes!. \n"); goto finish; } aes.pData = (unsigned char *) paramValue; aes.length = paramLength; PORT_Memcpy(aes.iv,ivValue,ivLength); paramsItem.data = (void *) &aes; paramsItem.len = sizeof(aes); break; default: paramsItem.data = (unsigned char *) paramValue; paramsItem.len = paramLength; break; } /* Get slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { goto finish; } /* Get base key */ if( JSS_PK11_getSymKeyPtr(env, baseKeyObj, &baseKey) != PR_SUCCESS) { PR_fprintf(PR_STDOUT, "PK11SymmetricKeyDeriver.nativeDeriveSymKey: Unable to extract symmetric base key!"); goto finish; } /* Ask NSS what the best slot for the given mechanism */ bestSlot = PK11_GetBestSlot(deriveMechanism, NULL); if( bestSlot == NULL) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't find suitable slot for sym key derivation! \n"); goto finish; } slotForKey = PK11_GetSlotFromKey(baseKey); int keyOnRequestedSlot = 0; if(slotForKey != slot) { keyOnRequestedSlot = 0; } else { keyOnRequestedSlot = 1; finalBaseKeySlot = slot; } if ( PK11_DoesMechanism( slot, deriveMechanism)) { if ( keyOnRequestedSlot ) { finalBaseKey = baseKey; } else { bestBaseKey = PK11_MoveSymKey( slot, CKA_ENCRYPT, 0, PR_FALSE, baseKey ); if(bestBaseKey == NULL) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't move Base Key to requested slot!\n"); goto finish; } finalBaseKey = bestBaseKey; finalBaseKeySlot = slot; } } else { bestBaseKey = PK11_MoveSymKey( bestSlot, CKA_ENCRYPT, 0, PR_FALSE, baseKey ); if(bestBaseKey == NULL) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't move Base Key to best slot!\n"); goto finish; } finalBaseKey = bestBaseKey; finalBaseKeySlot = bestSlot; } /* Assume we want to do a concatenation family here */ if( secondaryKeyObj != NULL) { if( JSS_PK11_getSymKeyPtr(env, secondaryKeyObj, &secondaryKey) != PR_SUCCESS) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't find secondary sym key!\n"); goto finish; } /* Make sure the secondary key is in the proper slot to do concatenation */ slotForSecondaryKey = PK11_GetSlotFromKey( secondaryKey ); if( finalBaseKeySlot != slotForSecondaryKey ) { finalSecondaryKey = PK11_MoveSymKey (finalBaseKeySlot, CKA_ENCRYPT, 0, PR_FALSE, secondaryKey); if( finalSecondaryKey == NULL) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey, Problem moving secondary key to proper slot.\n"); goto finish; } } else { finalSecondaryKey = secondaryKey; } if( paramValue == NULL) { keyhandle = PK11_GetSymKeyHandle(finalSecondaryKey); if( keyhandle == 0) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey, can't get handle for secondary sym key.\n"); goto finish; } paramsItem.data=(unsigned char *) &keyhandle; paramsItem.len=sizeof(keyhandle); } else { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: incorrect input parameter provided!\n"); goto finish; } } derivedKey = PK11_Derive(finalBaseKey, deriveMechanism, ¶msItem, targetMechanism, operation, keySize); if(derivedKey == NULL) { PR_fprintf(PR_STDOUT, "ERROR: Can't derive symmetric key, error: %d \n",PR_GetError()); goto finish; } if ( (finalSlot = PK11_GetSlotFromKey(derivedKey )) != slot) { newKey = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, derivedKey); if ( newKey == NULL ) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: error moving key to original slot, return anyway. \n"); newKey = derivedKey; derivedKey = NULL; } } else { newKey = derivedKey; derivedKey = NULL; } keyObj = JSS_PK11_wrapSymKey(env, &newKey); finish: if ( bestBaseKey != NULL ) { PK11_FreeSymKey ( bestBaseKey ); bestBaseKey = NULL; } if ( bestSecondaryKey != NULL ) { PK11_FreeSymKey ( bestSecondaryKey ); bestSecondaryKey = NULL; } if ( derivedKey != NULL) { PK11_FreeSymKey ( derivedKey ); derivedKey = NULL; } if (bestSlot != NULL ) { PK11_FreeSlot(bestSlot); bestSlot = NULL; } if ( slotForKey != NULL ) { PK11_FreeSlot( slotForKey ); slotForKey = NULL; } if ( finalSlot != NULL ) { PK11_FreeSlot( finalSlot ); finalSlot = NULL; } if ( finalSecondarySlot != NULL ) { PK11_FreeSlot( finalSecondarySlot ); finalSecondarySlot = NULL; } if ( slotForSecondaryKey != NULL ) { PK11_FreeSlot( slotForSecondaryKey ); slotForSecondaryKey = NULL; } JSS_DerefByteArray(env, param, paramValue, JNI_ABORT); JSS_DerefByteArray(env, iv, ivValue, JNI_ABORT); if( keyObj == NULL) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Unable to derive symmetric key! " "failure!"); } return keyObj; } jss-4.6.3/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.java000066400000000000000000000127301362106420000236650ustar00rootroot00000000000000/* ***** 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.pkcs11; import org.mozilla.jss.crypto.*; import java.security.InvalidKeyException; /*This operation is pkcs11 based only */ public class PK11SymmetricKeyDeriver implements SymmetricKeyDeriver { private PK11Token token = null; private SymmetricKey baseKey = null; private SymmetricKey secondaryKey = null; private long deriveMechanism = 0; private long targetMechanism = 0; private long operation = 0; private long keySize = 0; private byte[] param = null; private byte[] iv = null; public PK11SymmetricKeyDeriver(PK11Token token) { this.token = token; } /* Use with the encrypt type mechanisms Example: initDerive( symKey, (PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA) 4354L, derivationData, null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE, 16); */ public void initDerive(SymmetricKey baseKey, long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize) throws InvalidKeyException { reset(); if(baseKey == null) { throw new InvalidKeyException("Key is null"); } this.baseKey = baseKey; this.deriveMechanism = deriveMech; this.targetMechanism = targetMech; this.operation = operation; if ( param != null) { this.param = new byte[param.length]; System.arraycopy(param,0,this.param,0,param.length); } if ( iv != null) { this.iv = new byte[iv.length]; System.arraycopy(iv,0,this.iv,0,iv.length); } this.keySize = keySize; } /* Use with key extraction and key concatanation mechanisms Example Extraction: param: byte array that has the bit position of where to extract initDerive( derivedKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,8); Example Concat: initDerive( baseSymKey,secondarySymKey, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY,null,null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,0); */ public void initDerive(SymmetricKey baseKey, SymmetricKey secondaryKey, long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize) throws InvalidKeyException { reset(); if ( baseKey == null || secondaryKey == null) { throw new InvalidKeyException("Key is null"); } initDerive(baseKey, deriveMech, param,iv,targetMech,operation,keySize); this.secondaryKey = secondaryKey; } public SymmetricKey derive() throws TokenException { SymmetricKey result = deriveSymKey(this.baseKey,this.secondaryKey,this.deriveMechanism, this.param, this.iv, this.targetMechanism, this.operation,this.keySize); return result; } private SymmetricKey deriveSymKey(SymmetricKey baseKey, SymmetricKey secondaryKey, long deriveMechanism, byte[] param, byte[] iv, long targetMechanism, long operation, long keySize) throws TokenException, IllegalStateException { return nativeDeriveSymKey(token, baseKey, secondaryKey,deriveMechanism, param, iv, targetMechanism, operation, keySize); } public native SymmetricKey nativeDeriveSymKey(PK11Token token, SymmetricKey baseKey, SymmetricKey secondaryKey, long deriveMechanism, byte[] param, byte[] iv, long targetMechanism, long operation, long keySize); private void reset() { baseKey = null; secondaryKey = null; deriveMechanism = 0; targetMechanism = 0; operation = 0; keySize = 0; param = null; iv = null; } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Token.c000066400000000000000000000740121362106420000203010ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11Token.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "java_ids.h" #include "pk11util.h" #include #define ERRX 1 #define KEYTYPE_DSA_STRING "dsa" #define KEYTYPE_RSA_STRING "rsa" #define KEYTYPE_EC_STRING "ec" static CERTCertificateRequest* make_cert_request(JNIEnv *env, const char *subject, SECKEYPublicKey *pubk); static void GenerateCertRequest(JNIEnv *env, SECOidTag ktype, const char *subject, PK11SlotInfo *slot, unsigned char **b64request, void *params); /* these values are taken from PK11KeyPairGenerator.java */ #define DEFAULT_RSA_KEY_SIZE 2048 #define DEFAULT_RSA_PUBLIC_EXPONENT 0x10001 /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P K 1 1 T o k e n * * Create a PK11Token object from a PKCS #11 slot. * * slot is a pointer to a PKCS #11 slot, which must not be NULL. It will * be eaten by the wrapper, so you can't use it after you call this. * * Returns a new PK11Token object, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapPK11Token(JNIEnv *env, PK11SlotInfo **slot) { jclass tokenClass; jmethodID constructor; jbyteArray byteArray; jobject Token=NULL; jboolean internal; jboolean keyStorage; PR_ASSERT(env!=NULL && slot!=NULL && *slot!=NULL); internal = (*slot == PK11_GetInternalSlot()); keyStorage = (*slot == PK11_GetInternalKeySlot()); byteArray = JSS_ptrToByteArray(env, (void*)*slot); /* * Lookup the class and constructor */ tokenClass = (*env)->FindClass(env, PK11TOKEN_CLASS_NAME); if(tokenClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, tokenClass, PK11TOKEN_CONSTRUCTOR_NAME, PK11TOKEN_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* Call the constructor */ Token = (*env)->NewObject(env, tokenClass, constructor, byteArray, internal, keyStorage); finish: if(Token==NULL) { PK11_FreeSlot(*slot); } *slot = NULL; return Token; } /************************************************************************ * * P K 1 1 T o k e n . needs Login * * returns true if this token needs to be logged into before it can be used. */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_needsLogin (JNIEnv *env, jobject this) { PK11SlotInfo *slot; jboolean retval; PR_ASSERT(env!=NULL && this!=NULL); if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ retval = JNI_FALSE; goto finish; } PR_ASSERT(slot != NULL); if(PK11_NeedLogin(slot) == PR_TRUE) { retval = JNI_TRUE; } else { retval = JNI_FALSE; } finish: return retval; } /************************************************************************ * * P K 1 1 T o k e n . i s L o g g e d I n * * Returns true if this token is logged in. */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_isLoggedIn (JNIEnv *env, jobject this) { PK11SlotInfo *slot; jboolean retval; PR_ASSERT(env!=NULL && this!=NULL); if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ retval = JNI_FALSE; goto finish; } PR_ASSERT(slot != NULL); if(PK11_IsLoggedIn(slot, NULL) == PR_TRUE) { retval = JNI_TRUE; } else { retval = JNI_FALSE; } finish: return retval; } /************************************************************************ * * P K 1 1 T o k e n . n a t i v e L o g i n * * Attempts to login to the token with the given password callback. * Throws NotInitializedException if the token is not initialized. * Throws IncorrectPINException if the supplied PIN is incorrect. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_nativeLogin (JNIEnv *env, jobject this, jobject callback) { PK11SlotInfo *slot; PR_ASSERT(env!=NULL && this!=NULL && callback!=NULL); if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ goto finish; } PR_ASSERT(slot != NULL); /* Is the token initialized? */ if(PK11_NeedUserInit(slot)) { JSS_nativeThrow( env, TOKEN_NOT_INITIALIZED_EXCEPTION ); goto finish; } if(PK11_Authenticate(slot, PR_TRUE /*loadCerts*/, (void*)callback) != SECSuccess) { JSS_nativeThrow(env, INCORRECT_PASSWORD_EXCEPTION); goto finish; } /* Success! */ finish: return; } /************************************************************************ * * P K 1 1 T o k e n . l o g o u t */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_logout (JNIEnv *env, jobject this) { PK11SlotInfo *slot; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception occurred */ goto finish; } PR_ASSERT(slot != NULL); if( PK11_Logout(slot) != SECSuccess) { JSS_nativeThrowMsg( env, TOKEN_EXCEPTION, "Unable to logout token" ); goto finish; } finish: return; } /************************************************************************ * * P K 1 1 T o k e n . g e t L o g i n M o d e * * Returns the login mode (ONE_TIME, TIMEOUT, EVERY_TIME) for this token. * These constants must sync with the ones defined in CryptoToken. */ #define ONE_TIME 0 #define TIMEOUT 1 #define EVERY_TIME 2 /************************************************************************ * * P K 1 1 T o k e n . g e t L o g i n M o d e * */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_getLoginMode (JNIEnv *env, jobject this) { PK11SlotInfo *slot; jint mode=ONE_TIME; int askpw; int timeout; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot!=NULL); PK11_GetSlotPWValues(slot, &askpw, &timeout); if(askpw == -1) { mode = EVERY_TIME; } else if(askpw == 0) { mode = ONE_TIME; } else if(askpw == 1) { mode = TIMEOUT; } else { JSS_throw(env, TOKEN_EXCEPTION); goto finish; } finish: return mode; } /************************************************************************ * * P K 1 1 T o k e n . g e t L o g i n T i m e o u t M i n u t e s */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_getLoginTimeoutMinutes (JNIEnv *env, jobject this) { PK11SlotInfo *slot; int askpw; int timeout=0; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot!=NULL); PK11_GetSlotPWValues(slot, &askpw, &timeout); finish: return timeout; } /************************************************************************ * * P K 1 1 T o k e n . s e t L o g i n M o d e * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_setLoginMode (JNIEnv *env, jobject this, jint mode) { PK11SlotInfo *slot; int askpw, timeout; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot!=NULL); PK11_GetSlotPWValues(slot, &askpw, &timeout); if(mode == EVERY_TIME) { askpw = -1; } else if(mode == ONE_TIME) { askpw = 0; } else if(mode == TIMEOUT) { askpw = 1; } else { JSS_throw(env, TOKEN_EXCEPTION); goto finish; } PK11_SetSlotPWValues(slot, askpw, timeout); finish: ; } /************************************************************************ * * P K 1 1 T o k e n . s e t L o g i n T i m e o u t M i n u t e s * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_setLoginTimeoutMinutes (JNIEnv *env, jobject this, jint newTimeout) { PK11SlotInfo *slot; int askpw, timeout; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return; } PR_ASSERT(slot!=NULL); PK11_GetSlotPWValues(slot, &askpw, &timeout); PK11_SetSlotPWValues(slot, askpw, newTimeout); } /************************************************************************ * * P K 1 1 T o k e n . i s P r e s e n t * * Returns true if this token is present in the slot */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_isPresent (JNIEnv *env, jobject this) { PK11SlotInfo *slot; jboolean retval; PR_ASSERT(env!=NULL && this!=NULL); if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ retval = JNI_FALSE; goto finish; } PR_ASSERT(slot != NULL); if(PK11_IsPresent(slot) == PR_TRUE) { retval = JNI_TRUE; } else { retval = JNI_FALSE; } finish: return retval; } /************************************************************************ * * P K 1 1 T o k e n . P W I n i t a b l e * * Make sure this token can be initialized. Currently we only check the * internal module, since it can't be initialized more than once. * Presumably most tokens can have their PINs initialized arbitrarily * many times. */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_PWInitable (JNIEnv *env, jobject this) { PK11SlotInfo *slot=NULL; jboolean initable=JNI_FALSE; PR_ASSERT(env!=NULL && this!=NULL); /* * Convert Java objects to native objects */ if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ goto finish; } PR_ASSERT(slot!=NULL); if(slot != PK11_GetInternalKeySlot()) { /* We don't know about other tokens */ initable = JNI_TRUE; } else { if(PK11_NeedUserInit(slot)) { initable = JNI_TRUE; } else { /* Internal module only allows one init, after this you * need to do a changePIN */ initable = JNI_FALSE; } } finish: return initable; } /************************************************************************ * * P K 1 1 T o k e n . i n i t P a s s w o r d * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_initPassword (JNIEnv *env, jobject this, jbyteArray ssopw, jbyteArray userpw) { PK11SlotInfo *slot=NULL; char *szSsopw=NULL, *szUserpw=NULL; jboolean ssoIsCopy, userIsCopy; SECStatus initResult; PRErrorCode error; PR_ASSERT(env!=NULL && this!=NULL && ssopw!=NULL && userpw!=NULL); /* * Convert Java objects to native objects */ if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ goto finish; } szSsopw = (char*) (*env)->GetByteArrayElements(env, ssopw, &ssoIsCopy); szUserpw = (char*) (*env)->GetByteArrayElements(env, userpw, &userIsCopy); PR_ASSERT(slot!=NULL && szSsopw!=NULL && szUserpw!=NULL); /* * If we're on the internal module, make sure we can still be * initialized. */ if(slot == PK11_GetInternalKeySlot() && !PK11_NeedUserInit(slot)) { JSS_nativeThrowMsg(env, ALREADY_INITIALIZED_EXCEPTION, "Netscape Internal Key Token is already initialized"); goto finish; } /* * Initialize the PIN */ initResult = PK11_InitPin(slot, szSsopw, szUserpw); if(initResult != SECSuccess) { error = PR_GetError(); } /* * Throw exception if an error occurred */ if(initResult != SECSuccess) { if(error == SEC_ERROR_BAD_PASSWORD) { JSS_nativeThrowMsg( env, INCORRECT_PASSWORD_EXCEPTION, "Incorrect security officer PIN" ); } else { JSS_nativeThrowMsg( env, TOKEN_EXCEPTION, "Unable to initialize PIN" ); } } finish: /* * Free native objects */ if (szSsopw && ssoIsCopy) { JSS_wipeCharArray(szSsopw); } JSS_DerefByteArray(env, ssopw, szSsopw, JNI_ABORT); if (szUserpw && userIsCopy) { JSS_wipeCharArray(szUserpw); } JSS_DerefByteArray(env, userpw, szUserpw, JNI_ABORT); return; } /************************************************************************ * * P K 1 1 T o k e n . p a s s w o r d I s I n i t i a l i z e d * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_passwordIsInitialized (JNIEnv *env, jobject this) { PK11SlotInfo *slot=NULL; jboolean isInitialized = JNI_FALSE; PR_ASSERT(env!=NULL && this!=NULL); /* * Convert Java arguments to C */ if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot != NULL); if(slot == PK11_GetInternalKeySlot()) { /* special case for our Key slot */ isInitialized = ! PK11_NeedPWInit(); } else { isInitialized = ! PK11_NeedUserInit(slot); } finish: return isInitialized; } /************************************************************************ * * P K 1 1 T o k e n . c h a n g e P a s s w o r d * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_changePassword (JNIEnv *env, jobject this, jbyteArray oldPIN, jbyteArray newPIN) { PK11SlotInfo *slot=NULL; char *szOldPIN=NULL, *szNewPIN=NULL; jboolean oldIsCopy, newIsCopy; SECStatus changeResult; PRErrorCode error; PR_ASSERT(env!=NULL && this!=NULL && oldPIN!=NULL && newPIN!=NULL); /* * Convert Java objects to native objects */ if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ goto finish; } szOldPIN= (char*) (*env)->GetByteArrayElements(env, oldPIN, &oldIsCopy); szNewPIN= (char*) (*env)->GetByteArrayElements(env, newPIN, &newIsCopy); PR_ASSERT(slot!=NULL && szOldPIN!=NULL && szNewPIN!=NULL); /* * Change the PIN */ changeResult = PK11_ChangePW(slot, szOldPIN, szNewPIN); if(changeResult != SECSuccess) { error = PR_GetError(); } /* * Throw exception if an error occurred */ if(changeResult != SECSuccess) { if(error == SEC_ERROR_BAD_PASSWORD) { JSS_nativeThrowMsg( env, INCORRECT_PASSWORD_EXCEPTION, "Incorrect PIN" ); } else { JSS_nativeThrowMsg( env, TOKEN_EXCEPTION, "Unable to change PIN" ); } } finish: /* Free native objects */ if(szOldPIN && oldIsCopy) { JSS_wipeCharArray(szOldPIN); } JSS_DerefByteArray(env, oldPIN, szOldPIN, JNI_ABORT); if(szNewPIN && newIsCopy) { JSS_wipeCharArray(szNewPIN); } JSS_DerefByteArray(env, newPIN, szNewPIN, JNI_ABORT); return; } typedef enum { SSOPW, USERPW } pwType; /************************************************************************ * * p a s s w o r d I s C o r r e c t * * Checks the given password, which could be an SSO or a user password. * Returns JNI_TRUE if the password is correct, JNI_FALSE if it isn't, * and may throw an exception if something goes wrong on the token. */ static jboolean passwordIsCorrect (JNIEnv *env, jobject this, jbyteArray password, pwType type) { PK11SlotInfo *slot = NULL; char *pwBytes=NULL; jboolean isCopy; jboolean pwIsCorrect = JNI_FALSE; SECStatus status; int error; PR_ASSERT(env!=NULL && this!=NULL && password!=NULL); /* * Convert Java args to C */ if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } pwBytes = (char*) (*env)->GetByteArrayElements(env, password, &isCopy); PR_ASSERT(slot!=NULL && pwBytes != NULL); /* * Do the check */ if(type == SSOPW) { status = PK11_CheckSSOPassword(slot, pwBytes); } else { status = PK11_CheckUserPassword(slot, pwBytes); } if(status == SECSuccess) { pwIsCorrect = JNI_TRUE; } else { error = PR_GetError(); if(error == SEC_ERROR_BAD_PASSWORD) { /* just wrong password */ pwIsCorrect = JNI_FALSE; } else { /* some token problem */ JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "Unable to check password"); goto finish; } } finish: /* Free native objects */ if (pwBytes && isCopy) { JSS_wipeCharArray(pwBytes); } /* JNI_ABORT means don't copy back changes */ JSS_DerefByteArray(env, password, pwBytes, JNI_ABORT); return pwIsCorrect; } /************************************************************************ * * P K 1 1 T o k e n . u s e r P a s s w o r d I s C o r r e c t * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_userPasswordIsCorrect (JNIEnv *env, jobject this, jbyteArray password) { return passwordIsCorrect(env, this, password, USERPW); } /************************************************************************ * * P K 1 1 T o k e n . S S O P a s s w o r d I s C o r r e c t * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_SSOPasswordIsCorrect (JNIEnv *env, jobject this, jbyteArray password) { return passwordIsCorrect(env, this, password, SSOPW); } /************************************************************************ * * P K 1 1 T o k e n . g e t N a m e * * Returns the name of this token. */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_getName (JNIEnv *env, jobject this) { char *szName; PK11SlotInfo *slot; jstring name; jstring retval; PR_ASSERT(env!=NULL && this!=NULL); if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL ); /* an exception was thrown */ retval = NULL; goto finish; } PR_ASSERT(slot != NULL); szName = PK11_GetTokenName(slot); /* NULL C string converts to empty Java string */ if(szName == NULL) { szName = ""; } name = (*env)->NewStringUTF(env, szName); /* name could be NULL, if an OutOfMemoryError occurred. In that case, * we just return NULL and let the exception be thrown in Java */ #ifdef DEBUG if(name == NULL) { /* Make sure there is an exception before we return NULL */ PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); } #endif retval = name; finish: return retval; } /************************************************************************ * * T o k e n P r o x y . r e l e a s e N a t i v e R e s o u r c e s * * Free the PK11SlotInfo structure that underlies my token. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_TokenProxy_releaseNativeResources (JNIEnv *env, jobject this) { PK11SlotInfo *slot; PR_ASSERT(env!=NULL && this!=NULL); if(JSS_getPtrFromProxy(env, this, (void**)&slot) != PR_SUCCESS) { PR_ASSERT( PR_FALSE ); goto finish; } /* * PK11Token never stores a null pointer in its TokenProxy member, * but PK11Cert may store a null pointer in its TokenProxy member. * (A temporary certificate has a null slot pointer.) */ if(slot != NULL) { /* this actually only frees the data structure if we were the last * reference to it */ PK11_FreeSlot(slot); } finish: return; } /************************************************************************ * * J S S _ g e t T o k e n S l o t P t r * * Retrieve the PK11SlotInfo pointer of the given token. * * tokenObject: A reference to a Java PK11Token * ptr: address of a PK11SlotInfo* that will be loaded with the PK11SlotInfo * pointer of the given token. * returns: PR_SUCCESS if the operation was successful, PR_FAILURE if an * exception was thrown. */ PRStatus JSS_PK11_getTokenSlotPtr(JNIEnv *env, jobject tokenObject, PK11SlotInfo **ptr) { PR_ASSERT(env != NULL && tokenObject != NULL && ptr != NULL); /* * Get the pointer from the PK11Token, which has a Token Proxy member */ PR_ASSERT(sizeof(PK11SlotInfo*) == sizeof(void*)); return JSS_getPtrFromProxyOwner(env, tokenObject, PK11TOKEN_PROXY_FIELD, PK11TOKEN_PROXY_SIG, (void**)ptr); } /********************************************************************** * * PK11Token.doesAlgorithm * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_doesAlgorithm (JNIEnv *env, jobject this, jobject alg) { PK11SlotInfo *slot; CK_MECHANISM_TYPE mech; jboolean doesMech = JNI_FALSE; if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot != NULL); mech = JSS_getPK11MechFromAlg(env, alg); /* not an assertion, some algorithms don't have Mechanism yet */ /*PR_ASSERT( mech != CKM_INVALID_MECHANISM ); */ if( PK11_DoesMechanism(slot, mech) == PR_TRUE) { doesMech = JNI_TRUE; } /* HACK...exceptions */ if( PK11_IsInternal(slot) && mech == CKM_PBA_SHA1_WITH_SHA1_HMAC ) { /* Although the internal slot doesn't actually do this mechanism, * we do it by hand in PK11KeyGenerator.c */ doesMech = JNI_TRUE; } finish: return doesMech; } /*********************************************************************** * * PK11Token.isWritable * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_isWritable (JNIEnv *env, jobject this) { PK11SlotInfo *slot; if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { return JNI_FALSE; /* an exception was thrown, so it doesn't matter */ } PR_ASSERT(slot != NULL); return ! PK11_IsReadOnly(slot); } #define ZERO_SECITEM(item) {(item).len=0; (item).data=NULL;} int PK11_NumberObjectsFor(PK11SlotInfo*, CK_ATTRIBUTE*, int); /************************************************************************ * * P K 1 1 T o k e n . getCertRequest */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_generatePK10 (JNIEnv *env, jobject this, jstring subject, jint keysize, jstring keyType, jbyteArray P, jbyteArray Q, jbyteArray G) { PK11SlotInfo *slot; const char* c_subject=NULL; unsigned char *b64request=NULL; SECItem p, q, g; PQGParams *dsaParams=NULL; const char* c_keyType; SECOidTag signType = SEC_OID_UNKNOWN; PK11RSAGenParams rsaParams; void *params = NULL; PR_ASSERT(env!=NULL && this!=NULL); /* get keytype */ c_keyType = JSS_RefJString(env, keyType); if (0 == PL_strcasecmp(c_keyType, KEYTYPE_RSA_STRING)) { signType = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; if( keysize == -1 ) { rsaParams.keySizeInBits = DEFAULT_RSA_KEY_SIZE; } else { rsaParams.keySizeInBits = keysize; } rsaParams.pe = DEFAULT_RSA_PUBLIC_EXPONENT; params = (void *)&rsaParams; } else if (0 == PL_strcasecmp(c_keyType, KEYTYPE_DSA_STRING)) { signType = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; if (P==NULL || Q==NULL || G ==NULL) { /* shouldn't happen */ JSS_throw(env, INVALID_PARAMETER_EXCEPTION); } else { /* caller supplies PQG */ /* zero these so we can free them indiscriminately later */ ZERO_SECITEM(p); ZERO_SECITEM(q); ZERO_SECITEM(g); if( JSS_ByteArrayToOctetString(env, P, &p) || JSS_ByteArrayToOctetString(env, Q, &q) || JSS_ByteArrayToOctetString(env, G, &g) ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } dsaParams = PK11_PQG_NewParams(&p, &q, &g); if(dsaParams == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } } params = (void *)dsaParams; } else if (0 == PL_strcasecmp(c_keyType, KEYTYPE_EC_STRING)) { signType = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; /* get ec param */ } else { JSS_throw(env, INVALID_PARAMETER_EXCEPTION); } if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception occurred */ goto finish; } PR_ASSERT(slot != NULL); if(PK11_IsLoggedIn(slot, NULL) != PR_TRUE) { JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "token not logged in"); } /* get subject */ c_subject = JSS_RefJString(env, subject); /* call GenerateCertRequest() */ GenerateCertRequest(env, signType, c_subject, slot, &b64request, params); finish: /* release memory */ JSS_DerefJString(env, subject, c_subject); /* release memory */ JSS_DerefJString(env, keyType, c_keyType); if (signType == SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) { SECITEM_FreeItem(&p, PR_FALSE); SECITEM_FreeItem(&q, PR_FALSE); SECITEM_FreeItem(&g, PR_FALSE); PK11_PQG_DestroyParams(dsaParams); } if (b64request == NULL) { return NULL; } else { /* convert to String */ return (*env)->NewStringUTF(env, (const char *)b64request); } } /* * generate keypairs and further the request * the real thing will need keytype and pqg numbers (for DSA) */ void GenerateCertRequest(JNIEnv *env, SECOidTag signType, const char *subject, PK11SlotInfo *slot, unsigned char **b64request, void *params) { CERTCertificateRequest *req; SECKEYPrivateKey *privk = NULL; SECKEYPublicKey *pubk = NULL; SECStatus rv; PRArenaPool *arena; SECItem result_der, result; SECItem * VARIABLE_MAY_NOT_BE_USED blob; CK_MECHANISM_TYPE signMech; CK_MECHANISM_TYPE keygenMech; #ifdef DEBUG printf("in GenerateCertRequest(), subject=%s, ", subject); #endif /* * Use the tables to reduce the code of adding new * types of keys. */ signMech = PK11_AlgtagToMechanism(signType); if (signMech == CKM_INVALID_MECHANISM) { #ifdef DEBUG printf("Error getting KEYGEN Mechanism."); #endif } keygenMech = PK11_GetKeyGen(signMech); if( JSS_PK11_generateKeyPair(env, keygenMech, slot, &pubk, &privk, params, PR_FALSE, -1, -1) != SECSuccess) { #ifdef DEBUG printf("Error generating keypair."); #endif } #ifdef DEBUG printf("before make_cert_request"); #endif req = make_cert_request (env, subject, pubk); #ifdef DEBUG printf("after make_cert_request"); #endif if (req == NULL) { return; } result_der.len = 0; result_der.data = NULL; #ifdef DEBUG printf("before SEC_ASN1EncodeItem"); #endif /* der encode the request */ blob = SEC_ASN1EncodeItem(req->arena, &result_der, req, SEC_ASN1_GET(CERT_CertificateRequestTemplate)); /* sign the request */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( !arena ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); return; } rv = SEC_DerSignData(arena, &result, result_der.data, result_der.len, privk, signType); if (rv) { JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "signing of data failed"); PORT_FreeArena(arena, PR_FALSE); return; } *b64request = (unsigned char*) BTOA_DataToAscii(result.data, result.len); PORT_FreeArena(arena, PR_FALSE); #ifdef DEBUG printf("data = %s\n", *b64request); #endif } /****************************************************************** * * m a k e _ c e r t _ r e q u e s t */ static CERTCertificateRequest* make_cert_request(JNIEnv *env, const char *subject, SECKEYPublicKey *pubk) { CERTName *subj = NULL; CERTSubjectPublicKeyInfo *spki = NULL; CERTCertificateRequest *req = NULL; /* Create info about public key */ spki = SECKEY_CreateSubjectPublicKeyInfo(pubk); if (!spki) { JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "unable to create subject public key"); goto finish; } subj = CERT_AsciiToName ((char *)subject); if(subj == NULL) { JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "Invalid data in certificate description"); goto finish; } /* Generate certificate request */ req = CERT_CreateCertificateRequest(subj, spki, 0); if (!req) { JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "unable to make certificate request"); goto finish; } #ifdef DEBUG printf("certificate request generated\n"); #endif finish: if (subj) { CERT_DestroyName(subj); } if (spki) { SECKEY_DestroySubjectPublicKeyInfo(spki); } return req; } JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_importPublicKey( JNIEnv *env, jobject tokenObj, jobject pubKeyObj, jboolean permanent) { PK11SlotInfo *slot; SECKEYPublicKey *pubKey = NULL; PR_ASSERT(env != NULL && tokenObj != NULL && pubKeyObj != NULL); if (JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { PR_ASSERT((*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ return; } PR_ASSERT(slot != NULL); if (PK11_IsLoggedIn(slot, NULL) != PR_TRUE) { JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "token not logged in"); return; } if (PR_SUCCESS != JSS_PK11_getPubKeyPtr(env, pubKeyObj, &pubKey)) { return; // exception was thrown! } if (PK11_ImportPublicKey(slot, pubKey, permanent) == CK_INVALID_HANDLE) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "failed to import public key"); return; } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11Token.java000066400000000000000000000436531362106420000210070ustar00rootroot00000000000000/* 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.pkcs11; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import org.mozilla.jss.crypto.Algorithm; import org.mozilla.jss.crypto.AlreadyInitializedException; import org.mozilla.jss.crypto.Cipher; import org.mozilla.jss.crypto.CryptoStore; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.DigestAlgorithm; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.JSSMessageDigest; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.KeyPairGenerator; import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.KeyWrapper; import org.mozilla.jss.crypto.PQGParamGenException; import org.mozilla.jss.crypto.PQGParams; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.util.Assert; import org.mozilla.jss.util.IncorrectPasswordException; import org.mozilla.jss.util.NotImplementedException; import org.mozilla.jss.util.NullPasswordCallback; import org.mozilla.jss.util.Password; import org.mozilla.jss.util.PasswordCallback; import org.mozilla.jss.util.PasswordCallbackInfo; /** * A PKCS #11 token. Currently, these can only be obtained from the * CryptoManager class. * * @author nicolson * @version $Revision$ $Date$ * @see org.mozilla.jss.CryptoManager */ public final class PK11Token implements CryptoToken { protected TokenProxy tokenProxy; protected PK11Store cryptoStore; protected boolean mIsInternalCryptoToken; protected boolean mIsInternalKeyStorageToken; //////////////////////////////////////////////////// // exceptions //////////////////////////////////////////////////// /** * Thrown if the operation requires that the token be logged in, and it * isn't. */ static public class NotInitializedException extends IncorrectPasswordException { private static final long serialVersionUID = 1L; public NotInitializedException() {} public NotInitializedException(String mesg) {super(mesg);} } //////////////////////////////////////////////////// // public routines //////////////////////////////////////////////////// public org.mozilla.jss.crypto.Signature getSignatureContext(SignatureAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { assert(algorithm!=null); return Tunnel.constructSignature( algorithm, new PK11Signature(this, algorithm) ); } public JSSMessageDigest getDigestContext(DigestAlgorithm algorithm) throws NoSuchAlgorithmException, java.security.DigestException { if( ! doesAlgorithm(algorithm) ) { throw new NoSuchAlgorithmException(); } return new PK11MessageDigest(this, algorithm); } public Cipher getCipherContext(EncryptionAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { if( ! doesAlgorithm(algorithm) ) { throw new NoSuchAlgorithmException( algorithm+" is not supported by this token"); } return new PK11Cipher(this, algorithm); } public KeyGenerator getKeyGenerator(KeyGenAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { /* NSS is capable of finding the right token to do algorithm, so this call is prematurely bailing if( ! doesAlgorithm(algorithm) ) { throw new NoSuchAlgorithmException( algorithm+" is not supported by this token"); } */ return new PK11KeyGenerator(this, algorithm); } /** * Allows a SymmetricKey to be cloned on a different token. * * @exception SymmetricKey.NotExtractableException If the key material * cannot be extracted from the current token. * @exception InvalidKeyException If the owning token cannot process * the key to be cloned. */ public SymmetricKey cloneKey(SymmetricKey key) throws SymmetricKey.NotExtractableException, InvalidKeyException, TokenException { return PK11KeyGenerator.clone(key, this); } public PK11SymmetricKeyDeriver getSymmetricKeyDeriver() { return new PK11SymmetricKeyDeriver(this); } public KeyWrapper getKeyWrapper(KeyWrapAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { /* NSS is capable of finding the right token to do algorithm, so this call is prematurely bailing if( ! doesAlgorithm(algorithm) ) { throw new NoSuchAlgorithmException( algorithm+" is not supported by this token"); } */ return new PK11KeyWrapper(this, algorithm); } public java.security.SecureRandom getRandomGenerator() throws NotImplementedException, TokenException { throw new NotImplementedException(); } public org.mozilla.jss.crypto.KeyPairGenerator getKeyPairGenerator(KeyPairAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { assert(algorithm!=null); return new KeyPairGenerator(algorithm, new PK11KeyPairGenerator(this, algorithm)); } public native boolean isLoggedIn() throws TokenException; public native boolean needsLogin() throws TokenException; /** * Log into the token. If you are already logged in, this method has * no effect, even if the PIN is wrong. * * @param callback A callback to use to obtain the password, or a * Password object. * @exception NotInitializedException The token has not yet been * initialized. * @exception IncorrectPasswordException The specified password * was incorrect. */ public void login(PasswordCallback callback) throws NotInitializedException, IncorrectPasswordException, TokenException { if(callback == null) { callback = new NullPasswordCallback(); } nativeLogin(callback); } protected native void nativeLogin(PasswordCallback callback) throws NotInitializedException, IncorrectPasswordException, TokenException; /** * @return true if the token is writable, false if it is read-only. * Writable tokens can have their keys generated on the internal token * and then moved out. */ public native boolean isWritable(); /** * Determines if the given token is present on the system. * This would return false, for example, for a smart card reader * that didn't have a card inserted. */ public native boolean isPresent(); /** * Log out of the token. * * @exception TokenException If you are already logged in, or an * unspecified error occurs. */ public native void logout() throws TokenException; public native int getLoginMode() throws TokenException; public native void setLoginMode(int mode) throws TokenException; public native int getLoginTimeoutMinutes() throws TokenException; public native void setLoginTimeoutMinutes(int timeoutMinutes) throws TokenException; /** * Determines whether this is a removable token. For example, a smart card * is removable, while the Netscape internal module and a hardware * accelerator card are not removable. * @return true if the token is removable, false otherwise. */ //public native boolean isRemovable(); /** * Initialize PIN. This sets the user's new PIN, using the current * security officer PIN for authentication. * * @param ssopwcb The security officer's current password callback. * @param userpwcb The user's new password callback. * @exception IncorrectPasswordException If the security officer PIN is * incorrect. * @exception AlreadyInitializedException If the password hasn't already * been set. * @exception TokenException If the PIN was already initialized, * or there was an unspecified error in the token. */ public void initPassword(PasswordCallback ssopwcb, PasswordCallback userpwcb) throws IncorrectPasswordException, AlreadyInitializedException, TokenException { byte[] ssopwArray = null; byte[] userpwArray = null; Password ssopw=null; Password userpw=null; PasswordCallbackInfo pwcb = makePWCBInfo(); if(ssopwcb==null) { ssopwcb = new NullPasswordCallback(); } if(userpwcb==null) { userpwcb = new NullPasswordCallback(); } try { // Make sure the password hasn't already been set, doing special // checks for the internal module if(!PWInitable()) { throw new AlreadyInitializedException(); } // Verify the SSO Password, except on internal module if( isInternalKeyStorageToken() ) { ssopwArray = new byte[] {0}; } else { ssopw = ssopwcb.getPasswordFirstAttempt(pwcb); ssopwArray = Tunnel.getPasswordByteCopy(ssopw); while( ! SSOPasswordIsCorrect(ssopwArray) ) { Password.wipeBytes(ssopwArray); ssopw.clear(); ssopw = ssopwcb.getPasswordAgain(pwcb); ssopwArray = Tunnel.getPasswordByteCopy(ssopw); } } // Now change the PIN userpw = userpwcb.getPasswordFirstAttempt(pwcb); userpwArray = Tunnel.getPasswordByteCopy(userpw); initPassword(ssopwArray, userpwArray); } catch (PasswordCallback.GiveUpException e) { throw new IncorrectPasswordException(e.toString()); } finally { // zero-out the arrays if(ssopwArray != null) { Password.wipeBytes(ssopwArray); } if(ssopw != null) { ssopw.clear(); } if(userpwArray != null) { Password.wipeBytes(userpwArray); } if(userpw != null) { userpw.clear(); } } } /** * Make sure the PIN can be initialized. This is mainly to check the * internal module. */ protected native boolean PWInitable() throws TokenException; protected native boolean SSOPasswordIsCorrect(byte[] ssopw) throws TokenException, AlreadyInitializedException; protected native void initPassword(byte[] ssopw, byte[] userpw) throws IncorrectPasswordException, AlreadyInitializedException, TokenException; /** * Determine whether the token has been initialized yet. */ public native boolean passwordIsInitialized() throws TokenException; /** * Change password. This changes the user's PIN after it has already * been initialized. * * @param oldPINcb The user's old PIN callback. * @param newPINcb The new PIN callback. * @exception IncorrectPasswordException If the old PIN is incorrect. * @exception TokenException If some other error occurs on the token. * */ public void changePassword(PasswordCallback oldPINcb, PasswordCallback newPINcb) throws IncorrectPasswordException, TokenException { byte[] oldPW = null; byte[] newPW = null; Password oldPIN=null; Password newPIN=null; PasswordCallbackInfo pwcb = makePWCBInfo(); if(oldPINcb==null) { oldPINcb = new NullPasswordCallback(); } if(newPINcb==null) { newPINcb = new NullPasswordCallback(); } try { // Verify the old password oldPIN = oldPINcb.getPasswordFirstAttempt(pwcb); oldPW = Tunnel.getPasswordByteCopy(oldPIN); if( ! userPasswordIsCorrect(oldPW) ) { do { Password.wipeBytes(oldPW); oldPIN.clear(); oldPIN = oldPINcb.getPasswordAgain(pwcb); oldPW = Tunnel.getPasswordByteCopy(oldPIN); } while( ! userPasswordIsCorrect(oldPW) ); } // Now change the PIN newPIN = newPINcb.getPasswordFirstAttempt(pwcb); newPW = Tunnel.getPasswordByteCopy(newPIN); changePassword(oldPW, newPW); } catch (PasswordCallback.GiveUpException e) { throw new IncorrectPasswordException(e.toString()); } finally { if(oldPW != null) { Password.wipeBytes(oldPW); } if(oldPIN != null) { oldPIN.clear(); } if(newPW != null) { Password.wipeBytes(newPW); } if(newPIN != null) { newPIN.clear(); } } } protected PasswordCallbackInfo makePWCBInfo() { return new TokenCallbackInfo(getName()); } /** * Check the given password, return true if it's right, false if it's * wrong. */ protected native boolean userPasswordIsCorrect(byte[] pw) throws TokenException; /** * Change the password on the token from the old one to the new one. */ protected native void changePassword(byte[] oldPIN, byte[] newPIN) throws IncorrectPasswordException, TokenException; public native String getName(); public java.security.Provider getProvider() { throw new RuntimeException("PK11Token.getProvider() is not yet implemented"); } public CryptoStore getCryptoStore() { return cryptoStore; } /** * Determines whether this token is capable of performing the given * PKCS #11 mechanism. */ /* public boolean doesMechanism(Mechanism mech) { return doesMechanismNative(mech.getValue()); } */ /** * Deep-comparison operator. * * @return true if these tokens point to the same underlying native token. * false otherwise, or if compare is null. */ public boolean equals(Object obj) { if(obj==null) { return false; } else { if( ! (obj instanceof PK11Token) ) { return false; } return tokenProxy.equals(((PK11Token)obj).tokenProxy); } } //protected native boolean doesMechanismNative(int mech); /** * Determines whether this token is capable of performing the given * algorithm. */ public native boolean doesAlgorithm(Algorithm alg); /** * Generates a PKCS#10 certificate request including Begin/End brackets * @param subject subject dn of the certificate * @param keysize size of the key * @param keyType "rsa" or "dsa" * @param P The DSA prime parameter * @param Q The DSA sub-prime parameter * @param G The DSA base parameter * @return String that represents a PKCS#10 b64 encoded blob with * begin/end brackets */ public String generateCertRequest(String subject, int keysize, String keyType, byte[] P, byte[] Q, byte[] G) throws TokenException, InvalidParameterException, PQGParamGenException { if (keyType.equalsIgnoreCase("dsa")) { if ((P == null) && (Q == null) && (G == null)) { PQGParams pqg; try { pqg = PQGParams.generate(keysize); } catch (PQGParamGenException e) { throw e; } byte[] p = PQGParams.BigIntegerToUnsignedByteArray(pqg.getP()); byte[] q = PQGParams.BigIntegerToUnsignedByteArray(pqg.getQ()); byte[] g = PQGParams.BigIntegerToUnsignedByteArray(pqg.getG()); P = p; Q = q; G = g; String pk10String; try { pk10String = generatePK10(subject, keysize, keyType, p, q, g); } catch (TokenException e) { throw e; } catch (InvalidParameterException e) { throw e; } return ("-----BEGIN NEW CERTIFICATE REQUEST-----\n"+ pk10String + "\n-----END NEW CERTIFICATE REQUEST-----"); } else if ((P == null) || (Q == null) || (G == null)) { throw new InvalidParameterException("need all P, Q, and G"); } } String pk10String; try { pk10String = generatePK10(subject, keysize, keyType, P, Q, G); } catch (TokenException e) { throw e; } catch (InvalidParameterException e) { throw e; } return ("-----BEGIN NEW CERTIFICATE REQUEST-----\n"+ pk10String + "\n-----END NEW CERTIFICATE REQUEST-----"); } protected native String generatePK10(String subject, int keysize, String keyType, byte[] P, byte[] Q, byte[] G) throws TokenException, InvalidParameterException; //////////////////////////////////////////////////// // construction and finalization //////////////////////////////////////////////////// /* * Default constructor should never be called. */ protected PK11Token() { assert(false); } /** * Creates a new PK11Token. Should only be called from PK11Token's * native code. * @param pointer A byte array containing a pointer to a PKCS #11 slot. */ protected PK11Token(byte[] pointer, boolean internal, boolean keyStorage) { assert(pointer!=null); tokenProxy = new TokenProxy(pointer); mIsInternalCryptoToken = internal; mIsInternalKeyStorageToken = keyStorage; cryptoStore = new PK11Store(tokenProxy); } /* protected PK11Token(TokenProxy proxy) { assert(proxy!=null); this.tokenProxy = proxy; } */ public TokenProxy getProxy() { return tokenProxy; } /** * @return true if this is the internal token used for bulk crypto. */ public boolean isInternalCryptoToken() { return mIsInternalCryptoToken; } /** * @return true if this is the internal key storage token. */ public boolean isInternalKeyStorageToken() { return mIsInternalKeyStorageToken; } public native void importPublicKey( PublicKey pubKey, boolean permanent) throws TokenException; } /** * This class just hard-wires the type to be TOKEN so we don't have to mess * with Java constants in native code. */ class TokenCallbackInfo extends PasswordCallbackInfo { public TokenCallbackInfo(String name) { super(name, TOKEN); } } jss-4.6.3/org/mozilla/jss/pkcs11/PK11TokenCert.java000066400000000000000000000012741362106420000216160ustar00rootroot00000000000000/* 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.pkcs11; import org.mozilla.jss.crypto.*; /** * A user certificate that lives on a PKCS #11 token. */ public final class PK11TokenCert extends PK11Cert implements TokenCertificate { public byte[] getUniqueID() { return super.getUniqueID(); } public CryptoToken getOwningToken() { return super.getOwningToken(); } PK11TokenCert(byte[] certPtr, byte[] slotPtr, String nickname) { super(certPtr, slotPtr, nickname); } } jss-4.6.3/org/mozilla/jss/pkcs11/PKCS11Constants.java000066400000000000000000005040561362106420000221300ustar00rootroot00000000000000/** * PKCS11Constants.java - part of the JSS project * Copyright (C) 2018 Red Hat, Inc. * * This file is automatically generated (tools/build_pkcs11_constants.py) * from the contents of NSS's pkcs11t.h and pkcs11n.h headers. This * replaces the sun.security.pkcs11.wrapper.PKCS11Constants interface * which was removed from public visibility in JDK 9 due to the * introduction of modules. * * For more information, please see the documentation under * jss/docs/pkcs11_constants.md. * * Below are the copyright statements for the sourced files: */ /* Copyright statements from /usr/include/nss3/pkcs11t.h */ /* 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/. */ /* License to copy and use this software is granted provided that it is * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface * (Cryptoki)" in all material mentioning or referencing this software. * License is also granted to make and use derivative works provided that * such works are identified as "derived from the RSA Security Inc. PKCS #11 * Cryptographic Token Interface (Cryptoki)" in all material mentioning or * referencing the derived work. * RSA Security Inc. makes no representations concerning either the * merchantability of this software or the suitability of this software for * any particular purpose. It is provided "as is" without express or implied * warranty of any kind. */ /* Copyright statements from /usr/include/nss3/pkcs11n.h */ /* 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.pkcs11; public interface PKCS11Constants { /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_TRUE = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_FALSE = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_NULL_PTR = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_INVALID_SESSION = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_EFFECTIVELY_INFINITE = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_INVALID_HANDLE = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKN_SURRENDER = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_TOKEN_PRESENT = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_REMOVABLE_DEVICE = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_HW_SLOT = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_RNG = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_WRITE_PROTECTED = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_LOGIN_REQUIRED = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_USER_PIN_INITIALIZED = 0x00000008L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_RESTORE_KEY_NOT_NEEDED = 0x00000020L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_CLOCK_ON_TOKEN = 0x00000040L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_PROTECTED_AUTHENTICATION_PATH = 0x00000100L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_DUAL_CRYPTO_OPERATIONS = 0x00000200L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_TOKEN_INITIALIZED = 0x00000400L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_SECONDARY_AUTHENTICATION = 0x00000800L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_USER_PIN_COUNT_LOW = 0x00010000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_USER_PIN_FINAL_TRY = 0x00020000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_USER_PIN_LOCKED = 0x00040000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_USER_PIN_TO_BE_CHANGED = 0x00080000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_SO_PIN_COUNT_LOW = 0x00100000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_SO_PIN_FINAL_TRY = 0x00200000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_SO_PIN_LOCKED = 0x00400000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_SO_PIN_TO_BE_CHANGED = 0x00800000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKU_SO = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKU_USER = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKU_CONTEXT_SPECIFIC = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKS_RO_PUBLIC_SESSION = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKS_RO_USER_FUNCTIONS = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKS_RW_PUBLIC_SESSION = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKS_RW_USER_FUNCTIONS = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKS_RW_SO_FUNCTIONS = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_RW_SESSION = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_SERIAL_SESSION = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKO_DATA = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKO_CERTIFICATE = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKO_PUBLIC_KEY = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKO_PRIVATE_KEY = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKO_SECRET_KEY = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKO_HW_FEATURE = 0x00000005L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKO_DOMAIN_PARAMETERS = 0x00000006L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKO_MECHANISM = 0x00000007L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKO_VENDOR_DEFINED = 0x80000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKH_MONOTONIC_COUNTER = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKH_CLOCK = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKH_USER_INTERFACE = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKH_VENDOR_DEFINED = 0x80000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_RSA = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_DSA = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_DH = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_ECDSA = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_EC = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_X9_42_DH = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_KEA = 0x00000005L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_GENERIC_SECRET = 0x00000010L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_RC2 = 0x00000011L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_RC4 = 0x00000012L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_DES = 0x00000013L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_DES2 = 0x00000014L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_DES3 = 0x00000015L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_CAST = 0x00000016L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_CAST3 = 0x00000017L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_CAST5 = 0x00000018L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_CAST128 = 0x00000018L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_RC5 = 0x00000019L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_IDEA = 0x0000001AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_SKIPJACK = 0x0000001BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_BATON = 0x0000001CL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_JUNIPER = 0x0000001DL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_CDMF = 0x0000001EL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_AES = 0x0000001FL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_BLOWFISH = 0x00000020L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_TWOFISH = 0x00000021L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_CAMELLIA = 0x00000025L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_SEED = 0x00000026L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_VENDOR_DEFINED = 0x80000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKC_X_509 = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKC_X_509_ATTR_CERT = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKC_WTLS = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKC_VENDOR_DEFINED = 0x80000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_ARRAY_ATTRIBUTE = 0x40000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_CLASS = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_TOKEN = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_PRIVATE = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_LABEL = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_APPLICATION = 0x00000010L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_VALUE = 0x00000011L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_OBJECT_ID = 0x00000012L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_CERTIFICATE_TYPE = 0x00000080L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_ISSUER = 0x00000081L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_SERIAL_NUMBER = 0x00000082L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_AC_ISSUER = 0x00000083L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_OWNER = 0x00000084L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_ATTR_TYPES = 0x00000085L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_TRUSTED = 0x00000086L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_CERTIFICATE_CATEGORY = 0x00000087L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_JAVA_MIDP_SECURITY_DOMAIN = 0x00000088L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_URL = 0x00000089L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_HASH_OF_SUBJECT_PUBLIC_KEY = 0x0000008AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_HASH_OF_ISSUER_PUBLIC_KEY = 0x0000008BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_CHECK_VALUE = 0x00000090L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_KEY_TYPE = 0x00000100L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_SUBJECT = 0x00000101L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_ID = 0x00000102L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_SENSITIVE = 0x00000103L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_ENCRYPT = 0x00000104L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_DECRYPT = 0x00000105L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_WRAP = 0x00000106L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_UNWRAP = 0x00000107L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_SIGN = 0x00000108L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_SIGN_RECOVER = 0x00000109L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_VERIFY = 0x0000010AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_VERIFY_RECOVER = 0x0000010BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_DERIVE = 0x0000010CL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_START_DATE = 0x00000110L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_END_DATE = 0x00000111L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_MODULUS = 0x00000120L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_MODULUS_BITS = 0x00000121L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_PUBLIC_EXPONENT = 0x00000122L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_PRIVATE_EXPONENT = 0x00000123L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_PRIME_1 = 0x00000124L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_PRIME_2 = 0x00000125L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_EXPONENT_1 = 0x00000126L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_EXPONENT_2 = 0x00000127L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_COEFFICIENT = 0x00000128L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_PUBLIC_KEY_INFO = 0x00000129L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_PRIME = 0x00000130L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_SUBPRIME = 0x00000131L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_BASE = 0x00000132L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_PRIME_BITS = 0x00000133L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_SUBPRIME_BITS = 0x00000134L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_SUB_PRIME_BITS = 0x00000134L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_VALUE_BITS = 0x00000160L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_VALUE_LEN = 0x00000161L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_EXTRACTABLE = 0x00000162L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_LOCAL = 0x00000163L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_NEVER_EXTRACTABLE = 0x00000164L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_ALWAYS_SENSITIVE = 0x00000165L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_KEY_GEN_MECHANISM = 0x00000166L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_MODIFIABLE = 0x00000170L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_ECDSA_PARAMS = 0x00000180L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_EC_PARAMS = 0x00000180L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_EC_POINT = 0x00000181L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_SECONDARY_AUTH = 0x00000200L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_AUTH_PIN_FLAGS = 0x00000201L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_ALWAYS_AUTHENTICATE = 0x00000202L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_WRAP_WITH_TRUSTED = 0x00000210L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_WRAP_TEMPLATE = 0x40000211L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_UNWRAP_TEMPLATE = 0x40000212L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_HW_FEATURE_TYPE = 0x00000300L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_RESET_ON_INIT = 0x00000301L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_HAS_RESET = 0x00000302L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_PIXEL_X = 0x00000400L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_PIXEL_Y = 0x00000401L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_RESOLUTION = 0x00000402L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_CHAR_ROWS = 0x00000403L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_CHAR_COLUMNS = 0x00000404L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_COLOR = 0x00000405L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_BITS_PER_PIXEL = 0x00000406L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_CHAR_SETS = 0x00000480L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_ENCODING_METHODS = 0x00000481L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_MIME_TYPES = 0x00000482L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_MECHANISM_TYPE = 0x00000500L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_REQUIRED_CMS_ATTRIBUTES = 0x00000501L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_DEFAULT_CMS_ATTRIBUTES = 0x00000502L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_SUPPORTED_CMS_ATTRIBUTES = 0x00000503L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_ALLOWED_MECHANISMS = 0x40000600L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKA_VENDOR_DEFINED = 0x80000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RSA_PKCS_KEY_PAIR_GEN = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RSA_PKCS = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RSA_9796 = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RSA_X_509 = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_MD2_RSA_PKCS = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_MD5_RSA_PKCS = 0x00000005L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA1_RSA_PKCS = 0x00000006L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RIPEMD128_RSA_PKCS = 0x00000007L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RIPEMD160_RSA_PKCS = 0x00000008L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RSA_PKCS_OAEP = 0x00000009L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RSA_X9_31_KEY_PAIR_GEN = 0x0000000AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RSA_X9_31 = 0x0000000BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA1_RSA_X9_31 = 0x0000000CL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RSA_PKCS_PSS = 0x0000000DL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA1_RSA_PKCS_PSS = 0x0000000EL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DSA_KEY_PAIR_GEN = 0x00000010L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DSA = 0x00000011L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DSA_SHA1 = 0x00000012L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DH_PKCS_KEY_PAIR_GEN = 0x00000020L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DH_PKCS_DERIVE = 0x00000021L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_X9_42_DH_KEY_PAIR_GEN = 0x00000030L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_X9_42_DH_DERIVE = 0x00000031L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_X9_42_DH_HYBRID_DERIVE = 0x00000032L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_X9_42_MQV_DERIVE = 0x00000033L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA256_RSA_PKCS = 0x00000040L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA384_RSA_PKCS = 0x00000041L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA512_RSA_PKCS = 0x00000042L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA256_RSA_PKCS_PSS = 0x00000043L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA384_RSA_PKCS_PSS = 0x00000044L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA512_RSA_PKCS_PSS = 0x00000045L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA224_RSA_PKCS = 0x00000046L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA224_RSA_PKCS_PSS = 0x00000047L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC2_KEY_GEN = 0x00000100L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC2_ECB = 0x00000101L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC2_CBC = 0x00000102L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC2_MAC = 0x00000103L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC2_MAC_GENERAL = 0x00000104L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC2_CBC_PAD = 0x00000105L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC4_KEY_GEN = 0x00000110L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC4 = 0x00000111L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_KEY_GEN = 0x00000120L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_ECB = 0x00000121L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_CBC = 0x00000122L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_MAC = 0x00000123L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_MAC_GENERAL = 0x00000124L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_CBC_PAD = 0x00000125L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES2_KEY_GEN = 0x00000130L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES3_KEY_GEN = 0x00000131L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES3_ECB = 0x00000132L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES3_CBC = 0x00000133L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES3_MAC = 0x00000134L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES3_MAC_GENERAL = 0x00000135L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES3_CBC_PAD = 0x00000136L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CDMF_KEY_GEN = 0x00000140L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CDMF_ECB = 0x00000141L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CDMF_CBC = 0x00000142L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CDMF_MAC = 0x00000143L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CDMF_MAC_GENERAL = 0x00000144L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CDMF_CBC_PAD = 0x00000145L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_OFB64 = 0x00000150L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_OFB8 = 0x00000151L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_CFB64 = 0x00000152L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_CFB8 = 0x00000153L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_MD2 = 0x00000200L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_MD2_HMAC = 0x00000201L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_MD2_HMAC_GENERAL = 0x00000202L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_MD5 = 0x00000210L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_MD5_HMAC = 0x00000211L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_MD5_HMAC_GENERAL = 0x00000212L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA_1 = 0x00000220L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA_1_HMAC = 0x00000221L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA_1_HMAC_GENERAL = 0x00000222L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RIPEMD128 = 0x00000230L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RIPEMD128_HMAC = 0x00000231L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RIPEMD128_HMAC_GENERAL = 0x00000232L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RIPEMD160 = 0x00000240L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RIPEMD160_HMAC = 0x00000241L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RIPEMD160_HMAC_GENERAL = 0x00000242L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA256 = 0x00000250L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA256_HMAC = 0x00000251L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA256_HMAC_GENERAL = 0x00000252L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA384 = 0x00000260L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA384_HMAC = 0x00000261L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA384_HMAC_GENERAL = 0x00000262L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA512 = 0x00000270L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA512_HMAC = 0x00000271L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA512_HMAC_GENERAL = 0x00000272L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA224 = 0x00000255L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA224_HMAC = 0x00000256L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA224_HMAC_GENERAL = 0x00000257L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST_KEY_GEN = 0x00000300L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST_ECB = 0x00000301L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST_CBC = 0x00000302L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST_MAC = 0x00000303L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST_MAC_GENERAL = 0x00000304L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST_CBC_PAD = 0x00000305L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST3_KEY_GEN = 0x00000310L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST3_ECB = 0x00000311L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST3_CBC = 0x00000312L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST3_MAC = 0x00000313L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST3_MAC_GENERAL = 0x00000314L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST3_CBC_PAD = 0x00000315L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST5_KEY_GEN = 0x00000320L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST128_KEY_GEN = 0x00000320L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST5_ECB = 0x00000321L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST128_ECB = 0x00000321L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST5_CBC = 0x00000322L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST128_CBC = 0x00000322L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST5_MAC = 0x00000323L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST128_MAC = 0x00000323L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST5_MAC_GENERAL = 0x00000324L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST128_MAC_GENERAL = 0x00000324L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST5_CBC_PAD = 0x00000325L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAST128_CBC_PAD = 0x00000325L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC5_KEY_GEN = 0x00000330L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC5_ECB = 0x00000331L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC5_CBC = 0x00000332L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC5_MAC = 0x00000333L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC5_MAC_GENERAL = 0x00000334L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_RC5_CBC_PAD = 0x00000335L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_IDEA_KEY_GEN = 0x00000340L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_IDEA_ECB = 0x00000341L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_IDEA_CBC = 0x00000342L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_IDEA_MAC = 0x00000343L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_IDEA_MAC_GENERAL = 0x00000344L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_IDEA_CBC_PAD = 0x00000345L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_GENERIC_SECRET_KEY_GEN = 0x00000350L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CONCATENATE_BASE_AND_KEY = 0x00000360L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CONCATENATE_BASE_AND_DATA = 0x00000362L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CONCATENATE_DATA_AND_BASE = 0x00000363L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_XOR_BASE_AND_DATA = 0x00000364L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_EXTRACT_KEY_FROM_KEY = 0x00000365L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SSL3_PRE_MASTER_KEY_GEN = 0x00000370L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SSL3_MASTER_KEY_DERIVE = 0x00000371L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SSL3_KEY_AND_MAC_DERIVE = 0x00000372L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SSL3_MASTER_KEY_DERIVE_DH = 0x00000373L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS_PRE_MASTER_KEY_GEN = 0x00000374L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS_MASTER_KEY_DERIVE = 0x00000375L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS_KEY_AND_MAC_DERIVE = 0x00000376L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS_MASTER_KEY_DERIVE_DH = 0x00000377L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS_PRF = 0x00000378L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SSL3_MD5_MAC = 0x00000380L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SSL3_SHA1_MAC = 0x00000381L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_MD5_KEY_DERIVATION = 0x00000390L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_MD2_KEY_DERIVATION = 0x00000391L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA1_KEY_DERIVATION = 0x00000392L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA256_KEY_DERIVATION = 0x00000393L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA384_KEY_DERIVATION = 0x00000394L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA512_KEY_DERIVATION = 0x00000395L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SHA224_KEY_DERIVATION = 0x00000396L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_MD2_DES_CBC = 0x000003A0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_MD5_DES_CBC = 0x000003A1L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_MD5_CAST_CBC = 0x000003A2L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_MD5_CAST3_CBC = 0x000003A3L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_MD5_CAST5_CBC = 0x000003A4L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_MD5_CAST128_CBC = 0x000003A4L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_SHA1_CAST5_CBC = 0x000003A5L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_SHA1_CAST128_CBC = 0x000003A5L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_SHA1_RC4_128 = 0x000003A6L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_SHA1_RC4_40 = 0x000003A7L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_SHA1_DES3_EDE_CBC = 0x000003A8L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_SHA1_DES2_EDE_CBC = 0x000003A9L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_SHA1_RC2_128_CBC = 0x000003AAL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBE_SHA1_RC2_40_CBC = 0x000003ABL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PKCS5_PBKD2 = 0x000003B0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_PBA_SHA1_WITH_SHA1_HMAC = 0x000003C0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_WTLS_PRE_MASTER_KEY_GEN = 0x000003D0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_WTLS_MASTER_KEY_DERIVE = 0x000003D1L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC = 0x000003D2L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_WTLS_PRF = 0x000003D3L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE = 0x000003D4L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE = 0x000003D5L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS12_MASTER_KEY_DERIVE = 0x000003E0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS12_KEY_AND_MAC_DERIVE = 0x000003E1L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS12_MASTER_KEY_DERIVE_DH = 0x000003E2L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS12_KEY_SAFE_DERIVE = 0x000003E3L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS12_MAC = 0x000003E4L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS_MAC = 0x000003E4L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TLS_KDF = 0x000003E5L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_KEY_WRAP_LYNKS = 0x00000400L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_KEY_WRAP_SET_OAEP = 0x00000401L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CMS_SIG = 0x00000500L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SKIPJACK_KEY_GEN = 0x00001000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SKIPJACK_ECB64 = 0x00001001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SKIPJACK_CBC64 = 0x00001002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SKIPJACK_OFB64 = 0x00001003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SKIPJACK_CFB64 = 0x00001004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SKIPJACK_CFB32 = 0x00001005L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SKIPJACK_CFB16 = 0x00001006L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SKIPJACK_CFB8 = 0x00001007L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SKIPJACK_WRAP = 0x00001008L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SKIPJACK_PRIVATE_WRAP = 0x00001009L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SKIPJACK_RELAYX = 0x0000100AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_KEA_KEY_PAIR_GEN = 0x00001010L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_KEA_KEY_DERIVE = 0x00001011L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_FORTEZZA_TIMESTAMP = 0x00001020L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_BATON_KEY_GEN = 0x00001030L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_BATON_ECB128 = 0x00001031L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_BATON_ECB96 = 0x00001032L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_BATON_CBC128 = 0x00001033L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_BATON_COUNTER = 0x00001034L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_BATON_SHUFFLE = 0x00001035L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_BATON_WRAP = 0x00001036L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_ECDSA_KEY_PAIR_GEN = 0x00001040L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_EC_KEY_PAIR_GEN = 0x00001040L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_ECDSA = 0x00001041L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_ECDSA_SHA1 = 0x00001042L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_ECDH1_DERIVE = 0x00001050L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_ECDH1_COFACTOR_DERIVE = 0x00001051L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_ECMQV_DERIVE = 0x00001052L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_JUNIPER_KEY_GEN = 0x00001060L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_JUNIPER_ECB128 = 0x00001061L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_JUNIPER_CBC128 = 0x00001062L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_JUNIPER_COUNTER = 0x00001063L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_JUNIPER_SHUFFLE = 0x00001064L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_JUNIPER_WRAP = 0x00001065L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_FASTHASH = 0x00001070L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_KEY_GEN = 0x00001080L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_ECB = 0x00001081L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_CBC = 0x00001082L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_MAC = 0x00001083L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_MAC_GENERAL = 0x00001084L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_CBC_PAD = 0x00001085L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_CTR = 0x00001086L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_GCM = 0x00001087L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_CCM = 0x00001088L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_CTS = 0x00001089L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_CMAC = 0x0000108AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_CMAC_GENERAL = 0x0000108BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_XCBC_MAC = 0x0000108CL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_XCBC_MAC_96 = 0x0000108DL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_BLOWFISH_KEY_GEN = 0x00001090L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_BLOWFISH_CBC = 0x00001091L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TWOFISH_KEY_GEN = 0x00001092L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_TWOFISH_CBC = 0x00001093L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAMELLIA_KEY_GEN = 0x00000550L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAMELLIA_ECB = 0x00000551L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAMELLIA_CBC = 0x00000552L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAMELLIA_MAC = 0x00000553L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAMELLIA_MAC_GENERAL = 0x00000554L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAMELLIA_CBC_PAD = 0x00000555L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAMELLIA_ECB_ENCRYPT_DATA = 0x00000556L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_CAMELLIA_CBC_ENCRYPT_DATA = 0x00000557L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SEED_KEY_GEN = 0x00000650L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SEED_ECB = 0x00000651L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SEED_CBC = 0x00000652L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SEED_MAC = 0x00000653L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SEED_MAC_GENERAL = 0x00000654L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SEED_CBC_PAD = 0x00000655L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SEED_ECB_ENCRYPT_DATA = 0x00000656L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SEED_CBC_ENCRYPT_DATA = 0x00000657L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_ECB_ENCRYPT_DATA = 0x00001100L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES_CBC_ENCRYPT_DATA = 0x00001101L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES3_ECB_ENCRYPT_DATA = 0x00001102L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DES3_CBC_ENCRYPT_DATA = 0x00001103L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_ECB_ENCRYPT_DATA = 0x00001104L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_AES_CBC_ENCRYPT_DATA = 0x00001105L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DSA_PARAMETER_GEN = 0x00002000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_DH_PKCS_PARAMETER_GEN = 0x00002001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_X9_42_DH_PARAMETER_GEN = 0x00002002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SP800_108_COUNTER_KDF = 0x000003ACL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SP800_108_FEEDBACK_KDF = 0x000003ADL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_SP800_108_DOUBLE_PIPELINE_KDF = 0x000003AEL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKM_VENDOR_DEFINED = 0x80000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_HW = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_ENCRYPT = 0x00000100L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_DECRYPT = 0x00000200L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_DIGEST = 0x00000400L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_SIGN = 0x00000800L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_SIGN_RECOVER = 0x00001000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_VERIFY = 0x00002000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_VERIFY_RECOVER = 0x00004000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_GENERATE = 0x00008000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_GENERATE_KEY_PAIR = 0x00010000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_WRAP = 0x00020000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_UNWRAP = 0x00040000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_DERIVE = 0x00080000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_EC_F_P = 0x00100000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_EC_F_2M = 0x00200000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_EC_ECPARAMETERS = 0x00400000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_EC_NAMEDCURVE = 0x00800000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_EC_UNCOMPRESS = 0x01000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_EC_COMPRESS = 0x02000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_EXTENSION = 0x80000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_OK = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_CANCEL = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_HOST_MEMORY = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SLOT_ID_INVALID = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_GENERAL_ERROR = 0x00000005L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_FUNCTION_FAILED = 0x00000006L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_ARGUMENTS_BAD = 0x00000007L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_NO_EVENT = 0x00000008L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_NEED_TO_CREATE_THREADS = 0x00000009L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_CANT_LOCK = 0x0000000AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_ATTRIBUTE_READ_ONLY = 0x00000010L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_ATTRIBUTE_SENSITIVE = 0x00000011L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_ATTRIBUTE_TYPE_INVALID = 0x00000012L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_ATTRIBUTE_VALUE_INVALID = 0x00000013L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_DATA_INVALID = 0x00000020L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_DATA_LEN_RANGE = 0x00000021L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_DEVICE_ERROR = 0x00000030L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_DEVICE_MEMORY = 0x00000031L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_DEVICE_REMOVED = 0x00000032L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_ENCRYPTED_DATA_INVALID = 0x00000040L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_ENCRYPTED_DATA_LEN_RANGE = 0x00000041L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_FUNCTION_CANCELED = 0x00000050L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_FUNCTION_NOT_PARALLEL = 0x00000051L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_FUNCTION_NOT_SUPPORTED = 0x00000054L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_KEY_HANDLE_INVALID = 0x00000060L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_KEY_SIZE_RANGE = 0x00000062L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_KEY_TYPE_INCONSISTENT = 0x00000063L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_KEY_NOT_NEEDED = 0x00000064L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_KEY_CHANGED = 0x00000065L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_KEY_NEEDED = 0x00000066L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_KEY_INDIGESTIBLE = 0x00000067L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_KEY_FUNCTION_NOT_PERMITTED = 0x00000068L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_KEY_NOT_WRAPPABLE = 0x00000069L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_KEY_UNEXTRACTABLE = 0x0000006AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_MECHANISM_INVALID = 0x00000070L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_MECHANISM_PARAM_INVALID = 0x00000071L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_OBJECT_HANDLE_INVALID = 0x00000082L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_OPERATION_ACTIVE = 0x00000090L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_OPERATION_NOT_INITIALIZED = 0x00000091L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_PIN_INCORRECT = 0x000000A0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_PIN_INVALID = 0x000000A1L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_PIN_LEN_RANGE = 0x000000A2L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_PIN_EXPIRED = 0x000000A3L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_PIN_LOCKED = 0x000000A4L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SESSION_CLOSED = 0x000000B0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SESSION_COUNT = 0x000000B1L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SESSION_HANDLE_INVALID = 0x000000B3L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SESSION_PARALLEL_NOT_SUPPORTED = 0x000000B4L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SESSION_READ_ONLY = 0x000000B5L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SESSION_EXISTS = 0x000000B6L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SESSION_READ_ONLY_EXISTS = 0x000000B7L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SESSION_READ_WRITE_SO_EXISTS = 0x000000B8L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SIGNATURE_INVALID = 0x000000C0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SIGNATURE_LEN_RANGE = 0x000000C1L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_TEMPLATE_INCOMPLETE = 0x000000D0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_TEMPLATE_INCONSISTENT = 0x000000D1L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_TOKEN_NOT_PRESENT = 0x000000E0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_TOKEN_NOT_RECOGNIZED = 0x000000E1L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_TOKEN_WRITE_PROTECTED = 0x000000E2L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_UNWRAPPING_KEY_HANDLE_INVALID = 0x000000F0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_UNWRAPPING_KEY_SIZE_RANGE = 0x000000F1L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT = 0x000000F2L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_USER_ALREADY_LOGGED_IN = 0x00000100L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_USER_NOT_LOGGED_IN = 0x00000101L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_USER_PIN_NOT_INITIALIZED = 0x00000102L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_USER_TYPE_INVALID = 0x00000103L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_USER_ANOTHER_ALREADY_LOGGED_IN = 0x00000104L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_USER_TOO_MANY_TYPES = 0x00000105L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_WRAPPED_KEY_INVALID = 0x00000110L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_WRAPPED_KEY_LEN_RANGE = 0x00000112L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_WRAPPING_KEY_HANDLE_INVALID = 0x00000113L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_WRAPPING_KEY_SIZE_RANGE = 0x00000114L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_WRAPPING_KEY_TYPE_INCONSISTENT = 0x00000115L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_RANDOM_SEED_NOT_SUPPORTED = 0x00000120L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_RANDOM_NO_RNG = 0x00000121L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_DOMAIN_PARAMS_INVALID = 0x00000130L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_BUFFER_TOO_SMALL = 0x00000150L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_SAVED_STATE_INVALID = 0x00000160L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_INFORMATION_SENSITIVE = 0x00000170L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_STATE_UNSAVEABLE = 0x00000180L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_CRYPTOKI_NOT_INITIALIZED = 0x00000190L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_CRYPTOKI_ALREADY_INITIALIZED = 0x00000191L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_MUTEX_BAD = 0x000001A0L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_MUTEX_NOT_LOCKED = 0x000001A1L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_FUNCTION_REJECTED = 0x00000200L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_VENDOR_DEFINED = 0x80000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_LIBRARY_CANT_CREATE_OS_THREADS = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_OS_LOCKING_OK = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_DONT_BLOCK = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKG_MGF1_SHA1 = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKG_MGF1_SHA256 = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKG_MGF1_SHA384 = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKG_MGF1_SHA512 = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKG_MGF1_SHA224 = 0x00000005L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKZ_DATA_SPECIFIED = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKD_NULL = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKD_SHA1_KDF = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKD_SHA224_KDF = 0x00000005L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKD_SHA256_KDF = 0x00000006L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKD_SHA384_KDF = 0x00000007L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKD_SHA512_KDF = 0x00000008L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKD_SHA1_KDF_ASN1 = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKD_SHA1_KDF_CONCATENATE = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_SP800_108_ITERATION_VARIABLE = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_SP800_108_OPTIONAL_COUNTER = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_SP800_108_DKM_LENGTH = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_SP800_108_BYTE_ARRAY = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_SP800_108_COUNTER = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_SP800_108_DKM_LENGTH_SUM_OF_KEYS = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CK_SP800_108_DKM_LENGTH_SUM_OF_SEGMENTS = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKP_PKCS5_PBKD2_HMAC_SHA1 = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKP_PKCS5_PBKD2_HMAC_GOSTR3411 = 0x00000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKP_PKCS5_PBKD2_HMAC_SHA224 = 0x00000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKP_PKCS5_PBKD2_HMAC_SHA256 = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKP_PKCS5_PBKD2_HMAC_SHA384 = 0x00000005L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKP_PKCS5_PBKD2_HMAC_SHA512 = 0x00000006L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKP_PKCS5_PBKD2_HMAC_SHA512_224 = 0x00000007L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKP_PKCS5_PBKD2_HMAC_SHA512_256 = 0x00000008L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKZ_SALT_SPECIFIED = 0x00000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKO_KG_PARAMETERS = 0x00000006L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKF_EC_FP = 0x00100000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKR_KEY_PARAMS_INVALID = 0x0000006BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11t.h */ public static final long CKK_INVALID_KEY_TYPE = 0xFFFFFFFFL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long NSSCK_VENDOR_NSS = 0x4E534350L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NSS = 0xCE534350L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NSS_CRL = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NSS_SMIME = 0xCE534352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NSS_TRUST = 0xCE534353L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NSS_BUILTIN_ROOT_LIST = 0xCE534354L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NSS_NEWSLOT = 0xCE534355L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NSS_DELSLOT = 0xCE534356L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKK_NSS = 0xCE534350L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKK_NSS_PKCS8 = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKK_NSS_JPAKE_ROUND1 = 0xCE534352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKK_NSS_JPAKE_ROUND2 = 0xCE534353L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKK_NSS_CHACHA20 = 0xCE534354L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKC_NSS = 0xCE534350L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_DIGEST = 0x81000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_FLAGS_ONLY = 0x00000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS = 0xCE534350L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_URL = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_EMAIL = 0xCE534352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_SMIME_INFO = 0xCE534353L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_SMIME_TIMESTAMP = 0xCE534354L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_PKCS8_SALT = 0xCE534355L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_PASSWORD_CHECK = 0xCE534356L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_EXPIRES = 0xCE534357L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_KRL = 0xCE534358L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_PQG_COUNTER = 0xCE534364L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_PQG_SEED = 0xCE534365L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_PQG_H = 0xCE534366L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_PQG_SEED_BITS = 0xCE534367L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_MODULE_SPEC = 0xCE534368L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_OVERRIDE_EXTENSIONS = 0xCE534369L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_JPAKE_SIGNERID = 0xCE53436AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_JPAKE_PEERID = 0xCE53436BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_JPAKE_GX1 = 0xCE53436CL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_JPAKE_GX2 = 0xCE53436DL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_JPAKE_GX3 = 0xCE53436EL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_JPAKE_GX4 = 0xCE53436FL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_JPAKE_X2 = 0xCE534370L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_JPAKE_X2S = 0xCE534371L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_MOZILLA_CA_POLICY = 0xCE534372L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_SERVER_DISTRUST_AFTER = 0xCE534373L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NSS_EMAIL_DISTRUST_AFTER = 0xCE534374L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST = 0xCE536350L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_DIGITAL_SIGNATURE = 0xCE536351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_NON_REPUDIATION = 0xCE536352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_KEY_ENCIPHERMENT = 0xCE536353L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_DATA_ENCIPHERMENT = 0xCE536354L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_KEY_AGREEMENT = 0xCE536355L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_KEY_CERT_SIGN = 0xCE536356L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_CRL_SIGN = 0xCE536357L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_SERVER_AUTH = 0xCE536358L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_CLIENT_AUTH = 0xCE536359L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_CODE_SIGNING = 0xCE53635AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_EMAIL_PROTECTION = 0xCE53635BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_IPSEC_END_SYSTEM = 0xCE53635CL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_IPSEC_TUNNEL = 0xCE53635DL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_IPSEC_USER = 0xCE53635EL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_TIME_STAMPING = 0xCE53635FL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_TRUST_STEP_UP_APPROVED = 0xCE536360L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_CERT_SHA1_HASH = 0xCE5363B4L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_CERT_MD5_HASH = 0xCE5363B5L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_DB = 0xD5A0DB00L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_TRUST = 0x80000001L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_FAKE_RANDOM = 0x80000EFEL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_INVALID_MECHANISM = 0xFFFFFFFFL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS = 0xCE534350L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_AES_KEY_WRAP = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_AES_KEY_WRAP_PAD = 0xCE534352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_HKDF_SHA1 = 0xCE534353L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_HKDF_SHA256 = 0xCE534354L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_HKDF_SHA384 = 0xCE534355L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_HKDF_SHA512 = 0xCE534356L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_ROUND1_SHA1 = 0xCE534357L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_ROUND1_SHA256 = 0xCE534358L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_ROUND1_SHA384 = 0xCE534359L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_ROUND1_SHA512 = 0xCE53435AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_ROUND2_SHA1 = 0xCE53435BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_ROUND2_SHA256 = 0xCE53435CL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_ROUND2_SHA384 = 0xCE53435DL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_ROUND2_SHA512 = 0xCE53435EL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_FINAL_SHA1 = 0xCE53435FL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_FINAL_SHA256 = 0xCE534360L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_FINAL_SHA384 = 0xCE534361L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_JPAKE_FINAL_SHA512 = 0xCE534362L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_HMAC_CONSTANT_TIME = 0xCE534363L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_SSL3_MAC_CONSTANT_TIME = 0xCE534364L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_TLS_PRF_GENERAL_SHA256 = 0xCE534365L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256 = 0xCE534366L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256 = 0xCE534367L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 = 0xCE534368L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE = 0xCE534369L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH = 0xCE53436AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_CHACHA20_KEY_GEN = 0xCE53436BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_CHACHA20_POLY1305 = 0xCE53436CL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN = 0xCE53436DL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN = 0xCE53436EL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN = 0xCE53436FL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN = 0xCE534370L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_CHACHA20_CTR = 0xCE534371L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_IKE_PRF_PLUS_DERIVE = 0xCE534372L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_IKE_PRF_DERIVE = 0xCE534373L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_IKE1_PRF_DERIVE = 0xCE534374L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_IKE1_APP_B_PRF_DERIVE = 0xCE534375L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_PUB_FROM_PRIV = 0xCE534378L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA = 0xCE53437AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA = 0xCE53437BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA = 0xCE53437CL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_PBE_SHA1_DES_CBC = 0x80000002L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC = 0x80000003L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC = 0x80000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC = 0x80000005L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 = 0x80000006L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 = 0x80000007L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC = 0x80000008L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN = 0x80000009L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN = 0x8000000AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN = 0x8000000BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_TLS_PRF_GENERAL = 0x80000373L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKR_NSS = 0xCE534350L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKR_NSS_CERTDB_FAILED = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKR_NSS_KEYDB_FAILED = 0xCE534352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_VENDOR_DEFINED = 0x80000000L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NSS = 0xCE534350L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NSS_TRUSTED = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NSS_TRUSTED_DELEGATOR = 0xCE534352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NSS_MUST_VERIFY_TRUST = 0xCE534353L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NSS_NOT_TRUSTED = 0xCE53435AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NSS_TRUST_UNKNOWN = 0xCE534355L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NSS_VALID_DELEGATOR = 0xCE53435BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NSS_UNTRUSTED = 0xCE534353L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NSS_VALID = 0xCE53435AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NSS_MUST_VERIFY = 0xCE534354L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NETSCAPE_CRL = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NETSCAPE_SMIME = 0xCE534352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NETSCAPE_TRUST = 0xCE534353L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NETSCAPE_BUILTIN_ROOT_LIST = 0xCE534354L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NETSCAPE_NEWSLOT = 0xCE534355L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKO_NETSCAPE_DELSLOT = 0xCE534356L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKK_NETSCAPE_PKCS8 = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_URL = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_EMAIL = 0xCE534352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_SMIME_INFO = 0xCE534353L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_SMIME_TIMESTAMP = 0xCE534354L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_PKCS8_SALT = 0xCE534355L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_PASSWORD_CHECK = 0xCE534356L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_EXPIRES = 0xCE534357L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_KRL = 0xCE534358L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_PQG_COUNTER = 0xCE534364L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_PQG_SEED = 0xCE534365L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_PQG_H = 0xCE534366L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_PQG_SEED_BITS = 0xCE534367L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKA_NETSCAPE_MODULE_SPEC = 0xCE534368L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_AES_KEY_WRAP = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKM_NETSCAPE_AES_KEY_WRAP_PAD = 0xCE534352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKR_NETSCAPE_CERTDB_FAILED = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKR_NETSCAPE_KEYDB_FAILED = 0xCE534352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NETSCAPE_TRUSTED = 0xCE534351L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NETSCAPE_TRUSTED_DELEGATOR = 0xCE534352L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NETSCAPE_UNTRUSTED = 0xCE534353L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NETSCAPE_MUST_VERIFY = 0xCE534354L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NETSCAPE_TRUST_UNKNOWN = 0xCE534355L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NETSCAPE_VALID = 0xCE53435AL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long CKT_NETSCAPE_VALID_DELEGATOR = 0xCE53435BL; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long SFTK_MIN_USER_SLOT_ID = 0x00000004L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long SFTK_MAX_USER_SLOT_ID = 0x00000064L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long SFTK_MIN_FIPS_USER_SLOT_ID = 0x00000065L; /** * Content automatically generated; see NSS documentation for more information. * * Source file: /usr/include/nss3/pkcs11n.h */ public static final long SFTK_MAX_FIPS_USER_SLOT_ID = 0x0000007FL; } jss-4.6.3/org/mozilla/jss/pkcs11/TokenProxy.java000066400000000000000000000011221362106420000214350ustar00rootroot00000000000000/* 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.pkcs11; import org.mozilla.jss.util.NativeProxy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class TokenProxy extends NativeProxy { public static Logger logger = LoggerFactory.getLogger(TokenProxy.class); public TokenProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); } jss-4.6.3/org/mozilla/jss/pkcs11/Tunnel.java000066400000000000000000000022321362106420000205630ustar00rootroot00000000000000/* 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.pkcs11; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.SignatureSpi; import org.mozilla.jss.crypto.Signature; import org.mozilla.jss.util.Password; final class Tunnel { private static class CryptoTunnel extends org.mozilla.jss.crypto.Tunnel { public static Signature constructSignature(SignatureAlgorithm alg, SignatureSpi engine) { return ConstructSignature(alg, engine); } } private static class UtilTunnel extends org.mozilla.jss.util.Tunnel { public static byte[] getPasswordByteCopy(Password pw) { return GetPasswordByteCopy(pw); } } static Signature constructSignature(SignatureAlgorithm alg, SignatureSpi engine) { return CryptoTunnel.constructSignature(alg, engine); } static byte[] getPasswordByteCopy(Password pw) { return UtilTunnel.getPasswordByteCopy(pw); } } jss-4.6.3/org/mozilla/jss/pkcs11/attrs/000077500000000000000000000000001362106420000176115ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkcs11/attrs/CKAClass.java000066400000000000000000000060431362106420000220430ustar00rootroot00000000000000package org.mozilla.jss.pkcs11.attrs; import org.mozilla.jss.pkcs11.PKCS11Constants; /** * CKAClass is an instance of a PKCS#11 CK_ATTRIBUTE with type = CKA_CLASS. */ public class CKAClass extends CKAttribute { private long value; /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_CLASS and a * custom value. * * Note: it is generally recommended to use the subclasses of this class * instead of providing a custom value. */ public CKAClass(long value) { super(PKCS11Constants.CKA_CLASS); setValue(value); } /** * Set the value of this CKA_CLASS attribute. */ public void setValue(long value) { this.value = value; } /** * Get the value of this CKA_CLASS attribute. */ public long getValue() { return value; } protected native void acquireNativeResources(); protected native void releaseNativeResources(); /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_CLASS and value * CKO_DATA. */ public static class Data extends CKAClass { public Data() { super(PKCS11Constants.CKO_DATA); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_CLASS and value * CKO_CERTIFICATE. */ public static class Certificate extends CKAClass { public Certificate() { super(PKCS11Constants.CKO_CERTIFICATE); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_CLASS and value * CKO_PUBLIC_KEY. */ public static class PublicKey extends CKAClass { public PublicKey() { super(PKCS11Constants.CKO_PUBLIC_KEY); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_CLASS and value * CKO_PRIVATE_KEY. */ public static class PrivateKey extends CKAClass { public PrivateKey() { super(PKCS11Constants.CKO_PRIVATE_KEY); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_CLASS and value * CKO_SECRET_KEY. */ public static class SecretKey extends CKAClass { public SecretKey() { super(PKCS11Constants.CKO_SECRET_KEY); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_CLASS and value * CKO_HW_FEATURE. */ public static class HWFeature extends CKAClass { public HWFeature() { super(PKCS11Constants.CKO_HW_FEATURE); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_CLASS and value * CKO_DOMAIN_PARAMETERS. */ public static class DomainParameters extends CKAClass { public DomainParameters() { super(PKCS11Constants.CKO_DOMAIN_PARAMETERS); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_CLASS and value * CKO_MECHANISM. */ public static class Mechanism extends CKAClass { public Mechanism() { super(PKCS11Constants.CKO_MECHANISM); } } } jss-4.6.3/org/mozilla/jss/pkcs11/attrs/CKAKeyType.java000066400000000000000000000176311362106420000223750ustar00rootroot00000000000000package org.mozilla.jss.pkcs11.attrs; import org.mozilla.jss.pkcs11.PKCS11Constants; /** * CKA_KEY_TYPE is an instance of a PKCS#11 CK_ATTRIBUTE with * type = CKA_KEY_TYPE. */ public class CKAKeyType extends CKAttribute { private long value; /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and a * custom value. * * Note: it is generally recommended to use the subclasses of this class * instead of providing a custom value. */ public CKAKeyType(long value) { super(PKCS11Constants.CKA_KEY_TYPE); setValue(value); } /** * Set the value of this CKA_KEY_TYPE attribute. */ public void setValue(long value) { this.value = value; } /** * Get the value of this CKA_KEY_TYPE attribute. */ public long getValue() { return value; } protected native void acquireNativeResources(); protected native void releaseNativeResources(); /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_RSA. */ public static class RSA extends CKAKeyType { public RSA() { super(PKCS11Constants.CKK_RSA); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_DSA. */ public static class DSA extends CKAKeyType { public DSA() { super(PKCS11Constants.CKK_DSA); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_DH. */ public static class DH extends CKAKeyType { public DH() { super(PKCS11Constants.CKK_DH); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_ECDSA. */ public static class ECDSA extends CKAKeyType { public ECDSA() { super(PKCS11Constants.CKK_ECDSA); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_EC. */ public static class EC extends CKAKeyType { public EC() { super(PKCS11Constants.CKK_EC); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_X9_42_DH. */ public static class X9_42_DH extends CKAKeyType { public X9_42_DH() { super(PKCS11Constants.CKK_X9_42_DH); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_KEA. */ public static class KEA extends CKAKeyType { public KEA() { super(PKCS11Constants.CKK_KEA); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_GENERIC_SECRET. */ public static class GenericSecret extends CKAKeyType { public GenericSecret() { super(PKCS11Constants.CKK_GENERIC_SECRET); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_RC2. */ public static class RC2 extends CKAKeyType { public RC2() { super(PKCS11Constants.CKK_RC2); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_RC4. */ public static class RC4 extends CKAKeyType { public RC4() { super(PKCS11Constants.CKK_RC4); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_DES. */ public static class DES extends CKAKeyType { public DES() { super(PKCS11Constants.CKK_DES); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_DES2. */ public static class DES2 extends CKAKeyType { public DES2() { super(PKCS11Constants.CKK_DES2); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_DES3. */ public static class DES3 extends CKAKeyType { public DES3() { super(PKCS11Constants.CKK_DES3); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_CAST. */ public static class CAST extends CKAKeyType { public CAST() { super(PKCS11Constants.CKK_CAST); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_CAST3. */ public static class CAST3 extends CKAKeyType { public CAST3() { super(PKCS11Constants.CKK_CAST3); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_CAST5. */ public static class CAST5 extends CKAKeyType { public CAST5() { super(PKCS11Constants.CKK_CAST5); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_CAST128. */ public static class CAST128 extends CKAKeyType { public CAST128() { super(PKCS11Constants.CKK_CAST128); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_RC5. */ public static class RC5 extends CKAKeyType { public RC5() { super(PKCS11Constants.CKK_RC5); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_IDEA. */ public static class IDEA extends CKAKeyType { public IDEA() { super(PKCS11Constants.CKK_IDEA); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_SKIPJACK. */ public static class Skipjack extends CKAKeyType { public Skipjack() { super(PKCS11Constants.CKK_SKIPJACK); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_BATON. */ public static class BATON extends CKAKeyType { public BATON() { super(PKCS11Constants.CKK_BATON); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_JUNIPER. */ public static class JUNIPER extends CKAKeyType { public JUNIPER() { super(PKCS11Constants.CKK_JUNIPER); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_CDMF. */ public static class CDMF extends CKAKeyType { public CDMF() { super(PKCS11Constants.CKK_CDMF); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_AES. */ public static class AES extends CKAKeyType { public AES() { super(PKCS11Constants.CKK_AES); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_BLOWFISH. */ public static class Blowfish extends CKAKeyType { public Blowfish() { super(PKCS11Constants.CKK_BLOWFISH); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_TWOFISH. */ public static class Twofish extends CKAKeyType { public Twofish() { super(PKCS11Constants.CKK_TWOFISH); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_CAMELLIA. */ public static class Camellia extends CKAKeyType { public Camellia() { super(PKCS11Constants.CKK_CAMELLIA); } } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_KEY_TYPE and * value CKK_SEED. */ public static class Seed extends CKAKeyType { public Seed() { super(PKCS11Constants.CKK_SEED); } } } jss-4.6.3/org/mozilla/jss/pkcs11/attrs/CKAUsage.java000066400000000000000000000057471362106420000220540ustar00rootroot00000000000000package org.mozilla.jss.pkcs11.attrs; import org.mozilla.jss.pkcs11.PKCS11Constants; /** * CKAUsage is a collection of PKCS#11 CK_ATTRIBUTES which have common value * (CK_TRUE). */ public class CKAUsage extends CKAttribute { /** * Representation of a PKCS#11 CK_ATTRIBUTE with custom type, setting the * value to CK_TRUE. * * Note: it is generally recommended to use the subclasses of this class * instead of providing a custom value. */ public CKAUsage(long type) { super(type); } protected native void acquireNativeResources(); protected native void releaseNativeResources(); /** * CKAEncrypt is an instance of PKCS#11 CK_ATTRIBUTE with * type = CKA_ENCRYPT and value CK_TRUE. */ public static class Encrypt extends CKAUsage { public Encrypt() { super(PKCS11Constants.CKA_ENCRYPT); } } /** * CKADecrypt is an instance of PKCS#11 CK_ATTRIBUTE with * type = CKA_DECRYPT and value CK_TRUE. */ public static class Decrypt extends CKAUsage { public Decrypt() { super(PKCS11Constants.CKA_DECRYPT); } } /** * CKAWrap is an instance of PKCS#11 CK_ATTRIBUTE with * type = CKA_WRAP and value CK_TRUE. */ public static class Wrap extends CKAUsage { public Wrap() { super(PKCS11Constants.CKA_WRAP); } } /** * CKAUnwrap is an instance of PKCS#11 CK_ATTRIBUTE with * type = CKA_UNWRAP and value CK_TRUE. */ public static class Unwrap extends CKAUsage { public Unwrap() { super(PKCS11Constants.CKA_UNWRAP); } } /** * CKASign is an instance of PKCS#11 CK_ATTRIBUTE with * type = CKA_SIGN and value CK_TRUE. */ public static class Sign extends CKAUsage { public Sign() { super(PKCS11Constants.CKA_SIGN); } } /** * CKASignRecover is an instance of PKCS#11 CK_ATTRIBUTE with * type = CKA_SIGN_RECOVER and value CK_TRUE. */ public static class SignRecover extends CKAUsage { public SignRecover() { super(PKCS11Constants.CKA_SIGN_RECOVER); } } /** * CKAVerify is an instance of PKCS#11 CK_ATTRIBUTE with * type = CKA_VERIFY and value CK_TRUE. */ public static class Verify extends CKAUsage { public Verify() { super(PKCS11Constants.CKA_VERIFY); } } /** * CKAVerifyRecover is an instance of PKCS#11 CK_ATTRIBUTE with * type = CKA_VERIFY_RECOVER and value CK_TRUE. */ public static class VerifyRecover extends CKAUsage { public VerifyRecover() { super(PKCS11Constants.CKA_VERIFY_RECOVER); } } /** * CKADerive is an instance of PKCS#11 CK_ATTRIBUTE with * type = CKA_DERIVE and value CK_TRUE. */ public static class Derive extends CKAUsage { public Derive() { super(PKCS11Constants.CKA_DERIVE); } } } jss-4.6.3/org/mozilla/jss/pkcs11/attrs/CKAValueLen.java000066400000000000000000000023001362106420000225010ustar00rootroot00000000000000package org.mozilla.jss.pkcs11.attrs; import org.mozilla.jss.pkcs11.PKCS11Constants; /** * CKAClass is an instance of a PKCS#11 CK_ATTRIBUTE with type = CKA_CLASS. */ public class CKAValueLen extends CKAttribute { private long length = 0; /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_VALUE_LEN and * default length for the key type. * * Note that when key type is not specified and/or that mechanism lacks a * default size, the corresponding PKCS#11 call will error out. */ public CKAValueLen() { super(PKCS11Constants.CKA_VALUE_LEN); } /** * Representation of a PKCS#11 CK_ATTRIBUTE with type CKA_VALUE_LEN and a * specified length. */ public CKAValueLen(long length) { this(); setLength(length); } /** * Set the length specified by this CKA_VALUE_LEN attribute. */ public void setLength(long length) { this.length = length; } /** * Get the length of this CKA_VALUE_LEN attribute. */ public long getLength() { return length; } protected native void acquireNativeResources(); protected native void releaseNativeResources(); } jss-4.6.3/org/mozilla/jss/pkcs11/attrs/CKAttribute.c000066400000000000000000000153561362106420000221500ustar00rootroot00000000000000#include #include #include #include #include "CKAttribute.h" #include "StaticVoidPointer.h" #include "NativeEnclosure.h" #include "_jni/org_mozilla_jss_pkcs11_attrs_CKAClass.h" #include "_jni/org_mozilla_jss_pkcs11_attrs_CKAKeyType.h" #include "_jni/org_mozilla_jss_pkcs11_attrs_CKAUsage.h" #include "_jni/org_mozilla_jss_pkcs11_attrs_CKAValueLen.h" static const CK_BBOOL JSS_CK_TRUE = CK_TRUE; PRStatus JSS_PK11_WrapAttribute(JNIEnv *env, jobject this, void *ptr, size_t ptr_length) { jclass this_class; jfieldID field_id; jobject ptr_object; CK_ATTRIBUTE_PTR attr = calloc(1, sizeof(CK_ATTRIBUTE)); PR_ASSERT(env != NULL && this != NULL && attr != NULL); this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { goto failure; } field_id = (*env)->GetFieldID(env, this_class, "type", "J"); if (field_id == NULL) { goto failure; } attr->type = (CK_ULONG)((*env)->GetLongField(env, this, field_id)); attr->pValue = ptr; attr->ulValueLen = ptr_length; ptr_object = JSS_PR_wrapStaticVoidPointer(env, (void **)&attr); if (ptr_object == NULL) { goto failure; } if (JSS_PR_StoreNativeEnclosure(env, this, ptr_object, sizeof(CK_ATTRIBUTE)) != PR_SUCCESS) { goto failure; } return PR_SUCCESS; failure: memset(attr, 0, sizeof(CK_ATTRIBUTE)); free(attr); return PR_FAILURE; } PRStatus JSS_PK11_UnwrapAttribute(JNIEnv *env, jobject this, CK_ATTRIBUTE_PTR *attr) { jobject ptr_obj; jlong size = 0; PR_ASSERT(env != NULL && this != NULL && attr != NULL); if (JSS_PR_LoadNativeEnclosure(env, this, &ptr_obj, &size) != PR_SUCCESS) { goto failure; } if (JSS_PR_getStaticVoidRef(env, ptr_obj, (void **)attr) != PR_SUCCESS || *attr == NULL) { goto failure; } if (size != sizeof(CK_ATTRIBUTE)) { goto failure; } return PR_SUCCESS; failure: *attr = NULL; return PR_FAILURE; } /* ===== CKA_CLASS Attribute ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_attrs_CKAClass_acquireNativeResources(JNIEnv *env, jobject this) { jclass this_class; jfieldID field_id; CK_ULONG *ptr = calloc(1, sizeof(CK_ULONG)); PR_ASSERT(env != NULL && this != NULL && ptr != NULL); this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { goto failure; } field_id = (*env)->GetFieldID(env, this_class, "value", "J"); if (field_id == NULL) { goto failure; } *ptr = (CK_ULONG)((*env)->GetLongField(env, this, field_id)); if (JSS_PK11_WrapAttribute(env, this, (void *)ptr, sizeof(*ptr)) == PR_FAILURE) { goto failure; } return; failure: memset(ptr, 0, sizeof(*ptr)); free(ptr); } JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_attrs_CKAClass_releaseNativeResources(JNIEnv *env, jobject this) { CK_ATTRIBUTE_PTR attr = NULL; if (JSS_PK11_UnwrapAttribute(env, this, &attr) != PR_SUCCESS || attr == NULL) { return; } PR_ASSERT(attr->type == CKA_CLASS); PR_ASSERT(attr->pValue != NULL); PR_ASSERT(attr->ulValueLen == sizeof(CK_ULONG)); if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); free(attr->pValue); } memset(attr, 0, sizeof(CK_ATTRIBUTE)); free(attr); return; } /* ===== CKA_KEY_TYPE Attribute ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_attrs_CKAKeyType_acquireNativeResources(JNIEnv *env, jobject this) { jclass this_class; jfieldID field_id; CK_ULONG *ptr = calloc(1, sizeof(CK_ULONG)); PR_ASSERT(env != NULL && this != NULL && ptr != NULL); this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { goto failure; } field_id = (*env)->GetFieldID(env, this_class, "value", "J"); if (field_id == NULL) { goto failure; } *ptr = (CK_ULONG)((*env)->GetLongField(env, this, field_id)); JSS_PK11_WrapAttribute(env, this, (void *)ptr, sizeof(*ptr)); return; failure: memset(ptr, 0, sizeof(*ptr)); free(ptr); } JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_attrs_CKAKeyType_releaseNativeResources(JNIEnv *env, jobject this) { CK_ATTRIBUTE_PTR attr = NULL; if (JSS_PK11_UnwrapAttribute(env, this, &attr) != PR_SUCCESS || attr == NULL) { return; } PR_ASSERT(attr->type == CKA_KEY_TYPE); PR_ASSERT(attr->pValue != NULL); PR_ASSERT(attr->ulValueLen == sizeof(CK_ULONG)); if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); free(attr->pValue); } memset(attr, 0, sizeof(CK_ATTRIBUTE)); free(attr); return; } /* ===== CKA_{ENCRYPT,DECRYPT,...} Usage Attributes ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_attrs_CKAUsage_acquireNativeResources(JNIEnv *env, jobject this) { JSS_PK11_WrapAttribute(env, this, (void *)&JSS_CK_TRUE, sizeof(JSS_CK_TRUE)); } JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_attrs_CKAUsage_releaseNativeResources(JNIEnv *env, jobject this) { CK_ATTRIBUTE_PTR attr = NULL; if (JSS_PK11_UnwrapAttribute(env, this, &attr) != PR_SUCCESS || attr == NULL) { return; } /* Since the internal pValue member is always a reference to JSS_CK_TRUE, * don't free it! Only free the outer CK_ATTRIBUTE pointer. */ memset(attr, 0, sizeof(CK_ATTRIBUTE)); free(attr); } /* ===== CKA_VALUE_LEN Attribute ===== */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_attrs_CKAValueLen_acquireNativeResources(JNIEnv *env, jobject this) { jclass this_class; jfieldID field_id; CK_ULONG *ptr = calloc(1, sizeof(CK_ULONG)); PR_ASSERT(env != NULL && this != NULL && ptr != NULL); this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { goto failure; } field_id = (*env)->GetFieldID(env, this_class, "length", "J"); if (field_id == NULL) { goto failure; } *ptr = (CK_ULONG)((*env)->GetLongField(env, this, field_id)); if (JSS_PK11_WrapAttribute(env, this, (void *)ptr, sizeof(*ptr)) == PR_FAILURE) { goto failure; } return; failure: memset(ptr, 0, sizeof(*ptr)); free(ptr); } JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_attrs_CKAValueLen_releaseNativeResources(JNIEnv *env, jobject this) { CK_ATTRIBUTE_PTR attr = NULL; if (JSS_PK11_UnwrapAttribute(env, this, &attr) != PR_SUCCESS || attr == NULL) { return; } PR_ASSERT(attr->type == CKA_VALUE_LEN); PR_ASSERT(attr->pValue != NULL); PR_ASSERT(attr->ulValueLen == sizeof(CK_ULONG)); if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); free(attr->pValue); } memset(attr, 0, sizeof(CK_ATTRIBUTE)); free(attr); return; } jss-4.6.3/org/mozilla/jss/pkcs11/attrs/CKAttribute.h000066400000000000000000000003251362106420000221430ustar00rootroot00000000000000#include #include PRStatus JSS_PK11_WrapAttribute(JNIEnv *env, jobject this, void *ptr, size_t ptr_length); PRStatus JSS_PK11_UnwrapAttribute(JNIEnv *env, jobject this, CK_ATTRIBUTE_PTR *attr); jss-4.6.3/org/mozilla/jss/pkcs11/attrs/CKAttribute.java000066400000000000000000000022201362106420000226310ustar00rootroot00000000000000package org.mozilla.jss.pkcs11.attrs; import org.mozilla.jss.util.NativeEnclosure; /** * A CKAttribute is an instance of PKCS#11 CK_ATTRIBUTE. * * Each CK_ATTRIBUTE contains three parts: * 1. A type (type), * 2. A pointer to a value (pValue), * 3. The size of said value (ulValueLen). * * In the Java layer, CKAttribute has a member "type" to contain the type * of the CK_ATTRIBUTE. It takes on values from PKCS11Constants (pkcs11t.h * and pkcs11n.h) with prefix "CKA_". The two NativeEnclosure fields, * mPointer and mPointerSize wrap a pointer to the underlying CK_ATTRIBUTE * and its size respectively. They get allocated when open() is called, and * freed when close() is called. * * The value (numbers 2 and 3 above) get determined by the extending type, * and its corresponding native methods. Some use statically allocated values, * like CKAUsage's classes. Others are dynamically allocated pointers, such as * when referring to CK_ULONG values (as with CKAValueLen for instance). */ public abstract class CKAttribute extends NativeEnclosure { public long type; public CKAttribute(long type) { this.type = type; } } jss-4.6.3/org/mozilla/jss/pkcs11/pk11util.h000066400000000000000000000444501362106420000203060ustar00rootroot00000000000000/* 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/. */ /* need to include these first: * * certt.h * nspr.h * jni.h * secmodt.h */ #ifndef JSS_PK11_UTIL_H #define JSS_PK11_UTIL_H PR_BEGIN_EXTERN_C /*===================================================================== K E Y S =====================================================================*/ /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P r i v K e y * privk: will be eaten by the wrapper and set to NULL. * Returns: a new PK11PrivKey, or NULL if an exception occurred. */ jobject JSS_PK11_wrapPrivKey(JNIEnv *env, SECKEYPrivateKey **privk); /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P u b K e y * privk: will be eaten by the wrapper and set to NULL. * Returns: a new PK11PubKey, or NULL if an exception occurred. */ jobject JSS_PK11_wrapPubKey(JNIEnv *env, SECKEYPublicKey **pubk); /************************************************************************** * Given a PrivateKey object, extracts the SECKEYPrivateKey* and stores it * at the given address. * * privkObject: A JNI reference to a PrivateKey object. * ptr: Address of a SECKEYPrivateKey* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getPrivKeyPtr(JNIEnv *env, jobject privkObject, SECKEYPrivateKey** ptr); /*********************************************************************** * Given a PublicKey object, extracts the SECKEYPublicKey* and stores it * at the given address. * * pubkObject: A JNI reference to a PublicKey object. * ptr: Address of a SECKEYPublicKey* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getPubKeyPtr(JNIEnv *env, jobject pubkObject, SECKEYPublicKey** ptr); /*********************************************************************** * J S S _ P K 1 1 _ g e t S y m K e y P t r * * Given a Java PK11SymKey, extracts the C PK11SymKey and stores it at * the given address. */ PRStatus JSS_PK11_getSymKeyPtr(JNIEnv *env, jobject symKeyObject, PK11SymKey **ptr); /*********************************************************************** * * J S S _ P K 1 1 _ w r a p S y m K e y * symKey: will be stored in a Java wrapper. * Returns: a new PK11SymKey, or NULL if an exception occurred. */ jobject JSS_PK11_wrapSymKey(JNIEnv *env, PK11SymKey **symKey); /*********************************************************************** * JSS_PK11_getKeyType * * Converts a PrivateKey.KeyType object to a PKCS #11 key type. * * INPUTS * keyTypeObj * A org.mozilla.jss.crypto.PrivateKey.KeyType object. * RETURNS * The key type, or nullKey if an exception occurred. */ KeyType JSS_PK11_getKeyType(JNIEnv *env, jobject keyTypeObj); /*********************************************************************** * JSS_PK11_generateKeyPair * * Create a new key pair based on the passed in mechanism and parameters * * INPUTS * mechanism * A PKCS#11 KeyPair Mechanism * slot * Slot to generate the keypair in. * pubk * returned public key * privk * returned private key key * param * PKCS #11 mechanism parameters * temporary * boolean to say if the key is temporary or permanent * sensitive * int to say if the key should be sensitive or not (-1 is default) * extractable * int to say if the key should be extractable or not (-1 is default) * RETURNS * The SECStatus, SECSuccess of success, SECFailure on failure */ SECStatus JSS_PK11_generateKeyPair(JNIEnv *env, CK_MECHANISM_TYPE mechanism, PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privK, void *params, PRBool temporary, jint senstive, jint extractable); SECStatus JSS_PK11_generateKeyPair_withOpFlags(JNIEnv *env, CK_MECHANISM_TYPE mechanism, PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privk, void *params, PRBool temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask); /*===================================================================== C E R T I F I C A T E S =====================================================================*/ /****************************************************************** * * J S S _ P K 1 1 _ g e t C e r t P t r * * Given a PK11Cert object, extracts the CERTCertificate* and * stores it at the given address. * * certObject: A JNI reference to a JSS Certificate object. * ptr: Address of a CERTCertificate* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCertPtr(JNIEnv *env, jobject certObject, CERTCertificate **ptr); /****************************************************************** * * J S S _ P K 1 1 _ g e t C e r t S l o t P t r * * Given a PK11Cert object, extracts the PK11SlotInfo* and * stores it at the given address. * * certObject: A JNI reference to a JSS Certificate object. * ptr: Address of a PK11SlotInfo* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCertSlotPtr(JNIEnv *env, jobject certObject, PK11SlotInfo **ptr); /************************************************************************* * * J S S _ P K 1 1 _ f i n d C e r t A n d S l o t F r o m N i c k n a m e * * A variant of NSS's PK11_FindCertFromNickname function that also * returns a PK11SlotInfo* in *ppSlot. * * If nickname is of the format "token:nickname", the slot that * contains the specified token is returned. Otherwise the internal * key slot (which contains the permanent database token) is returned. */ CERTCertificate * JSS_PK11_findCertAndSlotFromNickname(const char *nickname, void *wincx, PK11SlotInfo **ppSlot); /*************************************************************************** * * J S S _ P K 1 1 _ f i n d C e r t s A n d S l o t F r o m N i c k n a m e * * A variant of NSS's PK11_FindCertsFromNickname function that also * returns a PK11SlotInfo* in *ppSlot. * * If nickname is of the format "token:nickname", the slot that * contains the specified token is returned. Otherwise the internal * key slot (which contains the permanent database token) is returned. */ CERTCertList * JSS_PK11_findCertsAndSlotFromNickname(char *nickname, void *wincx, PK11SlotInfo **ppSlot); /*********************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t A n d S l o t A n d N i c k n a m e * * Builds a PK11Cert object from a CERTCertificate, a PK11SlotInfo, and * a nickname. * ppCert: Pointer to pointer to CERTCertificate. The CERTCertificate * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this CERTCertificate again. To enforce this, *ppCert * will be set to NULL whether the functions fails or succeeds. * ppSlot: Pointer to pointer to PK11SlotInfo. The PK11SlotInfo * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this PK11SlotInfo again. To enforce this, *ppSlot * will be set to NULL whether the functions fails or succeeds. * nickname: the cert instance's nickname. * Returns: a new Java PK11Cert object, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCertAndSlotAndNickname(JNIEnv *env, CERTCertificate **ppCert, PK11SlotInfo **ppSlot, const char *nickname); /**************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t A n d S l o t * * Builds a PK11Cert object from a CERTCertificate and a PK11SlotInfo. * ppCert: Pointer to pointer to CERTCertificate. The CERTCertificate * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this CERTCertificate again. To enforce this, *ppCert * will be set to NULL whether the functions fails or succeeds. * ppSlot: Pointer to pointer to PK11SlotInfo. The PK11SlotInfo * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this PK11SlotInfo again. To enforce this, *ppSlot * will be set to NULL whether the functions fails or succeeds. * Returns: a new Java PK11Cert object, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCertAndSlot(JNIEnv *env, CERTCertificate **ppCert, PK11SlotInfo **ppSlot); /**************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t * * Builds a PK11Cert object from a CERTCertificate. * ppCert: Pointer to pointer to CERTCertificate. The CERTCertificate * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this CERTCertificate again. To enforce this, *ppCert * will be set to NULL whether the functions fails or succeeds. * Returns: a new Java PK11Cert object, or NULL if an exception was thrown. * * Use JSS_PK11_wrapCertAndSlot instead if it is important for the PK11Cert * object to have the correct slot pointer or the slot pointer is readily * available. */ jobject JSS_PK11_wrapCert(JNIEnv *env, CERTCertificate **ppCert); /**************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t C h a i n * * Builds an array of PK11Cert objects from a CERTCertList. * ppChain: Pointer to pointer to CERTCertList. The CERTCertList * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this CERTCertList again. To enforce this, *ppChain * will be set to NULL whether the functions fails or succeeds. * Returns: a new Java PK11Cert[] object, or NULL if an exception was thrown. */ jobjectArray JSS_PK11_wrapCertChain(JNIEnv *env, CERTCertList **ppChain); /*===================================================================== S T O R E S =====================================================================*/ /************************************************************************ * * J S S _ g e t S t o r e S l o t P t r * * Retrieve the PK11SlotInfo pointer of the given PK11Store. * * INPUTS * store * A reference to a Java PK11Store * slot * address of a PK11SlotInfo* that will be loaded with * the PK11SlotInfo pointer of the given token. * RETURNS * PR_SUCCESS if the operation was successful, PR_FAILURE if an * exception was thrown. */ PRStatus JSS_PK11_getStoreSlotPtr(JNIEnv *env, jobject store, PK11SlotInfo **slot); /*===================================================================== T O K E N S =====================================================================*/ /****************************************************************** ** ** J S S _ P K 1 1 _ m a k e C r y p t o T o k e n F r o m P K 1 1 ** ** Returns a new CryptoToken object, or NULL if an exception was thrown. **/ jobject JSS_PK11_makeCryptoTokenFromPK11(JNIEnv *env, jobject pk11token); /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P K 1 1 T o k e n * * Create a PK11Token object from a PKCS #11 slot. * * slot is a pointer to a PKCS #11 slot, which must not be NULL. It will * be eaten by the wrapper and set to NULL. * * Returns a new PK11Token object, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapPK11Token(JNIEnv *env, PK11SlotInfo **slot); /************************************************************************ * * J S S _ P K 1 1 _ g e t T o k e n S l o t P t r * * Retrieve the PK11SlotInfo pointer of the given token. * * tokenObject: A reference to a Java PK11Token * ptr: address of a PK11SlotInfo* that will be loaded with the PK11SlotInfo * pointer of the given token. * returns: PR_SUCCESS if the operation was successful, PR_FAILURE if an * exception was thrown. */ PRStatus JSS_PK11_getTokenSlotPtr(JNIEnv *env, jobject tokenObject, PK11SlotInfo **ptr); /*===================================================================== M O D U L E S =====================================================================*/ /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P K 1 1 M o d u l e * * Turns a SECMODModule* C structure into a PK11Module Java object. * * INPUTS * ptr * Address of a SECMODModule *. This pointer will be copied * into the new Java object, then set to NULL. * RETURNS * A new Java PK11Module object, or NULL if an exception was thrown. * In any case, the ptr parameter is eaten. */ jobject JSS_PK11_wrapPK11Module(JNIEnv *env, SECMODModule **module); /*********************************************************************** * * J S S _ P K 1 1 _ g e t M o d u l e P t r * * Retrieve the SECMODModule pointer of the given PK11Module. * * INPUTS * module * A reference to a Java PK11Module. * ptr * Address of a SECMODModule * that will be loaded with the * SECMODModule pointer of the given PK11Module. * RETURNS * PR_FAILURE if an exception was thrown, or PR_SUCCESS if the * peration succeeded. */ PRStatus JSS_PK11_getModulePtr(JNIEnv *env, jobject module, SECMODModule **ptr); /*===================================================================== C O N T E X T S =====================================================================*/ typedef enum { SGN_CONTEXT, VFY_CONTEXT } SigContextType; typedef struct SigContextProxyStr SigContextProxy; /*********************************************************************** * J S S _ P K 1 1 _ g e t S i g C o n t e x t * * Extracts the context pointer from a ContextProxy. * proxy: a non-NULL SigContextProxy object. * ptr: address of a SGNContext* or VFYContext* where the pointer will * be stored. * type: address of a SigContextType where the type of context will * be stored. * Returns: PR_SUCCESS, unless an exception was thrown. */ PRStatus JSS_PK11_getSigContext(JNIEnv *env, jobject proxy, void**pContext, SigContextType* pType); /********************************************************************** * * J S S _ P K 1 1 _ m a k e S i g C o n t e x t P r o x y * * Wraps a context in a ContextProxy. * * ctxt: address of a SGNContext* or VFYContext* that must not be NULL. * It will be eaten by the wrapper and set to NULL. * type: the type of context, SGN_CONTEXT or VFY_CONTEXT. * Returns: a new ContextProxy object wrapping the given context, * or NULL if an exception was thrown. */ jobject JSS_PK11_wrapSigContextProxy(JNIEnv *env, void **ctxt, SigContextType type); /*********************************************************************** * * J S S _ P K 1 1 _ g e t C i p h e r C o n t e x t * * Extracts the PK11Context from a CipherContextProxy. * * proxy * A CipherContextProxy. * * pContext * Address of a PK11Context*, which will be filled with the pointer * extracted from the CipherContextProxy. * * RETURNS * PR_SUCCESS for success, or PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCipherContext(JNIEnv *env, jobject proxy, PK11Context **pContext); /*********************************************************************** * * J S S _ P K 1 1 _ w r a p C i p h e r C o n t e x t P r o x y * * Wraps a PK11Context in a CipherContextProxy. * * context * address of a pointer to a PK11Context, which must not be NULL. * It will be eaten by the wrapper and set to NULL, even if the * function returns NULL. * * RETURNS * A new CipherContextProxy, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCipherContextProxy(JNIEnv *env, PK11Context **context); /*===================================================================== P K C S # 1 1 H A C K S =====================================================================*/ /*********************************************************************** * * J S S _ P K 1 1 _ g e t N e w S e s s i o n * * Creates a new session. If one cannot be created, the common shared session * is returned, and *owner is set to PR_FALSE. Otherwise, the new * session is returned and *owner is set to PR_TRUE. * * slot * The slot on which to open a session. * owner * Pointer to a PRBool which will set to PR_TRUE if a new session was * created, and to PR_FALSE if the shared session was returned. * * RETURNS * A session that can be used for cryptographic operations. If *owner * is false, the session is not owned by the called but rather is shared. */ CK_SESSION_HANDLE JSS_PK11_getNewSession(PK11SlotInfo *slot, PRBool *owner); /*********************************************************************** * * J S S _ P K 1 1 _ c l o s e S e s s i o n * * Closes a session that was returned by JSS_PK11_GetNewSession. * * slot * The slot on which this session lives. * * session * The session to close. * * owner * As returned by JSS_PK11_GetNewSession. PR_TRUE if the session was * created especially for the caller, PR_FALSE if it is the common * shared session. */ void JSS_PK11_closeSession(PK11SlotInfo *slot, CK_SESSION_HANDLE session, PRBool owner); /*********************************************************************** * * J S S _ P K 1 1 _ g e t E r r o r S t r i n g * * Returns a simple error string for a given PKCS #11 error. */ char* JSS_PK11_getErrorString(CK_RV crv); /*********************************************************************** * * getSupportedWrappingMechanism * * Returns a */ CK_MECHANISM_TYPE getSupportedWrappingMechanism(JNIEnv *env, jobject algObj, PK11SlotInfo *slot); PR_END_EXTERN_C #endif jss-4.6.3/org/mozilla/jss/pkcs12/000077500000000000000000000000001362106420000164555ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkcs12/AuthenticatedSafes.java000066400000000000000000000447531362106420000231010ustar00rootroot00000000000000/* 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.pkcs12; import java.io.CharConversionException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.crypto.IllegalBlockSizeException; import org.mozilla.jss.crypto.JSSSecureRandom; import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.pkcs7.ContentInfo; import org.mozilla.jss.pkcs7.EncryptedContentInfo; import org.mozilla.jss.pkcs7.EncryptedData; import org.mozilla.jss.util.Password; /** * An AuthenticatedSafes, which is a SEQUENCE of * SafeContents. */ public class AuthenticatedSafes implements ASN1Value { private SEQUENCE sequence; /** * The default number of hash iterations (1) when performing PBE keygen. */ public static final int DEFAULT_ITERATIONS = 1; /** * Salt length is variable with PKCS #12. NSS uses 16 bytes, MSIE * uses 20. We'll use 20 to get the 4 extra bytes of security. */ private static final int SALT_LENGTH = 20; /** * The default PBE key generation algorithm: SHA-1 with RC2 40-bit CBC. */ public static final PBEAlgorithm DEFAULT_KEY_GEN_ALG = PBEAlgorithm.PBE_SHA1_RC2_40_CBC; // security dynamics has a weird way of packaging things, we'll // work with it for debugging private static final boolean ACCEPT_SECURITY_DYNAMICS = false; /** * Default constructor, creates an empty AuthenticatedSafes. */ public AuthenticatedSafes() { sequence = new SEQUENCE(); } /** * Creates an AuthenticatedSafes from a SEQUENCE of ContentInfo. * @param sequence A non-null sequence of ContentInfo. */ public AuthenticatedSafes(SEQUENCE sequence) { if( sequence==null) { throw new IllegalArgumentException("parameter is null"); } for( int i = 0; i < sequence.size(); i++ ) { if( ! (sequence.elementAt(i) instanceof ContentInfo) ) { throw new IllegalArgumentException( "element "+i+" of sequence is not a ContentInfo"); } } this.sequence = sequence; } /** * Returns the raw SEQUENCE which constitutes this * AuthenticatedSafes. The elements of this sequence are some * form of SafeContents, wrapped in a ContentInfo or * an EncryptedData. */ public SEQUENCE getSequence() { return sequence; } /** * Returns the size of the sequence, which is the number of SafeContents * in this AuthenticatedSafes. */ public int getSize() { return sequence.size(); } /** * Returns true if the SafeContents at the given index in the * AuthenticatedSafes is encrypted. If it is encrypted, a password * must be supplied to getSafeContentsAt when accessing * this SafeContents. */ public boolean safeContentsIsEncrypted(int index) { ContentInfo ci = (ContentInfo) sequence.elementAt(index); return ci.getContentType().equals(ContentInfo.ENCRYPTED_DATA); } /** * Returns the SafeContents at the given index in the AuthenticatedSafes, * decrypting it if necessary. * *

The algorithm used to extract encrypted SafeContents does not * conform to version 1.0 of the spec. Instead, it conforms to the * draft 1.0 spec, because this is what Communicator and MSIE seem * to conform to. This looks like an implementation error that has * become firmly entrenched to preserve interoperability. The draft * spec dictates that the encrypted content in the EncryptedContentInfo * is the DER encoding of a SafeContents. This is simple enough. The * 1.0 final spec says that the SafeContents is wrapped in a ContentInfo, * then the ContentInfo is BER encoded, then the value octets (not the * tag or length) are encrypted. No wonder people stayed with the old way. * * @param password The password to use to decrypt the SafeContents if * it is encrypted. If the SafeContents is known to not be encrypted, * this parameter can be null. If the password is incorrect, the * decoding will fail somehow, probably with an InvalidBERException, * BadPaddingException, or IllegalBlockSizeException. * @param index The index of the SafeContents to extract. * @return A SafeContents object, which is merely a * SEQUENCE of SafeBags. * @exception IllegalArgumentException If no password was provided, * but the SafeContents is encrypted. */ public SEQUENCE getSafeContentsAt(Password password, int index) throws IllegalStateException, NotInitializedException, NoSuchAlgorithmException, InvalidBERException, IOException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, IllegalBlockSizeException, BadPaddingException { ContentInfo ci = (ContentInfo) sequence.elementAt(index); if( ci.getContentType().equals(ContentInfo.ENCRYPTED_DATA) ) { // SafeContents is encrypted if( password == null ) { // can't decrypt if we don't have a password throw new IllegalStateException("No password to decode "+ "encrypted SafeContents"); } EncryptedContentInfo encCI = ((EncryptedData)ci.getInterpretedContent()). getEncryptedContentInfo(); // this should be a BER-encoded SafeContents byte[] decrypted = encCI.decrypt(password, new PasswordConverter()); //print_byte_array(decrypted); try { SEQUENCE.OF_Template seqt = new SEQUENCE.OF_Template( SafeBag.getTemplate() ); return (SEQUENCE) ASN1Util.decode(seqt, decrypted); } catch(InvalidBERException e) { if( ACCEPT_SECURITY_DYNAMICS ) { // try the security dynamics approach ContentInfo.Template cit = ContentInfo.getTemplate(); ci = (ContentInfo) ASN1Util.decode(cit, decrypted); if( ! ci.getContentType().equals(ContentInfo.DATA) ) { throw new InvalidBERException(""); } OCTET_STRING os = (OCTET_STRING) ci.getInterpretedContent(); SEQUENCE.OF_Template seqt = new SEQUENCE.OF_Template( SafeBag.getTemplate() ); return (SEQUENCE) ASN1Util.decode(seqt, os.toByteArray()); } else { throw e; } } } else if( ci.getContentType().equals(ContentInfo.DATA) ) { // This SafeContents is not encrypted SEQUENCE.OF_Template seqt = new SEQUENCE.OF_Template( SafeBag.getTemplate() ); return (SEQUENCE) ASN1Util.decode(seqt, ((OCTET_STRING)ci.getInterpretedContent()). toByteArray() ); } else { throw new InvalidBERException("AuthenticatedSafes element is"+ " neither a Data or an EncryptedData"); } } static void print_byte_array(byte[] bytes) { int online=0; for(int i=0; i < bytes.length; i++, online++) { if( online > 25 ) { System.out.println(""); online=0; } System.out.print(Integer.toHexString(bytes[i]&0xff) + " "); } System.out.println(""); } /** * Returns the decrypted content from the encrypted content info. private static byte[] decryptEncryptedContentInfo(EncryptedContentInfo eci, Password pass) throws IllegalStateException,CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidBERException, IOException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, IllegalBlockSizeException, BadPaddingException { OCTET_STRING encryptedContent = eci.getEncryptedContent(); if( encryptedContent == null ) { return null; } // get the key gen parameters AlgorithmIdentifier algid = eci.getContentEncryptionAlgorithm(); KeyGenAlgorithm kgAlg = KeyGenAlgorithm.fromOID( algid.getOID() ); ASN1Value params = algid.getParameters(); if( params == null ) { throw new InvalidAlgorithmParameterException( "PBE algorithms require parameters"); } byte[] encodedParams = ASN1Util.encode(params); PBEParameter pbeParams = (PBEParameter) ASN1Util.decode( PBEParameter.getTemplate(), encodedParams ); PBEKeyGenParams kgp = new PBEKeyGenParams(pass, pbeParams.getSalt(), pbeParams.getIterations() ); // compute the key and IV CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( kgAlg ); kg.setCharToByteConverter( new PasswordConverter() ); kg.initialize( kgp ); SymmetricKey key = kg.generate(); // compute algorithm parameters EncryptionAlgorithm encAlg = keyGenAlgToEncryptionAlg(kgAlg); AlgorithmParameterSpec algParams; if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) { algParams = new IVParameterSpec( kg.generatePBE_IV() ); } else { algParams = null; } // perform the decryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initDecrypt(key, algParams ); return cipher.doFinal( encryptedContent.toByteArray() ); } */ /** * Appends an unencrypted SafeContents to the end of the AuthenticatedSafes. */ public void addSafeContents(SEQUENCE safeContents) { checkSafeContents(safeContents); ContentInfo ci = new ContentInfo( ASN1Util.encode(safeContents) ); sequence.addElement(ci); } /** * Verifies that each element is a SafeBag. Throws an * IllegalArgumentException otherwise. */ private static void checkSafeContents(SEQUENCE safeContents) { int size = safeContents.size(); for( int i = 0; i < size; i++) { if( ! (safeContents.elementAt(i) instanceof SafeBag) ) { throw new IllegalArgumentException( "Element "+i+" of SafeContents is not a SafeBag"); } } } /** * Encrypts a SafeContents and adds it to the AuthenticatedSafes. * * @param keyGenAlg The algorithm used to generate a key from the password. * Must be a PBE algorithm. DEFAULT_KEY_GEN_ALG is * usually fine here. It only provides 40-bit security, but if the * private key material is packaged in its own * EncryptedPrivateKeyInfo, the security of the SafeContents * is not as important. * @param password The password to use to generate the encryption key * and IV. * @param salt The salt to use to generate the key and IV. If null is * passed in, the salt will be generated randomly, which is usually * the right thing to do. * @param iterationCount The number of hash iterations to perform when * generating the key and IV. Use DEFAULT_ITERATIONS unless * you want to be clever. * @param safeContents A SafeContents, which is a SEQUENCE of SafeBags. * Each element of the sequence must in fact be an instance of * SafeBag. */ public void addEncryptedSafeContents(PBEAlgorithm keyGenAlg, Password password, byte[] salt, int iterationCount, SEQUENCE safeContents) throws NotInitializedException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException { try { // generate salt if necessary if( salt == null ) { // generate random salt JSSSecureRandom rand = CryptoManager.getInstance(). createPseudoRandomNumberGenerator(); salt = new byte[SALT_LENGTH]; rand.nextBytes(salt); } EncryptedContentInfo encCI = EncryptedContentInfo.createPBE(keyGenAlg, password, salt, iterationCount, new PasswordConverter(), ASN1Util.encode(safeContents)); EncryptedData encData = new EncryptedData(encCI); ContentInfo ci = new ContentInfo(encData); sequence.addElement( ci ); } catch( CharConversionException e ) { throw new RuntimeException("Unable to convert password: " + e.getMessage(), e); } } /* private static EncryptedContentInfo createEncryptedContentInfo(Password password, byte[] salt, int iterationCount, KeyGenAlgorithm keyGenAlg, SEQUENCE safeContents) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, BadPaddingException, IllegalBlockSizeException { try { // check key gen algorithm if( ! keyGenAlg.isPBEAlg() ) { throw new NoSuchAlgorithmException("Key generation algorithm"+ " is not a PBE algorithm"); } CryptoManager cman = CryptoManager.getInstance(); // generate salt if necessary if( salt == null ) { // generate random salt JSSSecureRandom rand = cman.createPseudoRandomNumberGenerator(); salt = new byte[SALT_LENGTH]; rand.nextBytes(salt); } // generate key CryptoToken token = cman.getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( keyGenAlg ); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( password, salt, iterationCount); kg.setCharToByteConverter( new PasswordConverter() ); kg.initialize(pbekgParams); SymmetricKey key = kg.generate(); // generate IV EncryptionAlgorithm encAlg = keyGenAlgToEncryptionAlg(keyGenAlg); AlgorithmParameterSpec params=null; if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) { params = new IVParameterSpec( kg.generatePBE_IV() ); } // perform encryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initEncrypt( key, params ); byte[] encrypted = cipher.doFinal( Cipher.pad( ASN1Util.encode(safeContents), encAlg.getBlockSize()) ); // make encryption algorithm identifier PBEParameter pbeParam = new PBEParameter( salt, iterationCount ); AlgorithmIdentifier encAlgID = new AlgorithmIdentifier( keyGenAlg.toOID(), pbeParam); // create EncryptedContentInfo EncryptedContentInfo encCI = new EncryptedContentInfo( ContentInfo.DATA, encAlgID, new OCTET_STRING(encrypted) ); return encCI; } catch( CharConversionException e ) { throw new RuntimeException("Unable to convert password: " + e.getMessage(), e); } } */ /* private static EncryptionAlgorithm keyGenAlgToEncryptionAlg(KeyGenAlgorithm kgAlg) throws NoSuchAlgorithmException { if( kgAlg==KeyGenAlgorithm.PBE_MD2_DES_CBC || kgAlg==KeyGenAlgorithm.PBE_MD5_DES_CBC || kgAlg==KeyGenAlgorithm.PBE_SHA1_DES_CBC) { return EncryptionAlgorithm.DES_CBC; } else if( kgAlg==KeyGenAlgorithm.PBE_SHA1_RC4_128 || kgAlg==KeyGenAlgorithm.PBE_SHA1_RC4_40 ) { return EncryptionAlgorithm.RC4; } else if( kgAlg==KeyGenAlgorithm.PBE_SHA1_DES3_CBC ) { return EncryptionAlgorithm.DES3_CBC; } else if( kgAlg==KeyGenAlgorithm.PBE_SHA1_RC2_128 || kgAlg==KeyGenAlgorithm.PBE_SHA1_RC2_40 ) { return EncryptionAlgorithm.RC2_CBC; } else { throw new NoSuchAlgorithmException(kgAlg.toString()); } } */ /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private 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.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template class for decoding an AuthenticatedSafes from its * BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.OF_Template seqt; public Template() { seqt = new SEQUENCE.OF_Template( ContentInfo.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 AuthenticatedSafes(seq); } } } jss-4.6.3/org/mozilla/jss/pkcs12/CertBag.java000066400000000000000000000130551362106420000206330ustar00rootroot00000000000000/* 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.pkcs12; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.IA5String; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * A PKCS #12 cert bag. */ public class CertBag implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Cert Type OIDs /////////////////////////////////////////////////////////////////////// private static final OBJECT_IDENTIFIER CERT_TYPES = OBJECT_IDENTIFIER.PKCS9.subBranch(22); public static final OBJECT_IDENTIFIER X509_CERT_TYPE = CERT_TYPES.subBranch(1); public static final OBJECT_IDENTIFIER SDSI_CERT_TYPE = CERT_TYPES.subBranch(2); /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private OBJECT_IDENTIFIER certType; private ANY cert; private SEQUENCE sequence; /** * Returns the certType field of the CertBag. Currently defined types are: *

    *
  • X509Certificate (X509_CERT_TYPE) *
  • SDSICertificate (SDSI_CERT_TYPE) *
*/ public OBJECT_IDENTIFIER getCertType() { return certType; } /** * Returns the cert field of the CertBag. */ public ANY getCert() { return cert; } /** * Returns the cert field of the CertBag based on its type. *
    *
  • If the type is X509_CERT_TYPE, returns * and OCTET_STRING which is the DER-encoding of an X.509 certificate. *
  • If the type is SDSI_CERT_TYPE, returns * an IA5String. *
  • For all other types, returns an ANY. *
* * @exception InvalidBERException If the cert is not encoded correctly. */ public ASN1Value getInterpretedCert() throws InvalidBERException { if( certType.equals(X509_CERT_TYPE) ) { return cert.decodeWith(OCTET_STRING.getTemplate()); } else if( certType.equals(SDSI_CERT_TYPE) ) { return cert.decodeWith(IA5String.getTemplate()); } else { return cert; } } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// /** * Creates a CertBag from a type and a cert. */ public CertBag(OBJECT_IDENTIFIER certType, ASN1Value cert) { if( certType==null || cert==null ) { throw new IllegalArgumentException("certType or cert is null"); } this.certType = certType; if( cert instanceof ANY ) { this.cert = (ANY) cert; } else { try { byte[] encoded = ASN1Util.encode(cert); this.cert = (ANY) ASN1Util.decode( ANY.getTemplate(), encoded); } catch(InvalidBERException e) { throw new RuntimeException("Unable to convert ASN1Value to ANY: "+ e.getMessage(), e); } } sequence = new SEQUENCE(); sequence.addElement(this.certType); sequence.addElement(new EXPLICIT(new Tag(0), this.cert) ); } /////////////////////////////////////////////////////////////////////// // 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 class for decoding CertBags from their BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OBJECT_IDENTIFIER.getTemplate() ); seqt.addElement( new EXPLICIT.Template( new Tag(0), 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 CertBag( (OBJECT_IDENTIFIER) seq.elementAt(0), ((EXPLICIT)seq.elementAt(1)).getContent() ); } } } jss-4.6.3/org/mozilla/jss/pkcs12/MacData.java000066400000000000000000000173551362106420000206250ustar00rootroot00000000000000/* 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.pkcs12; import java.io.CharConversionException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.DigestException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.DigestAlgorithm; import org.mozilla.jss.crypto.HMACAlgorithm; import org.mozilla.jss.crypto.JSSMessageDigest; import org.mozilla.jss.crypto.JSSSecureRandom; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.PBEKeyGenParams; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.pkcs7.DigestInfo; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.util.Password; public class MacData implements ASN1Value { private DigestInfo mac; private OCTET_STRING macSalt; private INTEGER macIterationCount; private static final int DEFAULT_ITERATIONS = 1; // 20 is the length of SHA-1 hash output private static final int SALT_LENGTH = 20; public DigestInfo getMac() { return mac; } public OCTET_STRING getMacSalt() { return macSalt; } public INTEGER getMacIterationCount() { return macIterationCount; } public MacData() { } /** * Creates a MacData from the given parameters. * * @param macIterationCount 1 is the default and should be used for * maximum compatibility. null can also be used, in which case * the macIterationCount will be omitted from the structure * (and the default value of 1 will be implied). */ public MacData(DigestInfo mac, OCTET_STRING macSalt, INTEGER macIterationCount) { if( mac==null || macSalt==null || macIterationCount==null ) { throw new IllegalArgumentException("null parameter"); } this.mac = mac; this.macSalt = macSalt; this.macIterationCount = macIterationCount; } /** * Creates a MacData by computing a HMAC on the given bytes. An HMAC * is a message authentication code, which is a keyed digest. It proves * not only that data has not been tampered with, but also that the * entity that created the HMAC possessed the symmetric key. * * @param password The password used to generate a key using a * PBE mechanism. * @param macSalt The salt used as input to the PBE key generation * mechanism. If null is passed in, new random salt will be created. * @param iterations The iteration count for creating the PBE key. * @param toBeMACed The data on which the HMAC will be computed. * @exception NotInitializedException If the crypto subsystem * has not been initialized yet. * @exception TokenException If an error occurs on a crypto token. */ public MacData( Password password, byte[] macSalt, int iterations, byte[] toBeMACed ) throws NotInitializedException, DigestException, TokenException, CharConversionException { CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalCryptoToken(); if (macSalt == null) { JSSSecureRandom rand = cm.createPseudoRandomNumberGenerator(); macSalt = new byte[SALT_LENGTH]; rand.nextBytes(macSalt); } PBEKeyGenParams params = new PBEKeyGenParams(password, macSalt, iterations); try { // generate key from password and salt KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.PBA_SHA1_HMAC); kg.setCharToByteConverter(new PasswordConverter()); kg.initialize(params); SymmetricKey key = kg.generate(); // perform the digesting JSSMessageDigest digest = token.getDigestContext(HMACAlgorithm.SHA1); digest.initHMAC(key); byte[] digestBytes = digest.digest(toBeMACed); // put everything into a DigestInfo AlgorithmIdentifier algID = new AlgorithmIdentifier(DigestAlgorithm.SHA1.toOID()); this.mac = new DigestInfo(algID, new OCTET_STRING(digestBytes)); this.macSalt = new OCTET_STRING(macSalt); this.macIterationCount = new INTEGER(iterations); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("SHA-1 HMAC algorithm not found on internal " + "token: " + e.getMessage(), e); } catch (InvalidAlgorithmParameterException e) { throw new RuntimeException("Invalid PBE algorithm parameters: " + e.getMessage(), e); } catch (java.lang.IllegalStateException e) { throw new RuntimeException("Illegal state: " + e.getMessage(), e); } catch (InvalidKeyException e) { throw new RuntimeException("Invalid key: " + e.getMessage(), e); } finally { params.clear(); } } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { return TAG; } private static final Tag TAG = SEQUENCE.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(mac); seq.addElement(macSalt); if( ! macIterationCount.equals(new INTEGER(DEFAULT_ITERATIONS)) ) { // 1 is the default, only include this element if it is not // the default seq.addElement(macIterationCount); } seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static final Template getTemplate() { return templateInstance; } /** * A Template for decoding a MacData from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( DigestInfo.getTemplate() ); seqt.addElement( OCTET_STRING.getTemplate() ); seqt.addElement( INTEGER.getTemplate(), new INTEGER(DEFAULT_ITERATIONS) ); } 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 MacData( (DigestInfo) seq.elementAt(0), (OCTET_STRING) seq.elementAt(1), (INTEGER) seq.elementAt(2) ); } } } jss-4.6.3/org/mozilla/jss/pkcs12/PFX.java000066400000000000000000000440251362106420000177620ustar00rootroot00000000000000/* 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.pkcs12; import java.io.BufferedInputStream; import java.io.CharConversionException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.DigestException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BMPString; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.crypto.JSSSecureRandom; import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.pkcs7.ContentInfo; import org.mozilla.jss.pkcs7.DigestInfo; import org.mozilla.jss.pkix.cert.Certificate; import org.mozilla.jss.pkix.primitive.Attribute; import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo; import org.mozilla.jss.pkix.primitive.PrivateKeyInfo; import org.mozilla.jss.util.Password; /** * The top level ASN.1 structure for a PKCS #12 blob. * *

The general procedure for creating a PFX blob is as follows:

    * *
  • Create instances of SafeBag containing things such as * private keys, certificates, or arbitrary secrets. *
  • Store the SafeBags in one or more SEQUENCEs. Each SEQUENCE is * called a SafeContents. *
  • Create an AuthenticatedSafes. Store each SafeContents into the * AuthenticatedSafes with addEncryptedSafeContents or * addSafeContents. *

    Standard procedure for browsers is for the AuthenticatedSafes to contain * two instances of SafeContents, one encrypted and the other not. * Anything you want encrypted can go in the encrypted SafeContents, * and anything you want in plaintext can go in the regular SafeContents. * Keep in mind that private key SafeBags usually consist of an * EncryptedPrivateKeyInfo, which has its own (strong) encryption, * in which case it is not essential that the SafeContents containing * the private key also be encrypted. *

  • Create a PFX containing the AuthenticatedSafes instance, using the * PFX(AuthenticatedSafes) constructor. *
  • Add a MAC to the PFX so it can be verified, using * PFX.computeMacData. *
* * To decode a PFX,
    * *
  • Use a PFX.Template to decode the ASN.1 into a * PFX object. *
  • Check the output of PFX.verifyAuthSafes to verify * the MAC on the PFX. *
  • Use PFX.getAuthSafes to extract the AuthenticatedSafes * instance. *
  • Use AuthenticatedSafes.getSafeContentsAt to grab the * SafeContents objects in the AuthenticatedSafes. *
  • Each SafeContents is a SEQUENCE of SafeBags, each of which may * contain a private key, cert, or arbitrary secret. *
*/ public class PFX implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private INTEGER version; private AuthenticatedSafes authSafes; private MacData macData; // may be null private byte[] encodedAuthSafes; // may be null // currently we are on version 3 of the standard private static final INTEGER VERSION = new INTEGER(3); /** * The default number of iterations to use when generating the MAC. * Currently, it is 1. */ public static final int DEFAULT_ITERATIONS = 1; public INTEGER getVersion() { return version; } public AuthenticatedSafes getAuthSafes() { return authSafes; } /** * Returns the MacData of this PFX, which is used to verify the contents. * This field is optional. If it is not present, null is returned. */ public MacData getMacData() { return macData; } private void setEncodedAuthSafes(byte[] encodedAuthSafes) { this.encodedAuthSafes = encodedAuthSafes; } /** * Verifies the HMAC on the authenticated safes, using the password * provided. * * @param password The password to use to compute the HMAC. * @param reason If supplied, the reason for the verification failure * will be appended to this StringBuffer. * @return true if the MAC verifies correctly, false otherwise. If * this PFX does not contain a MacData, returns false. */ public boolean verifyAuthSafes(Password password, StringBuffer reason) throws NotInitializedException { try { if(reason == null) { // this is just so we don't get a null pointer exception reason = new StringBuffer(); } if( macData == null ) { reason.append("No MAC present in PFX"); return false; } if( encodedAuthSafes == null ) { // We weren't decoded from a template, we were constructed, // so just verify the encoding of the AuthSafes provided to // the constructor. encodedAuthSafes = ASN1Util.encode(authSafes); } // create a new MacData based on the encoded Auth Safes DigestInfo macDataMac = macData.getMac(); MacData testMac = new MacData( password, macData.getMacSalt().toByteArray(), macData.getMacIterationCount().intValue(), encodedAuthSafes ); if( testMac.getMac().equals(macDataMac) ) { return true; } else { reason.append("Digests do not match"); return false; } } catch( java.security.DigestException e ) { e.printStackTrace(); reason.append("A DigestException occurred"); return false; } catch( TokenException e ) { reason.append("A TokenException occurred"); return false; } catch( CharConversionException e ) { reason.append("An exception occurred converting the password from"+ " chars to bytes"); return false; } } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Creates a PFX with the given parameters. */ public PFX( INTEGER version, AuthenticatedSafes authSafes, MacData macData) { if( version==null || authSafes==null ) { throw new IllegalArgumentException("null parameter"); } this.version = version; this.authSafes = authSafes; this.macData = macData; } /** * Creates a PFX with the default version. */ public PFX( AuthenticatedSafes authSafes, MacData macData ) { this( VERSION, authSafes, macData ); } /** * Creates a PFX with the default version and no MacData. The MacData * can be added later with computeMacData. * @see #computeMacData */ public PFX( AuthenticatedSafes authSafes ) { this( VERSION, authSafes, null ); } /** * Computes the macData field and adds it to the PFX. The macData field * is a Message Authentication Code of the AuthenticatedSafes, and * is used to prove the authenticity of the PFX. * * @param password The password to be used to create the password-based MAC. * @param salt The salt to be used. If null is passed in, a new salt * will be created from a random source. * @param iterationCount The iteration count for the key generation. * Use DEFAULT_ITERATIONS unless there's a need to be clever. */ public void computeMacData(Password password, byte[] salt, int iterationCount) throws NotInitializedException, DigestException, TokenException, CharConversionException { macData = new MacData( password, salt, iterationCount, ASN1Util.encode(authSafes) ); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { return TAG; } private static final Tag TAG = SEQUENCE.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(version); seq.addElement( new ContentInfo( ASN1Util.encode(authSafes) ) ); if(macData != null) { seq.addElement(macData); } seq.encode(implicitTag, ostream); } /** * A Template for decoding a BER-encoded PFX. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = SEQUENCE.getTemplate(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( ContentInfo.getTemplate() ); seqt.addOptionalElement( MacData.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); ContentInfo authSafesCI = (ContentInfo) seq.elementAt(1); if( ! authSafesCI.getContentType().equals(ContentInfo.DATA) ) { throw new InvalidBERException( "ContentInfo containing AuthenticatedSafes does not have"+ " content-type DATA"); } OCTET_STRING authSafesOS = (OCTET_STRING) authSafesCI.getInterpretedContent(); AuthenticatedSafes authSafes = (AuthenticatedSafes) ASN1Util.decode( AuthenticatedSafes.getTemplate(), authSafesOS.toByteArray() ); PFX pfx = new PFX( (INTEGER) seq.elementAt(0), authSafes, (MacData) seq.elementAt(2) ); // record the encoding of the auth safes so we can verify the // MAC later. We can't just re-encode the AuthSafes because // it is BER, and the re-encoding might be different from // the original encoding. pfx.setEncodedAuthSafes(authSafesOS.toByteArray()); return pfx; } } public static void main(String []args) { try { if( args.length != 2 ) { System.out.println("Usage: PFX "); System.exit(-1); } int certfile = 0; CryptoManager.initialize( args[0] ); // Decode the P12 file PFX.Template pfxt = new PFX.Template(); PFX pfx; FileInputStream fis = new FileInputStream(args[1]); try (BufferedInputStream in = new BufferedInputStream(fis, 2048)) { pfx = (PFX) pfxt.decode(in); } System.out.println("Decoded PFX"); // now peruse it for interesting info System.out.println("Version: "+pfx.getVersion()); AuthenticatedSafes authSafes = pfx.getAuthSafes(); SEQUENCE asSeq = authSafes.getSequence(); System.out.println("AuthSafes has "+ asSeq.size()+" SafeContents"); System.out.println("Enter password: "); Password pass = Password.readPasswordFromConsole(); // get new password System.out.println("Enter new password:"); Password newPass = Password.readPasswordFromConsole(); // verify the PFX StringBuffer sb = new StringBuffer(); if( pfx.verifyAuthSafes(pass, sb) ) { System.out.println("AuthSafes verifies correctly"); } else { System.out.println("AuthSafes failed to verify because: "+ sb); } // get new AuthSafes ready AuthenticatedSafes newAuthSafes = new AuthenticatedSafes(); for(int i=0; i < asSeq.size(); i++) { SEQUENCE safeContents = authSafes.getSafeContentsAt(pass,i); System.out.println("\n\nSafeContents #"+i+" has "+ safeContents.size()+" bags"); for(int j=0; j < safeContents.size(); j++) { SafeBag safeBag = (SafeBag) safeContents.elementAt(j); System.out.println("\nBag "+j+" has type "+ safeBag.getBagType() ); SET attribs = safeBag.getBagAttributes(); if( attribs == null ) { System.out.println("Bag has no attributes"); } else { for(int b=0; b < attribs.size(); b++) { Attribute a = (Attribute) attribs.elementAt(b); if( a.getType().equals(SafeBag.FRIENDLY_NAME)) { BMPString bs = (BMPString) ((ANY)a.getValues(). elementAt(0)).decodeWith( BMPString.getTemplate()); System.out.println("Friendly Name: "+bs); } else if(a.getType().equals(SafeBag.LOCAL_KEY_ID)){ OCTET_STRING os =(OCTET_STRING) ((ANY)a.getValues(). elementAt(0)).decodeWith( OCTET_STRING.getTemplate()); System.out.println("LocalKeyID:"); AuthenticatedSafes. print_byte_array(os.toByteArray()); } else { System.out.println("Unknown attribute type"); } } } ASN1Value val = safeBag.getInterpretedBagContent(); if( val instanceof PrivateKeyInfo ) { System.out.println("content is PrivateKeyInfo"); } else if( val instanceof EncryptedPrivateKeyInfo ) { EncryptedPrivateKeyInfo epki = ((EncryptedPrivateKeyInfo)val); System.out.println( "content is EncryptedPrivateKeyInfo, algoid:" + epki.getEncryptionAlgorithm().getOID()); PrivateKeyInfo pki = epki.decrypt(pass, new PasswordConverter() ); byte[] salt = new byte[20]; JSSSecureRandom rand = CryptoManager.getInstance(). getSecureRNG(); rand.nextBytes(salt); epki = EncryptedPrivateKeyInfo.createPBE( PBEAlgorithm.PBE_SHA1_DES3_CBC, newPass, salt, 1, new PasswordConverter(), pki); // replace the old safe bag with the new safeContents.insertElementAt( new SafeBag( safeBag.getBagType(), epki, safeBag.getBagAttributes()), j); safeContents.removeElementAt(j+1); } else if( val instanceof CertBag ) { System.out.println(" content is CertBag"); CertBag cb = (CertBag) val; if( cb.getCertType().equals(CertBag.X509_CERT_TYPE)) { OCTET_STRING os = (OCTET_STRING)cb.getInterpretedCert(); FileOutputStream fos = new FileOutputStream( "cert"+(certfile++)+".der"); os.encode(fos); fos.close(); Certificate cert = (Certificate) ASN1Util.decode(Certificate.getTemplate(), os.toByteArray()); cert.getInfo().print(System.out); } else { System.out.println("Unrecognized cert type"); } } else { System.out.println("content is ANY"); } } // Add the new safe contents to the authsafes if( authSafes.safeContentsIsEncrypted(i) ) { newAuthSafes.addEncryptedSafeContents( AuthenticatedSafes.DEFAULT_KEY_GEN_ALG, newPass, null, AuthenticatedSafes.DEFAULT_ITERATIONS, safeContents); } else { newAuthSafes.addSafeContents( safeContents ); } } // Create new PFX from new authsafes PFX newPfx = new PFX(newAuthSafes); newPfx.computeMacData(newPass, null, DEFAULT_ITERATIONS); FileOutputStream fos = new FileOutputStream("newjss.p12"); newPfx.encode(fos); fos.close(); } catch( Exception e ) { e.printStackTrace(); } } } jss-4.6.3/org/mozilla/jss/pkcs12/PasswordConverter.java000066400000000000000000000020401362106420000230060ustar00rootroot00000000000000/* 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.pkcs12; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.util.Assert; /** * Converts password chars to bytes. The output format is big-endian Unicode, * with two zero bytes of null-termination at the end. */ public final class PasswordConverter implements KeyGenerator.CharToByteConverter { public byte[] convert(char[] chars) { byte[] bytes = new byte[ (chars.length+1) * 2 ]; int c; // char index int b; // byte index for(c=0, b=0; c < chars.length; c++) { bytes[b++] = (byte) ((chars[c] & 0xff00) >>> 8); bytes[b++] = (byte) (chars[c] & 0xff); } bytes[b++] = 0; bytes[b++] = 0; assert(b == bytes.length); return bytes; } } jss-4.6.3/org/mozilla/jss/pkcs12/SafeBag.java000066400000000000000000000347131362106420000206200ustar00rootroot00000000000000/* 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.pkcs12; import java.io.CharConversionException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.DigestException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BMPString; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.crypto.JSSSecureRandom; import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.pkix.primitive.Attribute; import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo; import org.mozilla.jss.pkix.primitive.PrivateKeyInfo; import org.mozilla.jss.util.AssertionException; import org.mozilla.jss.util.Password; /** * A PKCS #12 SafeBag structure. */ public final class SafeBag implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private OBJECT_IDENTIFIER bagType; private ANY bagContent; private SET bagAttributes; // may be null public OBJECT_IDENTIFIER getBagType() { return bagType; } /** * Returns the contents of this bag as an ANY. */ public ANY getBagContent() { return bagContent; } /** * Returns the bagContent interpreted by type. * @return If type is KeyBag, a PrivateKeyInfo. *
If type is PKCS-8ShroudedKeyBag, an EncryptedPrivateKeyInfo. *
If type is CertBag, a CertBag. *
For any other type, returns an ANY. */ public ASN1Value getInterpretedBagContent() throws InvalidBERException { if( bagType.equals(KEY_BAG) ) { return bagContent.decodeWith(PrivateKeyInfo.getTemplate()); } else if( bagType.equals(PKCS8_SHROUDED_KEY_BAG)) { return bagContent.decodeWith(EncryptedPrivateKeyInfo.getTemplate()); } else if( bagType.equals(CERT_BAG) ) { return bagContent.decodeWith(CertBag.getTemplate()); } else { return bagContent; } } /** * Returns the attributes of this bag. May return null if this bag * has no attributes. Each element of the set is a * org.mozilla.jss.pkix.primitive.Attribute. */ public SET getBagAttributes() { return bagAttributes; } /////////////////////////////////////////////////////////////////////// // OIDs /////////////////////////////////////////////////////////////////////// /** * The OID branch for PKCS #12, version 1.0. */ public static final OBJECT_IDENTIFIER PKCS12_VERSION_1= OBJECT_IDENTIFIER.PKCS12.subBranch(10); /** * The OID branch for the PKCS #12 bag types. */ public static final OBJECT_IDENTIFIER PKCS12_BAG_IDS = PKCS12_VERSION_1.subBranch(1); /** * A bag containing a private key. The bag content is a KeyBag, * which is equivalent to a PKCS #8 PrivateKeyInfo */ public static final OBJECT_IDENTIFIER KEY_BAG = PKCS12_BAG_IDS.subBranch(1); /** * A bag containing a private key encrypted a la PKCS #8. The bag * content is a PKCS #8 EncryptedPrivateKeyInfo. */ public static final OBJECT_IDENTIFIER PKCS8_SHROUDED_KEY_BAG = PKCS12_BAG_IDS.subBranch(2); /** * A bag containing a certificate. The bag content is CertBag. */ public static final OBJECT_IDENTIFIER CERT_BAG = PKCS12_BAG_IDS.subBranch(3); /** * A bag containing a certificate revocation list. * The bag content is CRLBag. */ public static final OBJECT_IDENTIFIER CRL_BAG = PKCS12_BAG_IDS.subBranch(4); /** * A bag containing an arbitrary secret. The bag content is * SecretBag. */ public static final OBJECT_IDENTIFIER SECRET_BAG = PKCS12_BAG_IDS.subBranch(5); /** * A bag containing a nested SafeContent . The bag content is * SafeContents, which is merely a SEQUENCE of SafeBag. */ public static final OBJECT_IDENTIFIER SAFE_CONTENTS_BAG = PKCS12_BAG_IDS.subBranch(6); /** * A FriendlyName attribute. The value is a BMPString. */ public static final OBJECT_IDENTIFIER FRIENDLY_NAME = OBJECT_IDENTIFIER.PKCS9.subBranch(20); /** * A LocalKeyID attribute. The value is an octet string. */ public static final OBJECT_IDENTIFIER LOCAL_KEY_ID = OBJECT_IDENTIFIER.PKCS9.subBranch(21); /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Creates a new SafeBag from its components. * * @param bagType The type of this bag. For compatibility, it should * be one of the constants defined in this class. * @param bagContent The contents of the bag. The type of this parameter * is defined by the bagType parameter. * @param bagAttributes A SET of Attributes for this SafeBag. Since * attributes are optional, this parameter may be null. */ public SafeBag(OBJECT_IDENTIFIER bagType, ASN1Value bagContent, SET bagAttributes) { if( bagType==null || bagContent==null ) { throw new IllegalArgumentException("bagType or bagContent is null"); } this.bagType = bagType; try { if( bagContent instanceof ANY ) { this.bagContent = (ANY) bagContent; } else { byte[] encoded = ASN1Util.encode(bagContent); this.bagContent = (ANY) ASN1Util.decode(ANY.getTemplate(), encoded); } } catch( InvalidBERException e ) { throw new RuntimeException("Unable to convert ASN1Value to ANY: " + e.getMessage(), e); } this.bagAttributes = bagAttributes; } /** * Creates a SafeBag that contains an X.509 Certificate. * The SafeBag will have a localKeyID attribute equal * to the SHA-1 hash of the certificate, and a friendlyName * attribute equal to the supplied string. This is the way Communicator * makes a CertBag. The same localKeyID attribute should be stored * in the matching private key bag. * * @param cert A DER-encoded X.509 certificate. * @param friendlyName Will be stored in the friendlyName * attribute of the SafeBag. Should be the nickname of the cert. */ public static SafeBag createCertBag(byte[] cert, String friendlyName) throws DigestException, NoSuchAlgorithmException, InvalidBERException { return createCertBag(cert, friendlyName, getLocalKeyIDFromCert(cert)); } /** * Creates a SafeBag that contains an X.509 Certificate. * The SafeBag will have the given localKeyID attribute, * and a friendlyName * attribute equal to the supplied string. This is the way Communicator * makes a CertBag. The same localKeyID attribute should be stored * in the matching private key bag. * * @param cert A DER-encoded X.509 certificate. * @param friendlyName Will be stored in the friendlyName * attribute of the SafeBag. Should be the nickname of the cert. * @param localKeyID The bytes to used for the localKeyID. These should * be obtained from the getLocalKeyIDFromCert method. * @exception InvalidBERException If the cert is not a valid DER encoding. * @see #getLocalKeyIDFromCert */ public static SafeBag createCertBag(byte[] cert, String friendlyName, byte[] localKeyID) throws InvalidBERException { try { // create CertBag CertBag cb = new CertBag(CertBag.X509_CERT_TYPE, new ANY(cert) ); // setup attributes SET attributes = new SET(); // friendly name should be cert nickname attributes.addElement(new Attribute( FRIENDLY_NAME, new BMPString(friendlyName) )); attributes.addElement( new Attribute( LOCAL_KEY_ID, new OCTET_STRING(localKeyID) )); return new SafeBag(CERT_BAG, cb, attributes); } catch( CharConversionException e ) { throw new AssertionException("CharConversionException converting"+ " Unicode to BMPString"); } } /** * Computes the LocalKeyID attribute that should be stored with a key * and certificate. * * @param derCert A DER-encoded X.509 certificate. * @return The SHA-1 hash of the cert, which should be used as the * localKeyID attribute for the cert's SafeBag. */ public static final byte[] getLocalKeyIDFromCert(byte[] derCert) throws DigestException, NoSuchAlgorithmException { MessageDigest digester = MessageDigest.getInstance("SHA-1"); return digester.digest(derCert); } /** * Creates a SafeBag containing a PKCS-8ShroudedKeyBag, which is * an EncryptedPrivateKeyInfo. The key will be encrypted using * a triple-DES PBE algorithm, using the supplied password. * * @param privk The PrivateKeyInfo containing the private key. * @param friendlyName The nickname for the key; should be the same * as the nickname of the associated cert. * @param localKeyID The localKeyID for the key; should be the same as * the localKeyID of the associated cert. * @param password The password used to encrypt the private key. */ public static SafeBag createEncryptedPrivateKeyBag(PrivateKeyInfo privk, String friendlyName, byte[] localKeyID, Password password) throws NotInitializedException, TokenException { try { PBEAlgorithm pbeAlg = PBEAlgorithm.PBE_SHA1_DES3_CBC; final int DEFAULT_ITERATIONS = 1; byte[] salt = new byte[pbeAlg.getSaltLength()]; JSSSecureRandom rand = CryptoManager.getInstance().getSecureRNG(); rand.nextBytes(salt); EncryptedPrivateKeyInfo epki= EncryptedPrivateKeyInfo.createPBE( PBEAlgorithm.PBE_SHA1_DES3_CBC, password, salt, DEFAULT_ITERATIONS, new PasswordConverter(), privk); SET attributes = new SET(); attributes.addElement(new Attribute( FRIENDLY_NAME, new BMPString(friendlyName) )); attributes.addElement( new Attribute( LOCAL_KEY_ID, new OCTET_STRING(localKeyID) )); return new SafeBag(PKCS8_SHROUDED_KEY_BAG , epki, attributes); } catch(java.security.NoSuchAlgorithmException e) { throw new AssertionException( "Unable to find PBE algorithm: "+e); } catch(java.security.InvalidKeyException e) { throw new AssertionException( "InvalidKeyException while creating EncryptedContentInfo: "+e); } catch(java.security.InvalidAlgorithmParameterException e) { throw new AssertionException( "InvalidAlgorithmParameterException while creating"+ " EncryptedContentInfo: "+e); } catch(java.io.CharConversionException e) { throw new AssertionException( "CharConversionException while creating EncryptedContentInfo: "+ e); } } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private 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( bagType ); seq.addElement( new EXPLICIT(new Tag(0), bagContent) ); if( bagAttributes!=null ) { seq.addElement( bagAttributes ); } seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding SafeBags. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OBJECT_IDENTIFIER.getTemplate() ); seqt.addElement( new EXPLICIT.Template( new Tag(0), ANY.getTemplate() ) ); seqt.addOptionalElement( new SET.OF_Template( Attribute.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 { try { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new SafeBag( (OBJECT_IDENTIFIER) seq.elementAt(0), ((EXPLICIT)seq.elementAt(1)).getContent(), (SET) seq.elementAt(2) ); } catch( InvalidBERException e ) { throw new InvalidBERException(e, "SafeBag"); } } } } jss-4.6.3/org/mozilla/jss/pkcs12/SecretBag.java000066400000000000000000000100661362106420000211620ustar00rootroot00000000000000/* 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.pkcs12; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; public class SecretBag implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private OBJECT_IDENTIFIER secretType; private ANY secret; private SEQUENCE sequence; /** * Returns the type of secret stored in the SecretBag. */ public OBJECT_IDENTIFIER getSecretType() { return secretType; } /** * Returns the secret stored in the SecretBag. */ public ANY getSecret() { return secret; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Creates a SecretBag with the given secret type and secret. Neither * may be null. */ public SecretBag(OBJECT_IDENTIFIER secretType, ASN1Value secret) { if( secretType==null || secret==null ) { throw new IllegalArgumentException("SecretBag parameter is null"); } this.secretType = secretType; if( secret instanceof ANY ) { this.secret = (ANY) secret; } else { byte[] encoded = ASN1Util.encode(secret); try { this.secret = (ANY) ASN1Util.decode(ANY.getTemplate(), encoded); } catch(InvalidBERException e) { throw new RuntimeException("Unable to convert ASN1Value to ANY: " + e.getMessage(), e); } } sequence = new SEQUENCE(); sequence.addElement(secretType); sequence.addElement( new EXPLICIT(new Tag(0), this.secret) ); } /////////////////////////////////////////////////////////////////////// // 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 class for decoding SecretBags from BER. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OBJECT_IDENTIFIER.getTemplate() ); seqt.addElement( new EXPLICIT.Template( new Tag(0), 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 SecretBag( (OBJECT_IDENTIFIER)seq.elementAt(0), ((EXPLICIT)seq.elementAt(1)).getContent() ); } } } jss-4.6.3/org/mozilla/jss/pkcs12/package.html000066400000000000000000000005321362106420000207360ustar00rootroot00000000000000 Creating and interpreting PKCS #12 blobs. The PFX class is the top-level structure of a PKCS #12 blob. jss-4.6.3/org/mozilla/jss/pkcs7/000077500000000000000000000000001362106420000164015ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkcs7/Attribute.java000066400000000000000000000061011362106420000212050ustar00rootroot00000000000000/* 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.pkcs7; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * An Attribute, which has the following ASN.1 * definition (roughly): *
 *      Attribute ::= SEQUENCE {
 *          type        OBJECT IDENTIFIER,
 *          value       SET }
 * 
*/ public class Attribute implements ASN1Value { private OBJECT_IDENTIFIER type; private SET values; public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public Attribute(OBJECT_IDENTIFIER type, SET values) { this.type = type; this.values = values; } public Attribute(OBJECT_IDENTIFIER type, ASN1Value value) { this.type = type; this.values = new SET(); values.addElement(value); } public OBJECT_IDENTIFIER getType() { return type; } /** * If this AVA was constructed, returns the SET of ASN1Values passed to the * constructor. If this Attribute was decoded with an Attribute.Template, * returns a SET of ANYs. */ public SET getValues() { return values; } 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(type); seq.addElement(values); seq.encode(implicit, ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A Template for decoding an Attribute. */ 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 SET.OF_Template(new ANY.Template())); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); // The template should have enforced this assert(seq.size() == 2); return new Attribute( (OBJECT_IDENTIFIER) seq.elementAt(0), (SET) seq.elementAt(1)); } } } jss-4.6.3/org/mozilla/jss/pkcs7/ContentInfo.java000066400000000000000000000176471362106420000215110ustar00rootroot00000000000000/* 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.pkcs7; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * A PKCS #7 ContentInfo structure. */ public class ContentInfo implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; // XXX is this right? public static OBJECT_IDENTIFIER DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 1 }); public static OBJECT_IDENTIFIER SIGNED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 2 }); public static OBJECT_IDENTIFIER ENVELOPED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 3 }); public static OBJECT_IDENTIFIER SIGNED_AND_ENVELOPED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 4 }); public static OBJECT_IDENTIFIER DIGESTED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 5 }); public static OBJECT_IDENTIFIER ENCRYPTED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 6 }); private OBJECT_IDENTIFIER contentType; private ANY content; private SEQUENCE sequence = new SEQUENCE(); /** * Creates a ContentInfo with the given type and content. * * @param contentType The contentType of the ContentInfo. * @param content The content of the ContentInfo. May be null * to signify that the optional content field is not present. */ public ContentInfo(OBJECT_IDENTIFIER contentType, ASN1Value content) { this.contentType = contentType; sequence.addElement(contentType); if (content != null) { if( content instanceof ANY ) { this.content = (ANY) content; } else { // convert content to ANY try { this.content = (ANY) ASN1Util.decode(ANY.getTemplate(), ASN1Util.encode(content) ); } catch(InvalidBERException e) { throw new RuntimeException("Unable to convert " + "ASN1Value to ANY: " + e.getMessage(), e); } } sequence.addElement(new EXPLICIT(new Tag(0),content) ); } } /** * Creates a ContentInfo of type data. */ public ContentInfo(byte[] data) { this( DATA, new OCTET_STRING(data) ); } /** * Creates a ContentInfo of type signedData. */ public ContentInfo(SignedData sd) { this( SIGNED_DATA, sd); } /** * Creates a ContentInfo of type envelopedData. */ public ContentInfo(EnvelopedData ed) { this( ENVELOPED_DATA, ed ); } /** * Creates a ContentInfo of type signedAndEnvelopedData. */ public ContentInfo(SignedAndEnvelopedData sed) { this( SIGNED_AND_ENVELOPED_DATA, sed ); } /** * Creates a ContentInfo of type digestedData. */ public ContentInfo(DigestedData dd) { this( DIGESTED_DATA, dd ); } /** * Creates a ContentInfo of type encryptedData. */ public ContentInfo(EncryptedData ed) { this( ENCRYPTED_DATA, ed ); } /** * Returns the contentType field, which determines what kind of content * is contained in this ContentInfo. It will usually be one of the six * predefined types, but may also be a user-defined type. */ public OBJECT_IDENTIFIER getContentType() { return contentType; } /** * Returns true if the content field is present. */ public boolean hasContent() { return (content != null); } /** * Returns the content, interpreted based on its type. If there is no * content, null is returned. *

If the contentType is * one of the six standard types, the returned object will be of that * type. For example, if the ContentInfo has contentType signedData, * a SignedData object will be returned. If the contentType is data, * an OCTET_STRING will be returned. *

If the contentType is not one of the six standard types, * the returned object will be an ANY. */ public ASN1Value getInterpretedContent() throws InvalidBERException { if(contentType.equals(DATA)) { return content.decodeWith( new OCTET_STRING.Template() ); } else if( contentType.equals(SIGNED_DATA) ) { return content.decodeWith( new SignedData.Template() ); } else if( contentType.equals(ENVELOPED_DATA) ) { return content.decodeWith( new EnvelopedData.Template()); } else if( contentType.equals(SIGNED_AND_ENVELOPED_DATA) ) { return content.decodeWith( new SignedAndEnvelopedData.Template() ); } else if( contentType.equals(DIGESTED_DATA) ) { return content.decodeWith( new DigestedData.Template() ); } else if( contentType.equals(ENCRYPTED_DATA) ) { return content.decodeWith( new EncryptedData.Template()); } else { // unknown type return content; } } /** * Returns the content encoded as an ANY. If there is no content, * null is returned. */ public ANY getContent() { return content; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag,ostream); } public Tag getTag() { return ContentInfo.TAG; } /** * Returns a singleton instance of a decoding template for ContentInfo. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding a ContentInfo blob * */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return (tag.equals(ContentInfo.TAG)); } private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new OBJECT_IDENTIFIER.Template()); seqt.addOptionalElement( new EXPLICIT.Template( new Tag(0), new ANY.Template() )); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(ContentInfo.TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream ) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); assert(seq.size() == 2); ASN1Value content; if( seq.elementAt(1) == null ) { content = null; } else { content = ((EXPLICIT)seq.elementAt(1)).getContent(); } return new ContentInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), content ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkcs7/DigestInfo.java000066400000000000000000000071551362106420000213070ustar00rootroot00000000000000/* 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.pkcs7; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.util.Assert; public class DigestInfo implements ASN1Value { private AlgorithmIdentifier digestAlgorithm; private OCTET_STRING digest; private SEQUENCE sequence; public DigestInfo(AlgorithmIdentifier digestAlgorithm, OCTET_STRING digest){ if( digestAlgorithm==null || digest==null ) { throw new IllegalArgumentException(); } sequence = new SEQUENCE(); this.digestAlgorithm = digestAlgorithm; sequence.addElement(digestAlgorithm); this.digest = digest; sequence.addElement(digest); } public AlgorithmIdentifier getDigestAlgorithm() { return digestAlgorithm; } public OCTET_STRING getDigest() { return digest; } private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public boolean equals(Object obj) { if( obj==null || !(obj instanceof DigestInfo)) { return false; } DigestInfo di = (DigestInfo)obj; return byteArraysAreSame(di.digest.toByteArray(), digest.toByteArray()); } /** * Compares two non-null byte arrays. Returns true if they are identical, * false otherwise. */ private static boolean byteArraysAreSame(byte[] left, byte[] right) { assert(left!=null && right!=null); if( left.length != right.length ) { return false; } for(int i = 0 ; i < left.length ; i++ ) { if( left[i] != right[i] ) { return false; } } return true; } 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 class for decoding the BER encoding of a DigestInfo. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( AlgorithmIdentifier.getTemplate()); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream ostream) throws InvalidBERException, IOException { return decode(TAG, ostream); } public ASN1Value decode(Tag implicitTag, InputStream ostream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, ostream); return new DigestInfo( (AlgorithmIdentifier) seq.elementAt(0), (OCTET_STRING) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkcs7/DigestedData.java000066400000000000000000000100041362106420000215610ustar00rootroot00000000000000/* 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.pkcs7; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; public class DigestedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private INTEGER version; private AlgorithmIdentifier digestAlgorithm; private ContentInfo contentInfo; private OCTET_STRING digest; private SEQUENCE sequence; // for DER encoding public INTEGER getVersion() { return version; } public AlgorithmIdentifier getDigestAlgorithm() { return digestAlgorithm; } public ContentInfo getContentInfo() { return contentInfo; } public OCTET_STRING getDigest() { return digest; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// public DigestedData(INTEGER version, AlgorithmIdentifier digestAlgorithm, ContentInfo contentInfo, OCTET_STRING digest) { if( version==null || digestAlgorithm==null || contentInfo==null || digest==null ) { throw new IllegalArgumentException("DigestedData constructor" +" parameter is null"); } this.version = version; this.digestAlgorithm = digestAlgorithm; this.contentInfo = contentInfo; this.digest = digest; sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(digestAlgorithm); sequence.addElement(contentInfo); sequence.addElement(digest); } /////////////////////////////////////////////////////////////////////// // 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); } /** * A Template for decoding BER-encoded DigestData 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( ContentInfo.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 DigestedData( (INTEGER) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (ContentInfo) seq.elementAt(2), (OCTET_STRING) seq.elementAt(3) ); } } } jss-4.6.3/org/mozilla/jss/pkcs7/EncryptedContentInfo.java000066400000000000000000000323661362106420000233620ustar00rootroot00000000000000/* 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.pkcs7; import java.io.CharConversionException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.spec.RC2ParameterSpec; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.crypto.Cipher; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.IVParameterSpec; import org.mozilla.jss.crypto.IllegalBlockSizeException; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.PBEKeyGenParams; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.pkix.primitive.PBEParameter; import org.mozilla.jss.util.Assert; import org.mozilla.jss.util.Password; /** * The PKCS #7 type EncryptedContentInfo, which encapsulates * encrypted data. */ public class EncryptedContentInfo implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private OBJECT_IDENTIFIER contentType; private AlgorithmIdentifier contentEncryptionAlgorithm; private OCTET_STRING encryptedContent; // may be null private SEQUENCE sequence = new SEQUENCE(); public OBJECT_IDENTIFIER getContentType() { return contentType; } public AlgorithmIdentifier getContentEncryptionAlgorithm() { return contentEncryptionAlgorithm; } public OCTET_STRING getEncryptedContent() { return encryptedContent; } public boolean hasEncryptedContent() { return (encryptedContent!=null); } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Create a EnvelopedData ASN1 object. */ public EncryptedContentInfo( OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent) { this(contentType, contentEncryptionAlgorithm, encryptedContent, false); } public EncryptedContentInfo( OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent, boolean createHackedCRSCompatibleECI) { this.contentType = contentType; this.contentEncryptionAlgorithm = contentEncryptionAlgorithm; this.encryptedContent = encryptedContent; sequence.addElement(contentType); sequence.addElement(contentEncryptionAlgorithm); if(encryptedContent != null) { if (createHackedCRSCompatibleECI) { sequence.addElement(new EXPLICIT(new Tag(0), encryptedContent)); } else { sequence.addElement(new Tag(0), encryptedContent); } } } public static EncryptedContentInfo createCRSCompatibleEncryptedContentInfo(OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent) { return new EncryptedContentInfo(contentType, contentEncryptionAlgorithm, encryptedContent, true); } /////////////////////////////////////////////////////////////////////// // Crypto shortcuts /////////////////////////////////////////////////////////////////////// /** * Creates a new EncryptedContentInfo, where the data is encrypted * with a password-based key. * * @param keyGenAlg The algorithm for generating a symmetric key from * a password, salt, and iteration count. * @param password The password to use in generating the key. * @param salt The salt to use in generating the key. * @param iterationCount The number of hashing iterations to perform * while generating the key. * @param charToByteConverter The mechanism for converting the characters * in the password into bytes. If null, the default mechanism * will be used, which is UTF8. * @param toBeEncrypted The bytes to be encrypted and stored in the * EncryptedContentInfo. Before they are encrypted, they will be * padded using PKCS padding. */ public static EncryptedContentInfo createPBE(PBEAlgorithm keyGenAlg, Password password, byte[] salt, int iterationCount, KeyGenerator.CharToByteConverter charToByteConverter, byte[] toBeEncrypted) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, CharConversionException { try { // check key gen algorithm if( ! (keyGenAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("Key generation algorithm"+ " is not a PBE algorithm"); } PBEAlgorithm pbeAlg = keyGenAlg; CryptoManager cman = CryptoManager.getInstance(); // generate key CryptoToken token = cman.getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( keyGenAlg ); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( password, salt, iterationCount); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize(pbekgParams); SymmetricKey key = kg.generate(); // generate IV EncryptionAlgorithm encAlg = pbeAlg.getEncryptionAlg(); AlgorithmParameterSpec params=null; Class [] paramClasses = pbeAlg.getParameterClasses(); for (int i = 0; i < paramClasses.length; i ++) { if ( paramClasses[i].equals( javax.crypto.spec.IvParameterSpec.class ) ) { params = new IVParameterSpec(kg.generatePBE_IV()); break; } else if ( paramClasses[i].equals( RC2ParameterSpec.class ) ) { params = new RC2ParameterSpec(key.getStrength(), kg.generatePBE_IV()); break; } } // perform encryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initEncrypt( key, params ); byte[] encrypted = cipher.doFinal( Cipher.pad( toBeEncrypted, encAlg.getBlockSize()) ); // make encryption algorithm identifier PBEParameter pbeParam = new PBEParameter( salt, iterationCount ); AlgorithmIdentifier encAlgID = new AlgorithmIdentifier( keyGenAlg.toOID(), pbeParam); // create EncryptedContentInfo EncryptedContentInfo encCI = new EncryptedContentInfo( ContentInfo.DATA, encAlgID, new OCTET_STRING(encrypted) ); return encCI; } catch( IllegalBlockSizeException e ) { throw new RuntimeException("IllegalBlockSizeException in EncryptedContentInfo" +".createPBE: " + e.getMessage(), e); } catch( BadPaddingException e ) { throw new RuntimeException("BadPaddingException in EncryptedContentInfo" +".createPBE: " + e.getMessage(), e); } } /** * Decrypts the content of an EncryptedContentInfo encrypted with a * PBE key. * * @param pass The password to use in generating the PBE decryption key. * @param charToByteConverter The converter for converting the password * characters into bytes. May be null to use the default. * @return The decrypted contents of the EncryptedContentInfo. The contents * are first unpadded using the PKCS padding mechanism. */ public byte[] decrypt(Password pass, KeyGenerator.CharToByteConverter charToByteConverter) throws IllegalStateException,NotInitializedException, NoSuchAlgorithmException, InvalidBERException, IOException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, IllegalBlockSizeException, BadPaddingException { if( encryptedContent == null ) { return null; } // get the key gen parameters AlgorithmIdentifier algid = contentEncryptionAlgorithm; KeyGenAlgorithm kgAlg = KeyGenAlgorithm.fromOID( algid.getOID() ); if( !(kgAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("KeyGenAlgorithm is not a"+ " PBE algorithm"); } ASN1Value params = algid.getParameters(); if( params == null ) { throw new InvalidAlgorithmParameterException( "PBE algorithms require parameters"); } PBEParameter pbeParams; if( params instanceof PBEParameter) { pbeParams = (PBEParameter) params; } else { byte[] encodedParams = ASN1Util.encode(params); pbeParams = (PBEParameter) ASN1Util.decode( PBEParameter.getTemplate(), encodedParams ); } PBEKeyGenParams kgp = new PBEKeyGenParams(pass, pbeParams.getSalt(), pbeParams.getIterations() ); // compute the key and IV CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( kgAlg ); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize( kgp ); SymmetricKey key = kg.generate(); // compute algorithm parameters EncryptionAlgorithm encAlg = ((PBEAlgorithm)kgAlg).getEncryptionAlg(); AlgorithmParameterSpec algParams = null; Class [] paramClasses = encAlg.getParameterClasses(); for (int i = 0; i < paramClasses.length; i ++) { if ( paramClasses[i].equals( javax.crypto.spec.IvParameterSpec.class ) ) { algParams = new IVParameterSpec( kg.generatePBE_IV() ); break; } else if ( paramClasses[i].equals(RC2ParameterSpec.class ) ) { algParams = new RC2ParameterSpec(key.getStrength(), kg.generatePBE_IV()); break; } } // perform the decryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initDecrypt(key, algParams); return Cipher.unPad(cipher.doFinal( encryptedContent.toByteArray() )); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); /** * A template file for decoding a EnvelopedData blob * */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return (tag.equals(EncryptedContentInfo.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new OBJECT_IDENTIFIER.Template()); seqt.addElement(new AlgorithmIdentifier.Template()); seqt.addOptionalElement(new Tag(0), new OCTET_STRING.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); assert(seq.size() ==3); return new EncryptedContentInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (OCTET_STRING) seq.elementAt(2) ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkcs7/EncryptedData.java000066400000000000000000000102111362106420000217660ustar00rootroot00000000000000/* 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.pkcs7; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * The PKCS #7 structure EncryptedData. */ public class EncryptedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private INTEGER version; private EncryptedContentInfo encryptedContentInfo; private SEQUENCE sequence; /** * The default version number. This should always be used unless * you really know what you are doing. */ public static final INTEGER DEFAULT_VERSION = new INTEGER(0); /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Creates a new EncryptedData. * * @param version Should usually be DEFAULT_VERSION unless you are being * very clever. */ public EncryptedData( INTEGER version, EncryptedContentInfo encryptedContentInfo ) { if( version == null || encryptedContentInfo == null ) { throw new IllegalArgumentException("null parameter"); } sequence = new SEQUENCE(); this.version = version; sequence.addElement(version); this.encryptedContentInfo = encryptedContentInfo; sequence.addElement(encryptedContentInfo); } /** * Creates an EncryptedData with the default version. */ public EncryptedData( EncryptedContentInfo encryptedContentInfo ) { this( DEFAULT_VERSION, encryptedContentInfo ); } /////////////////////////////////////////////////////////////////////// // Accessor Methods /////////////////////////////////////////////////////////////////////// public INTEGER getVersion() { return version; } public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } /////////////////////////////////////////////////////////////////////// // 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); } public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); /** * A Template for decoding EncryptedData items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( EncryptedContentInfo.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 EncryptedData( (INTEGER) seq.elementAt(0), (EncryptedContentInfo) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkcs7/EnvelopedData.java000066400000000000000000000062741362106420000217700ustar00rootroot00000000000000/* 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.pkcs7; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; public class EnvelopedData implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private INTEGER version; private SET recipientInfos; private EncryptedContentInfo encryptedContentInfo; private SEQUENCE sequence = new SEQUENCE(); public INTEGER getVersion() { return version; } public SET getRecipientInfos() { return recipientInfos; } public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } /** * Create a EnvelopedData ASN1 object. */ public EnvelopedData( INTEGER version, SET recipientInfos, EncryptedContentInfo encryptedContentInfo) { this.version = version; this.recipientInfos = recipientInfos; this.encryptedContentInfo = encryptedContentInfo; sequence.addElement(version); sequence.addElement(recipientInfos); sequence.addElement(encryptedContentInfo); } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } /** * A template file for decoding a EnvelopedData blob * */ public static class Template implements ASN1Template { public Tag getTag() { return EnvelopedData.TAG; } public boolean tagMatch(Tag tag) { return (tag.equals(EnvelopedData.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(),istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new INTEGER.Template()); seqt.addElement(new SET.OF_Template(new RecipientInfo.Template())); seqt.addElement(new EncryptedContentInfo.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); assert(seq.size() ==3); return new EnvelopedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (EncryptedContentInfo) seq.elementAt(2) ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkcs7/IssuerAndSerialNumber.java000066400000000000000000000074151362106420000234610ustar00rootroot00000000000000/* 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.pkcs7; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.Name; import org.mozilla.jss.util.Assert; /** * An issuer name and serial number, used to uniquely identify a certificate. */ public class IssuerAndSerialNumber implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private Name issuer; private INTEGER serialNumber; private SEQUENCE sequence; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// /** * Constructs an IssuerAndSerialNumber from its components. * * @param issuer Must not be null. * @param serialNumber must not be null. */ public IssuerAndSerialNumber(Name issuer, INTEGER serialNumber) { if(issuer==null || serialNumber==null) { throw new IllegalArgumentException(); } sequence = new SEQUENCE(); this.issuer = issuer; sequence.addElement(issuer); this.serialNumber = serialNumber; sequence.addElement(serialNumber); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public Name getIssuer() { return issuer; } public INTEGER getSerialNumber() { return serialNumber; } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// static 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.encode(implicitTag, ostream); } /** * Returns a singleton template instance. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding an IssuerAndSerialNumber from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( Name.getTemplate() ); seqt.addElement( INTEGER.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); assert(seq.size() == 2); return new IssuerAndSerialNumber( (Name) seq.elementAt(0), (INTEGER) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkcs7/RecipientInfo.java000066400000000000000000000077141362106420000220130ustar00rootroot00000000000000/* 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.pkcs7; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.util.Assert; public class RecipientInfo implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private INTEGER version; private IssuerAndSerialNumber issuerAndSerialNumber; private AlgorithmIdentifier keyEncryptionAlgorithmID; private OCTET_STRING encryptedKey; private SEQUENCE sequence = new SEQUENCE(); public INTEGER getVersion() { return version; } public IssuerAndSerialNumber getissuerAndSerialNumber() { return issuerAndSerialNumber; } public AlgorithmIdentifier getKeyEncryptionAlgorithmID() { return keyEncryptionAlgorithmID; } public OCTET_STRING getEncryptedKey() { return encryptedKey; } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * Create a RecipientInfo ASN1 object. */ public RecipientInfo( INTEGER version, IssuerAndSerialNumber issuerAndSerialNumber, AlgorithmIdentifier keyEncryptionAlgorithmID, OCTET_STRING encryptedKey) { assert(issuerAndSerialNumber != null); assert(keyEncryptionAlgorithmID != null); assert(encryptedKey != null); this.version = version; this.issuerAndSerialNumber = issuerAndSerialNumber; this.keyEncryptionAlgorithmID = keyEncryptionAlgorithmID; this.encryptedKey = encryptedKey; sequence.addElement(version); sequence.addElement(issuerAndSerialNumber); sequence.addElement(keyEncryptionAlgorithmID); sequence.addElement(encryptedKey); } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } /** * A template file for decoding a RecipientInfo blob * */ public static class Template implements ASN1Template { public Tag getTag() { return RecipientInfo.TAG; } public boolean tagMatch(Tag tag) { return (tag.equals(RecipientInfo.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(),istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new INTEGER.Template()); seqt.addElement(new IssuerAndSerialNumber.Template()); seqt.addElement(new AlgorithmIdentifier.Template()); seqt.addElement(new OCTET_STRING.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); assert(seq.size() ==4); return new RecipientInfo( (INTEGER) seq.elementAt(0), (IssuerAndSerialNumber) seq.elementAt(1), (AlgorithmIdentifier) seq.elementAt(2), (OCTET_STRING) seq.elementAt(3) ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkcs7/SignedAndEnvelopedData.java000066400000000000000000000140211362106420000235320ustar00rootroot00000000000000/* 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.pkcs7; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; public class SignedAndEnvelopedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private INTEGER version; private SET recipientInfos; private SET digestAlgorithms; private EncryptedContentInfo encryptedContentInfo; private SET certificates; // may be null private SET crls; // may be null private SET signerInfos; private SEQUENCE sequence; // for encoding /** * Returns the version number. The current version is 1. */ public INTEGER getVersion() { return version; } /** * Returns a SET of RecipientInfo. */ public SET getRecipientInfos() { return recipientInfos; } /** * Returns a SET of AlgorithmIdentifier. */ public SET getDigestAlgorithms() { return digestAlgorithms; } /** * Returns the encrypted content. */ public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } /** * Returns a SET of ANYs. May return null if the * certificates field is not present. */ public SET getCertificates() { return certificates; } /** * Returns a SET of ANYs. May return null if the crls * field is not present. */ public SET getCrls() { return crls; } /** * Returns a SET of SignerInfo. */ public SET getSignerInfos() { return signerInfos; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// public SignedAndEnvelopedData( INTEGER version, SET recipientInfos, SET digestAlgorithms, EncryptedContentInfo encryptedContentInfo, SET certificates, SET crls, SET signerInfos) { if( version==null || recipientInfos==null || digestAlgorithms==null || encryptedContentInfo==null || signerInfos==null ) { throw new IllegalArgumentException( "SignedAndEnvelopedData constructor parameter is null"); } this.version = version; this.recipientInfos = recipientInfos; this.digestAlgorithms = digestAlgorithms; this.encryptedContentInfo = encryptedContentInfo; this.certificates = certificates; this.crls = crls; this.signerInfos = signerInfos; sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(recipientInfos); sequence.addElement(digestAlgorithms); sequence.addElement(encryptedContentInfo); if( certificates!=null ) { sequence.addElement(certificates); } if( crls!=null ) { sequence.addElement(crls); } sequence.addElement( signerInfos ); } /////////////////////////////////////////////////////////////////////// // 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); } /** * A Template class for decoding BER-encoded SignedAndEnvelopedData items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(INTEGER.getTemplate()); seqt.addElement(new SET.OF_Template(RecipientInfo.getTemplate())); seqt.addElement(new SET.OF_Template( AlgorithmIdentifier.getTemplate()) ); seqt.addElement(EncryptedContentInfo.getTemplate()); seqt.addOptionalElement(new Tag(0), new SET.OF_Template(ANY.getTemplate())); seqt.addOptionalElement(new Tag(1), new SET.OF_Template(ANY.getTemplate())); seqt.addElement(new SET.OF_Template(SignerInfo.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 SignedAndEnvelopedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (SET) seq.elementAt(2), (EncryptedContentInfo) seq.elementAt(3), (SET) seq.elementAt(4), (SET) seq.elementAt(5), (SET) seq.elementAt(6) ); } } } jss-4.6.3/org/mozilla/jss/pkcs7/SignedData.java000066400000000000000000000322421362106420000212520ustar00rootroot00000000000000/* 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.pkcs7; import java.io.*; import org.mozilla.jss.util.Assert; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.Certificate; /* CUT THIS??? *

Although all the normal functionality of a SignedData is supported * with high-level methods, there is a low-level API for setting the * individual fields of the structure. Using these calls is an unsupported * way of accomplishing unforeseen tasks. If you have reason to use these * methods, please notify the authors in case it is something that should * be added to the high-level interface. * */ /** * A PKCS #7 SignedData structure. This class implements version 1 * of the spec. *

The certificates field should only contain X.509 certificates. * PKCS #6 extended certificates will fail to decode properly. * @author stevep * @author nicolson */ public class SignedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private INTEGER version; private SET digestAlgorithms; private ContentInfo contentInfo; private SET certificates; // [0] optional, may be null private SET crls; // [1] optional, may be null private SET signerInfos; // This class implements version 1 of the spec. private static final INTEGER VERSION = new INTEGER(1); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Accessor methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private static void verifyNotNull(Object obj) { if( obj == null ) { throw new IllegalArgumentException(); } } /** * Returns the version of this SignedData. The current version of the * spec is version 1. */ public INTEGER getVersion() { return version; } /** * Low-level function to set the version. * @param version Must not be null. public void setVersion(INTEGER version) { verifyNotNull(version); this.version = version; } */ /** * Returns the digest algorithms used by the signers to digest the * signed content. There may be more than one, if different signers * use different digesting algorithms. */ public SET getDigestAlgorithmIdentifiers() { return digestAlgorithms; } /** * Low-level function to set the digest algorithm identifiers. * @param digestAlgIds Must not be null. public void setDigestAlgorithmIdentifiers(SET digestAlgIds) { verifyNotNull(digestAlgIds); this.digestAlgorithms = digestAlgIds; } */ /** * Returns the ContentInfo containing the signed content. The simple * case is for the content to be of type data, although any * content type can be signed. */ public ContentInfo getContentInfo() { return contentInfo; } /** * Low-level function to set the contentInfo. * @param ci Must not be null. public void setContentInfo(ContentInfo ci) { verifyNotNull(ci); this.contentInfo = ci; } */ /** * Returns the certificates field, which is a SET of * X.509 certificates (org.mozilla.jss.pkix.cert.Certificate). * PKCS #6 Extended Certificates are not supported by this implementation. * Returns null if this optional field is not present. * */ public SET getCertificates() { return certificates; } /** * Low-level function to set the certificates. * @param certs May be null to signify that the certificates * field is not present. public void setCertificates(SET certs) { this.certificates = certs; } */ /** * Returns true if the certificates field is present. */ public boolean hasCertificates() { return (certificates!=null); } /** * Returns the crls field, which contains a SET of certificate * revocation lists represented by ANYs (org.mozilla.jss.asn1.ANY). * */ public SET getCrls() { return crls; } /** * Low-level function to set the crls. * @param certs May be null to signify that the crls * field is not present. public void setCrls(SET crls) { this.crls = crls; } */ /** * Returns true if the crls field is present. */ public boolean hasCrls() { return (crls != null); } /** * Returns the signerInfos field, which is a SET of * org.mozilla.jss.pkcs7.SignerInfo. */ public SET getSignerInfos() { return signerInfos; } /** * Low-level function to set the SignerInfos. * @param signerInfos Must not be null. public void setSignerInfos(SET signerInfos) { verifyNotNull(sis); this.signerInfos = signerInfos; } */ /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Low-level constructor that merely initializes all fields to null. private SignedData() {} */ /** * Create a SignedData ASN1 object. Both certificates and CRLs * are optional. If you pass in a null for either value, that * parameter will not get written in the sequence. * * @param digestAlgorithms A SET of zero or more * algorithm identifiers. The purpose of this item is to list * the digest algorithms used by the various signers to digest * the signed content. This field will also be updated by * the addSigner method. If all the signers are added * with addSigner, it is not necessary to list * the digest algorithms here. *

If null is passed in, the * digestAlgorithms field will be initialized * with an empty SET. * @param contentInfo The content that is being signed. This parameter * may not be null. However, the content * field of the contentInfo may be omitted, in which case the * signatures contained in the SignerInfo structures * are presumed to be on externally-supplied data. * @param certificates A SET of org.mozilla.jss.pkix.cert.Certificate, * the certificates * containing the public keys used to sign the content. It may * also contain elements of the CA chain extending from the leaf * certificates. It is not necessary to include the CA chain, or * indeed to include any certificates, if the certificates are * expected to already be possessed by the recipient. The recipient * can use the issuer and serial number in the SignerInfo structure * to search for the necessary certificates. If this parameter is * null, the certificates field will be * omitted. * @param crls A SET of ASN1Values, which should encode to the ASN1 type * CertificateRevocationList. This implementation does * not interpret CRLs. If this parameter is null, * the crls field will be omitted. * @param signerInfos SignerInfo structures containing signatures * of the content. Additional signerInfos can be added with * the addSigner method. If this parameter is * null, the field will be initialized with an * empty SET. */ public SignedData( SET digestAlgorithms, ContentInfo contentInfo, SET certificates, SET crls, SET signerInfos) { version = VERSION; if(digestAlgorithms == null ) { this.digestAlgorithms = new SET(); } else { this.digestAlgorithms = digestAlgorithms; } verifyNotNull(contentInfo); this.contentInfo = contentInfo; // certificates may be null this.certificates = certificates; // crls may be null this.crls = crls; if(signerInfos == null) { this.signerInfos = new SET(); } else { this.signerInfos = signerInfos; } } /** * Constructor for creating a SignedData from its encoding. */ SignedData( INTEGER version, SET digestAlgorithms, ContentInfo contentInfo, SET certificates, SET crls, SET signerInfos ) { verifyNotNull(version); this.version = version; verifyNotNull(digestAlgorithms); this.digestAlgorithms = digestAlgorithms; verifyNotNull(contentInfo); this.contentInfo = contentInfo; // certificates may be null this.certificates = certificates; // crls may be null this.crls = crls; verifyNotNull(signerInfos); this.signerInfos = signerInfos; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Cryptographic functions /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { SEQUENCE sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(digestAlgorithms); sequence.addElement(contentInfo); if( certificates != null ) { sequence.addElement( new Tag(0), certificates ); } if( crls != null ) { sequence.addElement( new Tag(1), crls ); } sequence.addElement(signerInfos); sequence.encode(tag,ostream); } /** * A template file for decoding a SignedData blob * */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); // version seqt.addElement(INTEGER.getTemplate()); // digestAlgorithms seqt.addElement(new SET.OF_Template( AlgorithmIdentifier.getTemplate())); // content info seqt.addElement(ContentInfo.getTemplate()); // [0] IMPLICIT certificates OPTIONAL seqt.addOptionalElement( new Tag(0), new SET.OF_Template(Certificate.getTemplate())); // [1] IMPLICIT CertificateRevocationLists OPTIONAL seqt.addOptionalElement( new Tag(1), new SET.OF_Template(ANY.getTemplate())); // signerInfos seqt.addElement(new SET.OF_Template(SignerInfo.getTemplate())); } 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 implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); assert(seq.size() == 6); return new SignedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (ContentInfo) seq.elementAt(2), (SET) seq.elementAt(3), (SET) seq.elementAt(4), (SET) seq.elementAt(5) ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkcs7/SignerInfo.java000066400000000000000000000754601362106420000213230ustar00rootroot00000000000000/* 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.pkcs7; import java.io.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.crypto.*; import java.security.InvalidKeyException; import java.security.SignatureException; import java.security.NoSuchAlgorithmException; import java.security.MessageDigest; import org.mozilla.jss.*; import java.security.PublicKey; /* * The high-level interface takes care of all * the logic and cryptography. If you need to use the low-level interface, * please let us know what you are using it for. Perhaps it should be part * of the high-level interface. */ /** * A PKCS #7 SignerInfo. */ public class SignerInfo implements ASN1Value { //////////////////////////////////////////////// // PKCS #9 attributes //////////////////////////////////////////////// private static final OBJECT_IDENTIFIER CONTENT_TYPE = OBJECT_IDENTIFIER.PKCS.subBranch(9).subBranch(3); private static final OBJECT_IDENTIFIER MESSAGE_DIGEST = OBJECT_IDENTIFIER.PKCS.subBranch(9).subBranch(4); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private INTEGER version; private IssuerAndSerialNumber issuerAndSerialNumber; private AlgorithmIdentifier digestAlgorithm; private SET authenticatedAttributes; // [0] OPTIONAL private AlgorithmIdentifier digestEncryptionAlgorithm; private OCTET_STRING encryptedDigest; private SET unauthenticatedAttributes; // [1] OPTIONAL // we only do version 1 of PKCS #7 private static final INTEGER VERSION = new INTEGER(1); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Accessor methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Retrieves the version number of this SignerInfo. */ public INTEGER getVersion() { return version; } /** * Low-level method to set the version. * It is not normally necessary to call this. Use it at your own risk. public void setVersion(INTEGER version) { this.version = version; } */ /** * Retrieves the issuer and serial number of the certificate whose * private key was used to sign the SignerInfo. */ public IssuerAndSerialNumber getIssuerAndSerialNumber() { return issuerAndSerialNumber; } /** * Low-level method to set the issuerAndSerialNumber. * It is not normally necessary to call this. Use it at your own risk. public void setIssuerAndSerialNumber( IssuerAndSerialNumber iasn ) { this.issuerAndSerialNumber = iasn; } */ /** * Retrieves the DigestAlgorithm used in this SignerInfo. * * @exception NoSuchAlgorithmException If the algorithm is not recognized * by JSS. */ public DigestAlgorithm getDigestAlgorithm() throws NoSuchAlgorithmException { return DigestAlgorithm.fromOID( digestAlgorithm.getOID() ); } /** * Retrieves the DigestAlgorithmIdentifier used in this SignerInfo. */ public AlgorithmIdentifier getDigestAlgorithmIdentifer() { return digestAlgorithm; } /** * Low-level method to set the digest AlgorithmIdentifier. * It is not normally necessary to call this. Use it at your own risk. public void setDigestAlgorithmIdentifier(AlgorithmIdentifier algid) { this.digestAlgorithm = algid; } */ /** * Retrieves the authenticated attributes, if they exist. * */ public SET getAuthenticatedAttributes() { return authenticatedAttributes; } /** * Returns true if the authenticatedAttributes field is present. */ public boolean hasAuthenticatedAttributes() { return (authenticatedAttributes != null); } /** * Low-level method to set the authenticatedAttributes field. * It is not normally necessary to call this. Use it at your own risk. public void setAuthenticatedAttributes(SET authAttrib) { this.authenticatedAttributes = authAttrib; } */ /** * Returns the raw signature (digest encryption) algorithm used in this * SignerInfo. * * @exception NoSuchAlgorithmException If the algorithm is not recognized * by JSS. */ public SignatureAlgorithm getDigestEncryptionAlgorithm() throws NoSuchAlgorithmException { return SignatureAlgorithm.fromOID( digestEncryptionAlgorithm.getOID() ); } /** * Returns the DigestEncryptionAlgorithmIdentifier used in this SignerInfo. */ public AlgorithmIdentifier getDigestEncryptionAlgorithmIdentifier() { return digestEncryptionAlgorithm; } /** * Low-level method to set the digestEncryptionAlgorithm field. * It is not normally necessary to call this. Use it at your own risk. public void setDigestEncryptionAlgorithmIdentifier(AlgorithmIdentifier algid) { this.digestEncryptionAlgorithm= algid; } */ /** * Retrieves the encrypted digest. */ public byte[] getEncryptedDigest() { return encryptedDigest.toByteArray(); } /** * Low-level method to set the encryptedDigest field. * It is not normally necessary to call this. Use it at your own risk. public void setEncryptedDigest(byte[] ed) { this.encryptedDigest = new OCTET_STRING(ed); } */ /** * Retrieves the unauthenticated attributes, if they exist. * */ public SET getUnauthenticatedAttributes() { return unauthenticatedAttributes; } /** * Returns true if the unauthenticatedAttributes field is present. */ public boolean hasUnauthenticatedAttributes() { return (unauthenticatedAttributes!=null); } /** * Low-level method to set the unauthenticatedAttributes field. * It is not normally necessary to call this. Use it at your own risk. public void setUnauthenticatedAttributes(SET unauthAttrib) { this.unauthenticatedAttributes = unauthAttrib; } */ /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Low-level default constructor. All fields are initialized to null. * Before this SignerInfo can be processed or used in any way, all of * the fields except authenticatedAttributes and * unauthenticatedAttributes must be non-null. *

It is not normally necessary to call this constructor.Use it at * your own risk. public SignerInfo() { } */ /** * A constructor for creating a new SignerInfo from scratch. * * @param issuerAndSerialNumber The issuer and serial number of the * certificate from which the public key was extracted to create * this SignerInfo. * @param signingAlg The algorithm to be used to sign the content. * This should be a composite algorithm, such as * RSASignatureWithMD5Digest, instead of a raw algorithm, such as * RSASignature. * Note that the digest portion of this algorithm must be the same * algorithm as was used to digest the message content. * @param authenticatedAttributes An optional set of Attributes, which * will be signed along with the message content. This parameter may * be null, or the SET may be empty. DO NOT insert * the PKCS #9 content-type or message-digest attributes. They will * be added automatically if they are necessary. * @param unauthenticatedAttributes An optional set of Attributes, which * will be included in the SignerInfo but not signed. This parameter * may be null, or the SET may be empty. * @param messageDigest The digest of the message contents. The digest * must have been created with the digest algorithm specified by * the signingAlg parameter. * @param contentType The type of the ContentInfo that is being signed. * If it is not data, then the PKCS #9 attributes * content-type and message-digest will be automatically computed and * added to the authenticated attributes. */ public SignerInfo( IssuerAndSerialNumber issuerAndSerialNumber, SET authenticatedAttributes, SET unauthenticatedAttributes, OBJECT_IDENTIFIER contentType, byte[] messageDigest, SignatureAlgorithm signingAlg, PrivateKey signingKey ) throws InvalidKeyException, NoSuchAlgorithmException, NotInitializedException, SignatureException, TokenException { version = VERSION; this.issuerAndSerialNumber = issuerAndSerialNumber; this.digestAlgorithm = new AlgorithmIdentifier(signingAlg.getDigestAlg().toOID(),null); // if content-type is not data, add message-digest and content-type // to authenticated attributes. if( ! contentType.equals(ContentInfo.DATA) ) { if( authenticatedAttributes == null ) { authenticatedAttributes = new SET(); } Attribute attrib = new Attribute(CONTENT_TYPE, ContentInfo.DATA); authenticatedAttributes.addElement(attrib); attrib = new Attribute(MESSAGE_DIGEST, new OCTET_STRING(messageDigest) ); authenticatedAttributes.addElement(attrib); } digestEncryptionAlgorithm = new AlgorithmIdentifier( signingAlg.getRawAlg().toOID(),null ); if( authenticatedAttributes != null ) { assert( authenticatedAttributes.size() >= 2 ); this.authenticatedAttributes = authenticatedAttributes; } ////////////////////////////////////////////////// // create encrypted digest (signature) ////////////////////////////////////////////////// // compute the digest byte[] digest=null; DigestAlgorithm digestAlg = signingAlg.getDigestAlg(); if( authenticatedAttributes == null ) { // just use the message digest of the content digest = messageDigest; } else { // digest the contents octets of the authenticated attributes byte[] enc = ASN1Util.encode(authenticatedAttributes); MessageDigest md = MessageDigest.getInstance(digestAlg.toString()); digest = md.digest( enc ); } byte[] toBeSigned; if( signingAlg.getRawAlg() == SignatureAlgorithm.RSASignature ) { // put the digest in a DigestInfo SEQUENCE digestInfo = new SEQUENCE(); AlgorithmIdentifier digestAlgId = new AlgorithmIdentifier( digestAlg.toOID(),null ); digestInfo.addElement( digestAlgId ); digestInfo.addElement( new OCTET_STRING( digest ) ); toBeSigned = ASN1Util.encode(digestInfo); } else { toBeSigned = digest; } // encrypt the DER-encoded DigestInfo with the private key CryptoToken token = signingKey.getOwningToken(); Signature sig; sig = token.getSignatureContext( signingAlg.getRawAlg() ); sig.initSign(signingKey); sig.update(toBeSigned); encryptedDigest = new OCTET_STRING(sig.sign()); if( unauthenticatedAttributes != null ) { this.unauthenticatedAttributes = unauthenticatedAttributes; } } /** * A constructor for creating a new SignerInfo from its decoding. */ SignerInfo( INTEGER version, IssuerAndSerialNumber issuerAndSerialNumber, AlgorithmIdentifier digestAlgorithm, SET authenticatedAttributes, AlgorithmIdentifier digestEncryptionAlgorithm, byte[] encryptedDigest, SET unauthenticatedAttributes) { this.version = version; this.issuerAndSerialNumber = issuerAndSerialNumber; this.digestAlgorithm = digestAlgorithm; this.authenticatedAttributes = authenticatedAttributes; this.digestEncryptionAlgorithm = digestEncryptionAlgorithm; this.encryptedDigest = new OCTET_STRING(encryptedDigest); this.unauthenticatedAttributes = unauthenticatedAttributes; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Verification /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Verifies that this SignerInfo contains a valid signature of the * given message digest. If any authenticated attributes are present, * they are also validated. The verification algorithm is as follows: * Note that this does not verify the validity of the * the certificate itself, only the signature.

    * *
  • If no authenticated attributes are present, the content type is * verified to be data. Then it is verified that the message * digest passed * in, when encrypted with the given public key, matches the encrypted * digest in the SignerInfo. * *
  • If authenticated attributes are present, * two particular attributes must be present:
      *
    • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
    • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
    * After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * authenticatedAttributes field. * *
* * @param messageDigest The hash of the content that is signed by this * SignerInfo. * @param contentType The type of the content that is signed by this * SignerInfo. * @exception ObjectNotFoundException If no certificate matching the * the issuer name and serial number can be found. */ public void verify(byte[] messageDigest, OBJECT_IDENTIFIER contentType) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException, ObjectNotFoundException { CryptoManager cm = CryptoManager.getInstance(); X509Certificate cert = cm.findCertByIssuerAndSerialNumber( ASN1Util.encode(issuerAndSerialNumber.getIssuer()), issuerAndSerialNumber.getSerialNumber() ); verify(messageDigest, contentType, cert.getPublicKey()); } /** * Verifies that this SignerInfo contains a valid signature of the * given message digest. If any authenticated attributes are present, * they are also validated. The verification algorithm is as follows:
    * *
  • If no authenticated attributes are present, the content type is * verified to be data. Then it is verified that the message * digest passed * in, when encrypted with the given public key, matches the encrypted * digest in the SignerInfo. * *
  • If authenticated attributes are present, * two particular attributes must be present:
      *
    • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
    • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
    * After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * authenticatedAttributes field. * *
* * @param messageDigest The hash of the content that is signed by this * SignerInfo. * @param contentType The type of the content that is signed by this * SignerInfo. * @param pubkey The public key to use to verify the signature. */ public void verify(byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { if( authenticatedAttributes == null ) { verifyWithoutAuthenticatedAttributes(messageDigest, contentType, pubkey); } else { verifyWithAuthenticatedAttributes(messageDigest, contentType, pubkey); } } /** * Verifies that the message digest passed in, when encrypted with the * given public key, matches the encrypted digest in the SignerInfo. */ private void verifyWithoutAuthenticatedAttributes (byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { if( ! contentType.equals(ContentInfo.DATA) ) { // only data can be signed this way. Everything else has // to go into authenticatedAttributes. throw new SignatureException( "Content-Type is not DATA, but there are"+ " no authenticated attributes"); } SignatureAlgorithm sigAlg = SignatureAlgorithm.fromOID( digestEncryptionAlgorithm.getOID() ); byte[] toBeVerified; if( sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature ) { // create DigestInfo structure SEQUENCE digestInfo = new SEQUENCE(); digestInfo.addElement( new AlgorithmIdentifier(digestAlgorithm.getOID(), null) ); digestInfo.addElement( new OCTET_STRING(messageDigest) ); toBeVerified = ASN1Util.encode(digestInfo); } else { toBeVerified = messageDigest; } CryptoToken token = CryptoManager.getInstance() .getInternalCryptoToken(); Signature sig = token.getSignatureContext(sigAlg); sig.initVerify(pubkey); sig.update(toBeVerified); if( sig.verify(encryptedDigest.toByteArray()) ) { return; // success } else { throw new SignatureException( "Encrypted message digest parameter does not "+ "match encrypted digest in SignerInfo"); } } /** * Verifies a SignerInfo with authenticated attributes. If authenticated * attributes are present, then two particular attributes must * be present:
    *
  • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
  • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
* After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * authenticatedAttributes field. */ private void verifyWithAuthenticatedAttributes (byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { int numAttrib = authenticatedAttributes.size(); if(numAttrib < 2) { throw new SignatureException( "At least two authenticated attributes must be present:"+ " content-type and message-digest"); } // go through the authenticated attributes, verifying the // interesting ones boolean foundContentType = false; boolean foundMessageDigest = false; for( int i = 0; i < numAttrib; i++ ) { if( ! (authenticatedAttributes.elementAt(i) instanceof Attribute)) { throw new SignatureException( "Element of authenticatedAttributes is not an Attribute"); } Attribute attrib = (Attribute) authenticatedAttributes.elementAt(i); if( attrib.getType().equals(CONTENT_TYPE) ) { // content-type. Compare with what was passed in. SET vals = attrib.getValues(); if( vals.size() != 1 ) { throw new SignatureException( "Content-Type attribute "+ " does not have exactly one value"); } ASN1Value val = vals.elementAt(0); OBJECT_IDENTIFIER ctype; try { if( val instanceof OBJECT_IDENTIFIER ) { ctype = (OBJECT_IDENTIFIER) val; } else if( val instanceof ANY ) { ctype = (OBJECT_IDENTIFIER) ((ANY)val).decodeWith( OBJECT_IDENTIFIER.getTemplate() ); } else { // what the heck is it? not what it's supposed to be throw new InvalidBERException( "Content-Type authenticated attribute has unexpected"+ " content type"); } } catch( InvalidBERException e ) { throw new SignatureException( "Content-Type authenticated attribute does not have "+ "OBJECT IDENTIFIER value"); } // compare the content type in the attribute to the // contentType parameter if( ! ctype.equals( contentType ) ) { throw new SignatureException( "Content-type in authenticated attributes does not "+ "match content-type being verified"); } // content type is A-OK foundContentType = true; } else if( attrib.getType().equals(MESSAGE_DIGEST) ) { SET vals = attrib.getValues(); if( vals.size() != 1 ) { throw new SignatureException( "Message-digest attribute does not have"+ " exactly one value"); } ASN1Value val = vals.elementAt(0); byte[] mdigest; try { if( val instanceof OCTET_STRING ) { mdigest = ((OCTET_STRING)val).toByteArray(); } else if( val instanceof ANY ) { OCTET_STRING os; os = (OCTET_STRING) ((ANY)val).decodeWith( OCTET_STRING.getTemplate() ); mdigest = os.toByteArray(); } else { // what the heck is it? not what it's supposed to be throw new InvalidBERException( "Content-Type authenticated attribute has unexpected"+ " content type"); } } catch( InvalidBERException e ) { throw new SignatureException( "Message-digest attribute does not"+ " have OCTET STRING value"); } // compare the message digest in the attribute to the // message digest being verified if( ! byteArraysAreSame(mdigest, messageDigest) ) { throw new SignatureException( "Message-digest attribute does not"+ " match message digest being verified"); } // message digest is A-OK foundMessageDigest = true; } // we don't care about other attributes } if( !foundContentType ) { throw new SignatureException( "Authenticated attributes does not contain"+ " PKCS #9 content-type attribute"); } if( !foundMessageDigest ) { throw new SignatureException( "Authenticate attributes does not contain"+ " PKCS #9 message-digest attribute"); } SignatureAlgorithm sigAlg = SignatureAlgorithm.fromOID(digestEncryptionAlgorithm.getOID()); // All the authenticated attributes are present and correct. // Now verify the signature. CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); Signature sig = token.getSignatureContext( sigAlg ); sig.initVerify(pubkey); // verify the contents octets of the DER encoded authenticated attribs byte[] toBeDigested; toBeDigested = ASN1Util.encode(authenticatedAttributes); MessageDigest md = MessageDigest.getInstance( DigestAlgorithm.fromOID(digestAlgorithm.getOID()).toString() ); byte[] digest = md.digest(toBeDigested); byte[] toBeVerified; if( sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature ) { // create DigestInfo structure SEQUENCE digestInfo = new SEQUENCE(); digestInfo.addElement( new AlgorithmIdentifier(digestAlgorithm.getOID(),null) ); digestInfo.addElement( new OCTET_STRING(digest) ); toBeVerified = ASN1Util.encode(digestInfo); } else { toBeVerified = digest; } sig.update( toBeVerified ); if( ! sig.verify(encryptedDigest.toByteArray()) ) { // signature is invalid throw new SignatureException("encryptedDigest was not the correct"+ " signature of the contents octets of the DER-encoded"+ " authenticated attributes"); } // SUCCESSFULLY VERIFIED } /** * Compares two non-null byte arrays. Returns true if they are identical, * false otherwise. */ private static boolean byteArraysAreSame(byte[] left, byte[] right) { assert(left!=null && right!=null); if( left.length != right.length ) { return false; } for(int i = 0 ; i < left.length ; i++ ) { if( left[i] != right[i] ) { return false; } } return true; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // DER-encoding /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { SEQUENCE sequence = new SEQUENCE(); sequence.addElement( version ); sequence.addElement( issuerAndSerialNumber ); sequence.addElement( digestAlgorithm ); if( authenticatedAttributes != null ) { sequence.addElement( new Tag(0), authenticatedAttributes ); } sequence.addElement( digestEncryptionAlgorithm ); sequence.addElement( encryptedDigest ); if( unauthenticatedAttributes != null ) { sequence.addElement( new Tag(1), unauthenticatedAttributes ); } sequence.encode(tag,ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding a SignerInfo blob * */ public static class Template implements ASN1Template { SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); // serial number seqt.addElement(INTEGER.getTemplate()); // vn // issuerAndSerialNumber seqt.addElement(IssuerAndSerialNumber.getTemplate()); // issuer + sernum // digestAlgorithm seqt.addElement(AlgorithmIdentifier.getTemplate()); // digest alg // authenticatedAttributes seqt.addOptionalElement( new Tag(0), new SET.OF_Template(Attribute.getTemplate())); // digestEncryptionAlgorithm seqt.addElement(AlgorithmIdentifier.getTemplate()); // dig encr alg // encryptedDigest seqt.addElement(OCTET_STRING.getTemplate()); // encr digest // unauthenticated attributes seqt.addOptionalElement( new Tag(1), new SET.OF_Template(Attribute.getTemplate())); } 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 implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); assert(seq.size() == 7); return new SignerInfo( (INTEGER) seq.elementAt(0), (IssuerAndSerialNumber) seq.elementAt(1), (AlgorithmIdentifier) seq.elementAt(2), (SET) seq.elementAt(3), (AlgorithmIdentifier) seq.elementAt(4), ((OCTET_STRING) seq.elementAt(5)).toByteArray(), (SET) seq.elementAt(6) ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkcs7/package.html000066400000000000000000000004321362106420000206610ustar00rootroot00000000000000 Creating and interpeting PKCS #7 blobs. jss-4.6.3/org/mozilla/jss/pkix/000077500000000000000000000000001362106420000163255ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkix/cert/000077500000000000000000000000001362106420000172625ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkix/cert/Certificate.java000066400000000000000000000301641362106420000223530ustar00rootroot00000000000000/* 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.pkix.cert; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.SignatureException; import java.security.cert.CertificateException; import java.util.Calendar; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.InvalidKeyFormatException; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.KeyPairGenerator; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.Signature; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.pkix.primitive.Name; /** * An X.509 signed certificate. */ public class Certificate implements ASN1Value { private CertificateInfo info; private byte[] infoEncoding; private byte[] signature; private AlgorithmIdentifier algId; SEQUENCE sequence; Certificate(CertificateInfo info, byte[] infoEncoding, AlgorithmIdentifier algId, byte[] signature) throws IOException { this.info = info; this.infoEncoding = infoEncoding; this.algId = algId; this.signature = signature; // bundle everything into a SEQUENCE sequence = new SEQUENCE(); sequence.addElement( info ); sequence.addElement( algId ); sequence.addElement( new BIT_STRING( signature, 0 ) ); } /** * Creates and signs an X.509 Certificate. * @param info A CertificateInfo (TBSCertificate), which specifies * the actual information of the certificate. * @param privKey The private key with which to sign the certificate. * @param signingAlg The algorithm to use to sign the certificate. * It must match the algorithm specified in the CertificateInfo. * @exception IOException If an error occurred while encoding the * certificate. * @exception NotInitializedException Because this * operation involves cryptography (signing), CryptoManager must * be initialized before calling it. * @exception TokenException If an error occurs on a PKCS #11 token. * @exception NoSuchAlgorithmException If the OID for the signing algorithm * cannot be located. * @exception CertificateException If the signing algorithm specified * as a parameter does not match the one in the certificate info. * @exception InvalidKeyException If the key does not match the signing * algorithm. * @exception SignatureException If an error occurs while signing the * certificate. */ public Certificate(CertificateInfo info, java.security.PrivateKey privKey, SignatureAlgorithm signingAlg) throws IOException, NotInitializedException, TokenException, NoSuchAlgorithmException, CertificateException, InvalidKeyException, SignatureException { // make sure key is a Ninja private key if( !(privKey instanceof PrivateKey) ) { throw new InvalidKeyException("Private Key is does not belong to"+ " this provider"); } PrivateKey priv = (PrivateKey)privKey; // create algId and compare to the one in the cert info if(signingAlg.getSigningAlg() == SignatureAlgorithm.RSASignature) { algId = new AlgorithmIdentifier( signingAlg.toOID(), null ); } else { algId = new AlgorithmIdentifier( signingAlg.toOID() ); } if( ! info.getSignatureAlgId().getOID().equals(algId.getOID()) ) { throw new CertificateException("Signing Algorithm does not match"+ " the one specified in the CertificateInfo"); } // encode the cert info this.info = info; infoEncoding = ASN1Util.encode(info); // sign the info encoding CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = priv.getOwningToken(); Signature sig = token.getSignatureContext(signingAlg); sig.initSign(priv); sig.update(infoEncoding); signature = sig.sign(); // bundle everything into a SEQUENCE sequence = new SEQUENCE(); sequence.addElement( info ); sequence.addElement( algId ); sequence.addElement( new BIT_STRING( signature, 0 ) ); } /** * Verifies the signature on this certificate. Does not indicate * that the certificate is valid at any specific time. */ public void verify() throws InvalidKeyException, NotInitializedException, NoSuchAlgorithmException, CertificateException, SignatureException, InvalidKeyFormatException { verify( info.getSubjectPublicKeyInfo().toPublicKey() ); } /** * Verifies the signature on this certificate, using the given public key. * Does not indicate the certificate is valid at any specific time. */ public void verify(PublicKey key) throws InvalidKeyException, NoSuchAlgorithmException, CertificateException, SignatureException { try { CryptoManager cm = CryptoManager.getInstance(); verify(key, cm.getInternalCryptoToken()); } catch( NotInitializedException e ) { throw new SignatureException("CryptoManager not initialized"); } } /** * Verifies the signature on this certificate, using the given public * key and CryptoToken. Does not indicate the certificate is valid at * any specific time. */ public void verify(PublicKey key, CryptoToken token) throws NoSuchAlgorithmException, CertificateException, SignatureException, InvalidKeyException { try { Signature sig = token.getSignatureContext( SignatureAlgorithm.fromOID( info.getSignatureAlgId().getOID() ) ); sig.initVerify(key); sig.update(infoEncoding); if( ! sig.verify(signature) ) { throw new CertificateException("Signature is invalid"); } } catch(TokenException e) { throw new SignatureException("PKCS #11 token error: " + e.getMessage()); } } /** * Returns the information (TBSCertificate) contained in this certificate. */ public CertificateInfo getInfo() { return info; } private 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.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( CertificateInfo.getTemplate() ); seqt.addElement( new ANY.Template() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( BIT_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); ANY infoAny = (ANY)seq.elementAt(0); byte[] infoEncoding = infoAny.getEncoded(); CertificateInfo info = (CertificateInfo) infoAny.decodeWith( CertificateInfo.getTemplate() ); // although signature is a bit string, all algorithms we use // will produce an octet string. BIT_STRING bs = (BIT_STRING) seq.elementAt(2); if( bs.getPadCount() != 0 ) { throw new InvalidBERException("signature does not fall into"+ " an integral number of bytes"); } byte[] signature = bs.getBits(); return new Certificate( info, infoEncoding, (AlgorithmIdentifier) seq.elementAt(1), signature ); } } public static void main(String argv[]) { try { if(argv.length > 2 || argv.length < 1) { System.out.println("Usage: Certificate []"); System.exit(0); } CryptoManager.initialize( argv[0] ); CryptoManager cm = CryptoManager.getInstance(); Certificate cert; // read in a cert FileInputStream fis = new FileInputStream(argv[1]); try (BufferedInputStream bis = new BufferedInputStream(fis)) { cert = (Certificate) Certificate.getTemplate().decode(bis); } CertificateInfo info = cert.getInfo(); info.print(System.out); //X509Certificate hardcore = cm.findCertByNickname("Hardcore"); //PublicKey key = hardcore.getPublicKey(); cert.verify(); System.out.println("verified"); FileOutputStream fos = new FileOutputStream("certinfo.der"); info.encode(fos); fos.close(); // make a new public key CryptoToken token = cm.getInternalKeyStorageToken(); KeyPairGenerator kpg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA); kpg.initialize(512); System.out.println("Generating a new key pair..."); KeyPair kp = kpg.genKeyPair(); System.out.println("Generated key pair"); // set the certificate's public key info.setSubjectPublicKeyInfo(kp.getPublic()); // increment serial number int newSerial = info.getSerialNumber().intValue() + 1; info.setSerialNumber( new INTEGER(newSerial) ); // make new Name Name name = new Name(); name.addCommonName("Stra\u00dfenverk\u00e4ufer 'R' Us"); name.addCountryName("US"); name.addOrganizationName("Some Corporation"); name.addOrganizationalUnitName("some org unit?"); name.addLocalityName("Silicon Valley"); name.addStateOrProvinceName("California"); info.setIssuer(name); info.setSubject(name); // set validity Calendar cal = Calendar.getInstance(); cal.set(1997, Calendar.APRIL, 1); info.setNotBefore( cal.getTime() ); cal.set(2010, Calendar.APRIL, 1); info.setNotAfter( cal.getTime() ); System.out.println("About to create a new cert..."); // create a new cert from this certinfo Certificate genCert = new Certificate(info, kp.getPrivate(), SignatureAlgorithm.RSASignatureWithMD5Digest); System.out.println("Created new cert"); genCert.verify(); System.out.println("Cert verifies!"); fos = new FileOutputStream("gencert.der"); genCert.encode(fos); fos.close(); } catch( Exception e ) { e.printStackTrace(); } } } jss-4.6.3/org/mozilla/jss/pkix/cert/CertificateInfo.java000066400000000000000000000401411362106420000231630ustar00rootroot00000000000000/* 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.pkix.cert; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.security.PublicKey; import java.security.cert.CertificateException; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.CHOICE; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.GeneralizedTime; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.asn1.TimeBase; import org.mozilla.jss.asn1.UTCTime; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.pkix.primitive.Name; import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo; import org.mozilla.jss.util.Assert; /** * A TBSCertificate (to-be-signed certificate), the actual information in * a certificate apart from the signature. */ public class CertificateInfo implements ASN1Value { /** * An X.509 Certificate version. */ public static class Version { private Version() { } private Version(int vers, String string) { versionNumber = vers; this.string = string; } int versionNumber; String string; public boolean equals(Object obj) { if(obj == null || !(obj instanceof Version)) { return false; } return ((Version)obj).versionNumber == versionNumber; } public int getNumber() { return versionNumber; } /** * Creates a version number from its numeric encoding. */ public static Version fromInt(int versionNum) throws InvalidBERException { if( versionNum == 0 ) { return v1; } else if( versionNum == 1) { return v2; } else if( versionNum == 2) { return v3; } else { throw new InvalidBERException("Unrecognized version number"); } } public String toString() { return string; } public static final Version v1 = new Version(0, "v1"); public static final Version v2 = new Version(1, "v2"); public static final Version v3 = new Version(2, "v3"); } public static final Version v1 = Version.v1; public static final Version v2 = Version.v2; public static final Version v3 = Version.v3; // the last year for using UTCTime static final int UTCTIME_CUTOFF_YEAR = 2049; private Version version = v1; private INTEGER serialNumber; private AlgorithmIdentifier signatureAlgId; private Name issuer; private Date notBefore; private Date notAfter; private Name subject; private SubjectPublicKeyInfo subjectPublicKeyInfo; private BIT_STRING issuerUniqueIdentifier; // may be null private BIT_STRING subjectUniqueIdentifier; // may be null private SEQUENCE extensions; // if no extensions, size() == 0. Never null. /** * Creates a CertificateInfo with the required fields. */ public CertificateInfo(Version version, INTEGER serialNumber, AlgorithmIdentifier signatureAlgId, Name issuer, Date notBefore, Date notAfter, Name subject, SubjectPublicKeyInfo subjectPublicKeyInfo) { setVersion(version); setSerialNumber(serialNumber); setSignatureAlgId(signatureAlgId); setIssuer(issuer); setNotBefore(notBefore); setNotAfter(notAfter); setSubject(subject); setSubjectPublicKeyInfo(subjectPublicKeyInfo); extensions = new SEQUENCE(); } public void setVersion(Version version) { verifyNotNull(version); this.version = version; } public Version getVersion() { return version; } public void setSerialNumber(INTEGER serialNumber) { verifyNotNull(serialNumber); this.serialNumber = serialNumber; } public INTEGER getSerialNumber() { return serialNumber; } public void setSignatureAlgId(AlgorithmIdentifier signatureAlgId) { verifyNotNull(signatureAlgId); this.signatureAlgId = signatureAlgId; } public AlgorithmIdentifier getSignatureAlgId() { return signatureAlgId; } public void setIssuer(Name issuer) { verifyNotNull(issuer); this.issuer = issuer; } public Name getIssuer() { return issuer; } public void setNotBefore(Date notBefore) { verifyNotNull(notBefore); this.notBefore = notBefore; } public Date getNotBefore() { return notBefore; } public void setNotAfter(Date notAfter) { verifyNotNull(notAfter); this.notAfter = notAfter; } public Date getNotAfter() { return notAfter; } public void setSubject(Name subject) { verifyNotNull(subject); this.subject = subject; } public Name getSubject() { return subject; } public void setSubjectPublicKeyInfo( SubjectPublicKeyInfo subjectPublicKeyInfo) { verifyNotNull(subjectPublicKeyInfo); this.subjectPublicKeyInfo = subjectPublicKeyInfo; } /** * Extracts the SubjectPublicKeyInfo from the given public key and * stores it in the CertificateInfo. * * @exception InvalidBERException If an error occurs decoding the * the information extracted from the public key. */ public void setSubjectPublicKeyInfo( PublicKey pubk ) throws InvalidBERException, IOException { verifyNotNull(pubk); setSubjectPublicKeyInfo( new SubjectPublicKeyInfo(pubk) ); } public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return subjectPublicKeyInfo; } /** * @exception CertificateException If the certificate is a v1 certificate. */ public void setIssuerUniqueIdentifier(BIT_STRING issuerUniqueIdentifier) throws CertificateException { if(version==v1) { throw new CertificateException("issuerUniqueIdentifier cannot"+ " be specified for v1 certificate"); } verifyNotNull(issuerUniqueIdentifier); this.issuerUniqueIdentifier = issuerUniqueIdentifier; } public boolean hasIssuerUniqueIdentifier() { return (issuerUniqueIdentifier!=null); } /** * Should only be called if this field is present. */ public BIT_STRING getIssuerUniqueIdentifier() { assert(issuerUniqueIdentifier != null); return issuerUniqueIdentifier; } /** * @exception CertificateException If the certificate is a v1 certificate. */ public void setSubjectUniqueIdentifier(BIT_STRING subjectUniqueIdentifier) throws CertificateException { if(version==v1) { throw new CertificateException("subjectUniqueIdentifier cannot"+ " be specified for v1 certificate"); } verifyNotNull(subjectUniqueIdentifier); this.subjectUniqueIdentifier = subjectUniqueIdentifier; } public boolean hasSubjectUniqueIdentifier() { return (subjectUniqueIdentifier!=null); } public BIT_STRING getSubjectUniqueIdentifier() { assert(subjectUniqueIdentifier != null); return subjectUniqueIdentifier; } public boolean hasExtensions() { return extensions.size() > 0; } /** * Returns the extensions of this certificate. The sequence may be * empty, but this method will never return null. */ public SEQUENCE getExtensions() { return extensions; } /** * Linearly searches the extension list for an extension with the given * object identifier. If it finds one, returns true. Otherwise, * returns false. */ public boolean isExtensionPresent(OBJECT_IDENTIFIER oid) { return ( getExtension(oid) != null ); } /** * Linearly searches the extension list for an extension with the given * object identifier. It returns the first one it finds. If none are found, * returns null. */ public Extension getExtension(OBJECT_IDENTIFIER oid) { int numExtensions = extensions.size(); for( int i=0; i < numExtensions; ++i) { Extension ext = (Extension) extensions.elementAt(i); if( oid.equals(ext.getExtnId()) ) { return ext; } } return null; } /** * @exception CertificateException If the certificate is not a v3 * certificate. */ public void setExtensions(SEQUENCE extensions) throws CertificateException { if(version != v3) { throw new CertificateException("extensions can only be added to"+ " v3 certificates"); } int size = extensions.size(); for(int i=0; i < size; i++) { assert(extensions.elementAt(i) instanceof Extension); } verifyNotNull(extensions); this.extensions = extensions; } /** * @exception CertificateException If the certificate is not a v3 * certificate. */ public void addExtension(Extension extension) throws CertificateException { if(version != v3) { throw new CertificateException("extensions can only be added to"+ " v3 certificates"); } extensions.addElement(extension); } private void verifyNotNull(Object obj) { if( obj == null ) { throw new NullPointerException(); } } 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(); if( version != v1 ) { // v1 is the default seq.addElement(new EXPLICIT( new Tag(0), new INTEGER(version.getNumber()) ) ); } seq.addElement(serialNumber); seq.addElement(signatureAlgId); seq.addElement(issuer); SEQUENCE validity = new SEQUENCE(); validity.addElement( encodeValidityDate(notBefore) ); validity.addElement( encodeValidityDate(notAfter) ); seq.addElement(validity); seq.addElement(subject); seq.addElement(subjectPublicKeyInfo); if( issuerUniqueIdentifier != null ) { seq.addElement(new Tag(1), issuerUniqueIdentifier); } if( subjectUniqueIdentifier != null ) { seq.addElement(new Tag(2), subjectUniqueIdentifier); } if( extensions.size() > 0 ) { seq.addElement(new EXPLICIT(new Tag(3), extensions) ); } seq.encode(implicitTag, ostream); } /** * Returns the correct ASN1Value (UTCTime or GeneralizedTime) to represent * the given certificate validity date. */ private static ASN1Value encodeValidityDate(Date d) { Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("GMT") ); cal.setTime(d); if( cal.get(Calendar.YEAR) <= UTCTIME_CUTOFF_YEAR) { return new UTCTime(d); } else { return new GeneralizedTime(d); } } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public void print(PrintStream ps) throws IOException, InvalidBERException { ps.println("CertificateInfo:"); ps.println("Version: "+version); ps.println("Serial Number: "+serialNumber); ps.println("Sig OID: "+signatureAlgId.getOID()); ps.println("Issuer: "+issuer.getRFC1485()); ps.println("Not Before: "+notBefore); ps.println("Not After: "+notAfter); ps.println("Subject: "+subject.getRFC1485()); } /** * Template class for decoding a CertificateInfo. */ public static class Template implements ASN1Template { SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); EXPLICIT.Template versionTemp = EXPLICIT.getTemplate( new Tag(0), INTEGER.getTemplate() ); EXPLICIT defVersion = new EXPLICIT(new Tag(0), new INTEGER(v1.getNumber()) ); seqt.addElement( versionTemp, defVersion ); seqt.addElement(INTEGER.getTemplate()); //serial number seqt.addElement(AlgorithmIdentifier.getTemplate()); //signatureAlgId seqt.addElement(Name.getTemplate()); // issuer // deal with validity SEQUENCE.Template validity = new SEQUENCE.Template(); CHOICE.Template timeChoice = CHOICE.getTemplate(); timeChoice.addElement( UTCTime.getTemplate() ); timeChoice.addElement( GeneralizedTime.getTemplate() ); validity.addElement( timeChoice ); // notBefore validity.addElement( timeChoice ); // notAfter seqt.addElement(validity); seqt.addElement(Name.getTemplate()); //subject seqt.addElement(SubjectPublicKeyInfo.getTemplate()); seqt.addOptionalElement( new Tag(1), BIT_STRING.getTemplate() ); seqt.addOptionalElement( new Tag(2), BIT_STRING.getTemplate() ); // deal with extensions SEQUENCE.OF_Template extnTemp = new SEQUENCE.OF_Template( Extension.getTemplate() ); seqt.addOptionalElement( new EXPLICIT.Template( new Tag(3), extnTemp) ); } 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 { try { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); EXPLICIT exp = (EXPLICIT) seq.elementAt(0); Version version = Version.fromInt( ((INTEGER)exp.getContent()).intValue() ); SEQUENCE validity = (SEQUENCE) seq.elementAt(4); CHOICE choice = (CHOICE)validity.elementAt(0); Date notBefore = ((TimeBase)choice.getValue()).toDate(); choice = (CHOICE)validity.elementAt(1); Date notAfter = ((TimeBase)choice.getValue()).toDate(); CertificateInfo cinfo = new CertificateInfo( version, (INTEGER) seq.elementAt(1), // serial num (AlgorithmIdentifier) seq.elementAt(2), //sigAlgId (Name) seq.elementAt(3), // issuer notBefore, notAfter, (Name) seq.elementAt(5), // subject (SubjectPublicKeyInfo) seq.elementAt(6) ); if( seq.elementAt(7) != null ) { cinfo.setIssuerUniqueIdentifier( (BIT_STRING)seq.elementAt(7) ); } if( seq.elementAt(8) != null ) { cinfo.setSubjectUniqueIdentifier( (BIT_STRING)seq.elementAt(8)); } if( seq.elementAt(9) != null ) { exp = (EXPLICIT)seq.elementAt(9); cinfo.setExtensions( (SEQUENCE) exp.getContent() ); } return cinfo; } catch( CertificateException e ) { throw new InvalidBERException(e.getMessage()); } } } } jss-4.6.3/org/mozilla/jss/pkix/cert/Extension.java000066400000000000000000000060221362106420000221010ustar00rootroot00000000000000/* 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.pkix.cert; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BOOLEAN; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; public class Extension implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private OBJECT_IDENTIFIER extnId; /** * Returns the extension identifier. */ public OBJECT_IDENTIFIER getExtnId() { return extnId; } private boolean critical; public boolean getCritical() { return critical; } private OCTET_STRING extnValue; public OCTET_STRING getExtnValue() { return extnValue; } public Extension( OBJECT_IDENTIFIER extnId, boolean critical, OCTET_STRING extnValue ) { this.extnId = extnId; this.critical = critical; this.extnValue = extnValue; } 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( extnId ); if( critical == true ) { // false is default, so we only code true seq.addElement( new BOOLEAN(true) ); } seq.addElement( extnValue ); seq.encode(implicit, 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( OBJECT_IDENTIFIER.getTemplate() ); seqt.addElement( BOOLEAN.getTemplate(), new BOOLEAN(false) ); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag t) { return TAG.equals(t); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); return new Extension( (OBJECT_IDENTIFIER) seq.elementAt(0), ((BOOLEAN) seq.elementAt(1)).toBoolean(), (OCTET_STRING) seq.elementAt(2) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cert/SubjectKeyIdentifier.java000066400000000000000000000060311362106420000242000ustar00rootroot00000000000000/* 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.pkix.cert; import java.io.IOException; import java.io.InputStream; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; /** * Represent the Subject Key Identifier Extension. * * This extension, if present, provides a means of identifying the particular * public key used in an application. This extension by default is marked * non-critical. * *

Extensions are additional attributes which can be inserted in a X509 * v3 certificate. For example a "Driving License Certificate" could have * the driving license number as a extension. * *

Extensions are represented as a sequence of the extension identifier * (Object Identifier), a boolean flag stating whether the extension is to * be treated as being critical and the extension value itself (this is again * a DER encoding of the extension value). * * @author Michelle Zhao * @version 1.0 * @see Extension */ public class SubjectKeyIdentifier extends Extension { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private OCTET_STRING keyIdentifier; private static OBJECT_IDENTIFIER OID = new OBJECT_IDENTIFIER("2.5.29.14"); /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// /** * Constructs an SubjectKeyIdentifier from its components. * * @param keyIdentifier must not be null. */ public SubjectKeyIdentifier(OCTET_STRING keyIdentifier) { super(OID,false,keyIdentifier); } public SubjectKeyIdentifier(boolean critical, OCTET_STRING keyIdentifier) { super(OID,critical,keyIdentifier); } public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OBJECT_IDENTIFIER.getTemplate() ); seqt.addElement( BOOLEAN.getTemplate(), new BOOLEAN(false) ); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag t) { return TAG.equals(t); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); assert( ((OBJECT_IDENTIFIER) seq.elementAt(0)).equals(OID) ); return new SubjectKeyIdentifier( ((BOOLEAN) seq.elementAt(1)).toBoolean(), (OCTET_STRING) seq.elementAt(2) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cert/package.html000066400000000000000000000004671362106420000215520ustar00rootroot00000000000000 Encoding and decoding X.509 certificates and certificate extensions. jss-4.6.3/org/mozilla/jss/pkix/cmc/000077500000000000000000000000001362106420000170675ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkix/cmc/BodyPartReference.java000066400000000000000000000147061362106420000233050ustar00rootroot00000000000000/* ***** 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 java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.CHOICE; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * CMC BodyPartReference: *

 *      BodyPartReference::= CHOICE {
 *          bodyPartID       BodyPartID
 *          bodyPartPath     SEQUENCE SIZE (1..MAX) OF BodyPartID,
 *     }
 *
 * @author Christina Fu (cfu)
 * 
*/ 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 /////////////////////////////////////////////////////////////////////// /** * @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(id1.compareTo(BODYIDMAX) <= 0); bodyPartPath.addElement( id1 ); } /////////////////////////////////////////////////////////////////////// // member access /////////////////////////////////////////////////////////////////////// /** * Returns the type of BodyPartReference:
    *
  • BodyPartID *
  • BodyPartPath *
*/ 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( type == BodyPartPath); return SEQUENCE.TAG; } } public void encode(OutputStream ostream) throws IOException { if (type == BodyPartID ) { bodyPartID.encode(ostream); } else { 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( 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); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/CMCCertId.java000066400000000000000000000121331362106420000214270ustar00rootroot00000000000000/* 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.pkix.cmc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * CMC CMCCertId. *
 * The definition of IssuerSerial comes from RFC 3281.
 * CMCCertId ::= SEQUENCE {
 *      issuer      GeneralNames,
 *      serial      INTEGER
 *      issuerUID   UniqueIdentifier OPTIONAL}
 * 
*/ public class CMCCertId implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private SEQUENCE issuer; private INTEGER serial; private BIT_STRING issuerUID; private SEQUENCE sequence; /** * Returns the issuer field as an SEQUENCE of * ANY. The actual type of the field is GeneralNames. */ public SEQUENCE getIssuer() { return issuer; } /** * Returns the serial field. */ public INTEGER getSerial() { return serial; } /** * Returns the issuerUID field. */ public BIT_STRING getIssuerUID() { return issuerUID; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Constructs a new CMCCertId from its components. The * uniqueIdentifier component may be null. */ public CMCCertId(SEQUENCE issuer, INTEGER serial, BIT_STRING issuerUID) { if (issuer == null || serial == null) { throw new IllegalArgumentException( "parameter to CMCCertId constructor is null"); } if (issuer.size() == 0) { throw new IllegalArgumentException( "issuer parameter to CMCCertId constructor is empty"); } sequence = new SEQUENCE(); this.issuer = issuer; sequence.addElement(issuer); this.serial = serial; sequence.addElement(serial); if (issuerUID != null) { sequence.addElement(issuerUID); } } /** * Constructs a new CMCCertId from its components. The * issuerUID component may be null. */ public CMCCertId(ANY issuer, INTEGER serial, BIT_STRING issuerUID) { if (issuer == null || serial == null) { throw new IllegalArgumentException( "parameter to CMCCertId constructor is null"); } sequence = new SEQUENCE(); this.issuer = new SEQUENCE(); this.issuer.addElement(issuer); sequence.addElement(this.issuer); this.serial = serial; sequence.addElement(serial); if (issuerUID != null) { sequence.addElement(issuerUID); } } /////////////////////////////////////////////////////////////////////// // 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 CMCCertId. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new SEQUENCE.OF_Template(ANY.getTemplate())); seqt.addElement( INTEGER.getTemplate() ); seqt.addOptionalElement(BIT_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 CMCCertId((SEQUENCE)seq.elementAt(0), (INTEGER)seq.elementAt(1), (BIT_STRING)seq.elementAt(2)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/CMCStatusInfo.java000066400000000000000000000150601362106420000223560ustar00rootroot00000000000000/* 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.pkix.cmc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.asn1.UTF8String; import org.mozilla.jss.util.Assert; /** * CMC CMCStatusInfo: *
 *     CMCStatusInfo ::= SEQUENCE {
 *          cMCStatus           CMCStatus,
 *          bodyList            SEQUENCE SIZE (1..MAX) OF BodyPartID,
 *          statusString        UTF8String OPTIONAL,
 *          otherInfo           CHOICE {
 *            failInfo            CMCFailInfo,
 *            pendInfo            PendInfo } OPTIONAL
 *     }
 *     PendInfo ::= SEQUENCE {
 *          pendToken           OCTET STRING,
 *          pendTime            GeneralizedTime
 *     }
 * 
*/ public class CMCStatusInfo 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 String[] STATUS = {"success", "reserved", "failed", "pending", "not supported", "confirm required"}; /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * @param status A CMCStatus constant. * @param bodyList The sequence of bodyPartID. */ public CMCStatusInfo(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 bodyPartID. * @param statusString A String. * @param otherInfo The OtherInfo choice. */ public CMCStatusInfo(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 CMCStatusInfo from decoding. * @param status A CMCStatus constant. * @param bodyList The sequence of bodyPartID. * @param statusString A UTF8String. * @param otherInfo A CHOICE. */ public CMCStatusInfo(INTEGER status, SEQUENCE bodyList, UTF8String statusString, OtherInfo otherInfo) { this.status = status; this.bodyList = bodyList; this.statusString = statusString; this.otherInfo = otherInfo; } /** * Sets the statusString 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(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 { CMCStatusInfo psi; SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new CMCStatusInfo((INTEGER)seq.elementAt(0), (SEQUENCE)seq.elementAt(1), (UTF8String)seq.elementAt(2), (OtherInfo)seq.elementAt(3)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/CMCStatusInfoV2.java000066400000000000000000000221631362106420000225700ustar00rootroot00000000000000/* ***** 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 java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.asn1.UTF8String; import org.mozilla.jss.util.Assert; /** * CMCStatusInfoV2 replaces CMCStatusInfo in rfc 5272 * CMC CMCStatusInfoV2: *
 *     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)
 * 
*/ 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 /////////////////////////////////////////////////////////////////////// /** * @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 statusString 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(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)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/DecryptedPOP.java000066400000000000000000000131751362106420000222430ustar00rootroot00000000000000/* ***** 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 java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; /** * CMC DecryptedPOP: *
 *     DecryptedPOP ::= SEQUENCE {
 *         bodyPartID      BodyPartID,
 *         thePOPAlgID     AlgorithmIdentifier,
 *         thePOP         OCTET STRING
 *     }
 * 
* * @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 bodyPartID field. */ public INTEGER getBodyPartID() { return bodyPartID; } public AlgorithmIdentifier getThePOPAlgID() { return thePOPAlgID; } public OCTET_STRING getWitness() { return thePOP; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// 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) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/EncryptedPOP.java000066400000000000000000000146121362106420000222520ustar00rootroot00000000000000/* ***** 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 java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.cms.ContentInfo; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; /** * CMC EncryptedPOP: *
 *     EncryptedPOP ::= SEQUENCE {
 *         request       TaggedRequest,
 *         cms             ContentInfo,
 *         thePOPAlgID     AlgorithmIdentifier,
 *         witnessAlgID    AlgorithmIdentifier,
 *         witness         OCTET STRING
 *     }
 * 
* * @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 /////////////////////////////////////////////////////////////////////// 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) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/ExtendedFailInfo.java000066400000000000000000000120041362106420000230770ustar00rootroot00000000000000/* ***** 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 java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * ExtendedFailInfo per rfc 5272 * It is to be used in CMCStatusInfoV2 as a CHOICE of otherInfo * *
 *      ExtendedFailInfo ::= SEQUENCE {
 *          failInfoOID        OBJECT IDENTIFIER,
 *          failInfoValue       ANY DEFINED BY failInfoOID }
 * 
* * @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; } 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 ) { throw new RuntimeException("InvalidBERException while decoding as ANY: " + e.getMessage(), e); } } } 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(seq.size() == 2); return new ExtendedFailInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/GetCert.java000066400000000000000000000073551362106420000213010ustar00rootroot00000000000000/* 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.pkix.cmc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * CMC GetCert. *
 * GetCert ::= SEQUENCE {
 *      issuerName      GeneralName,
 *      serialNumber    INTEGER }
 * 
*/ public class GetCert implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private ANY issuerName; private INTEGER serialNumber; private SEQUENCE sequence; /** * Returns the issuerName field as an ANY. * The actual type of the field is GeneralName. */ public ANY getIssuer() { return issuerName; } /** * Returns the serialNumber field. */ public INTEGER getSerialNumber() { return serialNumber; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Constructs a new GetCert from its components. Neither * component may be null. */ public GetCert(ANY issuerName, INTEGER serialNumber) { if( issuerName == null || serialNumber == null ) { throw new IllegalArgumentException( "parameter to GetCert constructor is null"); } sequence = new SEQUENCE(); this.issuerName = issuerName; sequence.addElement(issuerName); this.serialNumber = serialNumber; sequence.addElement(serialNumber); } /////////////////////////////////////////////////////////////////////// // 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 GetCert. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( ANY.getTemplate() ); seqt.addElement( INTEGER.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 GetCert( (ANY) seq.elementAt(0), (INTEGER) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/IdentityProofV2.java000066400000000000000000000131501362106420000227410ustar00rootroot00000000000000/* ***** 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 java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; /** * CMC IdentityProofV2: * per rfc 5272 *
 *     IdentityProofV2 ::= SEQUENCE {
 *         hashAlgID      AlgorithmIdentifier,
 *         macAlgId       AlgorithmIdentifier,
 *         witness        OCTET STRING
 *     }
 * 
* * @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 /////////////////////////////////////////////////////////////////////// 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) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/LraPopWitness.java000066400000000000000000000077761362106420000225250ustar00rootroot00000000000000/* 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.pkix.cmc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * CMC LraPopWitness: *
 *      LraPopWitness::= SEQUENCE {
 *          pkiDataBodyid       BodyPartID
 *          bodyids             SEQUENCE SIZE (1..MAX) OF BodyPartID,
 *     }
 * 
*/ public class LraPopWitness implements ASN1Value { public static final INTEGER BODYIDMAX = new INTEGER("4294967295"); /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private INTEGER pkiDataBodyid; private SEQUENCE bodyIds; private SEQUENCE sequence; /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * @param pkiDataBodyid A PKI data BodyPartID. * @param bodyIds The sequence of bodyPartIDs. */ public LraPopWitness(INTEGER pkiDataBodyid, SEQUENCE bodyIds) { if (pkiDataBodyid == null || bodyIds == null) throw new IllegalArgumentException( "parameter to LraPopWitness constructor is null"); sequence = new SEQUENCE(); this.pkiDataBodyid = pkiDataBodyid; sequence.addElement(pkiDataBodyid); this.bodyIds = bodyIds; sequence.addElement(bodyIds); } /** * Adds a BodyPartID to the bodyIds SEQUENCE. */ public void addBodyPartId(int id) { INTEGER id1 = new INTEGER(id); assert(id1.compareTo(BODYIDMAX) <= 0); bodyIds.addElement( id1 ); } /////////////////////////////////////////////////////////////////////// // member access /////////////////////////////////////////////////////////////////////// public INTEGER getPKIDataBodyid() { return pkiDataBodyid; } public SEQUENCE getBodyIds() { return bodyIds; } /////////////////////////////////////////////////////////////////////// // decoding/encoding /////////////////////////////////////////////////////////////////////// public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(TAG, 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; } 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()) ); } 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 LraPopWitness((INTEGER)seq.elementAt(0), (SEQUENCE)seq.elementAt(1)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/OtherInfo.java000066400000000000000000000213401362106420000216270ustar00rootroot00000000000000/* 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.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.util.Assert; /** * CMCStatusInfoV2 OtherInfo: * *
 *   OtherInfo ::= CHOICE { 
 *       failInfo INTEGER, 
 *       pendInfo PendInfo,
 *       extendedFailInfo       SEQUENCE {  // ExtendedFailInfo
 *           failInfoOID            OBJECT IDENTIFIER,
 *           failInfoValue          AttributeValue
 *       } OPTIONAL
 *   }
 * 
* * @author Christina Fu (cfu) - updated for rfc5272 */ public class OtherInfo implements ASN1Value { // CMCFailInfo constants public static final int BAD_ALG = 0; public static final int BAD_MESSAGE_CHECK = 1; public static final int BAD_REQUEST = 2; public static final int BAD_TIME = 3; public static final int BAD_CERT_ID = 4; public static final int UNSUPORTED_EXT = 5; public static final int MUST_ARCHIVE_KEYS = 6; public static final int BAD_IDENTITY = 7; public static final int POP_REQUIRED = 8; public static final int POP_FAILED = 9; 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", "authenticated data fail"}; /** * The type of OtherInfo. */ public static class Type { private Type() { } 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 /////////////////////////////////////////////////////////////////////// private Type type; private INTEGER failInfo; // if type == FAIL private PendInfo pendInfo; // if type == PEND private ExtendedFailInfo extendedFailInfo; // if type == EXTENDED /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// // 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( 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( 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; } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// /** * Returns the type of OtherInfo:
    *
  • FAIL *
  • PEND *
  • EXTENDED *
*/ public Type getType() { return type; } /** * If type == FAIL, returns the failInfo field. Otherwise, * returns null. */ public INTEGER getFailInfo() { return failInfo; } /** * If type == PEND, returns the pendInfo field. Otherwise, * returns null. */ public PendInfo getPendInfo() { 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 if( type == FAIL ) { return INTEGER.TAG; } else if( type == PEND ){ return PendInfo.TAG; } else { assert( type == EXTENDED ); return ExtendedFailInfo.TAG; } } public void encode(OutputStream ostream) throws IOException { if( type == FAIL ) { failInfo.encode(ostream); } else if( type == PEND ){ pendInfo.encode(ostream); } else { 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); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a OtherInfo. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); choicet.addElement( INTEGER.getTemplate() ); choicet.addElement( PendInfo.getTemplate() ); choicet.addElement( ExtendedFailInfo.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 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( 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); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/OtherMsg.java000066400000000000000000000103731362106420000214660ustar00rootroot00000000000000/* 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.pkix.cmc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * CMC OtherMsg. *
 * The definition of OtherMsg comes from RFC 2797.
 * OtherMsg ::= SEQUENCE {
 *      bodyPartID      BodyPartID,
 *      otherMsgType    Object Identifier,
 *      otherMsgValue   ANY defined by otherMsgType}
 * 
*/ public class OtherMsg implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private INTEGER bodyPartID; private OBJECT_IDENTIFIER otherMsgType; private ANY otherMsgValue; private SEQUENCE sequence; /** * Returns the bodyPartID field. */ public INTEGER getBodyPartID() { return bodyPartID; } /** * Returns the otherMsgType field. */ public OBJECT_IDENTIFIER getOtherMsgType() { return otherMsgType; } /** * Returns the otherMsgValue field. */ public ANY getOtherMsgValue() { return otherMsgValue; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Constructs a new OtherMsg from its components. */ public OtherMsg(INTEGER bodyPartID, OBJECT_IDENTIFIER otherMsgType, ANY otherMsgValue) { if (bodyPartID == null || otherMsgType == null || otherMsgValue == null) { throw new IllegalArgumentException( "parameter to OtherMsg constructor is null"); } sequence = new SEQUENCE(); this.bodyPartID = bodyPartID; sequence.addElement(bodyPartID); this.otherMsgType = otherMsgType; sequence.addElement(otherMsgType); this.otherMsgValue = otherMsgValue; sequence.addElement(otherMsgValue); } /////////////////////////////////////////////////////////////////////// // 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 OtherMsg. */ 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 OtherMsg((INTEGER)seq.elementAt(0), (OBJECT_IDENTIFIER)seq.elementAt(1), (ANY)seq.elementAt(2)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/OtherReqMsg.java000066400000000000000000000137211362106420000221360ustar00rootroot00000000000000/* ***** 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 java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * CMC OtherReqMsg. *
 * 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}
 * 
* * @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 bodyPartID field. */ public INTEGER getBodyPartID() { return bodyPartID; } /** * Returns the requestMessageType field. */ public OBJECT_IDENTIFIER getOtherReqMsgType() { return requestMessageType; } /** * Returns the requestMessageValue field. */ public ANY getOtherReqMsgValue() { return requestMessageValue; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Constructs a new OtherReqMsg 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 OtherReqMsg. */ 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)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/PKIData.java000066400000000000000000000114231362106420000211500ustar00rootroot00000000000000/* 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.pkix.cmc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * A PKIData for CMC full enrollment request. * PKIData ::= SEQUENCE { * controlSequence SEQUENCE SIZE(0..MAX) OF TaggedAttribute, * reqSequence SEQUENCE SIZE(0..MAX) OF TaggedRequest, * cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo, * otherMsgSequence SEQUENCE SIZE(0..MAX) OF OtherMsg * } */ public class PKIData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private SEQUENCE sequence; private SEQUENCE controlSequence; private SEQUENCE reqSequence; private SEQUENCE cmsSequence; private SEQUENCE otherMsgSequence; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// /** * Constructs a PKIData from its components. * * @param controlSequence Sequence of TagggedAttribute. * @param reqSequence Sequence of TagggedRequest. * @param cmsSequence Sequence of TagggedContentInfo. * @param otherMsgSequence Sequence of OtherMsg. */ public PKIData(SEQUENCE controlSequence, SEQUENCE reqSequence, SEQUENCE cmsSequence, SEQUENCE otherMsgSequence) { sequence = new SEQUENCE(); this.controlSequence = controlSequence; sequence.addElement(controlSequence); this.reqSequence = reqSequence; sequence.addElement(reqSequence); this.cmsSequence = cmsSequence; sequence.addElement(cmsSequence); this.otherMsgSequence = otherMsgSequence; sequence.addElement(otherMsgSequence); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public SEQUENCE getControlSequence() { return controlSequence; } public SEQUENCE getReqSequence() { return reqSequence; } public SEQUENCE getCmsSequence() { return cmsSequence; } public SEQUENCE getOtherMsgSequence() { return otherMsgSequence; } /////////////////////////////////////////////////////////////////////// // DER encoding/decoding /////////////////////////////////////////////////////////////////////// static 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.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding an PKIData from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new SEQUENCE.OF_Template(TaggedAttribute.getTemplate()) ); seqt.addElement( new SEQUENCE.OF_Template(TaggedRequest.getTemplate()) ); seqt.addElement( new SEQUENCE.OF_Template(new ANY.Template()) ); seqt.addElement( new SEQUENCE.OF_Template(new ANY.Template()) ); } 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); assert(seq.size() == 4); return new PKIData( (SEQUENCE) seq.elementAt(0), (SEQUENCE) seq.elementAt(1), (SEQUENCE) seq.elementAt(2), (SEQUENCE) seq.elementAt(3)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/PendInfo.java000066400000000000000000000104261362106420000214370ustar00rootroot00000000000000/* 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.pkix.cmc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Date; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.GeneralizedTime; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * CMC PendInfo: *
 *   PendInfo ::= SEQUENCE {
 *       pendToken            OCTET STRING,
 *       pendTime             GeneralizedTime
 *   }
 * 
*/ public class PendInfo implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private SEQUENCE sequence; private OCTET_STRING pendToken; private GeneralizedTime pendTime; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// /** * Constructs a PendInfo from its components. * * @param pendToken the identifier. * @param pendTime the suggested time for the client to query the status. */ public PendInfo(OCTET_STRING pendToken, GeneralizedTime pendTime) { sequence = new SEQUENCE(); this.pendToken = pendToken; sequence.addElement(pendToken); this.pendTime = pendTime; sequence.addElement(pendTime); } /** * Constructs a PendInfo from requestId and date. * * @param reqId the request Id * @param date the suggested time for the client to query the status. */ public PendInfo(String reqId, Date date) { sequence = new SEQUENCE(); this.pendToken = new OCTET_STRING(reqId.getBytes()); sequence.addElement(new OCTET_STRING(reqId.getBytes())); this.pendTime = new GeneralizedTime(date); sequence.addElement(new GeneralizedTime(date)); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public GeneralizedTime getPendTime() { return pendTime; } public OCTET_STRING getPendToken() { return pendToken; } /////////////////////////////////////////////////////////////////////// // DER encoding/decoding /////////////////////////////////////////////////////////////////////// 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.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding an PendInfo from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OCTET_STRING.getTemplate() ); seqt.addElement( GeneralizedTime.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); assert(seq.size() == 2); return new PendInfo( (OCTET_STRING) seq.elementAt(0), (GeneralizedTime) seq.elementAt(1)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/PopLinkWitnessV2.java000066400000000000000000000133101362106420000230710ustar00rootroot00000000000000/* ***** 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 java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; /** * CMC PopLinkWitnessV2: * per rfc 5272 *
 *     PopLinkWitnessV2 ::= SEQUENCE {
 *         keyGenAlgorithm     AlgorithmIdentifier,
 *         macAlgorithm       AlgorithmIdentifier,
 *         witness        OCTET STRING
 *     }
 * 
* * @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 /////////////////////////////////////////////////////////////////////// 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) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/ResponseBody.java000066400000000000000000000105171362106420000223520ustar00rootroot00000000000000/* 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.pkix.cmc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * A ResponseBody for CMC full enrollment request. * ResponseBody ::= SEQUENCE { * controlSequence SEQUENCE SIZE(0..MAX) OF TaggedAttribute, * cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo, * otherMsgSequence SEQUENCE SIZE(0..MAX) OF OtherMsg * } */ public class ResponseBody implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private SEQUENCE sequence; private SEQUENCE controlSequence; private SEQUENCE cmsSequence; private SEQUENCE otherMsgSequence; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// /** * Constructs a ResponseBody from its components. * * @param controlSequence Sequence of TagggedAttribute. * @param cmsSequence Sequence of TagggedContentInfo. * @param otherMsgSequence Sequence of OtherMsg. */ public ResponseBody(SEQUENCE controlSequence, SEQUENCE cmsSequence, SEQUENCE otherMsgSequence) { sequence = new SEQUENCE(); this.controlSequence = controlSequence; sequence.addElement(controlSequence); this.cmsSequence = cmsSequence; sequence.addElement(cmsSequence); this.otherMsgSequence = otherMsgSequence; sequence.addElement(otherMsgSequence); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public SEQUENCE getControlSequence() { return controlSequence; } public SEQUENCE getCmsSequence() { return cmsSequence; } public SEQUENCE getOtherMsgSequence() { return otherMsgSequence; } /////////////////////////////////////////////////////////////////////// // DER encoding/decoding /////////////////////////////////////////////////////////////////////// static 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.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding an ResponseBody from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new SEQUENCE.OF_Template(TaggedAttribute.getTemplate()) ); seqt.addElement(new SEQUENCE.OF_Template(ANY.getTemplate()) ); seqt.addElement(new SEQUENCE.OF_Template(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); assert(seq.size() == 3); return new ResponseBody( (SEQUENCE) seq.elementAt(0), (SEQUENCE) seq.elementAt(1), (SEQUENCE) seq.elementAt(2)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/RevokeRequest.java000066400000000000000000000272141362106420000225440ustar00rootroot00000000000000/* ***** 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 java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.ENUMERATED; import org.mozilla.jss.asn1.GeneralizedTime; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.asn1.UTF8String; /** * CMC RevokeRequest. *
 * RevokeRequest ::= SEQUENCE {
 *      issuerName      Name,
 *      serialNumber    INTEGER,
 *      reason          CRLReason,
 *      invalidityDate  GeneralizedTime OPTIONAL,
 *      passphrase    OCTET STRING OPTIONAL,
 *      comment         UTF8String OPTIONAL }
 * 
* * 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 CRLReason, which can be used in the reason * field. */ public static final ENUMERATED unspecified = new ENUMERATED(0); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED keyCompromise = new ENUMERATED(1); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED cACompromise = new ENUMERATED(2); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED affiliationChanged = new ENUMERATED(3); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED superseded = new ENUMERATED(4); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED cessationOfOperation = new ENUMERATED(5); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED certificateHold = new ENUMERATED(6); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED removeFromCRL = new ENUMERATED(8); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED privilegeWithdrawn = new ENUMERATED(9); /** * A CRLReason, which can be used in the reason * 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 issuerName field as an ANY. */ public ANY getIssuerName() { return issuerName; } /** * Returns the serialNumber field. */ public INTEGER getSerialNumber() { return serialNumber; } /** * Returns the reason field, which should indicate the * reason for the revocation. The currently supported reasons are: *
     * CRLReason ::= ENUMERATED {
     *      unspecified             (0),
     *      keyCompromise           (1),
     *      cACompromise            (2),
     *      affiliationChanged      (3),
     *      superseded              (4),
     *      cessationOfOperation    (5),
     *      certificateHold         (6),
     *      removeFromCRL           (8),
     *      privilegeWithdrawn      (9),
     *      aACompromise            (10) }
     * 
* These are all defined as constants in this class. */ public ENUMERATED getReason() { return reason; } /** * Returns the invalidityDate field. Returns null * if the field is not present. */ public GeneralizedTime getInvalidityDate() { return invalidityDate; } /** * Returns the passphrase field. Returns * null if the field is not present. */ public OCTET_STRING getSharedSecret() { return passphrase; } /** * Returns the comment field. Returns null * if the field is not present. */ public UTF8String getComment() { return comment; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Constructs a new RevokeRequest from its components, * omitting the invalidityDate field. * * @deprecated This constructor is obsolete now that * invalidityDate has been added to the class. * * @param issuerName The issuerName field. * @param serialNumber The serialNumber field. * @param reason The reason field. The constants defined * in this class may be used. * @param passphrase The passphrase field. This field is * optional, so null may be used. * @param comment The comment field. This field is optional, * so null may be used. */ @Deprecated public RevokeRequest(ANY issuerName, INTEGER serialNumber, ENUMERATED reason, OCTET_STRING passphrase, UTF8String comment) { this(issuerName, serialNumber, reason, null, passphrase, comment); } /** * Constructs a new RevokeRequest from its components. * * @param issuerName The issuerName field. * @param serialNumber The serialNumber field. * @param reason The reason 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 null may be * used. * @param passphrase The passphrase field. This field is * optional, so null may be used. * @param comment The comment field. This field is optional, * so null 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 RevokeRequest. */ 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) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/TaggedAttribute.java000066400000000000000000000112661362106420000230170ustar00rootroot00000000000000/* 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.pkix.cmc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * A tagged attribute, which has the following ASN.1 * definition : *
 *   TaggedAttribute ::= SEQUENCE {
 *      bodyPartID         BodyPartId,
 *      attrType           OBJECT IDENTIFIER,
 *      attrValues         SET OF AttributeValue
 *   bodyIdMax INTEGER ::= 4294967295
 *
 *   BodyPartID ::= INTEGER(0..bodyIdMax)
 * 
*/ public class TaggedAttribute implements ASN1Value { public static final INTEGER BODYIDMAX = new INTEGER("4294967295"); /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private SEQUENCE sequence; private INTEGER bodyPartID; private OBJECT_IDENTIFIER type; private SET values; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// public TaggedAttribute(INTEGER bodyPartID, OBJECT_IDENTIFIER type, SET values) { sequence = new SEQUENCE(); assert(bodyPartID.compareTo(BODYIDMAX) <= 0); this.bodyPartID = bodyPartID; sequence.addElement(bodyPartID); this.type = type; sequence.addElement(type); this.values = values; sequence.addElement(values); } public TaggedAttribute(INTEGER bodyPartID, OBJECT_IDENTIFIER type, ASN1Value value) { sequence = new SEQUENCE(); assert(bodyPartID.compareTo(BODYIDMAX) <= 0); this.bodyPartID = bodyPartID; sequence.addElement(bodyPartID); this.type = type; sequence.addElement(type); this.values = new SET(); values.addElement(value); sequence.addElement(values); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public INTEGER getBodyPartID() { return bodyPartID; } public OBJECT_IDENTIFIER getType() { return type; } /** * If this AVA was constructed, returns the SET of ASN1Values passed to the * constructor. If this Attribute was decoded with an Attribute.Template, * returns a SET of ANYs. */ public SET getValues() { return values; } /////////////////////////////////////////////////////////////////////// // DER encoding/decoding /////////////////////////////////////////////////////////////////////// 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 implicit, OutputStream ostream) throws IOException { sequence.encode(implicit, ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A Template for decoding an Attribute. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( new OBJECT_IDENTIFIER.Template() ); seqt.addElement( new SET.OF_Template(new ANY.Template())); } 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 seq = (SEQUENCE) seqt.decode(implicit, istream); // The template should have enforced this assert(seq.size() == 3); return new TaggedAttribute( (INTEGER) seq.elementAt(0), (OBJECT_IDENTIFIER) seq.elementAt(1), (SET) seq.elementAt(2)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/TaggedCertificationRequest.java000066400000000000000000000102371362106420000252050ustar00rootroot00000000000000/* 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.pkix.cmc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkcs10.CertificationRequest; import org.mozilla.jss.util.Assert; /** * CMC TaggedCertificationRequest: *
 *   TaggedCertificationRequest ::= SEQUENCE {
 *       bodyPartID            BodyPartID,
 *       certificationRequest  CertificationRequest
 *   }
 *   bodyIdMax INTEGER ::= 4294967295
 *
 *   BodyPartID ::= INTEGER(0..bodyIdMax)
 * 
*/ public class TaggedCertificationRequest implements ASN1Value { public static final INTEGER BODYIDMAX = new INTEGER("4294967295"); /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private SEQUENCE sequence; private INTEGER bodyPartID; private CertificationRequest certificationRequest; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// /** * Constructs a TaggedCertificationRequest from its components. * * @param bodyPartID the identifier. * @param certificationRequest the pkcs10 request. */ public TaggedCertificationRequest(INTEGER bodyPartID, CertificationRequest certificationRequest) { sequence = new SEQUENCE(); assert(bodyPartID.compareTo(BODYIDMAX) <= 0); this.bodyPartID = bodyPartID; sequence.addElement(bodyPartID); this.certificationRequest = certificationRequest; sequence.addElement(certificationRequest); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public CertificationRequest getCertificationRequest() { return certificationRequest; } public INTEGER getBodyPartID() { return bodyPartID; } /////////////////////////////////////////////////////////////////////// // DER encoding/decoding /////////////////////////////////////////////////////////////////////// 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.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding an TaggedCertificationRequest from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( CertificationRequest.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); assert(seq.size() == 2); return new TaggedCertificationRequest( (INTEGER) seq.elementAt(0), (CertificationRequest) seq.elementAt(1)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/TaggedContentInfo.java000066400000000000000000000074471362106420000233100ustar00rootroot00000000000000/* 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.pkix.cmc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.cms.ContentInfo; /** * CMC TaggedContentInfo. *
 * The definition of TaggedContentInfo comes from RFC 2797 Section 3.6.
 * TaggedContentInfo ::= SEQUENCE {
 *      bodyPartID      BodyPartID,
 *      contentInfo     ContentInfo}
 * 
*/ public class TaggedContentInfo implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private INTEGER bodyPartID; private ContentInfo contentInfo; private SEQUENCE sequence; /** * Returns the bodyPartID field. */ public INTEGER getBodyPartID() { return bodyPartID; } /** * Returns the contentInfo field. */ public ContentInfo getContentInfo() { return contentInfo; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Constructs a new TaggedContentInfo from its components. */ public TaggedContentInfo(INTEGER bodyPartID, ContentInfo contentInfo) { if (bodyPartID == null || contentInfo == null) { throw new IllegalArgumentException( "parameter to TaggedContentInfo constructor is null"); } sequence = new SEQUENCE(); this.bodyPartID = bodyPartID; sequence.addElement(bodyPartID); this.contentInfo = contentInfo; sequence.addElement(contentInfo); } /////////////////////////////////////////////////////////////////////// // 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 TaggedContentInfo. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(INTEGER.getTemplate()); seqt.addElement(ContentInfo.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 TaggedContentInfo((INTEGER)seq.elementAt(0), (ContentInfo)seq.elementAt(1)); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/TaggedRequest.java000066400000000000000000000171341362106420000225040ustar00rootroot00000000000000/* 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.pkix.cmc; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.crmf.*; import java.io.*; import org.mozilla.jss.util.Assert; /** * CMC TaggedRequest: *
 *   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
 *   } 
 * 
*/ public class TaggedRequest implements ASN1Value { /** * The type of TaggedRequest. */ public static class Type { private Type() { } 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 /////////////////////////////////////////////////////////////////////// private Type type; private TaggedCertificationRequest tcr; // if type == PKCS10 private CertReqMsg crm; // if type == CRMF private OtherReqMsg orm; // if type == OTHER /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// // no default constructor public TaggedRequest() { } /** * 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. */ public TaggedRequest(Type type, TaggedCertificationRequest tcr, CertReqMsg crm) { this.type = type; this.tcr = tcr; 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 /////////////////////////////////////////////////////////////////////// /** * Returns the type of TaggedRequest:
    *
  • PKCS10 *
  • CRMF *
  • OTHER *
*/ public Type getType() { return type; } /** * If type == PKCS10, returns the tcr field. Otherwise, * returns null. */ public TaggedCertificationRequest getTcr() { return tcr; } /** * If type == CRMF, returns the crm field. Otherwise, * returns null. */ public CertReqMsg getCrm() { return crm; } /** * If type == OTHER, returns the orm field. Otherwise, * returns null. */ public OtherReqMsg getOrm() { return orm; } /////////////////////////////////////////////////////////////////////// // DER decoding/encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { if( type == PKCS10 ) { return Tag.get(0); } else if( type == CRMF ){ return Tag.get(1); } else { assert( type == OTHER ); return Tag.get(2); } } public void encode(OutputStream ostream) throws IOException { if( type == PKCS10 ) { tcr.encode(Tag.get(0), ostream); // a CHOICE must be explicitly tagged //EXPLICIT e = new EXPLICIT( Tag.get(0), tcr ); //e.encode(ostream); } 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( 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); } } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { //Assert.notReached("A CHOICE cannot be implicitly tagged " +implicitTag.getNum()); //tagAt() of SET.java actually returns the underlying type encode(ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a ProofOfPossession. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); //EXPLICIT.Template et = new EXPLICIT.Template( // Tag.get(0), TaggedCertificationRequest.getTemplate() ); //choicet.addElement( et ); choicet.addElement( Tag.get(0), TaggedCertificationRequest.getTemplate() ); //et = new EXPLICIT.Template( // Tag.get(1), CertReqMsg.getTemplate() ); //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) { return choicet.tagMatch(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { CHOICE c = (CHOICE) choicet.decode(istream); if( c.getTag().equals(Tag.get(0)) ) { //EXPLICIT e = (EXPLICIT) c.getValue(); //return new TaggedRequest(PKCS10, // (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( c.getTag().equals(Tag.get(2)) ); //EXPLICIT e = (EXPLICIT) c.getValue(); //return new TaggedRequest(OTHER, null, // (CertReqMsg) e.getContent() ); return new TaggedRequest(OTHER, null, null, (OtherReqMsg) c.getValue()); } } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { //Assert.notReached("A CHOICE cannot be implicitly tagged"); return decode(istream); } } } jss-4.6.3/org/mozilla/jss/pkix/cmc/package.html000066400000000000000000000004261362106420000213520ustar00rootroot00000000000000 Creating and interpeting CMC blobs. jss-4.6.3/org/mozilla/jss/pkix/cmmf/000077500000000000000000000000001362106420000172475ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkix/cmmf/CertOrEncCert.java000066400000000000000000000026731362106420000225640ustar00rootroot00000000000000/* 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.pkix.cmmf; import org.mozilla.jss.asn1.*; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.util.Assert; import java.io.ByteArrayOutputStream; public class CertOrEncCert implements ASN1Value { private ANY certificate; byte[] encoding; /** * @exception InvalidBERException If the certificate is not a valid * BER-encoding. */ public CertOrEncCert(byte[] encodedCert) throws IOException, InvalidBERException { certificate = new ANY( new Tag(0), encodedCert ); ByteArrayOutputStream bos = new ByteArrayOutputStream(); certificate.encodeWithAlternateTag(new Tag(0), bos); encoding = bos.toByteArray(); } public static final Tag TAG = new Tag(0); public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { ostream.write(encoding); } /** * @param implicitTag This parameter is ignored, because a CHOICE * cannot have an implicit tag. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { assert( implicitTag.equals(TAG) ); ostream.write(encoding); } } jss-4.6.3/org/mozilla/jss/pkix/cmmf/CertRepContent.java000066400000000000000000000112101362106420000230040ustar00rootroot00000000000000/* 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.pkix.cmmf; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * A CMMF CertRepContent. *
 * CertRepContent ::= SEQUENCE {
 *      caPubs      [1] SEQUENCE SIZE (1..MAX) OF Certificate OPTIONAL,
 *      response    SEQUENCE of CertResponse }
 * 
* @see org.mozilla.jss.pkix.cmmf.CertResponse */ public class CertRepContent implements ASN1Value { private byte[][] caPubs; // may be null private SEQUENCE response; /** * Creates a new CertRepContent. * * @param caPubs An array of DER-encoded X.509 Certificates. It may be * null if the caPubs field is to be omitted. * @param response A SEQUENCE of CertResponse objects. * Must not be null. */ public CertRepContent(byte[][] caPubs, SEQUENCE response) { this.caPubs = caPubs; this.response = response; } /** * Creates a new CertRepContent. The responses can be * added later with addCertResponse. * * @param caPubs An array of DER-encoded X.509 Certificates, must not * be null and must have at least one element. */ public CertRepContent(byte[][] caPubs) { this.caPubs = caPubs; response = new SEQUENCE(); } /** * Creates a new CertRepContent * * @param response A SEQUENCE of CertResponse objects. * Must not be null. */ public CertRepContent(SEQUENCE response) { this.caPubs = null; this.response = response; } /** * Adds another CertResponse. */ public void addCertResponse(CertResponse resp) { response.addElement(resp); } /** * Returns the caPubs field, which is an array of * DER-encoded X.509 Certificates. May return null if the * field is not present. */ public byte[][] getCaPubs() { return caPubs; } /** * Returns the response field, which is a SEQUENCE * of CertResponse */ public SEQUENCE getResponse() { return response; } 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 encoding = new SEQUENCE(); // create sequence of certificates if(caPubs != null) { SEQUENCE certs = new SEQUENCE(); for(int i = 0; i < caPubs.length; i++) { certs.addElement( new ANY( SEQUENCE.TAG, caPubs[i] ) ); } encoding.addElement( new Tag(1), certs ); } encoding.addElement( response ); encoding.encode(implicitTag, ostream); } public static void main(String argv[]) { if(argv.length != 2) { System.out.println("Usage: CertRepContent "); System.out.println("certfile should contain a DER-encoded X.509 "+ "certificate"); System.exit(-1); } try (FileInputStream certfile = new FileInputStream(argv[0]); FileOutputStream fos = new FileOutputStream(argv[1])) { byte[][] certs = new byte[2][]; certs[0] = new byte[ certfile.available() ]; certfile.read(certs[0]); certs[1] = certs[0]; PKIStatusInfo status = new PKIStatusInfo(PKIStatusInfo.rejection, PKIStatusInfo.badRequest | PKIStatusInfo.badTime ); status.addFreeText("And your mother dresses you funny"); status.addFreeText("so there"); CertifiedKeyPair ckp = new CertifiedKeyPair( new CertOrEncCert( certs[0] ) ); CertResponse resp = new CertResponse( new INTEGER(54), status, ckp); CertRepContent content = new CertRepContent(certs); content.addCertResponse(resp); content.encode(fos); System.out.println("Success!"); } catch( Exception e ) { e.printStackTrace(); } } } jss-4.6.3/org/mozilla/jss/pkix/cmmf/CertResponse.java000066400000000000000000000041461362106420000225330ustar00rootroot00000000000000/* 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.pkix.cmmf; import java.io.IOException; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; public class CertResponse implements ASN1Value { private INTEGER certReqId; private PKIStatusInfo status; private CertifiedKeyPair certifiedKeyPair; public CertResponse(INTEGER certReqId, PKIStatusInfo status) { this.certReqId = certReqId; this.status = status; } public CertResponse(INTEGER certReqId, PKIStatusInfo status, CertifiedKeyPair certifiedKeyPair) { this(certReqId, status); this.certifiedKeyPair = certifiedKeyPair; } public INTEGER getCertReqId() { return certReqId; } public PKIStatusInfo getPKIStatusInfo() { return status; } /** * Returns true if the certifiedKeyPair field is present. */ public boolean hasCertifiedKeyPair() { return (certifiedKeyPair != null); } /** * Returns the optional certified key pair. Should only be called if * the certifiedKeyPair field is present. */ public CertifiedKeyPair getCertifiedKeyPair() { assert(certifiedKeyPair!=null); return certifiedKeyPair; } 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( certReqId ); seq.addElement( status ); if( certifiedKeyPair != null ) { seq.addElement( certifiedKeyPair ); } seq.encode(implicitTag, ostream); } } jss-4.6.3/org/mozilla/jss/pkix/cmmf/CertifiedKeyPair.java000066400000000000000000000017061362106420000233010ustar00rootroot00000000000000/* 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.pkix.cmmf; import org.mozilla.jss.asn1.*; import java.io.OutputStream; import java.io.IOException; public class CertifiedKeyPair implements ASN1Value { private CertOrEncCert certOrEncCert; public CertifiedKeyPair(CertOrEncCert certOrEncCert) { this.certOrEncCert = certOrEncCert; } 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( certOrEncCert ); seq.encode(implicitTag, ostream); } } jss-4.6.3/org/mozilla/jss/pkix/cmmf/GetCRL.java000066400000000000000000000144411362106420000211760ustar00rootroot00000000000000/* 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.pkix.cmmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.GeneralizedTime; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * CMMF GetCRL. *
 * GetCRL ::= SEQUENCE {
 *      issuerName      Name,
 *      cRLName         GeneralName OPTIONAL,
 *      time            GeneralizedTime OPTIONAL,
 *      reasons         ReasonFlags OPTIONAL }
 * 
*/ public class GetCRL implements ASN1Value { /////////////////////////////////////////////////////////////////////// // constants /////////////////////////////////////////////////////////////////////// /** * A bit position in a ReasonFlags bit string. */ public static final int unused = 0; /** * A bit position in a ReasonFlags bit string. */ public static final int keyCompromise = 1; /** * A bit position in a ReasonFlags bit string. */ public static final int cACompromise = 2; /** * A bit position in a ReasonFlags bit string. */ public static final int affiliationChanged = 3; /** * A bit position in a ReasonFlags bit string. */ public static final int superseded = 4; /** * A bit position in a ReasonFlags bit string. */ public static final int cessationOfOperation = 5; /** * A bit position in a ReasonFlags bit string. */ public static final int certificateHold = 6; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private ANY issuerName; private ANY cRLName; // may be null private GeneralizedTime time; // may be null private BIT_STRING reasons; // may be null private SEQUENCE sequence; /** * Returns the issuerName field. */ public ANY getIssuerName() { return issuerName; } /** * Returns the cRLName field, which may be null. */ public ANY getCRLName() { return cRLName; } /** * Returns the time field, which may be null. */ public GeneralizedTime getTime() { return time; } /** * Returns the reasons field, which may be null. */ public BIT_STRING getReasons() { return reasons; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Constructs a GetCRL from its components. * * @param issuerName The issuer name of the CRL. This should be an ASN.1 * Name. * @param cRLName The name of the CRL, which may be null. * This should be an ASN.1 GeneralName. * @param time The time of the CRL, which may be null. * @param reasons Can be used to specify from among CRLs partitioned * by revocation reason. The BIT_STRING can be created from a * Java BitSet. The positions in the BitSet should be set or cleared * using the constants provided in this class. */ public GetCRL( ANY issuerName, ANY cRLName, GeneralizedTime time, BIT_STRING reasons ) { if( issuerName == null ) { throw new IllegalArgumentException( "issuerName parameter to GetCRL constructor is null"); } sequence = new SEQUENCE(); this.issuerName = issuerName; sequence.addElement(issuerName); this.cRLName = cRLName; sequence.addElement(cRLName); this.time = time; sequence.addElement(time); // Remove trailing zeroes in this bit string because it contains // flags. this.reasons = reasons; reasons.setRemoveTrailingZeroes(true); sequence.addElement(reasons); } /////////////////////////////////////////////////////////////////////// // 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 GetCRL. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( ANY.getTemplate() ); seqt.addOptionalElement( ANY.getTemplate() ); seqt.addOptionalElement( GeneralizedTime.getTemplate() ); seqt.addOptionalElement( BIT_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 GetCRL( (ANY) seq.elementAt(0), (ANY) seq.elementAt(1), (GeneralizedTime) seq.elementAt(2), (BIT_STRING) seq.elementAt(3) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cmmf/IssuerAndSubject.java000066400000000000000000000077161362106420000233420ustar00rootroot00000000000000/* 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.pkix.cmmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * CMMF IssuerAndSubject. *
 * IssuerAndSubject ::= SEQUENCE {
 *      issuer          Name,
 *      subject         Name,
 *      certReqId       INTEGER OPTIONAL }
 * 
*/ public class IssuerAndSubject implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private ANY issuer; private ANY subject; private INTEGER certReqId; // may be null private SEQUENCE sequence; /** * Returns the issuer field. */ public ANY getIssuer() { return issuer; } /** * Returns the subject field. */ public ANY getSubject() { return subject; } /** * Returns the certReqId field, which may be null. */ public INTEGER getCertReqId() { return certReqId; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// public IssuerAndSubject(ANY issuer, ANY subject, INTEGER certReqId) { if( issuer==null || subject==null ) { throw new IllegalArgumentException( "parameter to IssuerAndSubject constructor is null"); } sequence = new SEQUENCE(); this.issuer = issuer; sequence.addElement(issuer); this.subject = subject; sequence.addElement(subject); this.certReqId = certReqId; sequence.addElement(certReqId); } /////////////////////////////////////////////////////////////////////// // 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 an IssuerAndSubject. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( ANY.getTemplate() ); seqt.addElement( ANY.getTemplate() ); seqt.addOptionalElement( INTEGER.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 IssuerAndSubject( (ANY) seq.elementAt(0), (ANY) seq.elementAt(1), (INTEGER) seq.elementAt(2) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cmmf/PKIStatusInfo.java000066400000000000000000000133501362106420000225570ustar00rootroot00000000000000/* 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.pkix.cmmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.BitSet; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.asn1.UTF8String; public class PKIStatusInfo implements ASN1Value { private INTEGER status; private SEQUENCE statusString; private int failInfo; // bitwise AND private boolean hasFailInfo; // PKIStatus constants public static final int granted = 0; public static final int grantedWithMods = 1; public static final int rejection = 2; public static final int waiting = 3; public static final int revocationWarning = 4; public static final int revocationNotification = 5; public static final int keyUpdateWarning = 6; // PKIFailureInfo constants // The bit string encoded in four bytes, big-endian, bit 0 is MSB. public static final int badAlg = 0x80000000; public static final int badMessageCheck = 0x40000000; public static final int badRequest = 0x20000000; public static final int badTime = 0x10000000; public static final int badCertId = 0x08000000; public static final int badDataFormat = 0x04000000; public static final int wrongAuthority = 0x02000000; public static final int incorrectData = 0x01000000; public static final int missingTimeStamp = 0x00800000; /** * @param status A PKIStatus constant. * @param failInfo The bitwise AND of the PKIFailureInfo constants. */ public PKIStatusInfo(int status, int failInfo) { this.status = new INTEGER(status); statusString = new SEQUENCE(); this.failInfo = failInfo; hasFailInfo = true; } /** * Create a PKIStatusInfo with no failure info. * @param status A PKIStatus constant. */ public PKIStatusInfo(int status) { this.status = new INTEGER(status); statusString = new SEQUENCE(); hasFailInfo = false; } /** * Sets the statusString field. May be null, since this * field is optional. */ public void setStatusString(SEQUENCE statusString) { this.statusString = statusString; } /** * Adds a string to the statusString SEQUENCE. */ public void addFreeText(String s) { try { statusString.addElement( new UTF8String(s) ); } catch( java.io.CharConversionException e ) { throw new RuntimeException("Error encoding to UTF8: " + e.getMessage(), e); } } /** * Adds a UTF8String to the statusString SEQUENCE. */ public void addFreeText(UTF8String s) { statusString.addElement( s ); } 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); if( statusString.size() > 0 ) { seq.addElement( statusString ); } if(hasFailInfo) { // convert failInfo to BIT_STRING byte[] bytes = new byte[2]; bytes[0] = (byte) ((failInfo & 0xff000000) >>> 24); bytes[1] = (byte) ((failInfo & 0x00ff0000) >>> 16); int padCount = 7; // 7 unused bits BIT_STRING bs = new BIT_STRING(bytes, padCount); bs.setRemoveTrailingZeroes(true); seq.addElement( bs ); } 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.addOptionalElement( new SEQUENCE.OF_Template(UTF8String.getTemplate())); seqt.addOptionalElement( BIT_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 { PKIStatusInfo psi; SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); BIT_STRING failInfo = (BIT_STRING) seq.elementAt(2); if( failInfo == null ) { psi = new PKIStatusInfo(((INTEGER)seq.elementAt(0)).intValue()); } else { BitSet bs = failInfo.toBitSet(); int failinfo = 0; for(int i = 0, bit = 0x80000000; bit > 0; i++, bit >>>= 1 ) { if( bs.get(i) ) { failinfo |= bit; } } psi = new PKIStatusInfo(((INTEGER)seq.elementAt(0)).intValue(), failinfo); } psi.setStatusString( (SEQUENCE) seq.elementAt(1) ); return psi; } } } jss-4.6.3/org/mozilla/jss/pkix/cmmf/RevRepContent.java000066400000000000000000000120531362106420000226510ustar00rootroot00000000000000/* 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.pkix.cmmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.crmf.CertId; /** * CMMF RevRepContent. *
 * RevRepContent ::= SEQUENCE {
 *    status          SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
 *      -- in same order as was sent in RevReqContent
 *    revCerts        [0] SEQUENCE SIZE (1..MAX) OF CertId OPTIONAL,
 *      -- IDs for which revocation was requested (same order as status)
 *    crls            [1] SEQUENCE SIZE (1..MAX) OF CertificateList OPTIONAL
 *      -- the resulting CRLs (there may be more than one) }
 * 
*/ public class RevRepContent implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private SEQUENCE status; private SEQUENCE revCerts; // may be null private SEQUENCE crls; // may be null private SEQUENCE sequence; // for encoding /** * The status field, which is a SEQUENCE * of PKIStatusInfo. * * @see org.mozilla.jss.pkix.cmmf.PKIStatusInfo */ public SEQUENCE getStatus() { return status; } /** * The revCerts field, which is a SEQUENCE * of CertId. Returns null if this * field is not present. * * @see org.mozilla.jss.pkix.crmf.CertId */ public SEQUENCE getRevCerts() { return revCerts; } /** * The crls field, which is a SEQUENCE of * ANY. Returns null if this field * is not present. */ public SEQUENCE getCrls() { return crls; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Creates a new RevRepContent from its components. * * @param status A SEQUENCE of PKIStatusInfo. * @param revCerts A SEQUENCE of CertId. This * field is optional, so null may be used. * @param crls A SEQUENCE of ANY. This field * is optional, so null may be used. * @see org.mozilla.jss.pkix.cmmf.PKIStatusInfo */ public RevRepContent(SEQUENCE status, SEQUENCE revCerts, SEQUENCE crls) { sequence = new SEQUENCE(); this.status = status; sequence.addElement(status); this.revCerts = revCerts; sequence.addElement(Tag.get(0), revCerts); this.crls = crls; sequence.addElement(Tag.get(1), crls); } /////////////////////////////////////////////////////////////////////// // 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 for decoding a RevRepContent. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( new SEQUENCE.OF_Template( PKIStatusInfo.getTemplate() ) ); seqt.addOptionalElement( new SEQUENCE.OF_Template( CertId.getTemplate() ) ); seqt.addOptionalElement( new SEQUENCE.OF_Template( 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 RevRepContent( (SEQUENCE) seq.elementAt(0), (SEQUENCE) seq.elementAt(1), (SEQUENCE) seq.elementAt(2) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cmmf/RevRequest.java000066400000000000000000000247731362106420000222340ustar00rootroot00000000000000/* 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.pkix.cmmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.ENUMERATED; import org.mozilla.jss.asn1.GeneralizedTime; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.asn1.UTF8String; /** * CMMF RevRequest. *
 * RevRequest ::= SEQUENCE {
 *      issuerName      Name,
 *      serialNumber    INTEGER,
 *      reason          CRLReason,
 *      invalidityDate  GeneralizedTime OPTIONAL,
 *      sharedSecret    OCTET STRING OPTIONAL,
 *      comment         UTF8String OPTIONAL }
 * 
* 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 { /////////////////////////////////////////////////////////////////////// // Constants /////////////////////////////////////////////////////////////////////// /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED unspecified = new ENUMERATED(0); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED keyCompromise = new ENUMERATED(1); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED cACompromise = new ENUMERATED(2); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED affiliationChanged = new ENUMERATED(3); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED superseded = new ENUMERATED(4); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED cessationOfOperation = new ENUMERATED(5); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED certificateHold = new ENUMERATED(6); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED removeFromCRL = new ENUMERATED(8); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED privilegeWithdrawn = new ENUMERATED(9); /** * A CRLReason, which can be used in the reason * 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 sharedSecret; // may be null private UTF8String comment; // may be null private SEQUENCE sequence; /** * Returns the issuerName field as an ANY. */ public ANY getIssuerName() { return issuerName; } /** * Returns the serialNumber field. */ public INTEGER getSerialNumber() { return serialNumber; } /** * Returns the reason field, which should indicate the * reason for the revocation. The currently supported reasons are: *
     * CRLReason ::= ENUMERATED {
     *      unspecified             (0),
     *      keyCompromise           (1),
     *      cACompromise            (2),
     *      affiliationChanged      (3),
     *      superseded              (4),
     *      cessationOfOperation    (5),
     *      certificateHold         (6),
     *      removeFromCRL           (8),
     *      privilegeWithdrawn      (9),
     *      aACompromise            (10) }
     * 
* These are all defined as constants in this class. */ public ENUMERATED getReason() { return reason; } /** * Returns the invalidityDate field. Returns null * if the field is not present. */ public GeneralizedTime getInvalidityDate() { return invalidityDate; } /** * Returns the passphrase field. Returns * null if the field is not present. * @deprecated The passphrase field has been renamed * sharedSecret. Call getSharedSecret instead. */ @Deprecated public OCTET_STRING getPassphrase() { return sharedSecret; } /** * Returns the sharedSecret field. Returns * null if the field is not present. */ public OCTET_STRING getSharedSecret() { return sharedSecret; } /** * Returns the comment field. Returns null * if the field is not present. */ public UTF8String getComment() { return comment; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Constructs a new RevRequest from its components, * omitting the invalidityDate field. * * @deprecated This constructor is obsolete now that * invalidityDate has been added to the class. * * @param issuerName The issuerName field. * @param serialNumber The serialNumber field. * @param reason The reason field. The constants defined * in this class may be used. * @param sharedSecret The sharedSecret field. This field is * optional, so null may be used. * @param comment The comment field. This field is optional, * so null may be used. */ @Deprecated public RevRequest(ANY issuerName, INTEGER serialNumber, ENUMERATED reason, OCTET_STRING sharedSecret, UTF8String comment) { this(issuerName, serialNumber, reason, null, sharedSecret, comment); } /** * Constructs a new RevRequest from its components. * * @param issuerName The issuerName field. * @param serialNumber The serialNumber field. * @param reason The reason 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 null may be * used. * @param sharedSecret The sharedSecret field. This field is * optional, so null may be used. * @param comment The comment field. This field is optional, * so null may be used. */ public RevRequest(ANY issuerName, INTEGER serialNumber, ENUMERATED reason, GeneralizedTime invalidityDate, OCTET_STRING sharedSecret, UTF8String comment) { if( issuerName==null || serialNumber==null || reason==null ) { throw new IllegalArgumentException( "parameter to RevRequest 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.sharedSecret = sharedSecret; sequence.addElement(sharedSecret); 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 RevRequest. */ 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 RevRequest( (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) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cmmf/package.html000066400000000000000000000004121362106420000215250ustar00rootroot00000000000000 The PKIX CMMF protocol. jss-4.6.3/org/mozilla/jss/pkix/cms/000077500000000000000000000000001362106420000171075ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkix/cms/ContentInfo.java000066400000000000000000000176501362106420000222110ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * A PKCS #7 ContentInfo structure. */ public class ContentInfo implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; // XXX is this right? public static OBJECT_IDENTIFIER DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 1 }); public static OBJECT_IDENTIFIER SIGNED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 2 }); public static OBJECT_IDENTIFIER ENVELOPED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 3 }); public static OBJECT_IDENTIFIER SIGNED_AND_ENVELOPED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 4 }); public static OBJECT_IDENTIFIER DIGESTED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 5 }); public static OBJECT_IDENTIFIER ENCRYPTED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 6 }); private OBJECT_IDENTIFIER contentType; private ANY content; private SEQUENCE sequence = new SEQUENCE(); /** * Creates a ContentInfo with the given type and content. * * @param contentType The contentType of the ContentInfo. * @param content The content of the ContentInfo. May be null * to signify that the optional content field is not present. */ public ContentInfo(OBJECT_IDENTIFIER contentType, ASN1Value content) { this.contentType = contentType; sequence.addElement(contentType); if (content != null) { if( content instanceof ANY ) { this.content = (ANY) content; } else { // convert content to ANY try { this.content = (ANY) ASN1Util.decode(ANY.getTemplate(), ASN1Util.encode(content) ); } catch(InvalidBERException e) { throw new RuntimeException("Unable to convert "+ "ASN1Value to ANY: " + e.getMessage(), e); } } sequence.addElement(new EXPLICIT(new Tag(0),content) ); } } /** * Creates a ContentInfo of type data. */ public ContentInfo(byte[] data) { this( DATA, new OCTET_STRING(data) ); } /** * Creates a ContentInfo of type signedData. */ public ContentInfo(SignedData sd) { this( SIGNED_DATA, sd); } /** * Creates a ContentInfo of type envelopedData. */ public ContentInfo(EnvelopedData ed) { this( ENVELOPED_DATA, ed ); } /** * Creates a ContentInfo of type signedAndEnvelopedData. */ public ContentInfo(SignedAndEnvelopedData sed) { this( SIGNED_AND_ENVELOPED_DATA, sed ); } /** * Creates a ContentInfo of type digestedData. */ public ContentInfo(DigestedData dd) { this( DIGESTED_DATA, dd ); } /** * Creates a ContentInfo of type encryptedData. */ public ContentInfo(EncryptedData ed) { this( ENCRYPTED_DATA, ed ); } /** * Returns the contentType field, which determines what kind of content * is contained in this ContentInfo. It will usually be one of the six * predefined types, but may also be a user-defined type. */ public OBJECT_IDENTIFIER getContentType() { return contentType; } /** * Returns true if the content field is present. */ public boolean hasContent() { return (content != null); } /** * Returns the content, interpreted based on its type. If there is no * content, null is returned. *

If the contentType is * one of the six standard types, the returned object will be of that * type. For example, if the ContentInfo has contentType signedData, * a SignedData object will be returned. If the contentType is data, * an OCTET_STRING will be returned. *

If the contentType is not one of the six standard types, * the returned object will be an ANY. */ public ASN1Value getInterpretedContent() throws InvalidBERException { if(contentType.equals(DATA)) { return content.decodeWith( new OCTET_STRING.Template() ); } else if( contentType.equals(SIGNED_DATA) ) { return content.decodeWith( new SignedData.Template() ); } else if( contentType.equals(ENVELOPED_DATA) ) { return content.decodeWith( new EnvelopedData.Template()); } else if( contentType.equals(SIGNED_AND_ENVELOPED_DATA) ) { return content.decodeWith( new SignedAndEnvelopedData.Template() ); } else if( contentType.equals(DIGESTED_DATA) ) { return content.decodeWith( new DigestedData.Template() ); } else if( contentType.equals(ENCRYPTED_DATA) ) { return content.decodeWith( new EncryptedData.Template()); } else { // unknown type return content; } } /** * Returns the content encoded as an ANY. If there is no content, * null is returned. */ public ANY getContent() { return content; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag,ostream); } public Tag getTag() { return ContentInfo.TAG; } /** * Returns a singleton instance of a decoding template for ContentInfo. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding a ContentInfo blob * */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return (tag.equals(ContentInfo.TAG)); } private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new OBJECT_IDENTIFIER.Template()); seqt.addOptionalElement( new EXPLICIT.Template( new Tag(0), new ANY.Template() )); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(ContentInfo.TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream ) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); assert(seq.size() == 2); ASN1Value content; if( seq.elementAt(1) == null ) { content = null; } else { content = ((EXPLICIT)seq.elementAt(1)).getContent(); } return new ContentInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), content ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkix/cms/DigestInfo.java000066400000000000000000000071601362106420000220110ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.util.Assert; public class DigestInfo implements ASN1Value { private AlgorithmIdentifier digestAlgorithm; private OCTET_STRING digest; private SEQUENCE sequence; public DigestInfo(AlgorithmIdentifier digestAlgorithm, OCTET_STRING digest){ if( digestAlgorithm==null || digest==null ) { throw new IllegalArgumentException(); } sequence = new SEQUENCE(); this.digestAlgorithm = digestAlgorithm; sequence.addElement(digestAlgorithm); this.digest = digest; sequence.addElement(digest); } public AlgorithmIdentifier getDigestAlgorithm() { return digestAlgorithm; } public OCTET_STRING getDigest() { return digest; } private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public boolean equals(Object obj) { if( obj==null || !(obj instanceof DigestInfo)) { return false; } DigestInfo di = (DigestInfo)obj; return byteArraysAreSame(di.digest.toByteArray(), digest.toByteArray()); } /** * Compares two non-null byte arrays. Returns true if they are identical, * false otherwise. */ private static boolean byteArraysAreSame(byte[] left, byte[] right) { assert(left!=null && right!=null); if( left.length != right.length ) { return false; } for(int i = 0 ; i < left.length ; i++ ) { if( left[i] != right[i] ) { return false; } } return true; } 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 class for decoding the BER encoding of a DigestInfo. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( AlgorithmIdentifier.getTemplate()); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream ostream) throws InvalidBERException, IOException { return decode(TAG, ostream); } public ASN1Value decode(Tag implicitTag, InputStream ostream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, ostream); return new DigestInfo( (AlgorithmIdentifier) seq.elementAt(0), (OCTET_STRING) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cms/DigestedData.java000066400000000000000000000100071362106420000222720ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; public class DigestedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private INTEGER version; private AlgorithmIdentifier digestAlgorithm; private ContentInfo contentInfo; private OCTET_STRING digest; private SEQUENCE sequence; // for DER encoding public INTEGER getVersion() { return version; } public AlgorithmIdentifier getDigestAlgorithm() { return digestAlgorithm; } public ContentInfo getContentInfo() { return contentInfo; } public OCTET_STRING getDigest() { return digest; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// public DigestedData(INTEGER version, AlgorithmIdentifier digestAlgorithm, ContentInfo contentInfo, OCTET_STRING digest) { if( version==null || digestAlgorithm==null || contentInfo==null || digest==null ) { throw new IllegalArgumentException("DigestedData constructor" +" parameter is null"); } this.version = version; this.digestAlgorithm = digestAlgorithm; this.contentInfo = contentInfo; this.digest = digest; sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(digestAlgorithm); sequence.addElement(contentInfo); sequence.addElement(digest); } /////////////////////////////////////////////////////////////////////// // 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); } /** * A Template for decoding BER-encoded DigestData 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( ContentInfo.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 DigestedData( (INTEGER) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (ContentInfo) seq.elementAt(2), (OCTET_STRING) seq.elementAt(3) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cms/EncapsulatedContentInfo.java000066400000000000000000000110571362106420000245350ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * A CMS EncapsulatedContentInfo structure. */ public class EncapsulatedContentInfo implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; // XXX is this right? private OBJECT_IDENTIFIER contentType; private OCTET_STRING content; private SEQUENCE sequence = new SEQUENCE(); /** * Creates a EncapsulatedContentInfo with the given type and content. * * @param contentType The contentType of the EncapsulatedContentInfo. * @param content The content of the EncapsulatedContentInfo. May be null * to signify that the optional content field is not present. */ public EncapsulatedContentInfo(OBJECT_IDENTIFIER contentType, ASN1Value content) { this.contentType = contentType; sequence.addElement(contentType); if (content != null) { if( content instanceof OCTET_STRING) { this.content = (OCTET_STRING) content; } else { // convert content to OCTET_STRING this.content = new OCTET_STRING( ASN1Util.encode(content) ); } sequence.addElement(new EXPLICIT(new Tag(0), this.content) ); } } /** * Returns the contentType field, which determines what kind of content * is contained in this EncapsulatedContentInfo. */ public OBJECT_IDENTIFIER getContentType() { return contentType; } /** * Returns true if the content field is present. */ public boolean hasContent() { return (content != null); } /** * Returns the content encoded as an OCTET_STRING. If there is no content, * null is returned. */ public OCTET_STRING getContent() { return content; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag,ostream); } public Tag getTag() { return EncapsulatedContentInfo.TAG; } /** * Returns a singleton instance of a decoding template for EncapsulatedContentInfo. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding a EncapsulatedContentInfo blob * */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return (tag.equals(EncapsulatedContentInfo.TAG)); } private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new OBJECT_IDENTIFIER.Template()); seqt.addOptionalElement( new EXPLICIT.Template( new Tag(0), new OCTET_STRING.Template() )); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(EncapsulatedContentInfo.TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream ) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); assert(seq.size() == 2); ASN1Value content; if( seq.elementAt(1) == null ) { content = null; } else { content = ((EXPLICIT)seq.elementAt(1)).getContent(); } return new EncapsulatedContentInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), content ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkix/cms/EncryptedContentInfo.java000066400000000000000000000313231362106420000240600ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.CharConversionException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.crypto.Cipher; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.IVParameterSpec; import org.mozilla.jss.crypto.IllegalBlockSizeException; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.PBEKeyGenParams; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.pkix.primitive.PBEParameter; import org.mozilla.jss.util.Assert; import org.mozilla.jss.util.Password; /** * The PKCS #7 type EncryptedContentInfo, which encapsulates * encrypted data. */ public class EncryptedContentInfo implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private OBJECT_IDENTIFIER contentType; private AlgorithmIdentifier contentEncryptionAlgorithm; private OCTET_STRING encryptedContent; // may be null private SEQUENCE sequence = new SEQUENCE(); public OBJECT_IDENTIFIER getContentType() { return contentType; } public AlgorithmIdentifier getContentEncryptionAlgorithm() { return contentEncryptionAlgorithm; } public OCTET_STRING getEncryptedContent() { return encryptedContent; } public boolean hasEncryptedContent() { return (encryptedContent!=null); } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Create a EnvelopedData ASN1 object. */ public EncryptedContentInfo( OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent) { this(contentType, contentEncryptionAlgorithm, encryptedContent, false); } public EncryptedContentInfo( OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent, boolean createHackedCRSCompatibleECI) { this.contentType = contentType; this.contentEncryptionAlgorithm = contentEncryptionAlgorithm; this.encryptedContent = encryptedContent; sequence.addElement(contentType); sequence.addElement(contentEncryptionAlgorithm); if(encryptedContent != null) { if (createHackedCRSCompatibleECI) { sequence.addElement(new EXPLICIT(new Tag(0), encryptedContent)); } else { sequence.addElement(new Tag(0), encryptedContent); } } } public static EncryptedContentInfo createCRSCompatibleEncryptedContentInfo(OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent) { return new EncryptedContentInfo(contentType, contentEncryptionAlgorithm, encryptedContent, true); } /////////////////////////////////////////////////////////////////////// // Crypto shortcuts /////////////////////////////////////////////////////////////////////// /** * Creates a new EncryptedContentInfo, where the data is encrypted * with a password-based key. * * @param keyGenAlg The algorithm for generating a symmetric key from * a password, salt, and iteration count. * @param password The password to use in generating the key. * @param salt The salt to use in generating the key. * @param iterationCount The number of hashing iterations to perform * while generating the key. * @param charToByteConverter The mechanism for converting the characters * in the password into bytes. If null, the default mechanism * will be used, which is UTF8. * @param toBeEncrypted The bytes to be encrypted and stored in the * EncryptedContentInfo. Before they are encrypted, they will be * padded using PKCS padding. */ public static EncryptedContentInfo createPBE(PBEAlgorithm keyGenAlg, Password password, byte[] salt, int iterationCount, KeyGenerator.CharToByteConverter charToByteConverter, byte[] toBeEncrypted) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, CharConversionException { try { // check key gen algorithm if( ! (keyGenAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("Key generation algorithm"+ " is not a PBE algorithm"); } PBEAlgorithm pbeAlg = keyGenAlg; CryptoManager cman = CryptoManager.getInstance(); // generate key CryptoToken token = cman.getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( keyGenAlg ); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( password, salt, iterationCount); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize(pbekgParams); SymmetricKey key = kg.generate(); // generate IV EncryptionAlgorithm encAlg = pbeAlg.getEncryptionAlg(); AlgorithmParameterSpec params=null; Class [] paramClasses = pbeAlg.getParameterClasses(); for (int i = 0; i < paramClasses.length; i ++) { if ( paramClasses[i].equals( IVParameterSpec.class ) ) { params = new IVParameterSpec( kg.generatePBE_IV() ); break; } } // perform encryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initEncrypt( key, params ); byte[] encrypted = cipher.doFinal( Cipher.pad( toBeEncrypted, encAlg.getBlockSize()) ); // make encryption algorithm identifier PBEParameter pbeParam = new PBEParameter( salt, iterationCount ); AlgorithmIdentifier encAlgID = new AlgorithmIdentifier( keyGenAlg.toOID(), pbeParam); // create EncryptedContentInfo EncryptedContentInfo encCI = new EncryptedContentInfo( ContentInfo.DATA, encAlgID, new OCTET_STRING(encrypted) ); return encCI; } catch( IllegalBlockSizeException e ) { throw new RuntimeException("IllegalBlockSizeException in EncryptedContentInfo" +".createPBE: " + e.getMessage(), e); } catch( BadPaddingException e ) { throw new RuntimeException("BadPaddingException in EncryptedContentInfo" +".createPBE: " + e.getMessage(), e); } } /** * Decrypts the content of an EncryptedContentInfo encrypted with a * PBE key. * * @param pass The password to use in generating the PBE decryption key. * @param charToByteConverter The converter for converting the password * characters into bytes. May be null to use the default. * @return The decrypted contents of the EncryptedContentInfo. The contents * are first unpadded using the PKCS padding mechanism. */ public byte[] decrypt(Password pass, KeyGenerator.CharToByteConverter charToByteConverter) throws IllegalStateException,NotInitializedException, NoSuchAlgorithmException, InvalidBERException, IOException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, IllegalBlockSizeException, BadPaddingException { if( encryptedContent == null ) { return null; } // get the key gen parameters AlgorithmIdentifier algid = contentEncryptionAlgorithm; KeyGenAlgorithm kgAlg = KeyGenAlgorithm.fromOID( algid.getOID() ); if( !(kgAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("KeyGenAlgorithm is not a"+ " PBE algorithm"); } ASN1Value params = algid.getParameters(); if( params == null ) { throw new InvalidAlgorithmParameterException( "PBE algorithms require parameters"); } PBEParameter pbeParams; if( params instanceof PBEParameter) { pbeParams = (PBEParameter) params; } else { byte[] encodedParams = ASN1Util.encode(params); pbeParams = (PBEParameter) ASN1Util.decode( PBEParameter.getTemplate(), encodedParams ); } PBEKeyGenParams kgp = new PBEKeyGenParams(pass, pbeParams.getSalt(), pbeParams.getIterations() ); // compute the key and IV CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( kgAlg ); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize( kgp ); SymmetricKey key = kg.generate(); // compute algorithm parameters EncryptionAlgorithm encAlg = ((PBEAlgorithm)kgAlg).getEncryptionAlg(); AlgorithmParameterSpec algParams = null; Class [] paramClasses = encAlg.getParameterClasses(); for (int i = 0; i < paramClasses.length; i ++) { if ( paramClasses[i].equals( javax.crypto.spec.IvParameterSpec.class ) ) { algParams = new IVParameterSpec( kg.generatePBE_IV() ); break; } } // perform the decryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initDecrypt(key, algParams); return Cipher.unPad(cipher.doFinal( encryptedContent.toByteArray() )); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); /** * A template file for decoding a EnvelopedData blob * */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return (tag.equals(EncryptedContentInfo.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new OBJECT_IDENTIFIER.Template()); seqt.addElement(new AlgorithmIdentifier.Template()); seqt.addOptionalElement(new Tag(0), new OCTET_STRING.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); assert(seq.size() ==3); return new EncryptedContentInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (OCTET_STRING) seq.elementAt(2) ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkix/cms/EncryptedData.java000066400000000000000000000102141362106420000224770ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * The PKCS #7 structure EncryptedData. */ public class EncryptedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private INTEGER version; private EncryptedContentInfo encryptedContentInfo; private SEQUENCE sequence; /** * The default version number. This should always be used unless * you really know what you are doing. */ public static final INTEGER DEFAULT_VERSION = new INTEGER(0); /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Creates a new EncryptedData. * * @param version Should usually be DEFAULT_VERSION unless you are being * very clever. */ public EncryptedData( INTEGER version, EncryptedContentInfo encryptedContentInfo ) { if( version == null || encryptedContentInfo == null ) { throw new IllegalArgumentException("null parameter"); } sequence = new SEQUENCE(); this.version = version; sequence.addElement(version); this.encryptedContentInfo = encryptedContentInfo; sequence.addElement(encryptedContentInfo); } /** * Creates an EncryptedData with the default version. */ public EncryptedData( EncryptedContentInfo encryptedContentInfo ) { this( DEFAULT_VERSION, encryptedContentInfo ); } /////////////////////////////////////////////////////////////////////// // Accessor Methods /////////////////////////////////////////////////////////////////////// public INTEGER getVersion() { return version; } public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } /////////////////////////////////////////////////////////////////////// // 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); } public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); /** * A Template for decoding EncryptedData items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( EncryptedContentInfo.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 EncryptedData( (INTEGER) seq.elementAt(0), (EncryptedContentInfo) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cms/EnvelopedData.java000066400000000000000000000062761362106420000225000ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; public class EnvelopedData implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private INTEGER version; private SET recipientInfos; private EncryptedContentInfo encryptedContentInfo; private SEQUENCE sequence = new SEQUENCE(); public INTEGER getVersion() { return version; } public SET getRecipientInfos() { return recipientInfos; } public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } /** * Create a EnvelopedData ASN1 object. */ public EnvelopedData( INTEGER version, SET recipientInfos, EncryptedContentInfo encryptedContentInfo) { this.version = version; this.recipientInfos = recipientInfos; this.encryptedContentInfo = encryptedContentInfo; sequence.addElement(version); sequence.addElement(recipientInfos); sequence.addElement(encryptedContentInfo); } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } /** * A template file for decoding a EnvelopedData blob * */ public static class Template implements ASN1Template { public Tag getTag() { return EnvelopedData.TAG; } public boolean tagMatch(Tag tag) { return (tag.equals(EnvelopedData.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(),istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new INTEGER.Template()); seqt.addElement(new SET.OF_Template(new RecipientInfo.Template())); seqt.addElement(new EncryptedContentInfo.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); assert(seq.size() ==3); return new EnvelopedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (EncryptedContentInfo) seq.elementAt(2) ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkix/cms/IssuerAndSerialNumber.java000066400000000000000000000074201362106420000241630ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.Name; import org.mozilla.jss.util.Assert; /** * An issuer name and serial number, used to uniquely identify a certificate. */ public class IssuerAndSerialNumber implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private Name issuer; private INTEGER serialNumber; private SEQUENCE sequence; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// /** * Constructs an IssuerAndSerialNumber from its components. * * @param issuer Must not be null. * @param serialNumber must not be null. */ public IssuerAndSerialNumber(Name issuer, INTEGER serialNumber) { if(issuer==null || serialNumber==null) { throw new IllegalArgumentException(); } sequence = new SEQUENCE(); this.issuer = issuer; sequence.addElement(issuer); this.serialNumber = serialNumber; sequence.addElement(serialNumber); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public Name getIssuer() { return issuer; } public INTEGER getSerialNumber() { return serialNumber; } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// static 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.encode(implicitTag, ostream); } /** * Returns a singleton template instance. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding an IssuerAndSerialNumber from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( Name.getTemplate() ); seqt.addElement( INTEGER.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); assert(seq.size() == 2); return new IssuerAndSerialNumber( (Name) seq.elementAt(0), (INTEGER) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cms/RecipientInfo.java000066400000000000000000000077161362106420000225230ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.util.Assert; public class RecipientInfo implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private INTEGER version; private IssuerAndSerialNumber issuerAndSerialNumber; private AlgorithmIdentifier keyEncryptionAlgorithmID; private OCTET_STRING encryptedKey; private SEQUENCE sequence = new SEQUENCE(); public INTEGER getVersion() { return version; } public IssuerAndSerialNumber getissuerAndSerialNumber() { return issuerAndSerialNumber; } public AlgorithmIdentifier getKeyEncryptionAlgorithmID() { return keyEncryptionAlgorithmID; } public OCTET_STRING getEncryptedKey() { return encryptedKey; } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * Create a RecipientInfo ASN1 object. */ public RecipientInfo( INTEGER version, IssuerAndSerialNumber issuerAndSerialNumber, AlgorithmIdentifier keyEncryptionAlgorithmID, OCTET_STRING encryptedKey) { assert(issuerAndSerialNumber != null); assert(keyEncryptionAlgorithmID != null); assert(encryptedKey != null); this.version = version; this.issuerAndSerialNumber = issuerAndSerialNumber; this.keyEncryptionAlgorithmID = keyEncryptionAlgorithmID; this.encryptedKey = encryptedKey; sequence.addElement(version); sequence.addElement(issuerAndSerialNumber); sequence.addElement(keyEncryptionAlgorithmID); sequence.addElement(encryptedKey); } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } /** * A template file for decoding a RecipientInfo blob * */ public static class Template implements ASN1Template { public Tag getTag() { return RecipientInfo.TAG; } public boolean tagMatch(Tag tag) { return (tag.equals(RecipientInfo.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(),istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new INTEGER.Template()); seqt.addElement(new IssuerAndSerialNumber.Template()); seqt.addElement(new AlgorithmIdentifier.Template()); seqt.addElement(new OCTET_STRING.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); assert(seq.size() ==4); return new RecipientInfo( (INTEGER) seq.elementAt(0), (IssuerAndSerialNumber) seq.elementAt(1), (AlgorithmIdentifier) seq.elementAt(2), (OCTET_STRING) seq.elementAt(3) ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkix/cms/SignedAndEnvelopedData.java000066400000000000000000000140241362106420000242430ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; public class SignedAndEnvelopedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private INTEGER version; private SET recipientInfos; private SET digestAlgorithms; private EncryptedContentInfo encryptedContentInfo; private SET certificates; // may be null private SET crls; // may be null private SET signerInfos; private SEQUENCE sequence; // for encoding /** * Returns the version number. The current version is 1. */ public INTEGER getVersion() { return version; } /** * Returns a SET of RecipientInfo. */ public SET getRecipientInfos() { return recipientInfos; } /** * Returns a SET of AlgorithmIdentifier. */ public SET getDigestAlgorithms() { return digestAlgorithms; } /** * Returns the encrypted content. */ public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } /** * Returns a SET of ANYs. May return null if the * certificates field is not present. */ public SET getCertificates() { return certificates; } /** * Returns a SET of ANYs. May return null if the crls * field is not present. */ public SET getCrls() { return crls; } /** * Returns a SET of SignerInfo. */ public SET getSignerInfos() { return signerInfos; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// public SignedAndEnvelopedData( INTEGER version, SET recipientInfos, SET digestAlgorithms, EncryptedContentInfo encryptedContentInfo, SET certificates, SET crls, SET signerInfos) { if( version==null || recipientInfos==null || digestAlgorithms==null || encryptedContentInfo==null || signerInfos==null ) { throw new IllegalArgumentException( "SignedAndEnvelopedData constructor parameter is null"); } this.version = version; this.recipientInfos = recipientInfos; this.digestAlgorithms = digestAlgorithms; this.encryptedContentInfo = encryptedContentInfo; this.certificates = certificates; this.crls = crls; this.signerInfos = signerInfos; sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(recipientInfos); sequence.addElement(digestAlgorithms); sequence.addElement(encryptedContentInfo); if( certificates!=null ) { sequence.addElement(certificates); } if( crls!=null ) { sequence.addElement(crls); } sequence.addElement( signerInfos ); } /////////////////////////////////////////////////////////////////////// // 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); } /** * A Template class for decoding BER-encoded SignedAndEnvelopedData items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(INTEGER.getTemplate()); seqt.addElement(new SET.OF_Template(RecipientInfo.getTemplate())); seqt.addElement(new SET.OF_Template( AlgorithmIdentifier.getTemplate()) ); seqt.addElement(EncryptedContentInfo.getTemplate()); seqt.addOptionalElement(new Tag(0), new SET.OF_Template(ANY.getTemplate())); seqt.addOptionalElement(new Tag(1), new SET.OF_Template(ANY.getTemplate())); seqt.addElement(new SET.OF_Template(SignerInfo.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 SignedAndEnvelopedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (SET) seq.elementAt(2), (EncryptedContentInfo) seq.elementAt(3), (SET) seq.elementAt(4), (SET) seq.elementAt(5), (SET) seq.elementAt(6) ); } } } jss-4.6.3/org/mozilla/jss/pkix/cms/SignedData.java000066400000000000000000000326071362106420000217650ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.*; import org.mozilla.jss.util.Assert; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.Certificate; /* CUT THIS??? *

Although all the normal functionality of a SignedData is supported * with high-level methods, there is a low-level API for setting the * individual fields of the structure. Using these calls is an unsupported * way of accomplishing unforeseen tasks. If you have reason to use these * methods, please notify the authors in case it is something that should * be added to the high-level interface. * */ /** * A CMS SignedData structure. *

The certificates field should only contain X.509 certificates. * PKCS #6 extended certificates will fail to decode properly. * @author stevep * @author nicolson * @author mzhao */ public class SignedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private INTEGER version; private SET digestAlgorithms; private EncapsulatedContentInfo contentInfo; private SET certificates; // [0] optional, may be null private SET crls; // [1] optional, may be null private SET signerInfos; // This class implements version 3 of the spec. private static final INTEGER VERSION = new INTEGER(3); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Accessor methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private static void verifyNotNull(Object obj) { if( obj == null ) { throw new IllegalArgumentException(); } } /** * Returns the version of this SignedData. The current version of the * spec is version 3. */ public INTEGER getVersion() { return version; } /** * Low-level function to set the version. * @param version Must not be null. public void setVersion(INTEGER version) { verifyNotNull(version); this.version = version; } */ /** * Returns the digest algorithms used by the signers to digest the * signed content. There may be more than one, if different signers * use different digesting algorithms. */ public SET getDigestAlgorithmIdentifiers() { return digestAlgorithms; } /** * Low-level function to set the digest algorithm identifiers. * @param digestAlgIds Must not be null. public void setDigestAlgorithmIdentifiers(SET digestAlgIds) { verifyNotNull(digestAlgIds); this.digestAlgorithms = digestAlgIds; } */ /** * Returns the EncapsulatedContentInfo containing the signed content. The simple * case is for the content to be of type data, although any * content type can be signed. */ public EncapsulatedContentInfo getContentInfo() { return contentInfo; } /** * Low-level function to set the EncapsulatedcontentInfo. * @param ci Must not be null. public void setContentInfo(EncapsulatedContentInfo ci) { verifyNotNull(ci); this.contentInfo = ci; } */ /** * Returns the certificates field, which is a SET of * X.509 certificates (org.mozilla.jss.pkix.cert.Certificate). * PKCS #6 Extended Certificates are not supported by this implementation. * Returns null if this optional field is not present. * */ public SET getCertificates() { return certificates; } /** * Low-level function to set the certificates. * @param certs May be null to signify that the certificates * field is not present. public void setCertificates(SET certs) { this.certificates = certs; } */ /** * Returns true if the certificates field is present. */ public boolean hasCertificates() { return (certificates!=null); } /** * Returns the crls field, which contains a SET of certificate * revocation lists represented by ANYs (org.mozilla.jss.asn1.ANY). * */ public SET getCrls() { return crls; } /** * Low-level function to set the crls. * @param certs May be null to signify that the crls * field is not present. public void setCrls(SET crls) { this.crls = crls; } */ /** * Returns true if the crls field is present. */ public boolean hasCrls() { return (crls != null); } /** * Returns the signerInfos field, which is a SET of * org.mozilla.jss.pkix.cms.SignerInfo. */ public SET getSignerInfos() { return signerInfos; } /** * Low-level function to set the SignerInfos. * @param signerInfos Must not be null. public void setSignerInfos(SET signerInfos) { verifyNotNull(sis); this.signerInfos = signerInfos; } */ /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Low-level constructor that merely initializes all fields to null. private SignedData() {} */ /** * Create a SignedData ASN1 object. Both certificates and CRLs * are optional. If you pass in a null for either value, that * parameter will not get written in the sequence. * * @param digestAlgorithms A SET of zero or more * algorithm identifiers. The purpose of this item is to list * the digest algorithms used by the various signers to digest * the signed content. This field will also be updated by * the addSigner method. If all the signers are added * with addSigner, it is not necessary to list * the digest algorithms here. *

If null is passed in, the * digestAlgorithms field will be initialized * with an empty SET. * @param contentInfo The content that is being signed. This parameter * may not be null. However, the content * field of the contentInfo may be omitted, in which case the * signatures contained in the SignerInfo structures * are presumed to be on externally-supplied data. * @param certificates A SET of org.mozilla.jss.pkix.cert.Certificate, * the certificates * containing the public keys used to sign the content. It may * also contain elements of the CA chain extending from the leaf * certificates. It is not necessary to include the CA chain, or * indeed to include any certificates, if the certificates are * expected to already be possessed by the recipient. The recipient * can use the issuer and serial number in the SignerInfo structure * to search for the necessary certificates. If this parameter is * null, the certificates field will be * omitted. * @param crls A SET of ASN1Values, which should encode to the ASN1 type * CertificateRevocationList. This implementation does * not interpret CRLs. If this parameter is null, * the crls field will be omitted. * @param signerInfos SignerInfo structures containing signatures * of the content. Additional signerInfos can be added with * the addSigner method. If this parameter is * null, the field will be initialized with an * empty SET. */ public SignedData( SET digestAlgorithms, EncapsulatedContentInfo contentInfo, SET certificates, SET crls, SET signerInfos) { version = VERSION; if(digestAlgorithms == null ) { this.digestAlgorithms = new SET(); } else { this.digestAlgorithms = digestAlgorithms; } verifyNotNull(contentInfo); this.contentInfo = contentInfo; // certificates may be null this.certificates = certificates; // crls may be null this.crls = crls; if(signerInfos == null) { this.signerInfos = new SET(); } else { this.signerInfos = signerInfos; } } /** * Constructor for creating a SignedData from its encoding. */ SignedData( INTEGER version, SET digestAlgorithms, EncapsulatedContentInfo contentInfo, SET certificates, SET crls, SET signerInfos ) { verifyNotNull(version); this.version = version; verifyNotNull(digestAlgorithms); this.digestAlgorithms = digestAlgorithms; verifyNotNull(contentInfo); this.contentInfo = contentInfo; // certificates may be null this.certificates = certificates; // crls may be null this.crls = crls; verifyNotNull(signerInfos); this.signerInfos = signerInfos; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Cryptographic functions /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { SEQUENCE sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(digestAlgorithms); sequence.addElement(contentInfo); if( certificates != null ) { sequence.addElement( new Tag(0), certificates ); } if( crls != null ) { sequence.addElement( new Tag(1), crls ); } sequence.addElement(signerInfos); sequence.encode(tag,ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template file for decoding a SignedData blob * */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); // version seqt.addElement(INTEGER.getTemplate()); // digestAlgorithms seqt.addElement(new SET.OF_Template( AlgorithmIdentifier.getTemplate())); // content info seqt.addElement(EncapsulatedContentInfo.getTemplate()); // [0] IMPLICIT certificates OPTIONAL seqt.addOptionalElement( new Tag(0), new SET.OF_Template(Certificate.getTemplate())); // [1] IMPLICIT CertificateRevocationLists OPTIONAL seqt.addOptionalElement( new Tag(1), new SET.OF_Template(ANY.getTemplate())); // signerInfos seqt.addElement(new SET.OF_Template(SignerInfo.getTemplate())); } 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 implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); assert(seq.size() == 6); return new SignedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (EncapsulatedContentInfo) seq.elementAt(2), (SET) seq.elementAt(3), (SET) seq.elementAt(4), (SET) seq.elementAt(5) ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkix/cms/SignerIdentifier.java000066400000000000000000000140341362106420000232060ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.CHOICE; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * CMS SignerIdentifier: *

 * SignerIdentifier ::= CHOICE {
 *      issuerAndSerialNumber IssuerAndSerialNumber,
 *      subjectKeyIdentifier [0] SubjectKeyIdentifier }
 * 
*/ public class SignerIdentifier implements ASN1Value { /** * The type of SignerIdentifier. */ public static class Type { private Type() { } static Type ISSUER_AND_SERIALNUMBER = new Type(); static Type SUBJECT_KEY_IDENTIFIER = new Type(); } public static Type ISSUER_AND_SERIALNUMBER = Type.ISSUER_AND_SERIALNUMBER; public static Type SUBJECT_KEY_IDENTIFIER = Type.SUBJECT_KEY_IDENTIFIER; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private Type type; private IssuerAndSerialNumber issuerAndSerialNumber = null; // if type == ISSUER_AND_SERIALNUMBER private OCTET_STRING subjectKeyIdentifier = null; // if type == SUBJECT_KEY_IDENTIFIER /** * Returns the type of SignerIdentifier:
    *
  • ISSUER_AND_SERIALNUMBER *
  • SUBJECT_KEY_IDENTIFIER *
*/ public Type getType() { return type; } /** * If type == ISSUER_AND_SERIALNUMBER, returns the IssuerAndSerialNumber * field. Otherwise, returns null. */ public IssuerAndSerialNumber getIssuerAndSerialNumber() { return issuerAndSerialNumber; } /** * If type == SUBJECT_KEY_IDENTIFIER, returns the SubjectKeyIdentifier * field. Otherwise, returns null. */ public OCTET_STRING getSubjectKeyIdentifier() { return subjectKeyIdentifier; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// public SignerIdentifier(Type type, IssuerAndSerialNumber issuerAndSerialNumber, OCTET_STRING subjectKeyIdentifier) { this.type = type; this.issuerAndSerialNumber = issuerAndSerialNumber; this.subjectKeyIdentifier = subjectKeyIdentifier; } /** * Creates a new SignerIdentifier with the given IssuerAndSerialNumber field. */ public static SignerIdentifier createIssuerAndSerialNumber(IssuerAndSerialNumber ias) { return new SignerIdentifier( ISSUER_AND_SERIALNUMBER, ias, null ); } /** * Creates a new SignerIdentifier with the given SubjectKeyIdentifier field. */ public static SignerIdentifier createSubjectKeyIdentifier(OCTET_STRING ski) { return new SignerIdentifier(SUBJECT_KEY_IDENTIFIER , null, ski ); } /////////////////////////////////////////////////////////////////////// // decoding/encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { if( type == SUBJECT_KEY_IDENTIFIER ) { return Tag.get(0); } else { assert( type == ISSUER_AND_SERIALNUMBER ); return IssuerAndSerialNumber.TAG; } } public void encode(OutputStream ostream) throws IOException { if( type == SUBJECT_KEY_IDENTIFIER ) { // a CHOICE must be explicitly tagged //EXPLICIT e = new EXPLICIT( Tag.get(0), subjectKeyIdentifier ); //e.encode(ostream); subjectKeyIdentifier.encode(Tag.get(0), ostream); } else { assert( type == ISSUER_AND_SERIALNUMBER ); issuerAndSerialNumber.encode(ostream); } } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { //Assert.notReached("A CHOICE cannot be implicitly tagged"); encode(ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A Template for decoding a SignerIdentifier. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); //EXPLICIT.Template et = new EXPLICIT.Template( // Tag.get(0), OCTET_STRING.getTemplate() ); //choicet.addElement( et ); choicet.addElement( Tag.get(0), OCTET_STRING.getTemplate() ); choicet.addElement(IssuerAndSerialNumber.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() == SEQUENCE.TAG ) { return createIssuerAndSerialNumber( (IssuerAndSerialNumber) c.getValue() ); } else { assert( c.getTag().equals(Tag.get(0)) ); //EXPLICIT e = (EXPLICIT) c.getValue(); //ASN1Value dski = e.getContent(); //OCTET_STRING ski = (OCTET_STRING) e.getContent(); OCTET_STRING ski = (OCTET_STRING) c.getValue(); return createSubjectKeyIdentifier(ski); } } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { //Assert.notReached("A CHOICE cannot be implicitly tagged"); return decode(istream); } } } jss-4.6.3/org/mozilla/jss/pkix/cms/SignerInfo.java000066400000000000000000000716451362106420000220320ustar00rootroot00000000000000/* 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.pkix.cms; import java.io.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.crypto.*; import java.security.InvalidKeyException; import java.security.SignatureException; import java.security.NoSuchAlgorithmException; import java.security.MessageDigest; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.*; import java.security.PublicKey; /* * The high-level interface takes care of all * the logic and cryptography. If you need to use the low-level interface, * please let us know what you are using it for. Perhaps it should be part * of the high-level interface. */ /** * A CMS SignerInfo. */ public class SignerInfo implements ASN1Value { //////////////////////////////////////////////// // PKCS #9 attributes //////////////////////////////////////////////// private static final OBJECT_IDENTIFIER CONTENT_TYPE = OBJECT_IDENTIFIER.PKCS.subBranch(9).subBranch(3); private static final OBJECT_IDENTIFIER MESSAGE_DIGEST = OBJECT_IDENTIFIER.PKCS.subBranch(9).subBranch(4); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private INTEGER version; private SignerIdentifier signerIdentifier; private AlgorithmIdentifier digestAlgorithm; private SET signedAttributes; // [0] OPTIONAL private AlgorithmIdentifier digestEncryptionAlgorithm; private OCTET_STRING encryptedDigest; private SET unsignedAttributes; // [1] OPTIONAL /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Accessor methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Retrieves the version number of this SignerInfo. */ public INTEGER getVersion() { return version; } /** * Retrieves the SignerIdentifier. */ public SignerIdentifier getSignerIdentifier() { return signerIdentifier; } /** * Retrieves the DigestAlgorithm used in this SignerInfo. * * @exception NoSuchAlgorithmException If the algorithm is not * recognized by JSS. */ public DigestAlgorithm getDigestAlgorithm() throws NoSuchAlgorithmException { return DigestAlgorithm.fromOID( digestAlgorithm.getOID() ); } /** * Retrieves the DigestAlgorithmIdentifier used in this SignerInfo. */ public AlgorithmIdentifier getDigestAlgorithmIdentifer() { return digestAlgorithm; } /** * Retrieves the signed attributes, if they exist. * */ public SET getSignedAttributes() { return signedAttributes; } /** * Returns true if the signedAttributes field is present. */ public boolean hasSignedAttributes() { return (signedAttributes != null); } /** * Returns the raw signature (digest encryption) algorithm used in this * SignerInfo. * * @exception NoSuchAlgorithmException If the algorithm is not recognized * by JSS. */ public SignatureAlgorithm getDigestEncryptionAlgorithm() throws NoSuchAlgorithmException { return SignatureAlgorithm.fromOID( digestEncryptionAlgorithm.getOID() ); } /** * Returns the DigestEncryptionAlgorithmIdentifier used in this SignerInfo. */ public AlgorithmIdentifier getDigestEncryptionAlgorithmIdentifier() { return digestEncryptionAlgorithm; } /** * Retrieves the encrypted digest. */ public byte[] getEncryptedDigest() { return encryptedDigest.toByteArray(); } /** * Retrieves the unsigned attributes, if they exist. * */ public SET getUnsignedAttributes() { return unsignedAttributes; } /** * Returns true if the unsignedAttributes field is present. */ public boolean hasUnsignedAttributes() { return (unsignedAttributes!=null); } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * A constructor for creating a new SignerInfo from scratch. * * @param signerIdentifier The signerIdentifier of the * certificate from which the public key was extracted to create * this SignerInfo. * @param signingAlg The algorithm to be used to sign the content. * This should be a composite algorithm, such as * RSASignatureWithMD5Digest, instead of a raw algorithm, such as * RSASignature. * Note that the digest portion of this algorithm must be the same * algorithm as was used to digest the message content. * @param signedAttributes An optional set of Attributes, which * will be signed along with the message content. This parameter may * be null, or the SET may be empty. DO NOT insert * the PKCS #9 content-type or message-digest attributes. They will * be added automatically if they are necessary. * @param unsignedAttributes An optional set of Attributes, which * will be included in the SignerInfo but not signed. This parameter * may be null, or the SET may be empty. * @param messageDigest The digest of the message contents. The digest * must have been created with the digest algorithm specified by * the signingAlg parameter. * @param contentType The type of the ContentInfo that is being signed. * If it is not data, then the PKCS #9 attributes * content-type and message-digest will be automatically computed and * added to the signed attributes. */ public SignerInfo( SignerIdentifier signerIdentifier, SET signedAttributes, SET unsignedAttributes, OBJECT_IDENTIFIER contentType, byte[] messageDigest, SignatureAlgorithm signingAlg, PrivateKey signingKey ) throws InvalidKeyException, NoSuchAlgorithmException, NotInitializedException, SignatureException, TokenException { if (signerIdentifier == null) { throw new IllegalArgumentException("SignerIdentifier may not be null"); } this.signerIdentifier = signerIdentifier; if (SignerIdentifier.ISSUER_AND_SERIALNUMBER.equals(this.signerIdentifier.getType())) { this.version = new INTEGER(1); } else if (SignerIdentifier.SUBJECT_KEY_IDENTIFIER.equals(this.signerIdentifier.getType())) { this.version = new INTEGER(3); } else { throw new IllegalArgumentException("Unexpected SignerIdentifier type"); } this.digestAlgorithm = new AlgorithmIdentifier(signingAlg.getDigestAlg().toOID(),null); // if content-type is not data, add message-digest and content-type // to signed attributes. if( ! contentType.equals(ContentInfo.DATA) ) { if( signedAttributes == null ) { signedAttributes = new SET(); } Attribute attrib = new Attribute(CONTENT_TYPE, contentType); signedAttributes.addElement(attrib); attrib = new Attribute(MESSAGE_DIGEST, new OCTET_STRING(messageDigest) ); signedAttributes.addElement(attrib); } digestEncryptionAlgorithm = new AlgorithmIdentifier( signingAlg.toOID(),null ); if( signedAttributes != null ) { assert( signedAttributes.size() >= 2 ); this.signedAttributes = signedAttributes; } ////////////////////////////////////////////////// // create encrypted digest (signature) ////////////////////////////////////////////////// // compute the digest CryptoToken token = signingKey.getOwningToken(); Signature sig; byte[] toBeSigned = null; if (signedAttributes == null) { // just use the message digest of the content if (signingAlg.getRawAlg() == SignatureAlgorithm.RSASignature) { SEQUENCE digestInfo = createDigestInfo(messageDigest, false); toBeSigned = ASN1Util.encode(digestInfo); } else { toBeSigned = messageDigest; } sig = token.getSignatureContext(signingAlg.getRawAlg()); //data is already digested } else { byte[] encoding = ASN1Util.encode(signedAttributes); if (signingAlg.getRawAlg() == SignatureAlgorithm.RSASignature) { // put the digest in a DigestInfo SEQUENCE digestInfo = createDigestInfo(encoding, true); toBeSigned = ASN1Util.encode(digestInfo); sig = token.getSignatureContext(SignatureAlgorithm.RSASignature); } else { toBeSigned = encoding; sig = token.getSignatureContext(signingAlg); } } // encrypt the DER-encoded DigestInfo with the private key sig.initSign(signingKey); sig.update(toBeSigned); encryptedDigest = new OCTET_STRING(sig.sign()); if( unsignedAttributes != null ) { this.unsignedAttributes = unsignedAttributes; } } /** * A constructor for creating a new SignerInfo from its decoding. */ SignerInfo( INTEGER version, SignerIdentifier signerIdentifier, AlgorithmIdentifier digestAlgorithm, SET signedAttributes, AlgorithmIdentifier digestEncryptionAlgorithm, byte[] encryptedDigest, SET unsignedAttributes) { this.version = version; this.signerIdentifier = signerIdentifier; this.digestAlgorithm = digestAlgorithm; this.signedAttributes = signedAttributes; this.digestEncryptionAlgorithm = digestEncryptionAlgorithm; this.encryptedDigest = new OCTET_STRING(encryptedDigest); this.unsignedAttributes = unsignedAttributes; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Verification /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Verifies that this SignerInfo contains a valid signature of the * given message digest. If any signed attributes are present, * they are also validated. The verification algorithm is as follows: * Note that this does not verify the validity of the * the certificate itself, only the signature.
    * *
  • If no signed attributes are present, the content type is * verified to be data. Then it is verified that the message * digest passed * in, when encrypted with the given public key, matches the encrypted * digest in the SignerInfo. * *
  • If signed attributes are present, * two particular attributes must be present:
      *
    • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
    • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
    * After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * signedAttributes field. * *
* * @param messageDigest The hash of the content that is signed by this * SignerInfo. * @param contentType The type of the content that is signed by this * SignerInfo. * @exception ObjectNotFoundException If no certificate * matching the issuer name and serial number can be found. */ public void verify(byte[] messageDigest, OBJECT_IDENTIFIER contentType) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException, ObjectNotFoundException { CryptoManager cm = CryptoManager.getInstance(); if (signerIdentifier.getType().equals(SignerIdentifier.ISSUER_AND_SERIALNUMBER)) { IssuerAndSerialNumber issuerAndSerialNumber = signerIdentifier.getIssuerAndSerialNumber(); X509Certificate cert = cm.findCertByIssuerAndSerialNumber( ASN1Util.encode(issuerAndSerialNumber.getIssuer()), issuerAndSerialNumber.getSerialNumber() ); verify(messageDigest, contentType, cert.getPublicKey()); } else { assert( signerIdentifier.getType().equals(SignerIdentifier.SUBJECT_KEY_IDENTIFIER) ); // XXX Do we have method to get key using keyIdentifier } } /** * Verifies that this SignerInfo contains a valid signature of the * given message digest. If any signed attributes are present, * they are also validated. The verification algorithm is as follows:
    * *
  • If no signed attributes are present, the content type is * verified to be data. Then it is verified that the message * digest passed * in, when encrypted with the given public key, matches the encrypted * digest in the SignerInfo. * *
  • If signed attributes are present, * two particular attributes must be present:
      *
    • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
    • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
    * After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * signedAttributes field. * *
* * @param messageDigest The hash of the content that is signed by this * SignerInfo. * @param contentType The type of the content that is signed by this * SignerInfo. * @param pubkey The public key to use to verify the signature. */ public void verify(byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { if( signedAttributes == null ) { verifyWithoutSignedAttributes(messageDigest, contentType, pubkey); } else { verifyWithSignedAttributes(messageDigest, contentType, pubkey); } } /** * Verifies that the message digest passed in, when encrypted with the * given public key, matches the encrypted digest in the SignerInfo. */ private void verifyWithoutSignedAttributes (byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { if( ! contentType.equals(ContentInfo.DATA) ) { // only data can be signed this way. Everything else has // to go into signedAttributes. throw new SignatureException( "Content-Type is not DATA, but there are"+ " no signed attributes"); } SignatureAlgorithm sigAlg = SignatureAlgorithm.fromOID( digestEncryptionAlgorithm.getOID() ); CryptoToken token = CryptoManager.getInstance() .getInternalCryptoToken(); Signature sig; byte[] toBeVerified; if (sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature) { // create DigestInfo structure SEQUENCE digestInfo = createDigestInfo(messageDigest, false); toBeVerified = ASN1Util.encode(digestInfo); sig = token.getSignatureContext(sigAlg.getRawAlg()); } else { toBeVerified = messageDigest; sig = token.getSignatureContext(sigAlg); } sig.initVerify(pubkey); sig.update(toBeVerified); if( sig.verify(encryptedDigest.toByteArray()) ) { return; // success } else { throw new SignatureException( "Encrypted message digest parameter does not "+ "match encrypted digest in SignerInfo"); } } /** * Verifies a SignerInfo with signed attributes. If signed * attributes are present, then two particular attributes must * be present:
    *
  • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
  • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
* After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * signedAttributes field. */ private void verifyWithSignedAttributes (byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { int numAttrib = signedAttributes.size(); if(numAttrib < 2) { throw new SignatureException( "At least two signed attributes must be present:"+ " content-type and message-digest"); } // go through the signed attributes, verifying the // interesting ones boolean foundContentType = false; boolean foundMessageDigest = false; for( int i = 0; i < numAttrib; i++ ) { if( ! (signedAttributes.elementAt(i) instanceof Attribute)) { throw new SignatureException( "Element of signedAttributes is not an Attribute"); } Attribute attrib = (Attribute) signedAttributes.elementAt(i); if( attrib.getType().equals(CONTENT_TYPE) ) { // content-type. Compare with what was passed in. SET vals = attrib.getValues(); if( vals.size() != 1 ) { throw new SignatureException( "Content-Type attribute "+ " does not have exactly one value"); } ASN1Value val = vals.elementAt(0); OBJECT_IDENTIFIER ctype; try { if( val instanceof OBJECT_IDENTIFIER ) { ctype = (OBJECT_IDENTIFIER) val; } else if( val instanceof ANY ) { ctype = (OBJECT_IDENTIFIER) ((ANY)val).decodeWith( OBJECT_IDENTIFIER.getTemplate() ); } else { // what the heck is it? not what it's supposed to be throw new InvalidBERException( "Content-Type signed attribute has unexpected"+ " content type"); } } catch( InvalidBERException e ) { throw new SignatureException( "Content-Type signed attribute does not have "+ "OBJECT IDENTIFIER value"); } // compare the content type in the attribute to the // contentType parameter if( ! ctype.equals( contentType ) ) { throw new SignatureException( "Content-type in signed attributes does not "+ "match content-type being verified"); } // content type is A-OK foundContentType = true; } else if( attrib.getType().equals(MESSAGE_DIGEST) ) { SET vals = attrib.getValues(); if( vals.size() != 1 ) { throw new SignatureException( "Message-digest attribute does not have"+ " exactly one value"); } ASN1Value val = vals.elementAt(0); byte[] mdigest; try { if( val instanceof OCTET_STRING ) { mdigest = ((OCTET_STRING)val).toByteArray(); } else if( val instanceof ANY ) { OCTET_STRING os; os = (OCTET_STRING) ((ANY)val).decodeWith( OCTET_STRING.getTemplate() ); mdigest = os.toByteArray(); } else { // what the heck is it? not what it's supposed to be throw new InvalidBERException( "Content-Type signed attribute has unexpected"+ " content type"); } } catch( InvalidBERException e ) { throw new SignatureException( "Message-digest attribute does not"+ " have OCTET STRING value"); } // compare the message digest in the attribute to the // message digest being verified if( ! byteArraysAreSame(mdigest, messageDigest) ) { throw new SignatureException( "Message-digest attribute does not"+ " match message digest being verified"); } // message digest is A-OK foundMessageDigest = true; } // we don't care about other attributes } if( !foundContentType ) { throw new SignatureException( "Signed attributes does not contain"+ " PKCS #9 content-type attribute"); } if( !foundMessageDigest ) { throw new SignatureException( "Signed attributes does not contain"+ " PKCS #9 message-digest attribute"); } SignatureAlgorithm sigAlg = SignatureAlgorithm.fromOID( digestEncryptionAlgorithm.getOID() ); // All the signed attributes are present and correct. // Now verify the signature. CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); Signature sig; // verify the contents octets of the DER encoded signed attribs byte[] encoding = ASN1Util.encode(signedAttributes); byte[] toBeVerified; if (sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature) { // create DigestInfo structure SEQUENCE digestInfo = createDigestInfo(encoding, true); toBeVerified = ASN1Util.encode(digestInfo); sig = token.getSignatureContext(SignatureAlgorithm.RSASignature); } else { toBeVerified = encoding; sig = token.getSignatureContext(sigAlg); } sig.initVerify(pubkey); sig.update( toBeVerified ); if( ! sig.verify(encryptedDigest.toByteArray()) ) { // signature is invalid throw new SignatureException("encryptedDigest was not the correct"+ " signature of the contents octets of the DER-encoded"+ " signed attributes"); } // SUCCESSFULLY VERIFIED } private SEQUENCE createDigestInfo(byte[] data, boolean doDigest) throws NoSuchAlgorithmException { if(data == null || data.length == 0){ throw new IllegalArgumentException("Data to digest must be supplied"); } SEQUENCE digestInfo = new SEQUENCE(); digestInfo.addElement(this.digestAlgorithm); byte[] digest; if (doDigest) { MessageDigest md = MessageDigest.getInstance( DigestAlgorithm.fromOID(this.digestAlgorithm.getOID()).toString()); digest = md.digest(data); } else { digest = data; } digestInfo.addElement(new OCTET_STRING(digest)); return digestInfo; } /** * Compares two non-null byte arrays. Returns true if they are identical, * false otherwise. */ private static boolean byteArraysAreSame(byte[] left, byte[] right) { assert(left!=null && right!=null); if( left.length != right.length ) { return false; } for(int i = 0 ; i < left.length ; i++ ) { if( left[i] != right[i] ) { return false; } } return true; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // DER-encoding /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { SEQUENCE sequence = new SEQUENCE(); sequence.addElement( version ); sequence.addElement( signerIdentifier ); sequence.addElement( digestAlgorithm ); if( signedAttributes != null ) { sequence.addElement( new Tag(0), signedAttributes ); } sequence.addElement( digestEncryptionAlgorithm ); sequence.addElement( encryptedDigest ); if( unsignedAttributes != null ) { sequence.addElement( new Tag(1), unsignedAttributes ); } sequence.encode(tag,ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding a SignerInfo blob * */ public static class Template implements ASN1Template { SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); // serial number seqt.addElement(INTEGER.getTemplate()); // vn // issuerAndSerialNumber seqt.addElement(SignerIdentifier.getTemplate()); // signerId // digestAlgorithm seqt.addElement(AlgorithmIdentifier.getTemplate()); // digest alg // signedAttributes seqt.addOptionalElement( new Tag(0), new SET.OF_Template(Attribute.getTemplate())); // digestEncryptionAlgorithm seqt.addElement(AlgorithmIdentifier.getTemplate()); // dig encr alg // encryptedDigest seqt.addElement(OCTET_STRING.getTemplate()); // encr digest // unsigned attributes seqt.addOptionalElement( new Tag(1), new SET.OF_Template(Attribute.getTemplate())); } 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 implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); assert(seq.size() == 7); return new SignerInfo( (INTEGER) seq.elementAt(0), (SignerIdentifier) seq.elementAt(1), (AlgorithmIdentifier) seq.elementAt(2), (SET) seq.elementAt(3), (AlgorithmIdentifier) seq.elementAt(4), ((OCTET_STRING) seq.elementAt(5)).toByteArray(), (SET) seq.elementAt(6) ); } } // end of template } jss-4.6.3/org/mozilla/jss/pkix/cms/package.html000066400000000000000000000004261362106420000213720ustar00rootroot00000000000000 Creating and interpeting CMS blobs. jss-4.6.3/org/mozilla/jss/pkix/crmf/000077500000000000000000000000001362106420000172545ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkix/crmf/CertId.java000066400000000000000000000073121362106420000212740ustar00rootroot00000000000000/* 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.pkix.crmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * CRMF CertId. *
 * CertId ::= SEQUENCE {
 *      issuer          GeneralName,
 *      serialNumber    INTEGER }
 * 
*/ public class CertId implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private ANY issuer; private INTEGER serialNumber; private SEQUENCE sequence; /** * Returns the issuer field as an ANY. * The actual type of the field is GeneralName. */ public ANY getIssuer() { return issuer; } /** * Returns the serialNumber field. */ public INTEGER getSerialNumber() { return serialNumber; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Constructs a new CertId from its components. Neither * component may be null. */ public CertId(ANY issuer, INTEGER serialNumber) { if( issuer == null || serialNumber == null ) { throw new IllegalArgumentException( "parameter to CertId constructor is null"); } sequence = new SEQUENCE(); this.issuer = issuer; sequence.addElement(issuer); this.serialNumber = serialNumber; sequence.addElement(serialNumber); } /////////////////////////////////////////////////////////////////////// // 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 CertId. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( ANY.getTemplate() ); seqt.addElement( INTEGER.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 CertId( (ANY) seq.elementAt(0), (INTEGER) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/CertReqMsg.java000066400000000000000000000260241362106420000221370ustar00rootroot00000000000000/* 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.pkix.crmf; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.SignatureException; import java.text.DateFormat; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.InvalidKeyFormatException; import org.mozilla.jss.crypto.Signature; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.pkix.primitive.AVA; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo; import org.mozilla.jss.util.Assert; /** * This class models a CRMF CertReqMsg structure. */ public class CertReqMsg implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } /** * Retrieves the CertRequest contained in this structure. */ public CertRequest getCertReq() { return certReq; } private CertRequest certReq; /** * Returns true if this CertReqMsg has a * regInfo field. */ public boolean hasRegInfo() { return regInfo != null; } /** * Returns the regInfo field. Should only be called if the * field is present. */ public SEQUENCE getRegInfo() { assert(regInfo != null); return regInfo; } private SEQUENCE regInfo; /** * Returns true if this CertReqMsg has a * pop field. */ public boolean hasPop() { return pop != null; } /** * Returns the pop field. Should only be called if the * field is present. */ public ProofOfPossession getPop() { assert(pop != null); return pop; } private ProofOfPossession pop = null; /** * Constructs a CertReqmsg from a CertRequest and, optionally, * a pop and a regInfo. * @param pop May be NULL. * @param regInfo May be NULL. */ public CertReqMsg( CertRequest certReq, ProofOfPossession pop, SEQUENCE regInfo ) { this.certReq = certReq; this.pop = pop; this.regInfo = regInfo; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Verification /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// public void verify() throws SignatureException, InvalidKeyFormatException, NoSuchAlgorithmException, org.mozilla.jss.NotInitializedException, TokenException, java.security.InvalidKeyException, IOException{ CryptoToken token = CryptoManager.getInstance() .getInternalCryptoToken(); verify(token); } public void verify(CryptoToken token) throws SignatureException, InvalidKeyFormatException, NoSuchAlgorithmException, org.mozilla.jss.NotInitializedException, TokenException, java.security.InvalidKeyException, IOException{ ProofOfPossession.Type type = pop.getType(); if (type == ProofOfPossession.SIGNATURE) { POPOSigningKey sigkey = pop.getSignature(); AlgorithmIdentifier alg = sigkey.getAlgorithmIdentifier(); BIT_STRING sig_from = sigkey.getSignature(); ByteArrayOutputStream bo = new ByteArrayOutputStream(); certReq.encode(bo); byte[] toBeVerified = bo.toByteArray(); PublicKey pubkey = null; CertTemplate ct = certReq.getCertTemplate(); if (ct.hasPublicKey()) { SubjectPublicKeyInfo spi = ct.getPublicKey(); pubkey = spi.toPublicKey(); } SignatureAlgorithm sigAlg = SignatureAlgorithm.fromOID(alg.getOID()); Signature sig = token.getSignatureContext(sigAlg); sig.initVerify(pubkey); sig.update(toBeVerified); if( sig.verify(sig_from.getBits()) ) { //System.out.println("worked!!"); return; // success } else { throw new SignatureException( "Signed request information does not "+ "match signature in POP"); } } else if (type == ProofOfPossession.KEY_ENCIPHERMENT) { POPOPrivKey keyEnc = pop.getKeyEncipherment(); POPOPrivKey.Type ptype = keyEnc.getType(); if (ptype == POPOPrivKey.THIS_MESSAGE) { //BIT_STRING thisMessage = keyEnc.getThisMessage(); //This should be the same as from the archive control //It's verified by DRM. } else if (ptype == POPOPrivKey.SUBSEQUENT_MESSAGE) { new ChallengeResponseException("requested"); } } } /** * Encodes this CertReqMsg to the given OutputStream using * DER encoding. */ public void encode(OutputStream ostream) throws IOException { //Assert.notYetImplemented("CertReqMsg encoding"); encode(getTag(),ostream); } /** * Encodes this CertReqMsg to the given OutputStream using * DER encoding, with the given implicit tag. */ public void encode(Tag implicit, OutputStream ostream) throws IOException { //Assert.notYetImplemented("CertReqMsg encoding"); SEQUENCE sequence = new SEQUENCE(); sequence.addElement( certReq ); if (pop != null) sequence.addElement( pop ); if (regInfo != null) sequence.addElement( regInfo ); sequence.encode(implicit,ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A class for decoding CertReqMsg structures from a BER encoding. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag t) { return TAG.equals(t); } /** * Decodes a CertReqMsg from the given input stream. * * @return A new CertReqMsg. The return value may be cast * to a CertReqMsg. * @throws InvalidBERException If the data on the input stream is not * a valid BER encoding of a CertReqMsg. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } /** * Decodes a CertReqMsg from the given input stream, using * the given implicit tag. * * @param implicit The implicit tag for this item. This must be * supplied if the CertReqMsg appears in a context * where it is implicitly tagged. * @return A new CertReqMsg. The return value may be cast * to a CertReqMsg. * @throws InvalidBERException If the data on the input stream is not * a valid BER encoding of a CertReqMsg. */ public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement( new CertRequest.Template() ); seqt.addOptionalElement( new ProofOfPossession.Template()); seqt.addOptionalElement( new SEQUENCE.OF_Template( new AVA.Template() ) ); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); return new CertReqMsg( (CertRequest) seq.elementAt(0), (ProofOfPossession) seq.elementAt(1), (SEQUENCE) seq.elementAt(2) ); } } public static void main(String args[]) { try { if( args.length < 1 ) { System.err.println("Give an arg"); System.exit(0); } SEQUENCE.OF_Template seqt = new SEQUENCE.OF_Template( new CertReqMsg.Template() ); SEQUENCE seq=null; byte[] bytes; try (FileInputStream fis = new FileInputStream(args[0])) { bytes = new byte[fis.available()]; fis.read(bytes); } for(int i=0; i < 1; i++) { seq = (SEQUENCE) seqt.decode(new ByteArrayInputStream(bytes)); } System.out.println("Decoded "+seq.size()+" messages"); CertReqMsg reqmsg = (CertReqMsg) seq.elementAt(0); CertRequest certreq = reqmsg.getCertReq(); System.out.println("Request ID: "+certreq.getCertReqId() ); CertTemplate temp = certreq.getCertTemplate(); if( temp.hasVersion() ) { System.out.println("Version: "+temp.getVersion()); } else { System.out.println("No version"); } if( temp.hasSerialNumber() ) { System.out.println("Serial Number: "+temp.getSerialNumber()); } else { System.out.println("No serial number"); } if( temp.hasSigningAlg() ) { System.out.println("SigningAlg: "+temp.getSigningAlg().getOID()); } else { System.out.println("No signing alg"); } if( temp.hasIssuer() ) { System.out.println("Issuer: "+temp.getIssuer().getRFC1485()); } else { System.out.println("No issuer"); } if( temp.hasSubject() ) { System.out.println("Subject: "+temp.getSubject().getRFC1485()); } else { System.out.println("No subject: "); } if( temp.hasPublicKey() ) { System.out.println("Public Key: "+ temp.getPublicKey().getAlgorithmIdentifier().getOID() ); } else { System.out.println("No public key"); } if( temp.hasIssuerUID() ) { System.out.println("Issuer UID: "+new BigInteger(1, temp.getIssuerUID().getBits() ) ); } else { System.out.println("no issuer uid"); } if( temp.hasSubjectUID() ) { System.out.println("Subject UID: "+new BigInteger(1, temp.getIssuerUID().getBits() ) ); } else { System.out.println("no subject uid"); } if( temp.hasNotBefore() ) { System.out.println("Not Before: "+ DateFormat.getInstance().format( temp.getNotBefore() )); } if( temp.hasNotAfter() ) { System.out.println("Not After: "+ DateFormat.getInstance().format( temp.getNotAfter() )); } } catch( Exception e ) { e.printStackTrace(); } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/CertRequest.java000066400000000000000000000113001362106420000223600ustar00rootroot00000000000000/* 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.pkix.crmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AVA; /** * A PKIX CertRequest. Currently can only be decoded from its BER * encoding. There are no methods for constructing one. */ public class CertRequest implements ASN1Value { private INTEGER certReqId; private CertTemplate certTemplate; private SEQUENCE controls; // may be null /** * @param certReqId May NOT be null. * @param certTemplate May NOT be null. * @param controls May be null. */ public CertRequest(INTEGER certReqId, CertTemplate certTemplate, SEQUENCE controls) { if( certReqId == null ) { throw new NullPointerException("certReqId is null"); } this.certReqId = certReqId; if( certTemplate == null ) { throw new NullPointerException("certTemplate is null"); } this.certTemplate = certTemplate; this.controls = controls; } /** * Returns the certReqId (certificate request ID) field. */ public INTEGER getCertReqId() { return certReqId; } /** * Returns the CertTemplate field. */ public CertTemplate getCertTemplate() { return certTemplate; } /** * Returns the controls field. */ public SEQUENCE getControls() { return controls; } /** * Returns the number of optional Controls in the cert request. * The number may be zero. */ public int numControls() { if(controls == null) { return 0; } else { return controls.size(); } } /** * Returns the ith Control. i must be in the * range [0..numControls-1]. */ public AVA controlAt(int i) { if( controls == null ) { throw new ArrayIndexOutOfBoundsException(); } return (AVA) controls.elementAt(i); } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // DER-encoding /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } /** * This method is not yet supported. */ public void encode(OutputStream ostream) throws IOException { //Assert.notYetImplemented("CertRequest encoding"); encode(getTag(),ostream); } /** * This method is not yet supported. */ public void encode(Tag implicit, OutputStream ostream) throws IOException { //Assert.notYetImplemented("CertRequest encoding"); SEQUENCE sequence = new SEQUENCE(); sequence.addElement( certReqId ); sequence.addElement( certTemplate ); if (controls != null) sequence.addElement( controls ); sequence.encode(implicit,ostream); } /** * A Template class for constructing CertRequests from their * BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqTemplate; public Template() { seqTemplate = new SEQUENCE.Template(); seqTemplate.addElement( new INTEGER.Template() ); seqTemplate.addElement( new CertTemplate.Template() ); seqTemplate.addOptionalElement( new SEQUENCE.OF_Template( new AVA.Template() )); } 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 seq = (SEQUENCE) seqTemplate.decode(implicit, istream); return new CertRequest( (INTEGER) seq.elementAt(0), (CertTemplate) seq.elementAt(1), (SEQUENCE) seq.elementAt(2) ); } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/CertTemplate.java000066400000000000000000000373341362106420000225220ustar00rootroot00000000000000/* 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.pkix.crmf; import org.mozilla.jss.asn1.*; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.io.IOException; import java.util.Date; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.Extension; import java.util.Calendar; import java.util.TimeZone; /** * This class models a CRMF CertTemplate structure. */ public class CertTemplate implements ASN1Value { // All of these may be null private INTEGER version; private INTEGER serialNumber; private AlgorithmIdentifier signingAlg; private Name issuer; private Date notBefore; private Date notAfter; private Name subject; private SubjectPublicKeyInfo publicKey; private BIT_STRING issuerUID; private BIT_STRING subjectUID; private SEQUENCE extensions; /** * Creates an empty CertTemplate. Use the accessor methods to fill it * up with stuff. */ public CertTemplate() { } /** * Returns true if the version field is present. */ public boolean hasVersion() { return (version!=null); } /** * Returns the version field of this CertTemplate. */ public INTEGER getVersion() { return version; } /** * Sets the version field of this CertTemplate. */ public void setVersion(INTEGER version) { this.version = version; } /** * Returns true if the serialNumber field is present. */ public boolean hasSerialNumber() { return (serialNumber!=null); } /** * Returns the serialNumber field of this CertTemplate. */ public INTEGER getSerialNumber() { return serialNumber; } /** * Sets the serialNumber field of this CertTemplate. */ public void setSerialNumber(INTEGER serialNumber) { this.serialNumber = serialNumber; } /** * Returns true if the signingAlg field is present. */ public boolean hasSigningAlg() { return (signingAlg!=null); } /** * Returns the signingAlg field of this CertTemplate. */ public AlgorithmIdentifier getSigningAlg() { return signingAlg; } /** * Sets the signingAlg field of this CertTemplate. */ public void setSigningAlg(AlgorithmIdentifier signingAlg) { this.signingAlg = signingAlg; } /** * Returns true if the issuer field is present. */ public boolean hasIssuer() { return (issuer!=null); } /** * Returns the issuer field of this CertTemplate. */ public Name getIssuer() { return issuer; } /** * Sets the issuer field of this CertTemplate. */ public void setIssuer(Name issuer) { this.issuer = issuer; } /** * Returns true if the notBefore field is present. */ public boolean hasNotBefore() { return (notBefore!=null); } /** * Returns the notBefore field of this CertTemplate. */ public Date getNotBefore() { return notBefore; } /** * Sets the version field of this CertTemplate. */ public void setNotBefore(Date date) { this.notBefore = date; } /** * Returns true if the notAfter field is present. */ public boolean hasNotAfter() { return (notAfter!=null); } /** * Returns the notAfter field of this CertTemplate. */ public Date getNotAfter() { return notAfter; } /** * Sets the notAfter field of this CertTemplate. */ public void setNotAfter(Date date) { this.notAfter = date; } /** * Returns true if the subject field is present. */ public boolean hasSubject() { return (subject!=null); } /** * Sets the subject field of this CertTemplate. */ public Name getSubject() { return subject; } /** * Sets the subject field of this CertTemplate. */ public void setSubject(Name subject) { this.subject = subject; } /** * Returns true if the publicKey field is present. */ public boolean hasPublicKey() { return (publicKey!=null); } /** * Returns the publicKey field of this CertTemplate. */ public SubjectPublicKeyInfo getPublicKey() { return publicKey; } /** * Sets the publicKey field of this CertTemplate. */ public void setPublicKey(SubjectPublicKeyInfo publicKey) { this.publicKey = publicKey; } /** * Returns true if the issuerUID field is present. */ public boolean hasIssuerUID() { return (issuerUID!=null); } /** * Returns the issuerUID field of this CertTemplate. */ public BIT_STRING getIssuerUID() { return issuerUID; } /** * Sets the issuerUID field of this CertTemplate. */ public void setIssuerUID(BIT_STRING issuerUID) { this.issuerUID = issuerUID; } /** * Returns true if the subjectUID field is present. */ public boolean hasSubjectUID() { return (subjectUID!=null); } /** * Returns the subjectUID field of this CertTemplate. */ public BIT_STRING getSubjectUID() { return subjectUID; } /** * Sets the subjectUID field of this CertTemplate. */ public void setSubjectUID(BIT_STRING subjectUID) { this.subjectUID = subjectUID; } /** * Returns true if the extensions field is present. */ public boolean hasExtensions() { return (extensions!=null); } /** * Sets the extensions field of this CertTemplate. */ public void setExtensions(SEQUENCE extensions) { this.extensions = extensions; } /** * Returns the number of extensions present in the template. May be zero. */ public int numExtensions() { if(extensions == null) { return 0; } else { return extensions.size(); } } /** * Returns the ith extension. * @param idx The index of the extension to retrieve. Must be in the * range [ 0, numExtensions()-1 ]. */ public Extension extensionAt(int idx) { if(extensions == null) { throw new ArrayIndexOutOfBoundsException(); } return (Extension) extensions.elementAt(idx); } public void print(PrintStream ps, int indentSpaces) throws InvalidBERException, IOException { StringBuffer indentBuf = new StringBuffer(); for(int i=0; i < indentSpaces; i++) { indentBuf.append(" "); } String indent = indentBuf.toString(); if(version!=null) { ps.println("Version: "+version.toString()); } if(serialNumber!=null) { ps.println("Serial Number: "+serialNumber.toString()); } if(signingAlg!=null) { ps.println("Signing Algorithm: "+signingAlg.getOID().toString()); } if(issuer!=null) { ps.println("Issuer: "+issuer.getRFC1485()); } if(notBefore!=null) { ps.println("Not Before: " + notBefore); } if(notAfter!=null) { ps.println("Not After: " + notAfter); } if(subject!=null) { ps.println("Subject: " + subject.getRFC1485()); } if(publicKey!=null) { ps.println("publicKey is present"); } if(issuerUID != null ) { ps.println("issuerUID is present"); } if(subjectUID != null ) { ps.println("subjectUID is present"); } if(extensions != null ) { ps.println("Extensions is present, with "+extensions.size()+ " elements"); } } public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } // the last year for using UTCTime static final int UTCTIME_CUTOFF_YEAR = 2049; /** * Converts a Date into a UTCTime or GeneralizedTime, depending on * whether it falls before or after the cutoff date. */ private static TimeBase dateToASN1(Date d) { if(d==null) { return null; } Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("GMT") ); cal.setTime(d); if( cal.get(Calendar.YEAR) <= UTCTIME_CUTOFF_YEAR) { return new UTCTime(d); } else { return new GeneralizedTime(d); } } public void encode(Tag t, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(Tag.get(0), version); seq.addElement(Tag.get(1), serialNumber); seq.addElement(Tag.get(2), signingAlg); if( issuer!=null ) { // issuer is a CHOICE, so it must be EXPLICITly tagged seq.addElement(new EXPLICIT(Tag.get(3), issuer )); } if( notBefore!=null || notAfter!=null ) { SEQUENCE optionalVal = new SEQUENCE(); // notBefore & notAfter are CHOICES, so must be EXPLICITly tagged if( notBefore!=null ) { optionalVal.addElement( new EXPLICIT( Tag.get(0), dateToASN1(notBefore) ) ); } if( notAfter!=null ) { optionalVal.addElement( new EXPLICIT( Tag.get(1), dateToASN1(notAfter) ) ); } seq.addElement(Tag.get(4), optionalVal); } if( subject!=null ) { // subject is a CHOICE, so it must be EXPLICITly tagged seq.addElement(new EXPLICIT(Tag.get(5), subject)); } seq.addElement(Tag.get(6), publicKey); seq.addElement(Tag.get(7), issuerUID); seq.addElement(Tag.get(8), subjectUID); seq.addElement(Tag.get(9), extensions); seq.encode(t, ostream); } private static Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A class for decoding CertTemplates. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return TAG.equals(tag); } /** * Decodes a CertTemplate from its BER encoding. The return * value of this method */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { CHOICE.Template timeChoice = new CHOICE.Template(); timeChoice.addElement( new GeneralizedTime.Template() ); timeChoice.addElement( new UTCTime.Template() ); // optional validity. The times are CHOICEs, so they are // EXPLICITly tagged SEQUENCE.Template validity = new SEQUENCE.Template(); validity.addOptionalElement( new EXPLICIT.Template( Tag.get(0), timeChoice)); validity.addOptionalElement( new EXPLICIT.Template( Tag.get(1), timeChoice)); SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addOptionalElement( Tag.get(0), new INTEGER.Template() ); seqt.addOptionalElement( Tag.get(1), new INTEGER.Template() ); seqt.addOptionalElement( Tag.get(2), new AlgorithmIdentifier.Template() ); seqt.addOptionalElement( new EXPLICIT.Template(Tag.get(3), new Name.Template() )); seqt.addOptionalElement( Tag.get(4), validity ); seqt.addOptionalElement( new EXPLICIT.Template(Tag.get(5), new Name.Template() )); seqt.addOptionalElement( Tag.get(6), new SubjectPublicKeyInfo.Template() ); seqt.addOptionalElement( Tag.get(7), new BIT_STRING.Template() ); seqt.addOptionalElement( Tag.get(8), new BIT_STRING.Template() ); seqt.addOptionalElement( Tag.get(9), new SEQUENCE.OF_Template( new Extension.Template() ) ); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); CertTemplate ct = new CertTemplate(); ct.setVersion( (INTEGER) seq.elementAt(0) ); ct.setSerialNumber( (INTEGER) seq.elementAt(1) ); ct.setSigningAlg( (AlgorithmIdentifier) seq.elementAt(2) ); if( seq.elementAt(3) != null ) { ct.setIssuer((Name)((EXPLICIT)seq.elementAt(3)).getContent() ); } // validity EXPLICIT explicit; CHOICE choice; ASN1Value val; if( seq.elementAt(4) != null ) { explicit = (EXPLICIT) ((SEQUENCE)seq.elementAt(4)).elementAt(0); if( explicit != null ) { choice = (CHOICE) explicit.getContent(); val = choice.getValue(); if( val instanceof TimeBase ) { ct.setNotBefore( ((TimeBase)val).toDate() ); } } explicit = (EXPLICIT) ((SEQUENCE)seq.elementAt(4)).elementAt(1); if( explicit != null ) { choice = (CHOICE) explicit.getContent(); val = choice.getValue(); if( val instanceof TimeBase ) { ct.setNotAfter( ((TimeBase)val).toDate() ); } } } if( seq.elementAt(5) != null ) { ct.setSubject((Name)((EXPLICIT)seq.elementAt(5)).getContent() ); } ct.setPublicKey( (SubjectPublicKeyInfo) seq.elementAt(6) ); ct.setIssuerUID( (BIT_STRING) seq.elementAt(7) ); ct.setSubjectUID( (BIT_STRING) seq.elementAt(8) ); ct.setExtensions( (SEQUENCE) seq.elementAt(9) ); return ct; } } public static void main(String args[]) { try { CertTemplate ct = new CertTemplate(); Name name; ct.setVersion(new INTEGER(5)); ct.setSerialNumber(new INTEGER(13112)); name = new Name(); name.addCommonName("You"); name.addStateOrProvinceName("California"); ct.setIssuer(name); ct.setNotBefore(new Date()); name = new Name(); name.addCommonName("Me"); name.addCountryName("US"); ct.setSubject(name); ct.setIssuerUID( new BIT_STRING( new byte[] {0x00, 0x01}, 0 ) ); System.out.println("Constructed CertTemplate:"); byte[] encoded = ASN1Util.encode(ct); java.io.FileOutputStream fos = new java.io.FileOutputStream("certTemplate"); fos.write(encoded); fos.close(); ct.print(System.out, 0); CertTemplate newCt = (CertTemplate) ASN1Util.decode( CertTemplate.getTemplate(), encoded ); System.out.println("\nDecoded CertTemplate:"); newCt.print(System.out, 0); } catch( Exception e ) { e.printStackTrace(); } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/ChallengeResponseException.java000066400000000000000000000024721362106420000254040ustar00rootroot00000000000000/* 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.pkix.crmf; /** * An exception thrown when challenge response pop is requested. */ public class ChallengeResponseException extends java.lang.Exception { private static final long serialVersionUID = 1L; private ChallengeResponseException child=null; public ChallengeResponseException(String mesg) { super(mesg); } public ChallengeResponseException(ChallengeResponseException e, String mesg) { super(mesg); child = e; } /** * Prints out the exception class and error message, including * all the nested exceptions. */ public String toString() { if(child != null) { return (super.toString()+ " >> " + child.toStringNested()); } else { return super.toString(); } } /** * Prints out the error message of this exception, including all the * nested exceptions. */ public String toStringNested() { if(child != null) { return ( getMessage() + " >> " + child.toStringNested()); } else { return getMessage(); } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/Control.java000066400000000000000000000065461362106420000215520ustar00rootroot00000000000000/* 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.pkix.crmf; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.pkix.primitive.AVA; /** * A CRMF Control. */ public class Control extends AVA implements ASN1Value { // general CRMF OIDs public static final OBJECT_IDENTIFIER id_pkix = new OBJECT_IDENTIFIER( new long[] { 1, 3, 6, 1, 5, 5, 7 } ); public static final OBJECT_IDENTIFIER id_pkip = id_pkix.subBranch( 5 ); public static final OBJECT_IDENTIFIER id_regCtrl = id_pkip.subBranch( 1 ); // Control OIDs public static final OBJECT_IDENTIFIER id_regCtrl_regToken = id_regCtrl.subBranch(1); public static final OBJECT_IDENTIFIER id_regCtrl_authenticator = id_regCtrl.subBranch(2); public static final OBJECT_IDENTIFIER id_regCtrl_pkiPublicationInfo = id_regCtrl.subBranch(3); public static final OBJECT_IDENTIFIER id_regCtrl_pkiArchiveOptions = id_regCtrl.subBranch(4); public static final OBJECT_IDENTIFIER id_regCtrl_oldCertID = id_regCtrl.subBranch(5); public static final OBJECT_IDENTIFIER id_regCtrl_protocolEncrKey = id_regCtrl.subBranch(6); public Control(OBJECT_IDENTIFIER oid, ASN1Value value) { super(oid, value); } /** * Returns the value of this control as a UTF8String, if it actually * is a UTF8String. */ public UTF8String getUTF8String() throws InvalidBERException { return (UTF8String) getValue().decodeWith(UTF8String.getTemplate()); } /** * Returns the value of this control as a PKIArchiveOptions, if it * actually is a PKIArchiveOptions. */ public PKIArchiveOptions getPKIArchiveOptions() throws InvalidBERException { return (PKIArchiveOptions) getValue().decodeWith( PKIArchiveOptions.getTemplate() ); } /** * Returns the value of this control as a PKIPublicationInfo, if it * actually is a PKIPublicationInfo. */ public PKIPublicationInfo getPKIPublicationInfo() throws InvalidBERException { return (PKIPublicationInfo) getValue().decodeWith( PKIPublicationInfo.getTemplate() ); } /** * A template class for decoding a Control from a BER stream. */ public static class Template extends AVA.Template implements ASN1Template { private SEQUENCE.Template seqTemplate; public Template() { seqTemplate = new SEQUENCE.Template(); seqTemplate.addElement( new OBJECT_IDENTIFIER.Template() ); seqTemplate.addElement( new ANY.Template() ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqTemplate.decode(implicit, istream); OBJECT_IDENTIFIER oid = (OBJECT_IDENTIFIER) seq.elementAt(0); ANY any = (ANY) seq.elementAt(1); return new Control( oid, any ); } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/EncryptedKey.java000066400000000000000000000116671362106420000225400ustar00rootroot00000000000000/* 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.pkix.crmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.CHOICE; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; public class EncryptedKey implements ASN1Value { /** * The type of EncryptedKey. */ public static class Type { private Type() { } static final Type ENCRYPTED_VALUE = new Type(); static final Type ENVELOPED_DATA = new Type(); } public static final Type ENCRYPTED_VALUE = Type.ENCRYPTED_VALUE; public static final Type ENVELOPED_DATA = Type.ENVELOPED_DATA; /////////////////////////////////////////////////////////////////////// // member and member access /////////////////////////////////////////////////////////////////////// private Type type; private EncryptedValue encryptedValue; private ANY envelopedData; public Type getType() { return type; } /** * Should only be called if getType returns * ENCRYPTED_VALUE. */ public EncryptedValue getEncryptedValue() { return encryptedValue; } /** * Should only be called if getType returns * ENVELOPED_DATA. ANY is returned to prevent a circular * dependency between the org.mozilla.jss.pkcs7 package and the * org.mozilla.jss.pkix hierarchy. */ public ANY getEnvelopedData() { return envelopedData; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// public EncryptedKey(EncryptedValue encryptedValue) { this.type = ENCRYPTED_VALUE; this.encryptedValue = encryptedValue; this.tag = SEQUENCE.TAG; } public EncryptedKey(ANY envelopedData) { this.type = ENVELOPED_DATA; this.envelopedData = envelopedData; this.tag = new Tag(0); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private Tag tag; // set by constructor based on type public Tag getTag() { return tag; } public void encode(OutputStream ostream) throws IOException { encode(getTag(), ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { // no IMPLICIT tags allowed on ANY assert( getTag().equals(implicitTag)); if( type == ENCRYPTED_VALUE ) { assert( encryptedValue != null ); encryptedValue.encode(implicitTag, ostream); } else { assert(type == ENVELOPED_DATA); assert(envelopedData != null); envelopedData.encode(implicitTag, ostream); } } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding BER-encoded EncryptedKeys. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); choicet.addElement( EncryptedValue.getTemplate() ); choicet.addElement( new Tag(0), ANY.getTemplate() ); } public boolean tagMatch(Tag tag) { return choicet.tagMatch(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { try { CHOICE choice = (CHOICE) choicet.decode(istream); if( choice.getTag().equals(SEQUENCE.TAG) ) { return new EncryptedKey( (EncryptedValue) choice.getValue() ); } else { assert( choice.getTag().equals(new Tag(0)) ); return new EncryptedKey( (ANY) choice.getValue() ); } } catch(InvalidBERException e) { throw new InvalidBERException(e, "EncryptedKey"); } } /** * @param implicitTag This parameter is ignored, because a CHOICE * cannot have an implicitTag. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { throw new RuntimeException("EncryptedKey, being a CHOICE, cannot be"+ " implicitly tagged"); // return decode(istream); } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/EncryptedValue.java000066400000000000000000000142401362106420000230520ustar00rootroot00000000000000/* 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.pkix.crmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; /** * The CRMF structure EncryptedValue for storing the encrypted * key to be archived. */ public class EncryptedValue implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private AlgorithmIdentifier intendedAlg; // may be null private AlgorithmIdentifier symmAlg; // may be null private BIT_STRING encSymmKey; // may be null private AlgorithmIdentifier keyAlg; // may be null private OCTET_STRING valueHint; // may be null private BIT_STRING encValue; // may be null private SEQUENCE sequence; /** * May return null. */ public AlgorithmIdentifier getIntendedAlg() { return intendedAlg; } /** * May return null. */ public AlgorithmIdentifier getSymmAlg() { return symmAlg; } /** * May return null. */ public BIT_STRING getEncSymmKey() { return encSymmKey; } /** * May return null. */ public AlgorithmIdentifier getKeyAlg() { return keyAlg; } /** * May return null. */ public OCTET_STRING getValueHint() { return valueHint; } public BIT_STRING getEncValue() { return encValue; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * @param intendedAlg May be null. * @param symmAlg May be null. * @param encSymmKey May be null. * @param keyAlg May be null. * @param valueHint May be null. * @param encValue May not be null. */ public EncryptedValue( AlgorithmIdentifier intendedAlg, AlgorithmIdentifier symmAlg, BIT_STRING encSymmKey, AlgorithmIdentifier keyAlg, OCTET_STRING valueHint, BIT_STRING encValue ) { if( encValue == null ) { throw new IllegalArgumentException("encValue is null"); } this.intendedAlg = intendedAlg; this.symmAlg = symmAlg; this.encSymmKey = encSymmKey; this.keyAlg = keyAlg; this.valueHint = valueHint; this.encValue = encValue; sequence = new SEQUENCE(); if(intendedAlg!=null) { sequence.addElement( new Tag(0), intendedAlg ); } if( symmAlg!=null ) { sequence.addElement( new Tag(1), symmAlg ); } if( encSymmKey!=null ) { sequence.addElement( new Tag(2), encSymmKey ); } if( keyAlg!=null ) { sequence.addElement( new Tag(3), keyAlg ); } if( valueHint!=null ) { sequence.addElement( new Tag(4), valueHint ); } sequence.addElement(encValue); } /////////////////////////////////////////////////////////////////////// // 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 class for decoding BER-encoded EncryptedValues. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addOptionalElement( new Tag(0), AlgorithmIdentifier.getTemplate()); seqt.addOptionalElement( new Tag(1), AlgorithmIdentifier.getTemplate()); seqt.addOptionalElement( new Tag(2), BIT_STRING.getTemplate()); seqt.addOptionalElement( new Tag(3), AlgorithmIdentifier.getTemplate()); seqt.addOptionalElement( new Tag(4), OCTET_STRING.getTemplate()); seqt.addElement( BIT_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 { try { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new EncryptedValue( (AlgorithmIdentifier) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (BIT_STRING) seq.elementAt(2), (AlgorithmIdentifier) seq.elementAt(3), (OCTET_STRING) seq.elementAt(4), (BIT_STRING) seq.elementAt(5) ); } catch(InvalidBERException e ) { throw new InvalidBERException(e, "EncryptedValue"); } } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/PKIArchiveOptions.java000066400000000000000000000156371362106420000234340ustar00rootroot00000000000000/* 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.pkix.crmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BOOLEAN; import org.mozilla.jss.asn1.CHOICE; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; public class PKIArchiveOptions implements ASN1Value { /** * A type of PKIArchiveOption. */ public static class Type { private Type() { } static final Type ENCRYPTED_PRIV_KEY = new Type(); static final Type KEY_GEN_PARAMETERS = new Type(); static final Type ARCHIVE_REM_GEN_PRIV_KEY = new Type(); } public static final Type ENCRYPTED_PRIV_KEY = Type.ENCRYPTED_PRIV_KEY; public static final Type KEY_GEN_PARAMETERS = Type.KEY_GEN_PARAMETERS; public static final Type ARCHIVE_REM_GEN_PRIV_KEY = Type.ARCHIVE_REM_GEN_PRIV_KEY; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private EncryptedKey encryptedPrivKey; private OCTET_STRING keyGenParameters; private boolean archiveRemGenPrivKey; private Type type; /** * Returns the type of PKIArchiveOptions. */ public Type getType() { return type; } /** * Returns the encrypted key. Should only be called if the type * is ENCRYPTED_PRIV_KEY. */ public EncryptedKey getEncryptedKey( ) { assert(type == ENCRYPTED_PRIV_KEY); return encryptedPrivKey; } /** * Returns the key gen parameters. Should only be called if the type * is KEY_GEN_PARAMETERS. public byte[] getKeyGenParameters( ) { assert(type == KEY_GEN_PARAMETERS); return keyGenParameters; } /** * Returns the archiveRemGenPrivKey field, which indicates that * the sender wishes the receiver to generate and archive a key pair. * Should only be called if the type is * ARCHIVE_REM_GEN_PRIV_KEY. */ public boolean getArchiveRemGenPrivKey( ) { assert( type == ARCHIVE_REM_GEN_PRIV_KEY ); return archiveRemGenPrivKey; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// public PKIArchiveOptions( EncryptedKey eKey ) { encryptedPrivKey = eKey; type = ENCRYPTED_PRIV_KEY; tag = new Tag(0); } public PKIArchiveOptions( byte[] keyGenParameters ) { this.keyGenParameters = new OCTET_STRING(keyGenParameters); type = KEY_GEN_PARAMETERS; tag = new Tag(1); } public PKIArchiveOptions( boolean archiveRemGenPrivKey ) { this.archiveRemGenPrivKey = archiveRemGenPrivKey; type = ARCHIVE_REM_GEN_PRIV_KEY; tag = new Tag(2); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private Tag tag; // set by the constructor depending on the type public Tag getTag() { return tag; } /** * DER-encodes a PKIArchiveOptions. */ public void encode(OutputStream ostream) throws IOException { encode( getTag(), ostream ); } /** * DER-encodes a PKIArchiveOptions. * @param implicitTag This parameter is ignored. A CHOICE cannot * have an implicit tag. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { // no implicit tags on a CHOICE assert( implicitTag.equals(tag) ); if( type == ENCRYPTED_PRIV_KEY ) { // CHOICEs are always EXPLICITly tagged EXPLICIT explicit = new EXPLICIT( new Tag(0), encryptedPrivKey ); explicit.encode(tag, ostream); } else if( type == KEY_GEN_PARAMETERS ) { keyGenParameters.encode(tag, ostream); } else { assert( type == ARCHIVE_REM_GEN_PRIV_KEY ); (new BOOLEAN(archiveRemGenPrivKey)).encode(tag, ostream); } } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding PKIArchiveOptions. */ public static class Template implements ASN1Template { CHOICE.Template template; public Template() { template = new CHOICE.Template(); // CHOICEs are always EXPLICIT template.addElement( new EXPLICIT.Template( new Tag(0), new EncryptedKey.Template() )); template.addElement( new Tag(1), new OCTET_STRING.Template() ); template.addElement( new Tag(2), new BOOLEAN.Template() ); } /** * Returns true if the given tag can satisfy this CHOICE. */ public boolean tagMatch(Tag tag) { return template.tagMatch(tag); } /** * Decodes a PKIArchiveOptions. * @return A PKIArchiveOptions object. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { CHOICE choice = (CHOICE) template.decode(istream); if( choice.getTag().getNum() == 0 ) { EncryptedKey ekey = (EncryptedKey) ((EXPLICIT)choice.getValue()).getContent(); return new PKIArchiveOptions(ekey); } else if( choice.getTag().getNum() == 1 ) { OCTET_STRING kgp = (OCTET_STRING) choice.getValue(); return new PKIArchiveOptions(kgp.toByteArray()); } else if( choice.getTag().getNum() == 2 ) { BOOLEAN arckey = (BOOLEAN) choice.getValue(); return new PKIArchiveOptions(arckey.toBoolean()); } else { String s = "Unrecognized tag in PKIArchiveOptions"; throw new InvalidBERException(s); } } /** * Decodes a PKIArchiveOptions. * @param implicitTag This parameter is ignored. Since * PKIArchiveOptions is a CHOICE, it cannot have an implicit tag. * @return A PKIArchiveOptions object. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { return decode(istream); } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/PKIPublicationInfo.java000066400000000000000000000124521362106420000235540ustar00rootroot00000000000000/* 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.pkix.crmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * CRMF PKIPublicationInfo: *
 * PKIPublicationInfo ::= SEQUENCE {
 *      action          INTEGER {
 *          dontPublish     (0),
 *          pleasePublish   (1) },
 *      pubInfos SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL }
 *
 * SinglePubInfo ::= SEQUENCE {
 *      pubMethod       INTEGER {
 *          dontCare    (0),
 *          x500        (1),
 *          web         (2),
 *          ldap        (3) },
 *      pubLocation     GeneralName OPTIONAL }
 * 
*/ public class PKIPublicationInfo implements ASN1Value { /** * A PKIPublicationInfo action. */ public static final int DONT_PUBLISH = 0; /** * A PKIPublicationInfo action. */ public static final int PLEASE_PUBLISH = 1; /** * A SinglePubInfo publication method. */ public static final int DONT_CARE = 0; /** * A SinglePubInfo publication method. */ public static final int X500 = 1; /** * A SinglePubInfo publication method. */ public static final int WEB = 2; /** * A SinglePubInfo publication method. */ public static final int LDAP = 3; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private int action; private SEQUENCE pubInfos; // may be null /** * Returns the action field. */ public int getAction() { return action; } /** * Returns the number of SinglePubInfos. May be zero. */ public int numPubInfos() { if( pubInfos == null ) { return 0; } else { return pubInfos.size(); } } /** * Returns the pubMethod in the SinglePubInfo at the given index. * Should return DONT_CARE, X500, WEB, or LDAP. */ public int getPubMethod(int index) { return ((INTEGER)((SEQUENCE)pubInfos.elementAt(index)). elementAt(0)).intValue(); } /** * Returns the pubLocation in the SinglePubInfo at the given index. * May return null, since pubLocation is an optional field. */ public ANY getPubLocation(int index) { return (ANY) ((SEQUENCE)pubInfos.elementAt(index)).elementAt(1); } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// /** * Creates a new PKIPublicationInfo. * @param action DONT_PUBLISH or PLEASE_PUBLISH. * @param pubInfos A SEQUENCE of SinglePubInfo, may be null. */ public PKIPublicationInfo(int action, SEQUENCE pubInfos) { this.action = action; this.pubInfos = pubInfos; } /////////////////////////////////////////////////////////////////////// // decoding/encoding /////////////////////////////////////////////////////////////////////// private 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( new INTEGER(action) ); seq.addElement( pubInfos ); seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a PKIPublicationInfo. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); SEQUENCE.Template pubInfot = new SEQUENCE.Template(); pubInfot.addElement(INTEGER.getTemplate()); pubInfot.addOptionalElement(ANY.getTemplate()); seqt.addOptionalElement( new SEQUENCE.OF_Template(pubInfot) ); } 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 PKIPublicationInfo( ((INTEGER)seq.elementAt(0)).intValue(), (SEQUENCE) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/POPOPrivKey.java000066400000000000000000000166141362106420000222160ustar00rootroot00000000000000/* 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.pkix.crmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.CHOICE; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * CRMF POPOPrivKey: *
 * POPOPrivKey ::= CHOICE {
 *      thisMessage         [0] BIT STRING,
 *      subsequentMessage   [1] SubsequentMessage,
 *      dhMAC               [2] BIT STRING }
 *
 * SubsequentMessage ::= INTEGER {
 *      encrCert        (0),
 *      challengeResp   (1) }
 * 
*/ public class POPOPrivKey implements ASN1Value { /** * The type of POPOPrivKey. */ public static class Type { private Type() { } static final Type THIS_MESSAGE = new Type(); static final Type SUBSEQUENT_MESSAGE = new Type(); static final Type DHMAC = new Type(); } public static final Type THIS_MESSAGE = Type.THIS_MESSAGE; public static final Type SUBSEQUENT_MESSAGE = Type.SUBSEQUENT_MESSAGE; public static final Type DHMAC = Type.DHMAC; /** * The SubsequentMessage field is encrCert. */ public static final int ENCR_CERT = 0; /** * The SubsequentMessage field is challengeResp. */ public static final int CHALLENGE_RESP = 1; /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private Type type; private BIT_STRING thisMessage; // if type == THIS_MESSAGE private INTEGER subsequentMessage; // if type == SUBSEQUENT_MESSAGE private BIT_STRING dhMAC; // if type == DHMAC /** * Returns the type of POPOPrivKey: THIS_MESSAGE, SUBSEQUENT_MESSAGE, * or DHMAC. */ public Type getType() { return type; } /** * If type==THIS_MESSAGE, returns the thisMessage field. Otherwise, * returns null. */ public BIT_STRING getThisMessage() { return thisMessage; } /** * If type==SUBSEQUENT_MESSAGE, returns the subsequentMessage field. * Otherwise, returns null. The return value can be converted to an * integer and compared with ENCR_CERT and CHALLENGE_RESP. */ public INTEGER getSubsequentMessage() { return subsequentMessage; } /** * If type==DHMAC, returns the dhMAC field. Otherwise, returns null. */ public BIT_STRING getDhMAC() { return dhMAC; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private POPOPrivKey() { } private POPOPrivKey(Type type, BIT_STRING thisMessage, INTEGER subsequentMessage, BIT_STRING dhMAC) { this.type = type; this.thisMessage = thisMessage; this.subsequentMessage = subsequentMessage; this.dhMAC = dhMAC; } /** * Creates a new POPOPrivKey with the given thisMessage field. */ public static POPOPrivKey createThisMessage(BIT_STRING thisMessage) { return new POPOPrivKey(THIS_MESSAGE, thisMessage, null, null); } /** * Creates a new POPOPrivKey with the given subsequentMessage field. */ public static POPOPrivKey createSubsequentMessage(int subsequentMessage) { if(subsequentMessage!=ENCR_CERT && subsequentMessage!=CHALLENGE_RESP) { throw new IllegalArgumentException( "Illegal subsequentMessage value: " + subsequentMessage ); } return new POPOPrivKey(SUBSEQUENT_MESSAGE, null, new INTEGER(subsequentMessage), null); } /** * Creates a new POPOPrivKey with the given dhMAC field. */ public static POPOPrivKey createDhMAC(BIT_STRING dhMAC) { return new POPOPrivKey(DHMAC, null, null, dhMAC); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { if(type == THIS_MESSAGE) { return Tag.get(0); } else if(type == SUBSEQUENT_MESSAGE) { return Tag.get(1); } else { assert(type == DHMAC); return Tag.get(2); } } public void encode(OutputStream ostream) throws IOException { if(type == THIS_MESSAGE) { thisMessage.encode(Tag.get(0), ostream); } else if(type == SUBSEQUENT_MESSAGE) { subsequentMessage.encode(Tag.get(1), ostream); } else { assert(type == DHMAC); dhMAC.encode(Tag.get(2), ostream); } } /** * Should not be called, because POPOPrivKey is a CHOICE and cannot have * an implicit tag. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { throw new RuntimeException("POPOPrivKey is a CHOICE and cannot have an implicit tag"); // encode(ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a POPOPrivKey. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); choicet.addElement( Tag.get(0), BIT_STRING.getTemplate() ); choicet.addElement( Tag.get(1), INTEGER.getTemplate() ); choicet.addElement( Tag.get(2), BIT_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return choicet.tagMatch(tag); } /** * Should not be called, because POPOPrivKey is a CHOICE and cannot * have an implicit tag. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { throw new RuntimeException("POPOPrivKey is a CHOICE and cannot have an implicitTag"); // return decode(istream); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { CHOICE choice = (CHOICE) choicet.decode(istream); Tag chosen = choice.getTag(); if( chosen.equals(Tag.get(0)) ) { return createThisMessage( (BIT_STRING) choice.getValue() ); } else if( chosen.equals(Tag.get(1)) ) { INTEGER I = (INTEGER) choice.getValue(); int i = I.intValue(); if( i != ENCR_CERT && i != CHALLENGE_RESP ) { throw new InvalidBERException( "SubsequentMessage has invalid value: "+i); } return createSubsequentMessage( i ); } else { assert( chosen.equals(Tag.get(2)) ); return createDhMAC( (BIT_STRING) choice.getValue() ); } } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/POPOSigningKey.java000066400000000000000000000111211362106420000226600ustar00rootroot00000000000000/* 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.pkix.crmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; /** * CRMF POPOSigningKey: *
 * POPOSigningKey ::= SEQUENCE {
 *      poposkInput         [0] POPOSigningKeyInput OPTIONAL,
 *      algorithmIdentifier AlgorithmIdentifier,
 *      signature           BIT STRING }
 * 
*/ public class POPOSigningKey implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private ANY poposkInput; // may be null private AlgorithmIdentifier algorithmIdentifier; private BIT_STRING signature; private SEQUENCE sequence; /** * Retrieves the input to the Proof-of-Possession of the signing key. * May return null, because this field is optional. Returns an ANY * because this type is not currently parsed. */ public ANY getPoposkInput() { return poposkInput; } /** * Retrieves the algorithm identifier for the signature. */ public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } /** * Retrieves the signature. */ public BIT_STRING getSignature() { return signature; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Creates a POPOSigningKey. * @param poposkInput May be null. */ public POPOSigningKey(ANY poposkInput, AlgorithmIdentifier algorithmIdentifier, BIT_STRING signature) { if(algorithmIdentifier==null || signature==null) { throw new IllegalArgumentException("parameter to POPOSigningKey"+ " constructor is null"); } this.poposkInput = poposkInput; this.algorithmIdentifier = algorithmIdentifier; this.signature = signature; sequence = new SEQUENCE(); sequence.addElement( Tag.get(0), poposkInput ); sequence.addElement( algorithmIdentifier ); sequence.addElement( signature ); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(TAG, 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 POPOSigningKey. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addOptionalElement( new EXPLICIT.Template( Tag.get(0), ANY.getTemplate()) ); seqt.addElement( AlgorithmIdentifier.getTemplate()); seqt.addElement( BIT_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 POPOSigningKey( (ANY) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (BIT_STRING) seq.elementAt(2) ); } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/ProofOfPossession.java000066400000000000000000000166071362106420000235710ustar00rootroot00000000000000/* 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.pkix.crmf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.CHOICE; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.NULL; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * CRMF ProofOfPossession: *
 * ProofOfPossession ::= CHOICE {
 *      raVerified          [0] NULL,
 *      signature           [1] POPOSigningKey,
 *      keyEncipherment     [2] POPOPrivKey,
 *      keyAgreement        [3] POPOPrivKey }
 * 
*/ public class ProofOfPossession implements ASN1Value { /** * The type of ProofOfPossesion. */ public static class Type { private Type() { } static Type RA_VERIFIED = new Type(); static Type SIGNATURE = new Type(); static Type KEY_ENCIPHERMENT = new Type(); static Type KEY_AGREEMENT = new Type(); } public static Type RA_VERIFIED = Type.RA_VERIFIED; public static Type SIGNATURE = Type.SIGNATURE; public static Type KEY_ENCIPHERMENT = Type.KEY_ENCIPHERMENT; public static Type KEY_AGREEMENT = Type.KEY_AGREEMENT; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private Type type; private POPOSigningKey signature; // if type == SIGNATURE private POPOPrivKey keyEncipherment; // if type == KEY_ENCIPHERMENT private POPOPrivKey keyAgreement; // if type == KEY_AGREEMENT /** * Returns the type of ProofOfPossesion:
    *
  • RA_VERIFIED *
  • SIGNATURE *
  • KEY_ENCIPHERMENT *
  • KEY_AGREEMENT *
*/ public Type getType() { return type; } /** * If type == SIGNATURE, returns the signature field. Otherwise, * returns null. */ public POPOSigningKey getSignature() { return signature; } /** * If type == KEY_ENCIPHERMENT, returns the keyEncipherment field. * Otherwise, returns null. */ public POPOPrivKey getKeyEncipherment() { return keyEncipherment; } /** * If type == KEY_AGREEMENT, returns the keyAgreement field. Otherwise, * returns null. */ public POPOPrivKey getKeyAgreement() { return keyAgreement; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private ProofOfPossession() { } private ProofOfPossession(Type type, POPOSigningKey signature, POPOPrivKey keyEncipherment, POPOPrivKey keyAgreement) { this.type = type; this.signature = signature; this.keyEncipherment = keyEncipherment; this.keyAgreement = keyAgreement; } /** * Creates a new ProofOfPossesion with an raVerified field. */ public static ProofOfPossession createRaVerified() { return new ProofOfPossession( RA_VERIFIED, null, null, null ); } /** * Creates a new ProofOfPossesion with the given signature field. */ public static ProofOfPossession createSignature(POPOSigningKey signature) { return new ProofOfPossession( SIGNATURE, signature, null, null ); } /** * Creates a new ProofOfPossesion with the given keyEncipherment field. */ public static ProofOfPossession createKeyEncipherment(POPOPrivKey keyEncipherment) { return new ProofOfPossession( KEY_ENCIPHERMENT, null, keyEncipherment, null ); } /** * Creates a new ProofOfPossesion with the given keyAgreement field. */ public static ProofOfPossession createKeyAgreement(POPOPrivKey keyAgreement) { return new ProofOfPossession( KEY_AGREEMENT, null, null, keyAgreement ); } /////////////////////////////////////////////////////////////////////// // decoding/encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { if( type == RA_VERIFIED ) { return Tag.get(0); } else if( type == SIGNATURE ) { return Tag.get(1); } else if( type == KEY_ENCIPHERMENT ) { return Tag.get(2); } else { assert( type == KEY_AGREEMENT ); return Tag.get(3); } } public void encode(OutputStream ostream) throws IOException { if( type == RA_VERIFIED ) { (new NULL()).encode(Tag.get(0), ostream); } else if( type == SIGNATURE ) { signature.encode(Tag.get(1), ostream); } else if( type == KEY_ENCIPHERMENT ) { // a CHOICE must be explicitly tagged EXPLICIT e = new EXPLICIT( Tag.get(2), keyEncipherment ); e.encode(ostream); } else { assert( type == KEY_AGREEMENT ); // a CHOICE must be explicitly tagged EXPLICIT e = new EXPLICIT( Tag.get(3), keyAgreement ); e.encode(ostream); } } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { assert(implicitTag.equals(getTag())); encode(ostream); } /** * A Template for decoding a ProofOfPossession. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); choicet.addElement( Tag.get(0), NULL.getTemplate() ); choicet.addElement( Tag.get(1), POPOSigningKey.getTemplate() ); EXPLICIT.Template et = new EXPLICIT.Template( Tag.get(2), POPOPrivKey.getTemplate() ); choicet.addElement( et ); et = new EXPLICIT.Template( Tag.get(3), POPOPrivKey.getTemplate() ); choicet.addElement( et ); } 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(Tag.get(0)) ) { return createRaVerified(); } else if( c.getTag().equals(Tag.get(1)) ) { return createSignature( (POPOSigningKey) c.getValue() ); } else if( c.getTag().equals(Tag.get(2)) ) { EXPLICIT e = (EXPLICIT) c.getValue(); return createKeyEncipherment( (POPOPrivKey) e.getContent() ); } else { assert( c.getTag().equals(Tag.get(3)) ); EXPLICIT e = (EXPLICIT) c.getValue(); return createKeyAgreement( (POPOPrivKey) e.getContent() ); } } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { throw new RuntimeException("A CHOICE cannot be implicitly tagged"); // return decode(istream); } } } jss-4.6.3/org/mozilla/jss/pkix/crmf/package.html000066400000000000000000000004121362106420000215320ustar00rootroot00000000000000 The PKIX CRMF protocol. jss-4.6.3/org/mozilla/jss/pkix/primitive/000077500000000000000000000000001362106420000203355ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/pkix/primitive/AVA.java000066400000000000000000000060311362106420000216070ustar00rootroot00000000000000/* 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.pkix.primitive; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * An AttributeValueAssertion, which has the following ASN.1 * definition (roughly): *
 *      AttributeValueAssertion ::= SEQUENCE {
 *          type        OBJECT IDENTIFIER,
 *          value       ANY DEFINED BY type }
 * 
*/ public class AVA implements ASN1Value { private OBJECT_IDENTIFIER oid; private ANY value; public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public AVA(OBJECT_IDENTIFIER oid, ASN1Value value) { this.oid = oid; if( value instanceof ANY ) { this.value = (ANY) value; } else { byte[] encoded = ASN1Util.encode(value); try { this.value = (ANY) ASN1Util.decode(ANY.getTemplate(), encoded); } catch( InvalidBERException e ) { throw new RuntimeException("InvalidBERException while decoding as ANY: " + e.getMessage(), e); } } } public OBJECT_IDENTIFIER getOID() { return oid; } /** * Returns the value of this AVA, encoded as an ANY. */ public ANY getValue() { return value; } 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(oid); seq.addElement(value); seq.encode(implicit, ostream); } /** * A Template for decoding an AVA. */ 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(seq.size() == 2); return new AVA( (OBJECT_IDENTIFIER) seq.elementAt(0), seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkix/primitive/AlgorithmIdentifier.java000066400000000000000000000070601362106420000251340ustar00rootroot00000000000000/* 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.pkix.primitive; import org.mozilla.jss.asn1.*; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.util.Assert; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.security.NoSuchAlgorithmException; public class AlgorithmIdentifier implements ASN1Value { private OBJECT_IDENTIFIER oid; private ASN1Value parameters=null; private SEQUENCE sequence = new SEQUENCE(); public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } /** * Creates an AlgorithmIdentifier with no parameter. */ public AlgorithmIdentifier(OBJECT_IDENTIFIER oid) { this.oid = oid; sequence.addElement( oid ); } /** * Creates an AlgorithmIdentifier. * * @param parameters The algorithm parameters. A value of null * will be encoded with an ASN.1 NULL. */ public AlgorithmIdentifier(OBJECT_IDENTIFIER oid, ASN1Value parameters) { this.oid = oid; sequence.addElement( oid ); this.parameters = parameters; if( parameters != null ) { sequence.addElement(parameters); } else { sequence.addElement(new NULL()); } } public OBJECT_IDENTIFIER getOID() { return oid; } /** * If this instance was constructed, returns the * parameter passed in to the constructor. If this instance was * decoded from a template, returns an ANY that was read from the * BER stream. In either case, it will return null if no parameters * were supplied. */ public ASN1Value getParameters() { return parameters; } private static final AlgorithmIdentifier.Template templateInstance = new AlgorithmIdentifier.Template(); public static AlgorithmIdentifier.Template getTemplate() { return templateInstance; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { sequence.encode(implicit, ostream); } 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.addOptionalElement( new ANY.Template() ); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); // the template should have enforced this assert( seq.size() == 2 ); OBJECT_IDENTIFIER algOID = (OBJECT_IDENTIFIER)seq.elementAt(0); if (seq.elementAt(1) == null) { return new AlgorithmIdentifier( algOID // OID ); } else { return new AlgorithmIdentifier( (OBJECT_IDENTIFIER)seq.elementAt(0), // OID seq.elementAt(1) // parameters ); } } } // end of Template } jss-4.6.3/org/mozilla/jss/pkix/primitive/Attribute.java000066400000000000000000000061121362106420000231430ustar00rootroot00000000000000/* 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.pkix.primitive; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.util.Assert; /** * An Attribute, which has the following ASN.1 * definition (roughly): *
 *      Attribute ::= SEQUENCE {
 *          type        OBJECT IDENTIFIER,
 *          value       SET }
 * 
*/ public class Attribute implements ASN1Value { private OBJECT_IDENTIFIER type; private SET values; public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public Attribute(OBJECT_IDENTIFIER type, SET values) { this.type = type; this.values = values; } public Attribute(OBJECT_IDENTIFIER type, ASN1Value value) { this.type = type; this.values = new SET(); values.addElement(value); } public OBJECT_IDENTIFIER getType() { return type; } /** * If this AVA was constructed, returns the SET of ASN1Values passed to the * constructor. If this Attribute was decoded with an Attribute.Template, * returns a SET of ANYs. */ public SET getValues() { return values; } 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(type); seq.addElement(values); seq.encode(implicit, ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A Template for decoding an Attribute. */ 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 SET.OF_Template(new ANY.Template())); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); // The template should have enforced this assert(seq.size() == 2); return new Attribute( (OBJECT_IDENTIFIER) seq.elementAt(0), (SET) seq.elementAt(1)); } } } jss-4.6.3/org/mozilla/jss/pkix/primitive/DirectoryString.java000066400000000000000000000132041362106420000243330ustar00rootroot00000000000000/* 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.pkix.primitive; import java.io.CharConversionException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BMPString; import org.mozilla.jss.asn1.CHOICE; import org.mozilla.jss.asn1.CharacterString; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.PrintableString; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.asn1.TeletexString; import org.mozilla.jss.asn1.UTF8String; import org.mozilla.jss.asn1.UniversalString; import org.mozilla.jss.util.Assert; /** * An X.500 DirectoryString. * DirectoryString is defined as follows: *
 * DirectoryString ::= CHOICE {
 *      teletexString               TeletexString (SIZE (1..MAX)),
 *      printableString             PrintableString (SIZE (1..MAX)),
 *      universalString             UniversalString (SIZE (1..MAX)),
 *      utf8String                  UTF8String (SIZE (1..MAX)),
 *      bmpString                   BMPString (SIZE (1..MAX))  }
 * 
*/ public class DirectoryString implements ASN1Value { private CharacterString asn1String; /** * Encodes a Java String into a Directory String. * The following rules for choosing an encoding are from the * IETF * PKIX document Internet X.509 Public Key Infrastructure: * Certificate and CRL Profile:
    *
  • The preferred encoding is UTF8String, and all certificates * issued after December 31, 2003, MUST use UTF8String encoding, * with a few exceptions. *
  • Until December 31, 2003, strings that fit in the PrintableString * character set MAY use PrintableString. *
  • Until December 31, 2003, string that fit in the BMPString character * set MAY use BMPString. *
  • Strings that fit in neither the PrintableString nor the BMPString * character set MUST use UTF8String. *
* This is all very nice, but for backwards compatibility, what we really * do is:
    *
  • Try PrintableString *
  • Try TeletexString *
  • Try UniversalString *
*/ public DirectoryString(String s) throws CharConversionException { try { try { asn1String = new PrintableString(s); } catch( CharConversionException e ) { asn1String = new TeletexString(s); } } catch( CharConversionException e ) { asn1String = new UniversalString(s); } } /** * Creates a DirectoryString from an ASN.1 string. * @param s Must be a TeletexString, PrintableString, UniversalString, * UTF8String, or BMPString. */ public DirectoryString(CharacterString s) { if( !(s instanceof PrintableString ) && !(s instanceof BMPString) && !(s instanceof UTF8String) && !(s instanceof TeletexString) && !(s instanceof UniversalString) ) { throw new IllegalArgumentException("DirectoryString must be "+ "TeletexString, PrintableString, UniversalString, UTF8STring,"+ " or BMPString"); } asn1String = s; } /** * Converts an ASN.1 DirectoryString to a Java string. */ public String toString() { return asn1String.toString(); } public Tag getTag() { return asn1String.getTag(); } public void encode(OutputStream ostream) throws IOException { asn1String.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { asn1String.encode(implicitTag, ostream); } /** * Returns a singleton instance of the decoding template for this class. */ public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); /** * A Template for decoding DirectoryStrings from their BER encoding. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); choicet.addElement( PrintableString.getTemplate() ); choicet.addElement( BMPString.getTemplate() ); choicet.addElement( UTF8String.getTemplate() ); choicet.addElement( TeletexString.getTemplate() ); choicet.addElement( UniversalString.getTemplate() ); } public boolean tagMatch(Tag tag) { return choicet.tagMatch(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { CHOICE choice = (CHOICE) choicet.decode(istream); return new DirectoryString( (CharacterString) choice.getValue()); } /** * @param implicitTag This parameter is ignored, because * DirectoryStrings (being CHOICEs) cannot have implicit tags. * @exception InvalidBERException If the encoding does not contain a * valid DirectoryString. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { assert( tagMatch(implicitTag) ); return decode(istream); } } } jss-4.6.3/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java000066400000000000000000000457271362106420000257740ustar00rootroot00000000000000/* 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.pkix.primitive; import java.io.CharConversionException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.crypto.Cipher; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.IVParameterSpec; import org.mozilla.jss.crypto.IllegalBlockSizeException; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.KeyWrapper; import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.PBEKeyGenParams; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.util.Password; /** * PKCS #8 EncryptedPrivateKeyInfo. *
 * EncryptedPrivateKeyInfo ::= SEQUENCE {
 *      encryptionAlgorithm     AlgorithmIdentifier,
 *      encryptedData           OCTET STRING }
 * 
*/ public class EncryptedPrivateKeyInfo implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private AlgorithmIdentifier encryptionAlgorithm; private OCTET_STRING encryptedData; private SEQUENCE sequence; public AlgorithmIdentifier getEncryptionAlgorithm() { return encryptionAlgorithm; } public OCTET_STRING getEncryptedData() { return encryptedData; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Creates an EncryptedPrivateKeyInfo from its components. * */ public EncryptedPrivateKeyInfo( AlgorithmIdentifier encryptionAlgorithm, OCTET_STRING encryptedData) { if( encryptionAlgorithm==null || encryptedData==null ) { throw new IllegalArgumentException( "EncryptedPrivateKeyInfo parameter is null"); } this.encryptionAlgorithm = encryptionAlgorithm; this.encryptedData = encryptedData; sequence = new SEQUENCE(); sequence.addElement(encryptionAlgorithm); sequence.addElement(encryptedData); } /////////////////////////////////////////////////////////////////////// // crypto shortcuts /////////////////////////////////////////////////////////////////////// /** * Creates a new EncryptedPrivateKeyInfo, where the data is encrypted * with a password-based key. * * @param keyGenAlg The algorithm for generating a symmetric key from * a password, salt, and iteration count. * @param password The password to use in generating the key. * @param salt The salt to use in generating the key. * @param iterationCount The number of hashing iterations to perform * while generating the key. * @param charToByteConverter The mechanism for converting the characters * in the password into bytes. If null, the default mechanism * will be used, which is UTF8. * @param pki The PrivateKeyInfo to be encrypted and stored in the * EncryptedContentInfo. Before they are encrypted, they will be * padded using PKCS padding. */ public static EncryptedPrivateKeyInfo createPBE(PBEAlgorithm keyGenAlg, Password password, byte[] salt, int iterationCount, KeyGenerator.CharToByteConverter charToByteConverter, PrivateKeyInfo pki) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, CharConversionException { try { // check key gen algorithm if( ! (keyGenAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("Key generation algorithm"+ " is not a PBE algorithm"); } PBEAlgorithm pbeAlg = keyGenAlg; CryptoManager cman = CryptoManager.getInstance(); // generate key CryptoToken token = cman.getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( keyGenAlg ); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( password, salt, iterationCount); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize(pbekgParams); SymmetricKey key = kg.generate(); // generate IV EncryptionAlgorithm encAlg = pbeAlg.getEncryptionAlg(); AlgorithmParameterSpec params=null; Class [] paramClasses = pbeAlg.getParameterClasses(); for (int i = 0; i < paramClasses.length; i ++) { if ( paramClasses[i].equals( javax.crypto.spec.IvParameterSpec.class ) ) { params = new IVParameterSpec( kg.generatePBE_IV() ); break; } } // perform encryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initEncrypt( key, params ); byte[] encrypted = cipher.doFinal( Cipher.pad( ASN1Util.encode(pki), encAlg.getBlockSize()) ); // make encryption algorithm identifier PBEParameter pbeParam = new PBEParameter( salt, iterationCount ); AlgorithmIdentifier encAlgID = new AlgorithmIdentifier( keyGenAlg.toOID(), pbeParam); // create EncryptedPrivateKeyInfo EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo ( encAlgID, new OCTET_STRING(encrypted) ); return epki; } catch( IllegalBlockSizeException e ) { throw new RuntimeException("IllegalBlockSizeException in EncryptedContentInfo" +".createPBE: " + e.getMessage(), e); } catch( BadPaddingException e ) { throw new RuntimeException("BadPaddingException in EncryptedContentInfo" +".createPBE: " + e.getMessage(), e); } } /** * Export a private key in PBES2 format, using a random PBKDF2 salt. * * Token must support the CKM_PKCS5_PBKD2 mechanism. * * @param saltLen Length of salt in bytes (default: 16) * @param kdfIterations PBKDF2 iterations (default: 2000) * @param encAlg The symmetric encryption algorithm for enciphering the * private key. Determines the size of derived key. * @param pwd Password * @param charToByteConverter The mechanism for converting the characters * in the password into bytes. If null, the default mechanism * will be used, which is UTF8. * @param privateKeyInfo The encoded PrivateKeyInfo to be encrypted and * stored in the EncryptedContentInfo. */ public static EncryptedPrivateKeyInfo createPBES2( int saltLen, int kdfIterations, EncryptionAlgorithm encAlg, Password pwd, KeyGenerator.CharToByteConverter charToByteConverter, PrivateKeyInfo privateKeyInfo) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, CharConversionException { if (encAlg == null) throw new IllegalArgumentException("encAlg cannot be null"); if (pwd == null) throw new IllegalArgumentException("pwd cannot be null"); if (privateKeyInfo == null) throw new IllegalArgumentException("privateKeyInfo cannot be null"); if (kdfIterations < 1) kdfIterations = 2000; if (saltLen < 1) saltLen = 16; try { // generate random PBKDF2 salt SecureRandom random = new SecureRandom(); byte salt[] = new byte[saltLen]; random.nextBytes(salt); // derive symmetric key from passphrase using PBKDF2 CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( PBEAlgorithm.PBE_PKCS5_PBKDF2); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( pwd.getChars(), salt, kdfIterations, encAlg); if (charToByteConverter != null) kg.setCharToByteConverter(charToByteConverter); kg.initialize(pbekgParams); SymmetricKey sk = kg.generate(); // encrypt PrivateKeyInfo byte iv[] = new byte[encAlg.getBlockSize()]; random.nextBytes(iv); Cipher cipher = token.getCipherContext(encAlg); cipher.initEncrypt(sk, new IVParameterSpec(iv)); byte[] encData = cipher.doFinal(ASN1Util.encode(privateKeyInfo)); // construct KDF AlgorithmIdentifier SEQUENCE paramsKdf = new SEQUENCE(); paramsKdf.addElement(new OCTET_STRING(salt)); paramsKdf.addElement(new INTEGER(kdfIterations)); paramsKdf.addElement(new INTEGER(sk.getLength())); AlgorithmIdentifier algIdKdf = new AlgorithmIdentifier( PBEAlgorithm.PBE_PKCS5_PBKDF2.toOID(), paramsKdf); // construct encryption AlgorithmIdentifier AlgorithmIdentifier algIdEnc = new AlgorithmIdentifier( encAlg.toOID(), new OCTET_STRING(iv)); // construct "composite" PBES2 AlgorithmIdentifier SEQUENCE paramsPBES2 = new SEQUENCE(); paramsPBES2.addElement(algIdKdf); paramsPBES2.addElement(algIdEnc); AlgorithmIdentifier algIdPBES2 = new AlgorithmIdentifier( PBEAlgorithm.PBE_PKCS5_PBES2.toOID(), paramsPBES2); // construct EncryptedPrivateKeyInfo return new EncryptedPrivateKeyInfo(algIdPBES2, new OCTET_STRING(encData)); } catch (IllegalBlockSizeException e) { throw new RuntimeException("IllegalBlockSizeException in EncryptedContentInfo.createPBES2: " + e.getMessage(), e); } catch (BadPaddingException e) { throw new RuntimeException("BadPaddingException in EncryptedContentInfo.createPBES2: " + e.getMessage(), e); } } /** * Creates a new EncryptedPrivateKeyInfo, where the data is encrypted * with a password-based key- * with wrapping/unwrapping happening on token. * * @param keyGenAlg The algorithm for generating a symmetric key from * a password, salt, and iteration count. * @param password The password to use in generating the key. * @param salt The salt to use in generating the key. * @param iterationCount The number of hashing iterations to perform * while generating the key. * @param charToByteConverter The mechanism for converting the characters * in the password into bytes. If null, the default mechanism * will be used, which is UTF8. * @param pri The PrivateKey to be encrypted and stored in the * EncryptedContentInfo. */ public static EncryptedPrivateKeyInfo createPBE(PBEAlgorithm keyGenAlg, Password password, byte[] salt, int iterationCount, KeyGenerator.CharToByteConverter charToByteConverter, PrivateKey pri, CryptoToken token) throws NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, CharConversionException { try { // check key gen algorithm if( ! (keyGenAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("Key generation algorithm"+ " is not a PBE algorithm"); } PBEAlgorithm pbeAlg = keyGenAlg; // generate key KeyGenerator kg = token.getKeyGenerator( keyGenAlg ); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( password, salt, iterationCount); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize(pbekgParams); kg.temporaryKeys(true); SymmetricKey key = kg.generate(); // generate IV EncryptionAlgorithm encAlg = pbeAlg.getEncryptionAlg(); AlgorithmParameterSpec params=null; Class [] paramClasses = pbeAlg.getParameterClasses(); for (int i = 0; i < paramClasses.length; i ++) { if ( paramClasses[i].equals( javax.crypto.spec.IvParameterSpec.class ) ) { params = new IVParameterSpec( kg.generatePBE_IV() ); break; } } KeyWrapper wrapper = token.getKeyWrapper( KeyWrapAlgorithm.DES3_CBC_PAD); wrapper.initWrap(key, params); byte encrypted[] = wrapper.wrap(pri); // make encryption algorithm identifier PBEParameter pbeParam = new PBEParameter( salt, iterationCount ); AlgorithmIdentifier encAlgID = new AlgorithmIdentifier( keyGenAlg.toOID(), pbeParam); // create EncryptedPrivateKeyInfo EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo ( encAlgID, new OCTET_STRING(encrypted) ); return epki; } catch (Exception e) { System.out.println("createPBE: exception:"+e.toString()); throw new RuntimeException("Exception in EncryptedPrivateKeyInfo" + ".createPBE: " + e.getMessage(), e); } } /** * Decrypts an EncryptedPrivateKeyInfo that was encrypted with a PBE * algorithm. The algorithm and its parameters are extracted from * the EncryptedPrivateKeyInfo. * * @param pass The password to use to generate the PBE key. * @param charToByteConverter The converter to change the password * characters to bytes. If null, the default conversion is used. */ public PrivateKeyInfo decrypt(Password pass, KeyGenerator.CharToByteConverter charToByteConverter) throws NotInitializedException, NoSuchAlgorithmException, InvalidBERException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, IllegalBlockSizeException, BadPaddingException, CharConversionException { // get the key gen parameters AlgorithmIdentifier algid = encryptionAlgorithm; KeyGenAlgorithm kgAlg = KeyGenAlgorithm.fromOID(algid.getOID()); if( !(kgAlg instanceof PBEAlgorithm)) { throw new NoSuchAlgorithmException("KeyGenAlgorithm is not a "+ "PBE algorithm"); } ASN1Value params = algid.getParameters(); if( params == null ) { throw new InvalidAlgorithmParameterException( "PBE algorithms require parameters"); } PBEParameter pbeParams; if( params instanceof PBEParameter ) { pbeParams = (PBEParameter) params; } else { byte[] encodedParams = ASN1Util.encode(params); pbeParams = (PBEParameter) ASN1Util.decode(PBEParameter.getTemplate(), encodedParams); } PBEKeyGenParams kgp = new PBEKeyGenParams(pass, pbeParams.getSalt(), pbeParams.getIterations() ); // compute the key and IV CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( kgAlg ); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize(kgp); SymmetricKey key = kg.generate(); // compute algorithm parameters EncryptionAlgorithm encAlg = ((PBEAlgorithm)kgAlg).getEncryptionAlg(); AlgorithmParameterSpec algParams = null; Class [] paramClasses = encAlg.getParameterClasses(); for (int i = 0; i < paramClasses.length; i ++) { if ( paramClasses[i].equals( javax.crypto.spec.IvParameterSpec.class ) ) { algParams = new IVParameterSpec( kg.generatePBE_IV() ); break; } } // perform the decryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initDecrypt(key, algParams); byte[] decrypted = Cipher.unPad( cipher.doFinal( encryptedData.toByteArray() ) ); return (PrivateKeyInfo) ASN1Util.decode(PrivateKeyInfo.getTemplate(), decrypted); } /////////////////////////////////////////////////////////////////////// // 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 class for decoding EncryptedPrivateKeyInfos from BER. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); 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 EncryptedPrivateKeyInfo( (AlgorithmIdentifier) seq.elementAt(0), (OCTET_STRING) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkix/primitive/Name.java000066400000000000000000000230451362106420000220640ustar00rootroot00000000000000/* 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.pkix.primitive; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.CharConversionException; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.PrintableString; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * An X.500 Name. */ public class Name implements ASN1Value { SEQUENCE rdns; /** * Creates an empty Name. */ public Name() { rdns = new SEQUENCE(); } /** * Creates a name from a sequence of relative distinguished names. */ Name( SEQUENCE rdns ) { this.rdns = rdns; } /** * Adds a relative distinguished name to the Name. * * @param name A relative distinguished name (RDN) to be added to the Name. */ public void addElement( RDN name ) { rdns.addElement( name ); } /** * Adds a relative distinguished name containing a single AVA. * * @param ava An AttributeValueAssertion, which will be inserted as * the sole element of a new RDN, which will be stored in the Name. */ public void addElement( AVA ava ) { rdns.addElement( new RDN( ava ) ); } /** * Inserts the given RDN at the given index in the Name. */ public void insertElementAt( RDN name, int idx ) { rdns.insertElementAt( name, idx); } /** * Returns the RDN at the given index in the Name. */ public RDN elementAt( int idx ) { return (RDN) rdns.elementAt(idx); } /** * Removes the Name element at the given index. */ public void removeElementAt( int idx ) { rdns.removeElementAt( idx ); } /** * Returns the number of RDNs in the Name. */ public int size() { return rdns.size(); } public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { rdns.encode(ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { rdns.encode(implicit, ostream); } /** * The OID for the common name (CN) attribute. */ public static final OBJECT_IDENTIFIER commonName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 3 } ); /** * The OID for the country name (C) attribute. */ public static final OBJECT_IDENTIFIER countryName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 6 } ); /** * The OID for the locality name (L) attribute. */ public static final OBJECT_IDENTIFIER localityName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 7 } ); /** * The OID for the state or province name (S) attribute. */ public static final OBJECT_IDENTIFIER stateOrProvinceName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 8 } ); /** * The OID for the organization name (O) attribute. */ public static final OBJECT_IDENTIFIER organizationName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 10 } ); /** * The OID for the organizational unit name (OU) attribute. */ public static final OBJECT_IDENTIFIER organizationalUnitName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 11 } ); /** * Adds a common name (CN) to the Name. * @param CN The common name. * It will be formatted according to the IETF PKIX rules for * directory strings. */ public void addCommonName(String CN) throws CharConversionException { addElement( new AVA( commonName, new DirectoryString(CN) ) ); } /** * Adds a country name (C) to the Name. It must be exactly two characters. * @param C The country name. * It will be formatted according to the IETF PKIX rules for * directory strings. * @exception IllegalArgumentException If C.length() != 2. */ public void addCountryName(String C) throws CharConversionException { if( C.length() != 2 ) { throw new IllegalArgumentException("Country name must be exactly"+ " 2 characters"); } addElement( new AVA( countryName, new DirectoryString(C) ) ); } /** * Adds a locality name (L) to the Name. * @param L The locality name. * It will be formatted according to the IETF PKIX rules for * directory strings. */ public void addLocalityName(String L) throws CharConversionException { addElement( new AVA( localityName, new DirectoryString(L) ) ); } /** * Adds a state or province name (S) to the Name. * @param S The state or province name. * It will be formatted according to the IETF PKIX rules for * directory strings. */ public void addStateOrProvinceName(String S) throws CharConversionException { addElement( new AVA( stateOrProvinceName, new DirectoryString(S) ) ); } /** * Adds an organization name (O) to the Name. * @param O The organization name. * It will be formatted according to the IETF PKIX rules for * directory strings. */ public void addOrganizationName(String O) throws CharConversionException { addElement( new AVA( organizationName, new DirectoryString(O) ) ); } /** * Adds an organizational unit name (OU) to the Name. * @param OU The organizational unit name. * It will be formatted according to the IETF PKIX rules for * directory strings. */ public void addOrganizationalUnitName(String OU) throws CharConversionException { addElement( new AVA( organizationalUnitName, new DirectoryString(OU) ) ); } private String typeToString( OBJECT_IDENTIFIER type ) { if( type.equals(commonName) ) { return "CN"; } else if( type.equals(countryName) ) { return "C"; } else if( type.equals(localityName) ) { return "L"; } else if( type.equals(stateOrProvinceName) ) { return "S"; } else if( type.equals(organizationName) ) { return "O"; } else if( type.equals(organizationalUnitName) ) { return "OU"; } else { return null; } } private String AVAToString(AVA ava) throws InvalidBERException { OBJECT_IDENTIFIER oid = ava.getOID(); String type = typeToString( oid ); if( type == null ) { return ""; } else { return type + "=" + ava.getValue().decodeWith(DirectoryString.getTemplate()); } } public String getRFC1485() throws InvalidBERException { StringBuffer buf = new StringBuffer(80); for( int r = 0; r < rdns.size(); r++ ) { if( r > 0) { buf.append(", "); } buf.append( AVAToString( ((RDN)rdns.elementAt(r)).at(0)) ); } return buf.toString(); } private static final Name.Template templateInstance = new Name.Template(); public static Name.Template getTemplate() { return templateInstance; } public static void main(String args[]) { try { if(args.length == 0) { Name name = new Name(); OBJECT_IDENTIFIER oid; oid = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 10 } ); AVA ava = new AVA( oid, new PrintableString("Netscape") ); name.addElement( ava ); oid = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 3} ); ava = new AVA( oid, new PrintableString("moi")); name.addElement( ava ); name.encode(System.out); } else { Name.Template temp = new Name.Template(); Name name; FileInputStream fis = new FileInputStream(args[0]); try (BufferedInputStream bis = new BufferedInputStream(fis)) { name = (Name) temp.decode(bis); } System.out.println("Got name."); for( int i = 0; i < name.size(); i++ ) { AVA a = name.elementAt(i).at(0); PrintableString.Template pst = new PrintableString.Template(); PrintableString ps = (PrintableString) pst.decode( new ByteArrayInputStream( a.getValue().getEncoded() ) ); System.out.println("OID: "+a.getOID()+", String: "+ps); } System.out.println("End of name"); } } catch( Exception e) { e.printStackTrace(); } } 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.OF_Template seqt = new SEQUENCE.OF_Template( new RDN.Template() ); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); return new Name( seq ); } } } jss-4.6.3/org/mozilla/jss/pkix/primitive/PBEParameter.java000066400000000000000000000074561362106420000234630ustar00rootroot00000000000000/* 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.pkix.primitive; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; /** * PKCS #5 PBEParameter, and PKCS #12 pkcs-12PbeParams. The only * difference between the two is that PKCS #5 dictates that the size of the * salt must be 8 bytes, while PKCS #12 leaves the salt length undefined. * To work with both standards, this class does not check the length of the * salt but rather leaves that to the application. */ public class PBEParameter implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private byte[] salt; private int iterations; private SEQUENCE sequence; public byte[] getSalt() { return salt; } public int getIterations() { return iterations; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// /** * Creates a PBEParameter from a salt and iteration count. Neither * may be null. */ public PBEParameter(byte[] salt, int iterations) { this.salt = salt; this.iterations = iterations; sequence = new SEQUENCE(); sequence.addElement( new OCTET_STRING(salt) ); sequence.addElement( new INTEGER(iterations) ); } /** * Creates a PBEParameter from a salt and iteration count. Neither * may be null. */ public PBEParameter(OCTET_STRING salt, INTEGER iterations) { this( salt.toByteArray(), iterations.intValue() ); } /////////////////////////////////////////////////////////////////////// // 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 class for decoding a PBEParameter. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OCTET_STRING.getTemplate() ); seqt.addElement( INTEGER.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 PBEParameter( (OCTET_STRING) seq.elementAt(0), (INTEGER) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkix/primitive/PrivateKeyInfo.java000066400000000000000000000130731362106420000241030ustar00rootroot00000000000000/* 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.pkix.primitive; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.crypto.PrivateKey; public class PrivateKeyInfo implements ASN1Value, java.security.PrivateKey { private static final long serialVersionUID = 1L; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private INTEGER version; private AlgorithmIdentifier privateKeyAlgorithm; private OCTET_STRING privateKey; private SET attributes; // may be null private SEQUENCE sequence; public INTEGER getVersion() { return version; } public AlgorithmIdentifier getPrivateKeyAlgorithm() { return privateKeyAlgorithm; } public String getAlgorithm() { try { return PrivateKey.Type.fromOID(privateKeyAlgorithm.getOID()) .toString(); } catch( NoSuchAlgorithmException e ) { return null; } } public String getFormat() { return "PKCS#8"; } public byte[] getEncoded() { return privateKey.toByteArray(); } public OCTET_STRING getPrivateKey() { return privateKey; } /** * May return null if no attributes are present. */ public SET getAttributes() { return attributes; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /** * Create a PrivateKeyInfo from its components. * * @param attributes May be null if there are no attributes, in which * case the attributes field will be omitted from the DER encoding. * Each element must be a org.mozilla.jss.pkix.primitive.Attribute. */ public PrivateKeyInfo(INTEGER version, AlgorithmIdentifier privateKeyAlgorithm, OCTET_STRING privateKey, SET attributes) { if( version==null || privateKeyAlgorithm==null || privateKey==null ) { throw new IllegalArgumentException( "PrivateKeyInfo parameter is null"); } this.version = version; this.privateKeyAlgorithm = privateKeyAlgorithm; this.privateKey = privateKey; this.attributes = attributes; sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(privateKeyAlgorithm); sequence.addElement(privateKey); if(attributes!=null) { sequence.addElement( new Tag(0), attributes ); // make sure all the attributes are Attributes int size = attributes.size(); for(int i=0; i < size; i++) { if( ! (attributes.elementAt(i) instanceof Attribute) ) { throw new IllegalArgumentException("element "+i+ " of attributes is not an Attribute"); } } } } /////////////////////////////////////////////////////////////////////// // 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 class for decoding PrivateKeyInfos from BER. */ 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() ); seqt.addOptionalElement( new Tag(0), new SET.OF_Template( Attribute.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 PrivateKeyInfo( (INTEGER) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (OCTET_STRING) seq.elementAt(2), (SET) seq.elementAt(3) ); } } } jss-4.6.3/org/mozilla/jss/pkix/primitive/RDN.java000066400000000000000000000053371362106420000216330ustar00rootroot00000000000000/* 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.pkix.primitive; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.Tag; /** * A RelativeDistinguishedName, whose ASN.1 is: *
 * RelativeDistinguishedName ::= SET SIZE(1..MAX) OF AttributeValueAssertion
 * 
*/ public class RDN implements ASN1Value { private SET avas; /** * An RDN must have at least one element at all times, so an initial * element must be provided. */ public RDN(AVA initialElement) { avas = new SET(); avas.addElement(initialElement); } // This is for private use only, so we can be constructed from our // template. RDN(SET avas) { this.avas = avas; } public void add( AVA ava ) { avas.addElement( ava ); } public AVA at( int idx ) { return (AVA) avas.elementAt( idx ); } /** * @exception TooFewElementsException If removing this element would * result in the RDN being empty. */ public void removeAt( int idx ) throws TooFewElementsException { if( avas.size() <= 1 ) { throw new TooFewElementsException(); } avas.removeElementAt( idx ); } public int size() { return avas.size(); } public static final Tag TAG = SET.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { avas.encode(ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { avas.encode(implicit, ostream); } 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 { AVA.Template avatemp = new AVA.Template(); SET.OF_Template sett = new SET.OF_Template( avatemp ); SET set = (SET) sett.decode(implicit, istream); if(set.size() < 1) { throw new InvalidBERException("RDN with zero elements; "+ "an RDN must have at least one element"); } return new RDN(set); } } } jss-4.6.3/org/mozilla/jss/pkix/primitive/SubjectPublicKeyInfo.java000066400000000000000000000105441362106420000252270ustar00rootroot00000000000000/* 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.pkix.primitive; import org.mozilla.jss.asn1.*; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.security.PublicKey; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.InvalidKeyFormatException; import org.mozilla.jss.pkcs11.PK11PubKey; /** * A SubjectPublicKeyInfo, which stores information about a public key. * This class implements java.security.PublicKey. */ public class SubjectPublicKeyInfo extends java.security.spec.X509EncodedKeySpec implements ASN1Value, java.security.PublicKey { private static final long serialVersionUID = 1L; private AlgorithmIdentifier algorithm; private BIT_STRING subjectPublicKey; public String getAlgorithm() { try { return PrivateKey.Type.fromOID(algorithm.getOID()).toString(); } catch( NoSuchAlgorithmException e ) { // unknown algorithm return null; } } public byte[] getEncoded() { return ASN1Util.encode(this); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public BIT_STRING getSubjectPublicKey() { return subjectPublicKey; } private SubjectPublicKeyInfo() { super(new byte[] {0});} public SubjectPublicKeyInfo(AlgorithmIdentifier algorithm, BIT_STRING subjectPublicKey) { super( new byte[] {0} ); // super constructor can't handle null this.algorithm = algorithm; this.subjectPublicKey = subjectPublicKey; } public SubjectPublicKeyInfo(PublicKey pubk) throws InvalidBERException, IOException { super( new byte[] {0}); SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) ASN1Util.decode( getTemplate(), pubk.getEncoded() ); algorithm = spki.algorithm; subjectPublicKey = spki.subjectPublicKey; } 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 implicit, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement( algorithm ); seq.addElement( subjectPublicKey ); seq.encode( implicit, ostream ); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * Creates a PublicKey from the public key information. Currently * only RSA and DSA keys can be converted. * * @exception NoSuchAlgorithmException If the cryptographic provider * does not recognize the algorithm for this public key. * @exception InvalidKeyFormatException If the subjectPublicKey could * not be decoded correctly. */ public PublicKey toPublicKey() throws NoSuchAlgorithmException, InvalidKeyFormatException { if( subjectPublicKey.getPadCount() != 0 ) { throw new InvalidKeyFormatException(); } return PK11PubKey.fromSPKI(getEncoded()); } public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( BIT_STRING.getTemplate() ); } 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 seq = (SEQUENCE) seqt.decode(implicit, istream); return new SubjectPublicKeyInfo( (AlgorithmIdentifier) seq.elementAt(0), (BIT_STRING) seq.elementAt(1) ); } } } jss-4.6.3/org/mozilla/jss/pkix/primitive/TooFewElementsException.java000066400000000000000000000005501362106420000257570ustar00rootroot00000000000000/* 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.pkix.primitive; public class TooFewElementsException extends Exception { private static final long serialVersionUID = 1L; } jss-4.6.3/org/mozilla/jss/pkix/primitive/package.html000066400000000000000000000005261362106420000226210ustar00rootroot00000000000000 Frequently-used primitive ASN.1 types, such as AlgorithmIdentifier, PrivateKeyInfo, and X.500 Name. jss-4.6.3/org/mozilla/jss/provider/000077500000000000000000000000001362106420000172045ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/provider/java/000077500000000000000000000000001362106420000201255ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/provider/java/security/000077500000000000000000000000001362106420000217745ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/provider/java/security/IvAlgorithmParameters.java000066400000000000000000000037171362106420000271200ustar00rootroot00000000000000/* 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.provider.java.security; import java.io.IOException; import java.security.AlgorithmParametersSpi; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; /** * This class is only intended to be used to implement * CipherSpi.getAlgorithmParameters(). */ public class IvAlgorithmParameters extends AlgorithmParametersSpi { private AlgorithmParameterSpec ivParamSpec; public void engineInit(AlgorithmParameterSpec paramSpec) { ivParamSpec = paramSpec; } public T engineGetParameterSpec(Class clazz) throws InvalidParameterSpecException { if( clazz != null && !(clazz.isInstance(ivParamSpec)) ) { Class paramSpecClass = ivParamSpec.getClass(); throw new InvalidParameterSpecException( "Mozilla-JSS IvParameter spec class error" + paramSpecClass.getName()); } return clazz.cast(ivParamSpec); } public void engineInit(byte[] params) throws IOException { throw new IOException("engineInit(byte[]) not supported"); } public void engineInit(byte[] params, String format) throws IOException { throw new IOException("engineInit(byte[],String) not supported"); } public byte[] engineGetEncoded() throws IOException { throw new IOException("encoding IvAlgorithmParameters not supported"); } public byte[] engineGetEncoded(String format) throws IOException { throw new IOException("encoding IvAlgorithmParameters not supported"); } public String engineToString() { throw new RuntimeException("engineToString() not supported"); // return getClass().getName(); } } jss-4.6.3/org/mozilla/jss/provider/java/security/JSSKeyPairGeneratorSpi.java000066400000000000000000000044551362106420000271160ustar00rootroot00000000000000/* 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.provider.java.security; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.KeyPairGenerator; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.TokenRuntimeException; import org.mozilla.jss.crypto.TokenSupplierManager; class JSSKeyPairGeneratorSpi extends java.security.KeyPairGeneratorSpi { private KeyPairGenerator kpg; protected JSSKeyPairGeneratorSpi(KeyPairAlgorithm alg) { super(); CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); try { try { kpg = token.getKeyPairGenerator(alg); } catch(java.security.NoSuchAlgorithmException e) { throw new UnsupportedOperationException( "Token '" + token.getName() + "' does not support algorithm " + alg.toString()); } } catch(TokenException e) { throw new TokenRuntimeException(e.getMessage()); } } public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { kpg.initialize(params, random); } public void initialize(int keysize, SecureRandom random) { kpg.initialize(keysize, random); } public KeyPair generateKeyPair() { try { return kpg.genKeyPair(); } catch(TokenException e) { throw new TokenRuntimeException(e.getMessage()); } } public static class RSA extends JSSKeyPairGeneratorSpi { public RSA() { super(KeyPairAlgorithm.RSA); } } public static class DSA extends JSSKeyPairGeneratorSpi { public DSA() { super(KeyPairAlgorithm.DSA); } } public static class EC extends JSSKeyPairGeneratorSpi { public EC() { super(KeyPairAlgorithm.EC); } } } jss-4.6.3/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.c000066400000000000000000000644341362106420000247540ustar00rootroot00000000000000/* 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/. */ #include "_jni/org_mozilla_jss_provider_java_security_JSSKeyStoreSpi.h" #include #include #include #include #include #include #include #include #include "java_ids.h" static PRStatus getTokenSlotPtr(JNIEnv *env, jobject keyStoreObj, PK11SlotInfo **ptr) { return JSS_getPtrFromProxyOwner(env, keyStoreObj, "proxy", "Lorg/mozilla/jss/pkcs11/TokenProxy;", (void**)ptr); } typedef enum { PRIVKEY=0x01, PUBKEY=0x02, SYMKEY=0x04, CERT=0x08 } TokenObjectType; #define ALL_OBJECT_TYPES (PRIVKEY | PUBKEY | SYMKEY | CERT ) typedef struct { PRStatus status; PRBool deleteIt; PRBool stopIterating; } JSSTraversalStatus; #define INIT_TRAVSTAT {PR_FAILURE, PR_FALSE, PR_FALSE} /* * contract: you must throw an exception if you return PRFailure. */ typedef JSSTraversalStatus (*TokenObjectTraversalCallback) (JNIEnv* env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data); /* * objectType is bitwise-OR of all the object types you want to traverse. */ static PRStatus traverseTokenObjects (JNIEnv *env, PK11SlotInfo *slot, TokenObjectTraversalCallback cb, int objectTypes, void *data) { PRStatus status = PR_FAILURE; JSSTraversalStatus travstat = INIT_TRAVSTAT; SECKEYPrivateKeyList* privkList = NULL; SECKEYPublicKeyList* pubkList = NULL; PK11SymKey *symKey = NULL; CERTCertList *certList = NULL; /* * Get all private keys */ if( objectTypes & PRIVKEY ) { SECKEYPrivateKeyListNode *node = NULL; privkList = PK11_ListPrivKeysInSlot(slot, NULL /*nickname*/, NULL /*wincx*/); if( privkList != NULL ) { for( node = PRIVKEY_LIST_HEAD(privkList); ! PRIVKEY_LIST_END(node, privkList); node = PRIVKEY_LIST_NEXT(node) ) { travstat = cb(env, slot, PRIVKEY, (void*) node->key, data); if( travstat.status == PR_FAILURE ) { goto finish; } if( travstat.deleteIt ) { /* Setting "force" to PR_FALSE means that if there is a * matching cert, the key won't be deleted. * If the KeyStore API is being followed, the cert * should have the same nickname as the key. So * both will get deleted when we scan for matching * certs later. */ PK11_DeleteTokenPrivateKey(node->key, PR_FALSE /*force*/); node->key = NULL; PR_REMOVE_LINK(&node->links); /* we don't free node because it is allocated from * the list's arena and will get freed when the list * is freed. */ } if( travstat.stopIterating ) { goto stop_early; } } } } /* * Get all symmetric keys */ if(objectTypes & SYMKEY) { /* this function returns a chained list of symmetric keys */ symKey = PK11_ListFixedKeysInSlot(slot, NULL /*nickname*/, NULL/*wincx*/); while( symKey != NULL ) { PK11SymKey *deadKey; travstat = cb(env, slot, SYMKEY, (void*) symKey, data); if( travstat.status != PR_SUCCESS ) { goto finish; } if( travstat.deleteIt ) { /* this just deletes the PKCS #11 object. The data structure * is NOT deleted. */ PK11_DeleteTokenSymKey(symKey); } if( travstat.stopIterating ) { goto stop_early; } deadKey = symKey; symKey = PK11_GetNextSymKey(symKey); PK11_FreeSymKey(deadKey); } } /* * get all public keys */ if( objectTypes & PUBKEY ) { SECKEYPublicKeyListNode *node = NULL; pubkList = PK11_ListPublicKeysInSlot(slot, NULL /*nickname*/); if( pubkList != NULL ) { for( node = PUBKEY_LIST_HEAD(pubkList); ! PUBKEY_LIST_END(node, pubkList); node = PUBKEY_LIST_NEXT(node) ) { if( node->key == NULL ) { /* workaround NSS bug 130699: PK11_ListPublicKeysInSlot * returns NULL if slot contains token symmetric key */ continue; } travstat = cb(env, slot, PUBKEY, (void*) node->key, data); if( travstat.status != PR_SUCCESS ) { goto finish; } if( travstat.deleteIt ) { /* XXX!!! * Workaround for 125408: PK11_DeleteTokenPublic key asserts * Don't delete the public key. * PK11_DeleteTokenPublicKey(node->key); * node->key = NULL; * PR_REMOVE_LINK(&node->links); */ /* node is allocated from the list's arena, it will get * freed with the list */ } if( travstat.stopIterating ) { goto stop_early; } } /* * XXX!!! * Destroy the list before we move on. Why bother, since we'll * do it anyway in the finish block? Because of bug 125408. * If we delete the cert and private key while traversing certs, * we'll delete the public key too, and then we'll crash when * we free the same public key while destroying the list. */ SECKEY_DestroyPublicKeyList(pubkList); pubkList = NULL; } } /* * Get all certs */ if( objectTypes & CERT ) { CERTCertListNode *node = NULL; certList = PK11_ListCertsInSlot(slot); if( certList == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to list certificates on token"); goto finish; } for( node = CERT_LIST_HEAD(certList); ! CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node) ) { travstat = cb(env, slot, CERT, (void*) node->cert, data); if( travstat.status != PR_SUCCESS ) { goto finish; } if( travstat.deleteIt ) { /* * Since, in a KeyStore, certs and private keys go together, * remove the private key too, if there is one. * * The hack here is that PK11_DeleteTokenCertAndKey will * not delete the cert if there is no matching private key. * We want to the cert to be deleted even if the key isn't * there. So we only call that function if we're sure the * key is there. Otherwise we delete the cert directly. */ SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(node->cert, NULL /*wincx*/); PRBool keyPresent = (privKey != NULL); SECKEY_DestroyPrivateKey(privKey); if( keyPresent ) { PK11_DeleteTokenCertAndKey(node->cert, NULL /*wincx*/); } else { SEC_DeletePermCertificate(node->cert); } PR_REMOVE_LINK(&node->links); /* node is allocated from the list's arena, it will get freed * with the list */ } if( travstat.stopIterating ) { goto stop_early; } } } stop_early: status = PR_SUCCESS; finish: if( privkList != NULL ) { SECKEY_DestroyPrivateKeyList(privkList); } if( pubkList != NULL ) { SECKEY_DestroyPublicKeyList(pubkList); } while( symKey != NULL ) { PK11SymKey *deadKey; deadKey = symKey; symKey = PK11_GetNextSymKey(symKey); PK11_FreeSymKey(deadKey); } if( certList != NULL ) { CERT_DestroyCertList(certList); } return status; } /* allocates memory if type != CERT */ static char* getObjectNick(void *obj, TokenObjectType type) { switch(type) { case PRIVKEY: /* NOTE: this function allocates memory for the nickname */ return PK11_GetPrivateKeyNickname((SECKEYPrivateKey*)obj); case SYMKEY: /* NOTE: this function allocates memory for the nickname */ return PK11_GetSymKeyNickname((PK11SymKey*)obj); case PUBKEY: /* NOTE: this function allocates memory for the nickname */ return PK11_GetPublicKeyNickname((SECKEYPublicKey*)obj); case CERT: return ((CERTCertificate*)obj)->nickname; default: PR_ASSERT(PR_FALSE); return NULL; } } static void freeObjectNick(char *nick, TokenObjectType type) { if( type != CERT && nick != NULL) { PR_Free(nick); } } typedef struct { jobject setObj; jmethodID setAdd; } EngineAliasesCBInfo; static JSSTraversalStatus engineAliasesTraversalCallback (JNIEnv *env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data) { JSSTraversalStatus travStat = INIT_TRAVSTAT; EngineAliasesCBInfo *cbinfo = (EngineAliasesCBInfo*)data; char *nickname=NULL; nickname = getObjectNick(obj, type); if( nickname != NULL ) { jstring nickString; /* convert it to a string */ nickString = (*env)->NewStringUTF(env, nickname); freeObjectNick(nickname, type); if( nickString == NULL ) { /* exception was thrown */ goto finish; } /* store the string in the vector */ (*env)->CallBooleanMethod(env, cbinfo->setObj, cbinfo->setAdd, nickString); if( (*env)->ExceptionOccurred(env) ) { goto finish; } } travStat.status = PR_SUCCESS; finish: return travStat; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getRawAliases (JNIEnv *env, jobject this) { PK11SlotInfo *slot = NULL; jobject setObj=NULL; jmethodID setAdd=NULL; EngineAliasesCBInfo cbinfo; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } /* * Create the vector object and get its method IDs */ { jclass setClass; jmethodID setCons; setClass = (*env)->FindClass(env, "java/util/HashSet"); if( setClass == NULL ) { /* should have thrown an exception */ goto finish; } setCons = (*env)->GetMethodID(env, setClass, "", "()V"); if( setCons == NULL ) { goto finish; } setObj = (*env)->NewObject(env, setClass, setCons); if( setObj == NULL ) { goto finish; } setAdd = (*env)->GetMethodID(env, setClass, "add", "(Ljava/lang/Object;)Z"); if( setAdd == NULL ) { goto finish; } } cbinfo.setObj = setObj; cbinfo.setAdd = setAdd; /* * traverse all slot objects */ if( traverseTokenObjects( env, slot, engineAliasesTraversalCallback, ALL_OBJECT_TYPES, &cbinfo) != PR_SUCCESS ) { goto finish; } finish: return setObj; } typedef struct { const char *targetNickname; } EngineDeleteEntryCBInfo; static JSSTraversalStatus engineDeleteEntryTraversalCallback (JNIEnv *env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data) { EngineDeleteEntryCBInfo *cbinfo = (EngineDeleteEntryCBInfo*)data; JSSTraversalStatus status = INIT_TRAVSTAT; char *nickname = getObjectNick(obj, type); if( nickname != NULL && (PL_strcmp(nickname, cbinfo->targetNickname) == 0) ) { status.deleteIt = PR_TRUE; } freeObjectNick(nickname, type); status.status = PR_SUCCESS; return status; } JNIEXPORT void JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineDeleteEntry (JNIEnv *env, jobject this, jobject aliasString) { EngineDeleteEntryCBInfo cbinfo; PK11SlotInfo *slot = NULL; cbinfo.targetNickname = NULL; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } /* get the nickname */ cbinfo.targetNickname = JSS_RefJString(env, aliasString); if( cbinfo.targetNickname == NULL ) { goto finish; } /* traverse */ /* * traverse all slot objects */ traverseTokenObjects( env, slot, engineDeleteEntryTraversalCallback, ALL_OBJECT_TYPES, (void*) &cbinfo); finish: JSS_DerefJString(env, aliasString, cbinfo.targetNickname); } typedef struct { const char *targetNickname; CERTCertificate *cert; } EngineGetCertificateCBInfo; static JSSTraversalStatus engineGetCertificateTraversalCallback (JNIEnv *env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data) { JSSTraversalStatus travStat = INIT_TRAVSTAT; CERTCertificate *cert = (CERTCertificate*) obj; EngineGetCertificateCBInfo *cbinfo = (EngineGetCertificateCBInfo*)data; PR_ASSERT(type == CERT); /* shouldn't get called otherwise */ PR_ASSERT(cbinfo->cert == NULL); if( cert->nickname != NULL && PL_strcmp(cert->nickname, cbinfo->targetNickname) == 0 ) { cbinfo->cert = CERT_DupCertificate(cert); travStat.stopIterating = PR_TRUE; } travStat.status = PR_SUCCESS; return travStat; } static CERTCertificate* lookupCertByNickname(JNIEnv *env, jobject this, jstring alias) { PK11SlotInfo *slot; EngineGetCertificateCBInfo cbinfo = {NULL,NULL}; PRStatus status = PR_FAILURE; if( alias == NULL ) goto finish; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } cbinfo.targetNickname = JSS_RefJString(env, alias); if(cbinfo.targetNickname == NULL ) goto finish; status = traverseTokenObjects( env, slot, engineGetCertificateTraversalCallback, CERT, (void*) &cbinfo); finish: JSS_DerefJString(env, alias, cbinfo.targetNickname); if( status != PR_SUCCESS && cbinfo.cert != NULL) { CERT_DestroyCertificate(cbinfo.cert); cbinfo.cert = NULL; } return cbinfo.cert; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getCertObject (JNIEnv *env, jobject this, jstring alias) { CERTCertificate *cert = NULL; PK11SlotInfo *slot = NULL; jobject certObj = NULL; cert = lookupCertByNickname(env, this, alias); if( cert == NULL ) { goto finish; } if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } slot = PK11_ReferenceSlot(slot); certObj = JSS_PK11_wrapCertAndSlot(env, &cert, &slot); finish: if( cert != NULL ) { CERT_DestroyCertificate(cert); } if( slot != NULL ) { PK11_FreeSlot(slot); } if( certObj == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); } return certObj; } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getDERCert (JNIEnv *env, jobject this, jstring alias) { CERTCertificate * cert = NULL; jbyteArray derCertBA = NULL; cert = lookupCertByNickname(env, this, alias); if( cert == NULL ) { goto finish; } derCertBA = JSS_SECItemToByteArray(env, &cert->derCert); finish: if( cert != NULL) { CERT_DestroyCertificate(cert); } if( derCertBA == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); } return derCertBA; } JNIEXPORT jstring JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getCertNickname (JNIEnv *env, jobject this, jbyteArray derCertBA) { PK11SlotInfo *slot=NULL; SECItem *derCert=NULL; CERTCertificate * cert=NULL; CERTCertificate searchCert; jstring nickString = NULL; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } /* convert derCert to SECItem */ derCert = JSS_ByteArrayToSECItem(env, derCertBA); if( derCert == NULL ) { /* exception was thrown */ goto finish; } /* lookup cert by derCert */ searchCert.derCert = *derCert; cert = PK11_FindCertFromDERCert(slot, &searchCert, NULL /*wincx*/); if( cert == NULL ) { /* not found. return NULL */ goto finish; } /* convert cert nickname to Java string */ nickString = (*env)->NewStringUTF(env, cert->nickname); finish: if( derCert != NULL ) { SECITEM_FreeItem(derCert, PR_TRUE /*freeit*/); } if( cert != NULL ) { CERT_DestroyCertificate(cert); } return nickString; } typedef struct { const char *label; SECKEYPrivateKey *privk; PK11SymKey *symk; } FindKeyCBInfo; static JSSTraversalStatus findKeyCallback (JNIEnv *env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data) { JSSTraversalStatus status = INIT_TRAVSTAT; FindKeyCBInfo *cbinfo = (FindKeyCBInfo*)data; char *objNick = getObjectNick(obj, type); status.status = PR_SUCCESS; PR_ASSERT(cbinfo->privk==NULL && cbinfo->symk==NULL); if( PL_strcmp(objNick, cbinfo->label) == 0 ) { /* found it */ status.stopIterating = PR_TRUE; switch( type ) { case PRIVKEY: cbinfo->privk = (SECKEYPrivateKey*)obj; break; case SYMKEY: cbinfo->symk = (PK11SymKey*)obj; break; default: PR_ASSERT(PR_FALSE); status.status = PR_FAILURE; } } freeObjectNick(objNick, type); return status; } typedef struct { const char *targetNickname; SECKEYPrivateKey *privk; } GetKeyByCertNickCBInfo; static JSSTraversalStatus getKeyByCertNickCallback (JNIEnv *env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data) { JSSTraversalStatus travStat = INIT_TRAVSTAT; CERTCertificate *cert = (CERTCertificate*) obj; GetKeyByCertNickCBInfo *cbinfo = (GetKeyByCertNickCBInfo*) data; PR_ASSERT(type == CERT); /* shouldn't get called otherwise */ PR_ASSERT(cbinfo->privk == NULL); if( cert->nickname != NULL && PL_strcmp(cert->nickname, cbinfo->targetNickname) == 0 ) { travStat.stopIterating = PR_TRUE; cbinfo->privk = PK11_FindPrivateKeyFromCert(slot, cert, NULL /*wincx*/); if( cbinfo->privk ) { printf("Found private key from cert with label '%s'\n", cert->nickname); } } travStat.status = PR_SUCCESS; return travStat; } /* * This is only here for backward compatibility. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineGetKey (JNIEnv *env, jobject this, jstring alias, jcharArray password) { PR_ASSERT(0); JSS_throwMsg(env, "java/lang/RuntimeException", "Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engine" "GetKey not implemented"); return NULL; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineGetKeyNative (JNIEnv *env, jobject this, jstring alias, jcharArray password) { PK11SlotInfo *slot=NULL; FindKeyCBInfo keyCbinfo = {NULL, NULL, NULL}; GetKeyByCertNickCBInfo certCbinfo = {NULL, NULL}; jobject keyObj = NULL; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } if( alias == NULL ) { goto finish; } /* * first look for a matching key */ keyCbinfo.label = JSS_RefJString(env, alias); if( keyCbinfo.label == NULL ) { goto finish; } if( traverseTokenObjects( env, slot, findKeyCallback, PRIVKEY | SYMKEY, &keyCbinfo) != PR_SUCCESS ) { goto finish; } if(keyCbinfo.privk != NULL ) { /* found a matching private key */ keyObj = JSS_PK11_wrapPrivKey(env, &keyCbinfo.privk); } else if( keyCbinfo.symk != NULL ) { /* found a matching symmetric key */ keyObj = JSS_PK11_wrapSymKey(env, &keyCbinfo.symk); } if( keyObj == NULL ) { /* * If we didn't find a matching key, look for a matching cert */ certCbinfo.targetNickname = JSS_RefJString(env, alias); if(certCbinfo.targetNickname == NULL ) goto finish; if( traverseTokenObjects( env, slot, getKeyByCertNickCallback, CERT, (void*) &certCbinfo) != PR_SUCCESS ) { goto finish; } if( certCbinfo.privk != NULL ) { keyObj = JSS_PK11_wrapPrivKey(env, &certCbinfo.privk); } } finish: JSS_DerefJString(env, alias, keyCbinfo.label); JSS_DerefJString(env, alias, certCbinfo.targetNickname); PR_ASSERT( keyCbinfo.privk==NULL && keyCbinfo.symk==NULL); PR_ASSERT( certCbinfo.privk==NULL ); return keyObj; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineIsCertificateEntry (JNIEnv *env, jobject this, jstring alias) { PK11SlotInfo *slot; EngineGetCertificateCBInfo cbinfo = {NULL,NULL}; jboolean retVal = JNI_FALSE; if( alias == NULL ) goto finish; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } cbinfo.targetNickname = JSS_RefJString(env, alias); if(cbinfo.targetNickname == NULL ) goto finish; if( traverseTokenObjects( env, slot, engineGetCertificateTraversalCallback, CERT, (void*) &cbinfo) != PR_SUCCESS ) { goto finish; } if( cbinfo.cert != NULL ) { unsigned int allTrust; CERTCertTrust trust; SECStatus status; status = CERT_GetCertTrust(cbinfo.cert, &trust); if( status != SECSuccess ) { goto finish; } allTrust = trust.sslFlags | trust.emailFlags | trust.objectSigningFlags; if( (allTrust & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA)) && !(allTrust & CERTDB_USER) ) { /* It's a trusted cert and not a user cert. */ retVal = JNI_TRUE; } } finish: JSS_DerefJString(env, alias, cbinfo.targetNickname); if( cbinfo.cert != NULL) { CERT_DestroyCertificate(cbinfo.cert); } return retVal; } JNIEXPORT void JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineSetKeyEntryNative (JNIEnv *env, jobject this, jstring alias, jobject keyObj, jcharArray password, jobjectArray certChain) { jclass privkClass, symkClass; const char *nickname = NULL; SECKEYPrivateKey *tokenPrivk=NULL; PK11SymKey *tokenSymk=NULL; if( keyObj==NULL || alias==NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } nickname = JSS_RefJString(env, alias); if( nickname == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } privkClass = (*env)->FindClass(env, PK11PRIVKEY_CLASS_NAME); symkClass = (*env)->FindClass(env, PK11SYMKEY_CLASS_NAME); if( privkClass==NULL || symkClass==NULL) { ASSERT_OUTOFMEM(env); goto finish; } if( (*env)->IsInstanceOf(env, keyObj, privkClass) ) { SECKEYPrivateKey *privk; if( JSS_PK11_getPrivKeyPtr(env, keyObj, &privk) != PR_SUCCESS ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to extract NSS key from private key object"); goto finish; } tokenPrivk = PK11_ConvertSessionPrivKeyToTokenPrivKey(privk, NULL); if( tokenPrivk == NULL ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to copy private key to permanent token object"); goto finish; } if( PK11_SetPrivateKeyNickname(tokenPrivk, nickname) != SECSuccess ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to set alias of copied private key"); goto finish; } } else if( (*env)->IsInstanceOf(env, keyObj, symkClass) ) { PK11SymKey *symk; if( JSS_PK11_getSymKeyPtr(env, keyObj, &symk) != PR_SUCCESS ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to extract NSS key from symmetric key object"); goto finish; } tokenSymk = PK11_ConvertSessionSymKeyToTokenSymKey(symk, NULL); if( tokenSymk == NULL ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to copy symmetric key to permanent token object"); goto finish; } if( PK11_SetSymKeyNickname(tokenSymk, nickname) != SECSuccess ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to set alias of symmetric key"); goto finish; } } else { JSS_throwMsg(env, KEYSTORE_EXCEPTION, "Unrecognized key type: must be JSS private key (PK11PrivKey) or" " JSS symmetric key (PK11SymKey)"); goto finish; } finish: JSS_DerefJString(env, alias, nickname); if( tokenPrivk != NULL ) { SECKEY_DestroyPrivateKey(tokenPrivk); } if( tokenSymk != NULL ) { PK11_FreeSymKey(tokenSymk); } } jss-4.6.3/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.java000066400000000000000000000473451362106420000254550ustar00rootroot00000000000000/* 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.provider.java.security; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NoSuchTokenException; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.crypto.CryptoStore; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.NoSuchItemOnTokenException; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenCertificate; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.netscape.security.util.Utils; import org.mozilla.jss.pkcs11.PK11Token; import org.mozilla.jss.pkcs11.PK11Cert; import org.mozilla.jss.pkcs11.TokenProxy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The JSS implementation of the JCA KeyStore SPI. * *

Implementation notes *

    *
  1. deleteEntry will delete all entries with that label. If the entry is a * cert with a matching private key, it will also delete the private key. * *
  2. getCertificate returns first cert with matching nickname. Returns it as * a PK11Cert, when possible. * *
  3. getCreationDate is unsupported because NSS doesn't store that * information. * *
  4. getKey first looks for a private/symmetric key with the given label. * It returns the first one it finds. If it doesn't find one, it looks for a * cert with the given nickname. If it finds one, it returns the private key * for that cert. * *
  5. isCertificateEntry returns true if there is a cert with this nickname, * but it doesn't have a private key. isKeyEntry returns true if there is a key * with this nickname, or if there is a cert with this nickname and the cert * has an associated private key. * *
  6. load updates the token in the keystore. * *
  7. store is a no-op. * *
  8. setCertificateEntry doesn't work.NSS doesn't have a way of storing a * certificate on a specific token unless it has an associated private key. * That rules out trusted certificate entries. * *
  9. setKeyEntry not supported yet. Need to convert a temporary key * into a permanent key. *
*/ public class JSSKeyStoreSpi extends java.security.KeyStoreSpi { public static Logger logger = LoggerFactory.getLogger(JSSKeyStoreSpi.class); CryptoToken token; protected TokenProxy proxy; public JSSKeyStoreSpi() { logger.debug("JSSKeyStoreSpi: ()"); CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); PK11Token pk11tok = (PK11Token)token; proxy = pk11tok.getProxy(); } String[] parseAlias(String alias) { String tokenName; String nickname; String[] parts = StringUtils.splitPreserveAllTokens(alias, ':'); if (parts.length == 1) { tokenName = null; nickname = parts[0]; } else if (parts.length == 2) { tokenName = StringUtils.defaultIfEmpty(parts[0], null); nickname = parts[1]; } else { throw new RuntimeException("Invalid alias: " + alias); } logger.debug("JSSKeyStoreSpi: token: " + tokenName); logger.debug("JSSKeyStoreSpi: nickname: " + nickname); return new String[] { tokenName, nickname }; } public Enumeration engineAliases() { logger.debug("JSSKeyStoreSpi: engineAliases()"); return Collections.enumeration(getAliases()); } public Collection getAliases() { logger.debug("JSSKeyStoreSpi: getAliases()"); Set aliases = new LinkedHashSet<>(); try { List tokens = new ArrayList<>(); CryptoManager cm = CryptoManager.getInstance(); if (token == null) { logger.debug("JSSKeyStoreSpi: getting aliases from all tokens"); Enumeration e = cm.getAllTokens(); while (e.hasMoreElements()) { CryptoToken t = e.nextElement(); if (t == cm.getInternalCryptoToken()) { continue; // exclude crypto token } tokens.add(t); } } else { logger.debug("JSSKeyStoreSpi: getting aliases from keystore token"); tokens.add(token); } for (CryptoToken token : tokens) { String tokenName; if (token == cm.getInternalKeyStorageToken()) { tokenName = null; logger.debug("JSSKeyStoreSpi: token: internal"); } else { tokenName = token.getName(); logger.debug("JSSKeyStoreSpi: token: " + tokenName); } CryptoStore store = token.getCryptoStore(); logger.debug("JSSKeyStoreSpi: - certificates:"); for (X509Certificate cert : store.getCertificates()) { String nickname = cert.getNickname(); logger.debug("JSSKeyStoreSpi: - " + nickname); aliases.add(nickname); } logger.debug("JSSKeyStoreSpi: - private keys:"); for (PrivateKey privateKey : store.getPrivateKeys()) { // convert key ID into hexadecimal String keyID = Utils.HexEncode(privateKey.getUniqueID()); String nickname; if (tokenName == null) { nickname = keyID; } else { nickname = tokenName + ":" + keyID; } logger.debug("JSSKeyStoreSpi: - " + nickname); aliases.add(nickname); } } return aliases; } catch (NotInitializedException e) { throw new RuntimeException(e); } catch (TokenException e) { throw new RuntimeException(e); } } public boolean engineContainsAlias(String alias) { logger.debug("JSSKeyStoreSpi: engineContainsAlias(" + alias + ")"); return getAliases().contains(alias); } public void engineDeleteEntry(String alias) throws KeyStoreException { try { CryptoManager manager = CryptoManager.getInstance(); try { logger.debug("JSSKeyStoreSpi: searching for cert"); X509Certificate cert = manager.findCertByNickname(alias); CryptoToken token; if (cert instanceof TokenCertificate) { TokenCertificate tokenCert = (TokenCertificate) cert; token = tokenCert.getOwningToken(); } else { token = manager.getInternalKeyStorageToken(); } CryptoStore store = token.getCryptoStore(); logger.debug("JSSKeyStoreSpi: deleting cert: " + alias); store.deleteCertOnly(cert); return; } catch (ObjectNotFoundException e) { logger.debug("JSSKeyStoreSpi: cert not found, searching for key"); } String[] parts = parseAlias(alias); String tokenName = parts[0]; String nickname = parts[1]; CryptoToken token; if (tokenName == null) { token = manager.getInternalKeyStorageToken(); } else { token = manager.getTokenByName(tokenName); } CryptoStore store = token.getCryptoStore(); logger.debug("JSSKeyStoreSpi: searching for private key"); for (PrivateKey privateKey : store.getPrivateKeys()) { // convert key ID into hexadecimal String keyID = Utils.HexEncode(privateKey.getUniqueID()); logger.debug("JSSKeyStoreSpi: - " + keyID); if (!nickname.equals(keyID)) { continue; } try { logger.debug("JSSKeyStoreSpi: searching for public key: " + nickname); PublicKey publicKey = store.findPublicKey(privateKey); logger.debug("JSSKeyStoreSpi: deleting public key: " + nickname); store.deletePublicKey(publicKey); } catch (ObjectNotFoundException e) { logger.debug("JSSKeyStoreSpi: public key not found: " + nickname); } logger.debug("JSSKeyStoreSpi: deleting private key: " + nickname); store.deletePrivateKey(privateKey); return; } logger.debug("JSSKeyStoreSpi: entry not found: " + alias); throw new KeyStoreException("Entry not found: " + alias); } catch (NotInitializedException e) { throw new KeyStoreException(e); } catch (NoSuchTokenException e) { throw new KeyStoreException(e); } catch (TokenException e) { throw new KeyStoreException(e); } catch (NoSuchItemOnTokenException e) { throw new KeyStoreException(e); } } public Certificate engineGetCertificate(String alias) { logger.debug("JSSKeyStoreSpi: engineGetCertificate(" + alias + ")"); try { CryptoManager cm = CryptoManager.getInstance(); X509Certificate cert = cm.findCertByNickname(alias); logger.debug("JSSKeyStoreSpi: cert found: " + alias); if (cert instanceof PK11Cert) { return (PK11Cert) cert; } byte[] bytes = cert.getEncoded(); InputStream is = new ByteArrayInputStream(bytes); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); return certFactory.generateCertificate(is); } catch (ObjectNotFoundException e) { logger.debug("JSSKeyStoreSpi: cert not found: " + alias); return null; } catch (NotInitializedException e) { throw new RuntimeException(e); } catch (TokenException e) { throw new RuntimeException(e); } catch (CertificateEncodingException e) { throw new RuntimeException(e); } catch (CertificateException e) { throw new RuntimeException(e); } } public String engineGetCertificateAlias(Certificate cert) { logger.debug("JSSKeyStoreSpi: engineGetCertificateAlias()"); try { if (cert instanceof PK11Cert) { PK11Cert _c = (PK11Cert) cert; return _c.getNickname(); } return getCertNickname( cert.getEncoded() ); } catch(CertificateEncodingException e) { return null; } } private native String getCertNickname(byte[] derCert); public Certificate[] engineGetCertificateChain(String alias) { logger.debug("JSSKeyStoreSpi: engineGetCertificateChain(" + alias + ")"); try { logger.debug("JSSKeyStoreSpi: searching for leaf cert"); CryptoManager cm = CryptoManager.getInstance(); X509Certificate leaf = cm.findCertByNickname(alias); logger.debug("JSSKeyStoreSpi: building cert chain"); X509Certificate[] certs = cm.buildCertificateChain(leaf); Certificate[] chain = new Certificate[certs.length]; CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); for (int i = 0; i < certs.length; i++) { X509Certificate cert = certs[i]; logger.debug("JSSKeyStoreSpi: - " + cert.getSubjectDN()); if (cert instanceof PK11Cert) { chain[i] = (PK11Cert) cert; continue; } byte[] bytes = cert.getEncoded(); InputStream is = new ByteArrayInputStream(bytes); chain[i] = certFactory.generateCertificate(is); } return chain; } catch (ObjectNotFoundException e) { logger.debug("leaf cert not found: " + alias); return null; } catch (NotInitializedException e) { throw new RuntimeException(e); } catch (TokenException e) { throw new RuntimeException(e); } catch (CertificateException e) { throw new RuntimeException(e); } } /* * Not supported. */ public java.util.Date engineGetCreationDate(String alias) { logger.debug("JSSKeyStoreSpi: engineGetCreationDate(" + alias + ")"); return null; } public Key engineGetKey(String alias, char[] password) { logger.debug("JSSKeyStoreSpi: engineGetKey(" + alias + ")"); try { CryptoManager cm = CryptoManager.getInstance(); logger.debug("JSSKeyStoreSpi: searching for cert"); try { X509Certificate cert = cm.findCertByNickname(alias); logger.debug("JSSKeyStoreSpi: found cert: " + alias); PrivateKey privateKey = cm.findPrivKeyByCert(cert); logger.debug("JSSKeyStoreSpi: found private key: " + alias); return privateKey; } catch (ObjectNotFoundException e) { logger.debug("JSSKeyStoreSpi: cert/key not found, searching for key"); } String[] parts = parseAlias(alias); String tokenName = parts[0]; String nickname = parts[1]; CryptoToken token; if (tokenName == null) { token = cm.getInternalKeyStorageToken(); } else { token = cm.getTokenByName(tokenName); } CryptoStore store = token.getCryptoStore(); logger.debug("JSSKeyStoreSpi: searching for private key"); for (PrivateKey privateKey : store.getPrivateKeys()) { // convert key ID into hexadecimal String keyID = Utils.HexEncode(privateKey.getUniqueID()); logger.debug("JSSKeyStoreSpi: - " + keyID); if (nickname.equals(keyID)) { logger.debug("JSSKeyStoreSpi: found private key: " + nickname); return privateKey; } } logger.debug("JSSKeyStoreSpi: searching for symmetric key"); for (SymmetricKey symmetricKey : store.getSymmetricKeys()) { logger.debug("JSSKeyStoreSpi: - " + symmetricKey.getNickName()); if (nickname.equals(symmetricKey.getNickName())) { logger.debug("JSSKeyStoreSpi: found symmetric key: " + nickname); return new SecretKeyFacade(symmetricKey); } } logger.debug("JSSKeyStoreSpi: key not found: " + nickname); return null; } catch (NoSuchTokenException e) { throw new RuntimeException(e); } catch (NotInitializedException e) { throw new RuntimeException(e); } catch (TokenException e) { throw new RuntimeException(e); } } /** * Returns true if there is a cert with this nickname but there is no * key associated with the cert. */ public boolean engineIsCertificateEntry(String alias) { logger.debug("JSSKeyStoreSpi: engineIsCertificateEntry(" + alias + ")"); try { CryptoManager cm = CryptoManager.getInstance(); cm.findCertByNickname(alias); logger.debug("JSSKeyStoreSpi: cert found: " + alias); return true; } catch (ObjectNotFoundException e) { logger.debug("JSSKeyStoreSpi: cert not found: " + alias); return false; } catch (NotInitializedException e) { throw new RuntimeException(e); } catch (TokenException e) { throw new RuntimeException(e); } } /** * Returns true if there is a key with this alias, or if * there is a cert with this alias that has an associated key. */ public boolean engineIsKeyEntry(String alias) { logger.debug("JSSKeyStoreSpi: engineIsKeyEntry(" + alias + ")"); /* this is somewhat wasteful but we can speed it up later */ return engineGetKey(alias, null) != null; } public void engineLoad(InputStream stream, char[] password) throws IOException { logger.debug("JSSKeyStoreSpi: engineLoad(stream, password)"); } public void engineLoad(KeyStore.LoadStoreParameter param) throws IOException { logger.debug("JSSKeyStoreSpi: engineLoad(param)"); if (!(param instanceof JSSLoadStoreParameter)) { throw new IOException("Invalid keystore parameter type: " + param.getClass().getName()); } JSSLoadStoreParameter jssParam = (JSSLoadStoreParameter) param; token = jssParam.getToken(); try { logger.debug("JSSKeyStoreSpi: token: " + token.getName()); } catch (TokenException e) { throw new IOException(e); } } /** * NSS doesn't have a way of storing a certificate on a specific token * unless it has an associated private key. That rules out * trusted certificate entries, so we can't supply this method currently. */ public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException { logger.debug("JSSKeyStoreSpi: engineSetCertificateEntry(" + alias + ")"); throw new KeyStoreException( "Storing trusted certificate entries to a JSS KeyStore is not" + " supported."); } public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException { logger.debug("JSSKeyStoreSpi: engineSetKeyEntry(" + alias + ", key, chain)"); throw new KeyStoreException("Storing plaintext keys is not supported."+ "Store the key as a handle instead."); } public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { logger.debug("JSSKeyStoreSpi: engineSetKeyEntry(" + alias + ", key, password, chain)"); if( key instanceof SecretKeyFacade ) { SecretKeyFacade skf = (SecretKeyFacade)key; engineSetKeyEntryNative(alias, skf.key, password, chain); } else { engineSetKeyEntryNative(alias, key, password, chain); } } private native void engineSetKeyEntryNative(String alias, Object key, char[] password, Certificate[] chain) throws KeyStoreException; public int engineSize() { logger.debug("JSSKeyStoreSpi: engineSize()"); return getAliases().size(); } public void engineStore(OutputStream stream, char[] password) throws IOException { logger.debug("JSSKeyStoreSpi: engineStore()"); } } jss-4.6.3/org/mozilla/jss/provider/java/security/JSSLoadStoreParameter.java000066400000000000000000000013541362106420000267570ustar00rootroot00000000000000/* 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.provider.java.security; import java.security.KeyStore.LoadStoreParameter; import java.security.KeyStore.ProtectionParameter; import org.mozilla.jss.crypto.CryptoToken; public class JSSLoadStoreParameter implements LoadStoreParameter { CryptoToken token; public JSSLoadStoreParameter(CryptoToken token) { this.token = token; } @Override public ProtectionParameter getProtectionParameter() { return null; } public CryptoToken getToken() { return token; } } jss-4.6.3/org/mozilla/jss/provider/java/security/JSSMessageDigestSpi.java000066400000000000000000000076751362106420000264360ustar00rootroot00000000000000/* 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.provider.java.security; import java.security.DigestException; import java.security.MessageDigestSpi; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.DigestAlgorithm; import org.mozilla.jss.crypto.JSSMessageDigest; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.TokenRuntimeException; import org.mozilla.jss.crypto.TokenSupplierManager; public abstract class JSSMessageDigestSpi extends MessageDigestSpi { private JSSMessageDigest digest; protected JSSMessageDigestSpi(DigestAlgorithm alg) { super(); CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); try { CryptoManager cm = CryptoManager.getInstance(); CryptoToken ikst = cm.getInternalKeyStorageToken(); if( token.equals(ikst) ) { // InternalKeyStorageToken doesn't support message digesting token = cm.getInternalCryptoToken(); } try { digest = token.getDigestContext(alg); } catch(java.security.NoSuchAlgorithmException e) { throw new UnsupportedOperationException( "Token '" + token.getName() + "' does not support " + "algorithm " + alg.toString()); } } catch(TokenException e) { throw new TokenRuntimeException(e.getMessage()); } catch(DigestException e1) { throw new TokenRuntimeException(e1.getMessage()); } catch(NotInitializedException e2) { throw new TokenRuntimeException(e2.getMessage()); } } public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } public byte[] engineDigest() { try { return digest.digest(); } catch(java.security.DigestException de) { throw new TokenRuntimeException(de.getMessage()); } } public int engineDigest(byte[] buf, int offset, int len) throws DigestException { return digest.digest(buf, offset, len); } public int engineGetDigestLength() { return digest.getOutputSize(); } public void engineReset() { try { digest.reset(); } catch(java.security.DigestException de) { throw new TokenRuntimeException(de.getMessage()); } } public void engineUpdate(byte input) { try { digest.update(input); } catch(java.security.DigestException de) { throw new TokenRuntimeException(de.getMessage()); } } public void engineUpdate(byte[] input, int offset, int len) { try { digest.update(input,offset,len); } catch(java.security.DigestException de) { throw new TokenRuntimeException(de.getMessage()); } } public static class SHA1 extends JSSMessageDigestSpi { public SHA1() { super( DigestAlgorithm.SHA1 ); } } public static class SHA256 extends JSSMessageDigestSpi { public SHA256() { super( DigestAlgorithm.SHA256 ); } } public static class SHA384 extends JSSMessageDigestSpi { public SHA384() { super( DigestAlgorithm.SHA384 ); } } public static class SHA512 extends JSSMessageDigestSpi { public SHA512() { super( DigestAlgorithm.SHA512 ); } } public static class MD5 extends JSSMessageDigestSpi { public MD5() { super( DigestAlgorithm.MD5 ); } } public static class MD2 extends JSSMessageDigestSpi { public MD2() { super( DigestAlgorithm.MD2 ); } } } jss-4.6.3/org/mozilla/jss/provider/java/security/JSSSecureRandomSpi.java000066400000000000000000000017371362106420000262720ustar00rootroot00000000000000/* 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.provider.java.security; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.crypto.JSSSecureRandom; public class JSSSecureRandomSpi extends java.security.SecureRandomSpi { private static final long serialVersionUID = 1L; JSSSecureRandom engine; public JSSSecureRandomSpi() { super(); engine = TokenSupplierManager.getTokenSupplier().getSecureRNG(); } protected byte[] engineGenerateSeed(int numBytes) { byte[] bytes = new byte[numBytes]; engine.nextBytes(bytes); return bytes; } protected void engineNextBytes(byte[] bytes) { engine.nextBytes(bytes); } protected void engineSetSeed(byte[] seed) { engine.setSeed(seed); } } jss-4.6.3/org/mozilla/jss/provider/java/security/JSSSignatureSpi.java000066400000000000000000000174521362106420000256450ustar00rootroot00000000000000/* 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.provider.java.security; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.X509EncodedKeySpec; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.TokenSupplierManager; class JSSSignatureSpi extends java.security.SignatureSpi { org.mozilla.jss.crypto.Signature sig; SignatureAlgorithm alg; protected JSSSignatureSpi(SignatureAlgorithm alg) { this.alg = alg; } public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } public void engineInitSign(java.security.PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { // discard the random engineInitSign(privateKey); } public void engineInitSign(java.security.PrivateKey privateKey) throws InvalidKeyException { try { sig = getSigContext(privateKey); sig.initSign((PrivateKey)privateKey); } catch(java.security.NoSuchAlgorithmException e) { throw new InvalidKeyException("Algorithm not supported"); } catch(TokenException e) { throw new InvalidKeyException("Token exception occurred"); } } private org.mozilla.jss.crypto.Signature getSigContext(java.security.PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeyException, TokenException { CryptoToken token; PrivateKey privk; if( ! (privateKey instanceof PrivateKey) ) { throw new InvalidKeyException(); } privk = (PrivateKey)privateKey; token = privk.getOwningToken(); return token.getSignatureContext(alg); } public void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { try { CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); sig = token.getSignatureContext(alg); // convert the public key into a JSS public key if necessary if( ! (publicKey instanceof org.mozilla.jss.pkcs11.PK11PubKey) ) { if( ! publicKey.getFormat().equalsIgnoreCase("X.509") ) { throw new InvalidKeyException( "Unsupported public key format: " + publicKey.getFormat()); } X509EncodedKeySpec encodedKey = new X509EncodedKeySpec(publicKey.getEncoded()); KeyFactory fact = KeyFactory.getInstance( publicKey.getAlgorithm(), "Mozilla-JSS"); publicKey = fact.generatePublic(encodedKey); } sig.initVerify(publicKey); } catch(NoSuchProviderException e) { throw new InvalidKeyException("Unable to convert non-JSS key " + "to JSS key"); } catch(java.security.spec.InvalidKeySpecException e) { throw new InvalidKeyException("Unable to convert non-JSS key " + "to JSS key"); } catch(java.security.NoSuchAlgorithmException e) { throw new InvalidKeyException("Algorithm not supported"); } catch(TokenException e) { throw new InvalidKeyException("Token exception occurred"); } } public void engineUpdate(byte b) throws SignatureException { try { sig.update(b); } catch( TokenException e) { throw new SignatureException("TokenException: "+e.toString()); } } public void engineUpdate(byte[] b, int off, int len) throws SignatureException { try { sig.update(b, off, len); } catch( TokenException e) { throw new SignatureException("TokenException: "+e.toString()); } } public byte[] engineSign() throws SignatureException { try { return sig.sign(); } catch(TokenException e) { throw new SignatureException("TokenException: "+e.toString()); } } public int engineSign(byte[] outbuf, int offset, int len) throws SignatureException { try { return sig.sign(outbuf, offset, len); } catch(TokenException e) { throw new SignatureException("TokenException: "+e.toString()); } } public boolean engineVerify(byte[] sigBytes) throws SignatureException { try { return sig.verify(sigBytes); } catch( TokenException e) { throw new SignatureException("TokenException: "+e.toString()); } } public void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { try { sig.setParameter(params); } catch( TokenException e ) { throw new InvalidAlgorithmParameterException( "TokenException: "+e.toString()); } } public Object engineGetParameter(String param) throws InvalidParameterException { throw new InvalidParameterException( "name/value parameters not supported"); } public void engineSetParameter(String param, Object value) throws InvalidParameterException { throw new InvalidParameterException( "name/value parameters not supported"); } public static class DSA extends JSSSignatureSpi { public DSA() { super(SignatureAlgorithm.DSASignatureWithSHA1Digest); } } public static class SHA1EC extends JSSSignatureSpi { public SHA1EC() { super(SignatureAlgorithm.ECSignatureWithSHA1Digest); } } public static class SHA256EC extends JSSSignatureSpi { public SHA256EC() { super(SignatureAlgorithm.ECSignatureWithSHA256Digest); } } public static class SHA384EC extends JSSSignatureSpi { public SHA384EC() { super(SignatureAlgorithm.ECSignatureWithSHA384Digest); } } public static class SHA512EC extends JSSSignatureSpi { public SHA512EC() { super(SignatureAlgorithm.ECSignatureWithSHA512Digest); } } public static class MD2RSA extends JSSSignatureSpi { public MD2RSA() { super(SignatureAlgorithm.RSASignatureWithMD2Digest); } } public static class MD5RSA extends JSSSignatureSpi { public MD5RSA() { super(SignatureAlgorithm.RSASignatureWithMD5Digest); } } public static class SHA1RSA extends JSSSignatureSpi { public SHA1RSA() { super(SignatureAlgorithm.RSASignatureWithSHA1Digest); } } public static class SHA256RSA extends JSSSignatureSpi { public SHA256RSA() { super(SignatureAlgorithm.RSASignatureWithSHA256Digest); } } public static class SHA384RSA extends JSSSignatureSpi { public SHA384RSA() { super(SignatureAlgorithm.RSASignatureWithSHA384Digest); } } public static class SHA512RSA extends JSSSignatureSpi { public SHA512RSA() { super(SignatureAlgorithm.RSASignatureWithSHA512Digest); } } } jss-4.6.3/org/mozilla/jss/provider/java/security/KeyFactorySpi1_2.java000066400000000000000000000257171362106420000257110ustar00rootroot00000000000000/* 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.provider.java.security; import java.io.PrintWriter; import java.io.StringWriter; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.pkcs11.PK11PrivKey; import org.mozilla.jss.pkcs11.PK11PubKey; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.pkix.primitive.PrivateKeyInfo; import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo; import org.mozilla.jss.util.Assert; public class KeyFactorySpi1_2 extends java.security.KeyFactorySpi { protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { if( keySpec instanceof RSAPublicKeySpec ) { RSAPublicKeySpec spec = (RSAPublicKeySpec) keySpec; // Generate a DER RSA public key SEQUENCE seq = new SEQUENCE(); seq.addElement( new INTEGER(spec.getModulus())); seq.addElement( new INTEGER(spec.getPublicExponent())); return PK11PubKey.fromRaw( PrivateKey.RSA, ASN1Util.encode(seq) ); } else if( keySpec instanceof DSAPublicKeySpec ) { // We need to import both the public value and the PQG parameters. // The only way to get all that information in DER is to send // a full SubjectPublicKeyInfo. So we encode all the information // into an SPKI. DSAPublicKeySpec spec = (DSAPublicKeySpec) keySpec; SEQUENCE pqg = new SEQUENCE(); pqg.addElement( new INTEGER(spec.getP()) ); pqg.addElement( new INTEGER(spec.getQ()) ); pqg.addElement( new INTEGER(spec.getG()) ); OBJECT_IDENTIFIER oid = null; try { oid = SignatureAlgorithm.DSASignature.toOID(); } catch(NoSuchAlgorithmException e ) { throw new RuntimeException("No such algorithm: " + e.getMessage(), e); } AlgorithmIdentifier algID = new AlgorithmIdentifier( oid, pqg ); INTEGER publicValue = new INTEGER(spec.getY()); byte[] encodedPublicValue = ASN1Util.encode(publicValue); SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo( algID, new BIT_STRING(encodedPublicValue, 0) ); return PK11PubKey.fromSPKI( ASN1Util.encode(spki) ); // // requires JAVA 1.5 // //} else if( keySpec instanceof ECPublicKeySpec ) { // // We need to import both the public value and the curve. // // The only way to get all that information in DER is to send // // a full SubjectPublicKeyInfo. So we encode all the information // // into an SPKI. // // ECPublicKeySpec spec = (ECPublicKeySpec) keySpec; // AlgorithmParameters algParams = getInstance("ECParameters"); // // algParameters.init(spec.getECParameters()); // OBJECT_IDENTIFIER oid = null; // try { // oid = SignatureAlgorithm.ECSignature.toOID(); // } catch(NoSuchAlgorithmException ex ) { // Assert.notReached("no such algorithm as DSA?"); // } // AlgorithmIdentifier algID = // new AlgorithmIdentifier(oid, ecParams.getParams() ); // INTEGER publicValueX = new INTEGER(spec.getW().getAffineX()); // INTEGER publicValueY = new INTEGER(spec.getW().getAffineY()); // byte[] encodedPublicValue; // encodedPublicValue[0] = EC_UNCOMPRESSED_POINT; // encodedPublicValue += spec.getW().getAffineX().toByteArray(); // encodedPublicValue += spec.getW().getAffineY().toByteArray(); // // byte[] encodedPublicValue = ASN1Util.encode(publicValue); // SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo( // algID, new BIT_STRING(encodedPublicValue, 0) ); // // return PK11PubKey.fromSPKI( ASN1Util.encode(spki) ); // // use the following for EC keys in 1.4.2 } else if( keySpec instanceof X509EncodedKeySpec ) { // // SubjectPublicKeyInfo // X509EncodedKeySpec spec = (X509EncodedKeySpec) keySpec; return PK11PubKey.fromSPKI( spec.getEncoded() ); } throw new InvalidKeySpecException("Unsupported KeySpec type: " + keySpec.getClass().getName()); } /** * We don't support RSAPrivateKeySpec because it doesn't have enough * information. You need to provide an RSAPrivateCrtKeySpec. */ protected java.security.PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { try { if( keySpec instanceof RSAPrivateCrtKeySpec ) { // // PKCS #1 RSAPrivateKey // RSAPrivateCrtKeySpec spec = (RSAPrivateCrtKeySpec) keySpec; SEQUENCE privKey = new SEQUENCE(); privKey.addElement( new INTEGER(0) ) ; // version privKey.addElement( new INTEGER(spec.getModulus()) ); privKey.addElement( new INTEGER(spec.getPublicExponent()) ); privKey.addElement( new INTEGER(spec.getPrivateExponent()) ); privKey.addElement( new INTEGER(spec.getPrimeP()) ); privKey.addElement( new INTEGER(spec.getPrimeQ()) ); privKey.addElement( new INTEGER(spec.getPrimeExponentP()) ); privKey.addElement( new INTEGER(spec.getPrimeExponentQ()) ); privKey.addElement( new INTEGER(spec.getCrtCoefficient()) ); AlgorithmIdentifier algID = new AlgorithmIdentifier( PrivateKey.RSA.toOID(), null ); OCTET_STRING encodedPrivKey = new OCTET_STRING( ASN1Util.encode(privKey) ); PrivateKeyInfo pki = new PrivateKeyInfo( new INTEGER(0), // version algID, encodedPrivKey, (SET)null // OPTIONAL SET OF Attribute ); return PK11PrivKey.fromPrivateKeyInfo( ASN1Util.encode(pki), TokenSupplierManager.getTokenSupplier().getThreadToken() ); } else if( keySpec instanceof DSAPrivateKeySpec ) { DSAPrivateKeySpec spec = (DSAPrivateKeySpec) keySpec; SEQUENCE pqgParams = new SEQUENCE(); pqgParams.addElement(new INTEGER(spec.getP())); pqgParams.addElement(new INTEGER(spec.getQ())); pqgParams.addElement(new INTEGER(spec.getG())); AlgorithmIdentifier algID = new AlgorithmIdentifier( PrivateKey.DSA.toOID(), pqgParams ); OCTET_STRING privateKey = new OCTET_STRING( ASN1Util.encode(new INTEGER(spec.getX())) ); PrivateKeyInfo pki = new PrivateKeyInfo( new INTEGER(0), // version algID, privateKey, null // OPTIONAL SET OF Attribute ); // Derive the public key from the private key BigInteger y = spec.getG().modPow(spec.getX(), spec.getP()); byte[] yBA = y.toByteArray(); // we need to chop off a leading zero byte if( y.bitLength() % 8 == 0 ) { byte[] newBA = new byte[yBA.length-1]; assert(newBA.length >= 0); System.arraycopy(yBA, 1, newBA, 0, newBA.length); yBA = newBA; } return PK11PrivKey.fromPrivateKeyInfo( ASN1Util.encode(pki), TokenSupplierManager.getTokenSupplier().getThreadToken(), yBA ); } else if( keySpec instanceof PKCS8EncodedKeySpec ) { return PK11PrivKey.fromPrivateKeyInfo( (PKCS8EncodedKeySpec)keySpec, TokenSupplierManager.getTokenSupplier().getThreadToken() ); } throw new InvalidKeySpecException("Unsupported KeySpec type: " + keySpec.getClass().getName()); } catch(TokenException te) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); te.printStackTrace(pw); throw new InvalidKeySpecException("TokenException: " + sw.toString()); } } protected T engineGetKeySpec(Key key, Class keySpec) throws InvalidKeySpecException { throw new InvalidKeySpecException( "Exporting raw key data is not supported. Wrap the key instead."); } /** * Translates key by calling getEncoded() to get its encoded form, * then importing the key from its encoding. Two formats are supported: * "X.509", which is decoded with an X509EncodedKeySpec; * and "PKCS#8", which is decoded with a PKCS8EncodedKeySpec. * *

This method is not well standardized: the documentation is very vague * about how the key is supposed to be translated. It is better * to move keys around by wrapping and unwrapping them; or by manually * translating to a KeySpec, then manually translating back to a Key. */ protected Key engineTranslateKey(Key key) throws InvalidKeyException { byte[] encoded = key.getEncoded(); String format = key.getFormat(); try { if( format.equals("SubjectPublicKeyInfo") || format.equalsIgnoreCase("X.509")) { X509EncodedKeySpec spec = new X509EncodedKeySpec(encoded); return engineGeneratePublic(spec); } else if( format.equals("PrivateKeyInfo") || format.equalsIgnoreCase("PKCS#8")) { PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(encoded); return engineGeneratePrivate(spec); } } catch(InvalidKeySpecException e) { throw new InvalidKeyException(e.getMessage()); } throw new InvalidKeyException( "Unsupported encoding format: " + format); } } jss-4.6.3/org/mozilla/jss/provider/java/security/RC2AlgorithmParameters.java000066400000000000000000000037671362106420000271350ustar00rootroot00000000000000/* 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.provider.java.security; import java.io.IOException; import java.security.AlgorithmParametersSpi; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.RC2ParameterSpec; /** * This class is only intended to be used to implement * CipherSpi.getAlgorithmParameters(). */ public class RC2AlgorithmParameters extends AlgorithmParametersSpi { private RC2ParameterSpec RC2ParamSpec; public void engineInit(AlgorithmParameterSpec paramSpec) { RC2ParamSpec = (RC2ParameterSpec) paramSpec; } public T engineGetParameterSpec(Class clazz) throws InvalidParameterSpecException { if( clazz != null && !clazz.isInstance(RC2ParamSpec) ) { Class paramSpecClass = RC2ParamSpec.getClass(); throw new InvalidParameterSpecException( "RC2 getParameterSpec has class " + paramSpecClass.getName()); } return clazz.cast(RC2ParamSpec); } public void engineInit(byte[] params) throws IOException { throw new IOException("engineInit(byte[]) not supported"); } public void engineInit(byte[] params, String format) throws IOException { throw new IOException("engineInit(byte[],String) not supported"); } public byte[] engineGetEncoded() throws IOException { throw new IOException("encoding RC2AlgorithmParameters not supported"); } public byte[] engineGetEncoded(String format) throws IOException { throw new IOException("encoding RC2AlgorithmParameters not supported"); } public String engineToString() { String str = new String("Mozilla-JSS RC2AlgorithmParameters " + getClass().getName()); return str; } } jss-4.6.3/org/mozilla/jss/provider/javax/000077500000000000000000000000001362106420000203155ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/provider/javax/crypto/000077500000000000000000000000001362106420000216355ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/provider/javax/crypto/JSSCipherSpi.java000066400000000000000000000463541362106420000247620ustar00rootroot00000000000000/* 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.provider.javax.crypto; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.ShortBufferException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.crypto.Algorithm; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.TokenRuntimeException; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.pkcs11.PK11PrivKey; import org.mozilla.jss.pkcs11.PK11PubKey; import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo; import org.mozilla.jss.util.Assert; class JSSCipherSpi extends javax.crypto.CipherSpi { private String algFamily=null; private String algMode=null; private String algPadding=null; CryptoToken token = null; private org.mozilla.jss.crypto.Cipher cipher=null; private EncryptionAlgorithm encAlg = null; private org.mozilla.jss.crypto.KeyWrapper wrapper=null; private KeyWrapAlgorithm wrapAlg = null; private AlgorithmParameterSpec params = null; private int blockSize; //keyStrength is used for RC2ParameterSpec and EncryptionAlgorithm.lookup private int keyStrength; protected JSSCipherSpi(String algFamily) { this.algFamily = algFamily; token = TokenSupplierManager.getTokenSupplier().getThreadToken(); } public void engineSetMode(String mode) { this.algMode = mode; } public void engineSetPadding(String padding) { this.algPadding = padding; } static private SecretKey importKey(Key key) throws InvalidKeyException { if (key instanceof SecretKey) { SecretKey sKey = (SecretKey) key; SecretKeyFactory fact = null; try { fact = SecretKeyFactory.getInstance(sKey.getAlgorithm(), "Mozilla-JSS"); } catch (NoSuchAlgorithmException e) { throw new InvalidKeyException( "Unable to translate key with Algorithm" + key.getAlgorithm()); } catch (NoSuchProviderException ex) { throw new InvalidKeyException( "Unable to find provider, this should not happen"); } return fact.translateKey(sKey); }else { throw new InvalidKeyException("Invalid key type: " + key.getClass().getName()); } } public void engineInit(int opmode, Key key, AlgorithmParameterSpec givenParams, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { try { // throw away any previous state cipher = null; wrapper = null; params = givenParams; if( algFamily==null ) { throw new InvalidAlgorithmParameterException( "incorrectly specified algorithm"); } if( opmode != Cipher.ENCRYPT_MODE && opmode != Cipher.DECRYPT_MODE && opmode != Cipher.WRAP_MODE && opmode != Cipher.UNWRAP_MODE ) { throw new InvalidKeyException("Invalid opmode"); } StringBuffer buf = new StringBuffer(); buf.append(algFamily); if( algMode != null ) { buf.append('/'); buf.append(algMode); } if( algPadding != null ) { buf.append('/'); buf.append(algPadding); } if( opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.DECRYPT_MODE ) { if( ! (key instanceof SecretKeyFacade) ) { key = importKey(key); } SymmetricKey symkey = ((SecretKeyFacade)key).key; // lookup the encryption algorithm keyStrength = symkey.getStrength(); encAlg = EncryptionAlgorithm.lookup(algFamily, algMode, algPadding, keyStrength); blockSize = encAlg.getBlockSize(); if( !token.doesAlgorithm(encAlg) ) { throw new NoSuchAlgorithmException( encAlg.toString() + " is not supported by this token " + token.getName()); } cipher = token.getCipherContext(encAlg); if( opmode == Cipher.ENCRYPT_MODE ) { if( params == noAlgParams ) { // we're supposed to generate some params params = generateAlgParams(encAlg, blockSize); } cipher.initEncrypt(symkey, params); } else if( opmode == Cipher.DECRYPT_MODE ) { if( params == noAlgParams) { params = null; } cipher.initDecrypt(symkey, params); } } else { assert( opmode==Cipher.WRAP_MODE || opmode==Cipher.UNWRAP_MODE); wrapAlg = KeyWrapAlgorithm.fromString(buf.toString()); blockSize = wrapAlg.getBlockSize(); wrapper = token.getKeyWrapper(wrapAlg); // generate params if necessary if( params == noAlgParams ) { if( opmode == Cipher.WRAP_MODE ) { params = generateAlgParams(wrapAlg, blockSize); } else { assert(opmode == Cipher.UNWRAP_MODE); params = null; } } if( key instanceof org.mozilla.jss.crypto.PrivateKey ) { if( opmode != Cipher.UNWRAP_MODE ) { throw new InvalidKeyException( "Private key can only be used for unwrapping"); } wrapper.initUnwrap( (org.mozilla.jss.crypto.PrivateKey) key, params ); } else if( key instanceof PublicKey ) { if( opmode != Cipher.WRAP_MODE ) { throw new InvalidKeyException( "Public key can only be used for wrapping"); } wrapper.initWrap((PublicKey) key, params); } else if( key instanceof org.mozilla.jss.crypto.SecretKeyFacade) { org.mozilla.jss.crypto.SecretKeyFacade sk = (org.mozilla.jss.crypto.SecretKeyFacade) key; if( opmode == Cipher.WRAP_MODE ) { wrapper.initWrap( sk.key, params ); } else { assert(opmode==Cipher.UNWRAP_MODE); wrapper.initUnwrap( sk.key, params ); } } else { throw new InvalidKeyException("Invalid key type: " + key.getClass().getName()); } } } catch (NoSuchAlgorithmException e) { throw new InvalidAlgorithmParameterException(e.getMessage()); } catch(TokenException te) { throw new TokenRuntimeException(te.getMessage()); } } public void engineInit(int opmode, Key key, AlgorithmParameters givenParams, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { try { AlgorithmParameterSpec gp = null; if (algFamily.compareToIgnoreCase("RC2") == 0) { gp = givenParams.getParameterSpec( javax.crypto.spec.RC2ParameterSpec.class ); } else if (algMode.compareToIgnoreCase("CBC") == 0) { gp = givenParams.getParameterSpec( javax.crypto.spec.IvParameterSpec.class ); } if (gp != null) { engineInit(opmode, key, gp, random); } else { throw new InvalidAlgorithmParameterException("Unknown Parameter Spec"); } } catch(Exception e) { throw new InvalidAlgorithmParameterException(e.getMessage()); } } public void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { engineInit(opmode, key, noAlgParams, random); } catch(InvalidAlgorithmParameterException e) { throw new InvalidKeyException(e.getMessage()); } } private AlgorithmParameterSpec generateAlgParams(Algorithm alg, int blockSize) throws InvalidKeyException { Class [] paramClasses = alg.getParameterClasses(); AlgorithmParameterSpec algParSpec = null; if( paramClasses == null ) { // no parameters are needed return null; } // generate an IV byte[] iv = new byte[blockSize]; try { SecureRandom random = SecureRandom.getInstance("pkcs11prng", "Mozilla-JSS"); random.nextBytes(iv); } catch (Exception e) { throw new RuntimeException(e); } for (int i = 0; i < paramClasses.length; i ++) { if( paramClasses[i].equals( javax.crypto.spec.IvParameterSpec.class ) ) { algParSpec = new javax.crypto.spec.IvParameterSpec(iv); break; } else if ( paramClasses[i].equals( RC2ParameterSpec.class ) ) { algParSpec = new RC2ParameterSpec(keyStrength, iv); break; } } return algParSpec; } private static class NoAlgParams implements AlgorithmParameterSpec { } private static final NoAlgParams noAlgParams = new NoAlgParams(); public int engineGetBlockSize() { return blockSize; } public byte[] engineGetIV() { if( params == null ) { return null; } if( params instanceof IvParameterSpec) { return ((IvParameterSpec)params).getIV(); } else if( params instanceof RC2ParameterSpec ) { return ((RC2ParameterSpec)params).getIV(); } else { return null; } } public AlgorithmParameters engineGetParameters() { AlgorithmParameters algParams = null; try { if(( params instanceof IvParameterSpec ) || ( params instanceof RC2ParameterSpec )) { algParams = AlgorithmParameters.getInstance(algFamily); algParams.init(params); } } catch(NoSuchAlgorithmException e) { throw new RuntimeException("Unable to get parameters: " + e.getMessage(), e); } catch(InvalidParameterSpecException e) { throw new RuntimeException("Unable to get parameters: " + e.getMessage(), e); } return algParams; } public int engineGetOutputSize(int inputLen) { int total = (blockSize-1) + inputLen; return ((total / blockSize) + 1) * blockSize; } public byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) { if(cipher == null) { // Cipher is supposed to catch an illegal state, so we should never // get here throw new IllegalStateException(); } try { return cipher.update(input, inputOffset, inputLen); } catch(TokenException te) { throw new TokenRuntimeException(te.getMessage()); } } public int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException { byte[] bytes = engineUpdate(input, inputOffset, inputLen); if( bytes.length > output.length-outputOffset ) { throw new ShortBufferException(bytes.length + " needed, " + (output.length-outputOffset) + " supplied"); } System.arraycopy(bytes, 0, output, outputOffset, bytes.length); return bytes.length; } public byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { if( cipher == null ) { // Cipher is supposed to catch an illegal state, so we should never // get here throw new IllegalStateException(); } try { if( input == null || inputLen == 0) { return cipher.doFinal(); } else { return cipher.doFinal(input, inputOffset, inputLen); } } catch(IllegalStateException ise) { throw ise; } catch(org.mozilla.jss.crypto.IllegalBlockSizeException ibse) { throw new IllegalBlockSizeException(ibse.getMessage()); } catch(TokenException te) { throw new TokenRuntimeException(te.getMessage()); } } public int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { byte[] bytes = engineDoFinal(input, inputOffset, inputLen); if( bytes.length > output.length-outputOffset ) { throw new ShortBufferException(bytes.length + " needed, " + (output.length-outputOffset) + " supplied"); } System.arraycopy(bytes, 0, output, outputOffset, bytes.length); return bytes.length; } public byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException { if( wrapper == null ) { throw new IllegalStateException(); } try { if( key instanceof org.mozilla.jss.crypto.PrivateKey ) { return wrapper.wrap( (org.mozilla.jss.crypto.PrivateKey) key); } else if( key instanceof org.mozilla.jss.crypto.SecretKeyFacade) { return wrapper.wrap( ((org.mozilla.jss.crypto.SecretKeyFacade)key).key ); } else { throw new InvalidKeyException("Unsupported key type: " + key.getClass().getName()); } } catch(IllegalStateException ise) { throw ise; } catch(TokenException te) { throw new TokenRuntimeException(te.getMessage()); } } public Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException { if( wrapper == null ) { throw new IllegalStateException(); } try { switch(wrappedKeyType) { case Cipher.SECRET_KEY: return engineUnwrapSecret(wrappedKey, wrappedKeyAlgorithm); case Cipher.PRIVATE_KEY: return engineUnwrapPrivate(wrappedKey, wrappedKeyAlgorithm); case Cipher.PUBLIC_KEY: throw new UnsupportedOperationException( "Unable to unwrap public keys"); default: throw new NoSuchAlgorithmException( "Invalid key type: " + wrappedKeyType); } } catch(IllegalStateException ise) { throw ise; } } private Key engineUnwrapSecret(byte[] wrappedKey, String wrappedKeyAlg) throws InvalidKeyException, NoSuchAlgorithmException { try { int idx = wrappedKeyAlg.indexOf('/'); if( idx != -1 ) { wrappedKeyAlg = wrappedKeyAlg.substring(0, idx); } SymmetricKey.Type wrappedKeyType = SymmetricKey.Type.fromName(wrappedKeyAlg); // Specify 0 for key length. This will use the default key length. // Won't work for algorithms without a default, like RC4, unless a // padded algorithm is used. SymmetricKey key = wrapper.unwrapSymmetric(wrappedKey, wrappedKeyType, 0); return new SecretKeyFacade(key); } catch(StringIndexOutOfBoundsException e) { throw new NoSuchAlgorithmException("Unknown algorithm: " + wrappedKeyAlg); } catch(TokenException te ) { throw new TokenRuntimeException(te.getMessage()); } catch(InvalidAlgorithmParameterException iape ) { throw new NoSuchAlgorithmException("Invalid algorithm parameters" + iape.getMessage()); } } private Key engineUnwrapPrivate(byte[] wrappedKey, String wrappedKeyAlg) throws InvalidKeyException, NoSuchAlgorithmException { throw new NoSuchAlgorithmException( "Unwrapping private keys via the JCA interface is not supported: "+ "http://bugzilla.mozilla.org/show_bug.cgi?id=135328"); } public int engineGetKeySize(Key key) throws InvalidKeyException { if( key instanceof PK11PrivKey ) { return ((PK11PrivKey)key).getStrength(); } else if( key instanceof PK11PubKey ) { try { byte[] encoded = ((PK11PubKey)key).getEncoded(); SubjectPublicKeyInfo.Template spkiTemp = new SubjectPublicKeyInfo.Template(); SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) ASN1Util.decode(spkiTemp, encoded); BIT_STRING pk = spki.getSubjectPublicKey(); return pk.getBits().length - pk.getPadCount(); } catch(InvalidBERException e) { throw new InvalidKeyException("Exception while decoding " + "public key: " + e.getMessage()); } } else if( key instanceof SecretKeyFacade ) { SymmetricKey symkey = ((SecretKeyFacade)key).key; return symkey.getLength(); } else { key = importKey(key); SymmetricKey symkey = ((SecretKeyFacade)key).key; return symkey.getLength(); } } static public class DES extends JSSCipherSpi { public DES() { super("DES"); } } static public class DESede extends JSSCipherSpi { public DESede() { super("DESede"); } } static public class AES extends JSSCipherSpi { public AES() { super("AES"); } } static public class RC4 extends JSSCipherSpi { public RC4() { super("RC4"); } } static public class RSA extends JSSCipherSpi { public RSA() { super("RSA"); } } static public class RC2 extends JSSCipherSpi { public RC2() { super("RC2"); } } } jss-4.6.3/org/mozilla/jss/provider/javax/crypto/JSSKeyGeneratorSpi.java000066400000000000000000000123021362106420000261310ustar00rootroot00000000000000/* 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.provider.javax.crypto; import java.io.CharConversionException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.SecretKey; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.TokenRuntimeException; import org.mozilla.jss.crypto.TokenSupplierManager; class JSSKeyGeneratorSpi extends javax.crypto.KeyGeneratorSpi { private KeyGenerator keyGenerator= null; protected JSSKeyGeneratorSpi(KeyGenAlgorithm alg) { try { CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); keyGenerator = token.getKeyGenerator(alg); } catch( TokenException te) { throw new TokenRuntimeException(te.getMessage()); } catch(NoSuchAlgorithmException nsae) { throw new TokenRuntimeException(nsae.getMessage()); } } protected void engineInit(int keysize, SecureRandom random) throws InvalidParameterException { try { keyGenerator.initialize(keysize); } catch(InvalidAlgorithmParameterException e) { throw new InvalidParameterException(e.getMessage()); } } protected void engineInit( SecureRandom random) throws InvalidParameterException { // no-op. KeyGenerator.initialize isn't called if there // are no arguments. } protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { keyGenerator.initialize(params); } protected SecretKey engineGenerateKey() { try { return new SecretKeyFacade( keyGenerator.generate() ); } catch(IllegalStateException ise) { throw new TokenRuntimeException( "IllegalStateException: " + ise.getMessage()); } catch(TokenException te) { throw new TokenRuntimeException( te.getMessage()); } catch(CharConversionException cce) { throw new TokenRuntimeException( "CharConversionException: " + cce.getMessage()); } } public static class DES extends JSSKeyGeneratorSpi { public DES() { super(KeyGenAlgorithm.DES); } } public static class DESede extends JSSKeyGeneratorSpi { public DESede() { super(KeyGenAlgorithm.DESede); } } public static class AES extends JSSKeyGeneratorSpi { public AES() { super(KeyGenAlgorithm.AES); } } public static class RC4 extends JSSKeyGeneratorSpi { public RC4() { super(KeyGenAlgorithm.RC4); } } public static class RC2 extends JSSKeyGeneratorSpi { public RC2() { super(KeyGenAlgorithm.RC2); } } public static class HmacSHA1 extends JSSKeyGeneratorSpi { public HmacSHA1() { super(KeyGenAlgorithm.SHA1_HMAC); } } public static class PBAHmacSHA1 extends JSSKeyGeneratorSpi { public PBAHmacSHA1() { super(KeyGenAlgorithm.PBA_SHA1_HMAC); } } public static class HmacSHA256 extends JSSKeyGeneratorSpi { public HmacSHA256() { super(KeyGenAlgorithm.SHA256_HMAC); } } public static class HmacSHA384 extends JSSKeyGeneratorSpi { public HmacSHA384() { super(KeyGenAlgorithm.SHA384_HMAC); } } public static class HmacSHA512 extends JSSKeyGeneratorSpi { public HmacSHA512() { super(KeyGenAlgorithm.SHA512_HMAC); } } public static class KbkdfCounter extends JSSKeyGeneratorSpi { public KbkdfCounter() { super(KeyGenAlgorithm.SP800_108_COUNTER_KDF); } } public static class KbkdfFeedback extends JSSKeyGeneratorSpi { public KbkdfFeedback() { super(KeyGenAlgorithm.SP800_108_FEEDBACK_KDF); } } public static class KbkdfDoublePipeline extends JSSKeyGeneratorSpi { public KbkdfDoublePipeline() { super(KeyGenAlgorithm.SP800_108_DOUBLE_PIPELINE_KDF); } } public static class KbkdfCounterData extends JSSKeyGeneratorSpi { public KbkdfCounterData() { super(KeyGenAlgorithm.NSS_SP800_108_COUNTER_KDF_DERIVE_DATA); } } public static class KbkdfFeedbackData extends JSSKeyGeneratorSpi { public KbkdfFeedbackData() { super(KeyGenAlgorithm.NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA); } } public static class KbkdfDoublePipelineData extends JSSKeyGeneratorSpi { public KbkdfDoublePipelineData() { super(KeyGenAlgorithm.NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA); } } } jss-4.6.3/org/mozilla/jss/provider/javax/crypto/JSSKeyManager.java000066400000000000000000000125511362106420000251070ustar00rootroot00000000000000/* BEGIN COPYRIGHT BLOCK * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Copyright (C) 2017 Red Hat, Inc. * All rights reserved. * END COPYRIGHT BLOCK */ package org.mozilla.jss.provider.javax.crypto; import java.net.Socket; import java.security.Principal; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import javax.net.ssl.X509KeyManager; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.pkcs11.PK11Cert; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class JSSKeyManager implements X509KeyManager { final static Logger logger = LoggerFactory.getLogger(JSSKeyManager.class); @Override public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket socket) { logger.debug("JSSKeyManager: chooseClientAlias()"); logger.debug("JSSKeyManager: key types:"); for (String keyType : keyTypes) { logger.debug("JSSKeyManager: - " + keyType); } logger.debug("JSSKeyManager: issuers:"); for (Principal issuer : issuers) { logger.debug("JSSKeyManager: - " + issuer.getName()); } return null; // not implemented } @Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { logger.debug("JSSKeyManager: chooseServerAlias()"); logger.debug("JSSKeyManager: key type: " + keyType); logger.debug("JSSKeyManager: issuers:"); for (Principal issuer : issuers) { logger.debug("JSSKeyManager: - " + issuer.getName()); } return null; // not implemented } public org.mozilla.jss.crypto.X509Certificate getCertificate(String alias) { try { CryptoManager cm = CryptoManager.getInstance(); return cm.findCertByNickname(alias); } catch (Exception e) { logger.error(e.getMessage(), e); throw new RuntimeException(e); } } @Override public X509Certificate[] getCertificateChain(String alias) { logger.debug("JSSKeyManager: getCertificateChain(" + alias + ")"); try { CryptoManager cm = CryptoManager.getInstance(); org.mozilla.jss.crypto.X509Certificate cert = cm.findCertByNickname(alias); org.mozilla.jss.crypto.X509Certificate[] chain = cm.buildCertificateChain(cert); logger.debug("JSSKeyManager: cert chain:"); Collection list = new ArrayList<>(); for (org.mozilla.jss.crypto.X509Certificate c : chain) { if (!(c instanceof PK11Cert)) { logger.error("JSSKeyManager: Can't cast to PK11Cert: " + c); } logger.debug("JSSKeyManager: - " + c.getSubjectDN()); list.add((PK11Cert) c); } return list.toArray(new X509Certificate[list.size()]); } catch (Throwable e) { logger.error(e.getMessage(), e); throw new RuntimeException(e); } } @Override public String[] getClientAliases(String keyType, Principal[] issuers) { logger.debug("JSSKeyManager: getClientAliases()"); logger.debug("JSSKeyManager: key type: " + keyType); logger.debug("JSSKeyManager: issuers:"); for (Principal issuer : issuers) { logger.debug("JSSKeyManager: - " + issuer.getName()); } return null; // not implemented } @Override public PrivateKey getPrivateKey(String alias) { logger.debug("JSSKeyManager: getPrivateKey(" + alias + ")"); try { CryptoManager cm = CryptoManager.getInstance(); org.mozilla.jss.crypto.X509Certificate cert = cm.findCertByNickname(alias); PrivateKey privateKey = cm.findPrivKeyByCert(cert); logger.debug("JSSKeyManager: key found: " + alias); return privateKey; } catch (ObjectNotFoundException e) { logger.debug("JSSKeyManager: key not found: " + alias); return null; } catch (Throwable e) { logger.error(e.getMessage(), e); throw new RuntimeException(e); } } @Override public String[] getServerAliases(String keyType, Principal[] issuers) { logger.debug("JSSKeyManager: getServerAliases()"); logger.debug("JSSKeyManager: key type: " + keyType); logger.debug("JSSKeyManager: issuers:"); for (Principal issuer : issuers) { logger.debug("JSSKeyManager: - " + issuer.getName()); } return null; // not implemented } } jss-4.6.3/org/mozilla/jss/provider/javax/crypto/JSSKeyManagerFactory.java000066400000000000000000000022151362106420000264330ustar00rootroot00000000000000package org.mozilla.jss.provider.javax.crypto; import java.security.*; import javax.net.ssl.*; import org.mozilla.jss.*; import org.mozilla.jss.util.*; import org.mozilla.jss.provider.java.security.*; public class JSSKeyManagerFactory extends KeyManagerFactorySpi { protected void engineInit(KeyStore ks, char[] password) throws KeyStoreException { try { // At most, we can update the password callback if one doesn't exist. CryptoManager cm = CryptoManager.getInstance(); if (cm.getPasswordCallback() == null && password != null) { PasswordCallback callback = new Password(password); cm.setPasswordCallback(callback); } } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } protected void engineInit(ManagerFactoryParameters spec) { // There is absolutely nothing we can do here, so exit without // initializing anything. } protected KeyManager[] engineGetKeyManagers() { KeyManager[] kms = new KeyManager[1]; kms[0] = new JSSKeyManager(); return kms; } } jss-4.6.3/org/mozilla/jss/provider/javax/crypto/JSSMacSpi.java000066400000000000000000000077341362106420000242470ustar00rootroot00000000000000/* 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.provider.javax.crypto; import java.security.DigestException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.spec.AlgorithmParameterSpec; import org.mozilla.jss.crypto.CMACAlgorithm; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.DigestAlgorithm; import org.mozilla.jss.crypto.HMACAlgorithm; import org.mozilla.jss.crypto.JSSMessageDigest; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenRuntimeException; import org.mozilla.jss.crypto.TokenSupplierManager; class JSSMacSpi extends javax.crypto.MacSpi { private JSSMessageDigest digest=null; private DigestAlgorithm alg; protected JSSMacSpi(DigestAlgorithm alg) { try { this.alg = alg; CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); digest = token.getDigestContext(alg); } catch( DigestException de) { throw new TokenRuntimeException(de.getMessage()); } catch(NoSuchAlgorithmException nsae) { throw new TokenRuntimeException(nsae.getMessage()); } } public int engineGetMacLength() { return alg.getOutputSize(); } public void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { try { SymmetricKey real_key; if (key instanceof SecretKeyFacade) { SecretKeyFacade facade = (SecretKeyFacade)key; real_key = facade.key; } else if (key instanceof SymmetricKey) { real_key = (SymmetricKey)key; } else { throw new InvalidKeyException("Must use a key created by JSS! Try exporting the key data and importing it via SecretKeyFactory."); } digest.initHMAC(real_key); } catch(DigestException de) { throw new InvalidKeyException( "DigestException: " + de.getMessage()); } } public void engineUpdate(byte input) { try { digest.update(input); } catch(DigestException de) { throw new TokenRuntimeException("DigestException: " + de.getMessage()); } } public void engineUpdate(byte[] input, int offset, int len) { try { digest.update(input, offset, len); } catch(DigestException de) { throw new TokenRuntimeException("DigestException: " + de.getMessage()); } } public byte[] engineDoFinal() { try { return digest.digest(); } catch(DigestException de) { throw new TokenRuntimeException("DigestException: " + de.getMessage()); } } public void engineReset() { try { digest.reset(); } catch(DigestException de) { throw new TokenRuntimeException("DigestException: " + de.getMessage()); } } public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } public static class HmacSHA1 extends JSSMacSpi { public HmacSHA1() { super(HMACAlgorithm.SHA1); } } public static class HmacSHA256 extends JSSMacSpi { public HmacSHA256() { super(HMACAlgorithm.SHA256); } } public static class HmacSHA384 extends JSSMacSpi { public HmacSHA384() { super(HMACAlgorithm.SHA384); } } public static class HmacSHA512 extends JSSMacSpi { public HmacSHA512() { super(HMACAlgorithm.SHA512); } } public static class CmacAES extends JSSMacSpi { public CmacAES() { super(CMACAlgorithm.AES); } } } jss-4.6.3/org/mozilla/jss/provider/javax/crypto/JSSNativeTrustManager.java000066400000000000000000000027711362106420000266520ustar00rootroot00000000000000package org.mozilla.jss.provider.javax.crypto; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; /** * JSSNativeTrustManager is a JSSEngine TrustManager utilizing existing native * certificate checking functionality of NSS and JSS, compatible with the old * SSLSocket checks. * * Note: This class isn't compatible with external (non-JSS) SSLEngines. * * The only configuration possible is in CryptoManager's OCSP Policy, which * this obeys. No other configuration is possible. This is more performant * than other TrustManagers, because it saves a JNI call and handles the NSS * callback directly. */ public class JSSNativeTrustManager implements X509TrustManager { private String error_msg = getClass().getName() + " should not be used " + "directly! Please use it with JSSEngine. Note " + "that this TrustManager must be the only one " + "passed to JSSEngine."; @Override public void checkClientTrusted(X509Certificate[] certChain, String authType) throws CertificateException { throw new RuntimeException(error_msg); } @Override public void checkServerTrusted(X509Certificate[] certChain, String authType) throws CertificateException { throw new RuntimeException(error_msg); } @Override public X509Certificate[] getAcceptedIssuers() { throw new RuntimeException(error_msg); } } jss-4.6.3/org/mozilla/jss/provider/javax/crypto/JSSSecretKeyFactorySpi.java000066400000000000000000000415241362106420000267700ustar00rootroot00000000000000/* 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.provider.javax.crypto; import java.io.CharConversionException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.SecretKeyFactorySpi; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.KeyWrapper; import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.PBEKeyGenParams; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.TokenRuntimeException; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.util.Password; class JSSSecretKeyFactorySpi extends SecretKeyFactorySpi { private KeyGenAlgorithm alg = null; private CryptoToken token = null; protected JSSSecretKeyFactorySpi(KeyGenAlgorithm alg) { this.alg = alg; token = TokenSupplierManager.getTokenSupplier().getThreadToken(); } private SecretKey generateKeyFromBits(byte[] bits, SymmetricKey.Type keyType) throws NoSuchAlgorithmException, TokenException, InvalidKeySpecException, InvalidAlgorithmParameterException { try { KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.PLAINTEXT); wrapper.initUnwrap(); SymmetricKey symk = wrapper.unwrapSymmetric(bits, keyType, 0); return new SecretKeyFacade(symk); } catch(InvalidKeyException e) { throw new InvalidKeySpecException(e.getMessage()); } } private static PBEKeyGenParams makePBEKeyGenParams(PBEKeySpec spec) throws InvalidKeySpecException { // The PBEKeySpec in JCE 1.2.1 does not contain salt or iteration. // The PBEKeySpec in JDK 1.4 does contain salt and iteration. // If this is a JCE 1.2.1 PBEKeySpec, we don't have enough // information and we have to throw an exception. If it's a JDK 1.4 // PBEKeySpec, we can get the information. The only way I know of // to find this out at runtime and be compatible with both // versions is to use the reflection API. Class specClass = spec.getClass(); try { Method getSaltMethod = specClass.getMethod("getSalt", (java.lang.Class[]) null); Method getIterationMethod = specClass.getMethod("getIterationCount", (java.lang.Class[]) null); byte[] salt = (byte[]) getSaltMethod.invoke(spec, (java.lang.Object[]) null); Integer itCountObj = (Integer) getIterationMethod.invoke(spec, (java.lang.Object[]) null); int iterationCount = itCountObj.intValue(); Password pass = new Password(spec.getPassword()); PBEKeyGenParams params = new PBEKeyGenParams(pass, salt, iterationCount); pass.clear(); return params; } catch(NoSuchMethodException nsme) { // fall through } catch(SecurityException se) { throw new InvalidKeySpecException( "SecurityException calling getMethod() on the key " + "spec's class: " + se.getMessage()); } catch(IllegalAccessException iae) { throw new InvalidKeySpecException( "IllegalAccessException invoking method on PBEKeySpec: " + iae.getMessage()); } catch(InvocationTargetException ite) { String message=""; Throwable t = ite.getTargetException(); if( t != null ) { message = t.getMessage(); } throw new InvalidKeySpecException( "InvocationTargetException invoking method on PBEKeySpec: "+ message); } throw new InvalidKeySpecException( "This version of PBEKeySpec is unsupported. It must " + "implement getSalt() and getIterationCount(). The PBEKeySpec in " + "JDK 1.4 works, as does org.mozilla.jss.crypto.PBEKeyGenParams. " + "The PBEKeySpec in JCE 1.2.1 and earlier does NOT work."); } public SecretKey engineGenerateSecret(KeySpec spec) throws InvalidKeySpecException { try { if( spec instanceof PBEKeySpec || spec instanceof PBEKeyGenParams) { PBEKeyGenParams params; if( spec instanceof PBEKeySpec ) { params = makePBEKeyGenParams((PBEKeySpec)spec); } else { params = (org.mozilla.jss.crypto.PBEKeyGenParams) spec; } org.mozilla.jss.crypto.KeyGenerator gen =token.getKeyGenerator(alg); gen.initialize(params); SymmetricKey symk = gen.generate(); params.clear(); return new SecretKeyFacade(symk); } else if (spec instanceof DESedeKeySpec) { if( alg != KeyGenAlgorithm.DES3 ) { throw new InvalidKeySpecException( "Incorrect KeySpec type (" + spec.getClass().getName() + ") for algorithm (" + alg.toString() + ")"); } return generateKeyFromBits( ((DESedeKeySpec)spec).getKey(), SymmetricKey.Type.DES3 ); } else if (spec instanceof DESKeySpec) { if( alg != KeyGenAlgorithm.DES ) { throw new InvalidKeySpecException( "Incorrect KeySpec type (" + spec.getClass().getName() + ") for algorithm (" + alg.toString() + ")"); } return generateKeyFromBits( ((DESKeySpec)spec).getKey(), SymmetricKey.Type.DES ); } else if( spec instanceof SecretKeySpec ) { SecretKeySpec kspec = (SecretKeySpec) spec; SymmetricKey.Type type = SymmetricKey.Type.fromName( kspec.getAlgorithm()); return generateKeyFromBits( kspec.getEncoded(), type); } else { throw new InvalidKeySpecException( "Unsupported KeySpec: " + spec.getClass().getName()); } } catch(TokenException te) { throw new TokenRuntimeException(te.getMessage()); } catch(InvalidAlgorithmParameterException iape) { throw new InvalidKeySpecException( "InvalidAlgorithmParameterException: " + iape.getMessage()); } catch(IllegalStateException e) { throw (TokenRuntimeException) new TokenRuntimeException("IllegalStateException: " + e.getMessage()).initCause(e); } catch(CharConversionException e) { throw new InvalidKeySpecException("CharConversionException: " + e.getMessage(), e); } catch(NoSuchAlgorithmException e) { throw new InvalidKeySpecException("NoSuchAlgorithmException: " + e.getMessage(), e); } } public KeySpec engineGetKeySpec(SecretKey key, Class keySpec) throws InvalidKeySpecException { try { if( ! (key instanceof SecretKeyFacade) ) { throw new InvalidKeySpecException("key is not a JSS key"); } SymmetricKey symkey = ((SecretKeyFacade)key).key; byte[] keyBits = symkey.getKeyData(); SymmetricKey.Type keyType = symkey.getType(); if( keySpec.equals(DESedeKeySpec.class) ) { if( keyType != SymmetricKey.Type.DES3 ) { throw new InvalidKeySpecException( "key/spec mismatch: " + keyType + " key, DESede spec"); } return new DESedeKeySpec(keyBits); } else if( keySpec.equals(DESKeySpec.class) ) { if( keyType != SymmetricKey.Type.DES ) { throw new InvalidKeySpecException( "key/spec mismatch: " + keyType + " key, DES spec"); } return new DESKeySpec(keyBits); } else if( keySpec.equals(SecretKeySpec.class) ) { return new SecretKeySpec(keyBits, keyType.toString()); } else { throw new InvalidKeySpecException( "Unsupported key spec: " + keySpec.getName()); } } catch(SymmetricKey.NotExtractableException e) { throw new InvalidKeySpecException("Key is not extractable: " + e.getMessage(), e); } catch(InvalidKeyException e) { // This gets thrown by the key spec constructor if there's something // wrong with the key bits. But since those key bits came from // a real key, this should never happen. throw new InvalidKeySpecException("Invalid key: " + e.getMessage(), e); } } public SecretKey engineTranslateKey(SecretKey key) throws InvalidKeyException { if( key instanceof SecretKeyFacade ) { // try cloning the key try { SymmetricKey oldkey = ((SecretKeyFacade)key).key; CryptoToken owningToken = oldkey.getOwningToken(); org.mozilla.jss.crypto.KeyGenerator keygen = token.getKeyGenerator(oldkey.getType().getKeyGenAlg()); SymmetricKey newkey = keygen.clone(oldkey); return new SecretKeyFacade(newkey); } catch(SymmetricKey.NotExtractableException nee) { // no way around this, we fail throw new InvalidKeyException("key is not extractable"); } catch(TokenException te) { // fall through and try doing it the long way } catch(NoSuchAlgorithmException nsae) { throw new InvalidKeyException("Unsupported algorithm: " + nsae.getMessage()); } } // try extracting the key value and then creating a new key try { byte[] keyBits = key.getEncoded(); if( keyBits == null ) { throw new InvalidKeyException("Key is not extractable"); } SymmetricKey.Type keyType = SymmetricKey.Type.fromName( key.getAlgorithm() ); return generateKeyFromBits( keyBits, keyType); } catch( NoSuchAlgorithmException nsae ) { throw new InvalidKeyException("Unsupported algorithm: " + key.getAlgorithm()); } catch(TokenException te) { throw new InvalidKeyException("Token failed to process key: " + te.getMessage()); } catch(InvalidKeySpecException ikse) { throw new InvalidKeyException("Invalid key spec: " + ikse.getMessage()); } catch(InvalidAlgorithmParameterException iape) { throw new InvalidKeyException("Invalid algorithm parameters: " + iape.getMessage()); } } public static void main(String args[]) { try { CryptoManager.initialize("."); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalCryptoToken(); cm.setThreadToken(tok); org.mozilla.jss.crypto.KeyGenerator keygen = tok.getKeyGenerator(KeyGenAlgorithm.DES3); SymmetricKey symk = keygen.generate(); SecretKeyFacade origKey = new SecretKeyFacade(symk); JSSSecretKeyFactorySpi fact = new JSSSecretKeyFactorySpi(KeyGenAlgorithm.DES3); DESedeKeySpec kspec = (DESedeKeySpec) fact.engineGetKeySpec(origKey, DESedeKeySpec.class); SecretKeyFacade newKey = (SecretKeyFacade) fact.engineGenerateSecret(kspec); org.mozilla.jss.crypto.Cipher cipher = tok.getCipherContext(EncryptionAlgorithm.DES3_ECB); cipher.initEncrypt(origKey.key); String original = "Hello, World!!!!"; byte[] cipherText = cipher.doFinal( original.getBytes("UTF-8") ); System.out.println("ciphertext is " + cipherText.length + " bytes"); cipher.initDecrypt(newKey.key); byte[] plainText = cipher.doFinal(cipherText); System.out.println("recovered plaintext is " + plainText.length + " bytes"); String recovered = new String(plainText, "UTF-8"); System.out.println("Recovered '" + recovered + "'"); if( ! recovered.equals(original) ) { throw new Exception("recovered string is different from original"); } char[] pw = "foobarpw".toCharArray(); byte[] salt = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }; int iterationCount = 2; // generate a PBE key the old-fashioned way keygen = tok.getKeyGenerator(PBEAlgorithm.PBE_SHA1_DES3_CBC); PBEKeyGenParams jssKeySpec = new PBEKeyGenParams(pw, salt, iterationCount); keygen.initialize(jssKeySpec); symk = keygen.generate(); byte[] keydata = symk.getKeyData(); // generate a PBE key with the JCE SecretKeyFactory keyFact = SecretKeyFactory.getInstance("PBEWithSHA1AndDESede", "Mozilla-JSS"); newKey = (SecretKeyFacade) keyFact.generateSecret(jssKeySpec); byte[] newkeydata = newKey.key.getKeyData(); if( ! java.util.Arrays.equals(keydata, newkeydata) ) { throw new Exception("generated PBE keys are different"); } System.out.println("generated PBE keys are the same"); /* XXX JDK 1.4 ONLY // now try with a JDK 1.4 PBEKeySpec PBEKeySpec keySpec = new PBEKeySpec(pw, salt, iterationCount); newKey = (SecretKeyFacade) keyFact.generateSecret(keySpec); if( ! java.util.Arrays.equals(keydata, newKey.key.getKeyData()) ) { throw new Exception("generated PBE keys are different"); } System.out.println("generated PBE keys are the same"); */ System.exit(0); } catch(Throwable t) { t.printStackTrace(); System.exit(-1); } } public static class DES extends JSSSecretKeyFactorySpi { public DES() { super(KeyGenAlgorithm.DES); } } public static class DESede extends JSSSecretKeyFactorySpi { public DESede() { super(KeyGenAlgorithm.DESede); } } public static class AES extends JSSSecretKeyFactorySpi { public AES() { super(KeyGenAlgorithm.AES); } } public static class RC4 extends JSSSecretKeyFactorySpi { public RC4() { super(KeyGenAlgorithm.RC4); } } public static class RC2 extends JSSSecretKeyFactorySpi { public RC2() { super(KeyGenAlgorithm.RC2); } } public static class PBE_MD5_DES_CBC extends JSSSecretKeyFactorySpi { public PBE_MD5_DES_CBC() { super(PBEAlgorithm.PBE_MD5_DES_CBC); } } public static class PBE_SHA1_DES_CBC extends JSSSecretKeyFactorySpi { public PBE_SHA1_DES_CBC() { super(PBEAlgorithm.PBE_SHA1_DES_CBC); } } public static class PBE_SHA1_DES3_CBC extends JSSSecretKeyFactorySpi { public PBE_SHA1_DES3_CBC() { super(PBEAlgorithm.PBE_SHA1_DES3_CBC); } } public static class PBE_SHA1_RC4_128 extends JSSSecretKeyFactorySpi { public PBE_SHA1_RC4_128() { super(PBEAlgorithm.PBE_SHA1_RC4_128); } } public static class HmacSHA1 extends JSSSecretKeyFactorySpi { public HmacSHA1() { super(KeyGenAlgorithm.SHA1_HMAC); } } public static class PBAHmacSHA1 extends JSSSecretKeyFactorySpi { public PBAHmacSHA1() { super(KeyGenAlgorithm.PBA_SHA1_HMAC); } } public static class HmacSHA256 extends JSSSecretKeyFactorySpi { public HmacSHA256() { super(KeyGenAlgorithm.SHA256_HMAC); } } public static class HmacSHA384 extends JSSSecretKeyFactorySpi { public HmacSHA384() { super(KeyGenAlgorithm.SHA384_HMAC); } } public static class HmacSHA512 extends JSSSecretKeyFactorySpi { public HmacSHA512() { super(KeyGenAlgorithm.SHA512_HMAC); } } public static class GenericSecret extends JSSSecretKeyFactorySpi { public GenericSecret() { super(KeyGenAlgorithm.GENERIC_SECRET); } } } jss-4.6.3/org/mozilla/jss/provider/javax/crypto/JSSTrustManager.java000066400000000000000000000167421362106420000255060ustar00rootroot00000000000000/* BEGIN COPYRIGHT BLOCK * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Copyright (C) 2017 Red Hat, Inc. * All rights reserved. * END COPYRIGHT BLOCK */ package org.mozilla.jss.provider.javax.crypto; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import javax.net.ssl.X509TrustManager; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.pkcs11.PK11Cert; import org.mozilla.jss.netscape.security.util.Cert; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class JSSTrustManager implements X509TrustManager { final static Logger logger = LoggerFactory.getLogger(JSSTrustManager.class); final static String SERVER_AUTH_OID = "1.3.6.1.5.5.7.3.1"; final static String CLIENT_AUTH_OID = "1.3.6.1.5.5.7.3.2"; public boolean allowMissingExtendedKeyUsage = false; public void configureAllowMissingExtendedKeyUsage(boolean allow) { allowMissingExtendedKeyUsage = allow; } public void checkCertChain(X509Certificate[] certChain, String keyUsage) throws Exception { logger.debug("JSSTrustManager: checkCertChain(" + keyUsage + ")"); // sort cert chain from root to leaf certChain = Cert.sortCertificateChain(certChain); for (X509Certificate cert : certChain) { logger.debug("JSSTrustManager: - " + cert.getSubjectDN()); } // get CA certs X509Certificate[] caCerts = getAcceptedIssuers(); // validating cert chain from root to leaf for (int i = 0; i < certChain.length; i++) { X509Certificate cert = certChain[i]; // validating key usage on leaf cert only String usage; if (i == certChain.length - 1) { usage = keyUsage; } else { usage = null; } checkCert(cert, caCerts, usage); // use the current cert as the CA cert for the next cert in the chain caCerts = new X509Certificate[] { cert }; } } public void checkCert(X509Certificate cert, X509Certificate[] caCerts, String keyUsage) throws Exception { logger.debug("JSSTrustManager: checkCert(" + cert.getSubjectDN() + "):"); boolean[] aki = cert.getIssuerUniqueID(); logger.debug("JSSTrustManager: cert AKI: " + Arrays.toString(aki)); X509Certificate issuer = null; for (X509Certificate caCert : caCerts) { boolean[] ski = caCert.getSubjectUniqueID(); logger.debug("JSSTrustManager: SKI of " + caCert.getSubjectDN() + ": " + Arrays.toString(ski)); try { cert.verify(caCert.getPublicKey(), "Mozilla-JSS"); issuer = caCert; break; } catch (Exception e) { logger.debug("JSSTrustManager: invalid certificate: " + e); } } if (issuer == null) { throw new CertificateException("Unable to validate signature: " + cert.getSubjectDN()); } logger.debug("JSSTrustManager: cert signed by " + issuer.getSubjectDN()); logger.debug("JSSTrustManager: checking validity range:"); logger.debug("JSSTrustManager: - not before: " + cert.getNotBefore()); logger.debug("JSSTrustManager: - not after: " + cert.getNotAfter()); cert.checkValidity(); if (keyUsage != null) { List extendedKeyUsages = cert.getExtendedKeyUsage(); logger.debug("JSSTrustManager: checking extended key usages:"); if (extendedKeyUsages != null) { for (String extKeyUsage : extendedKeyUsages) { logger.debug("JSSTrustManager: - " + extKeyUsage); } } boolean haveKeyUsage = extendedKeyUsages != null && extendedKeyUsages.contains(keyUsage); boolean allowedToSkip = extendedKeyUsages == null && allowMissingExtendedKeyUsage; if (haveKeyUsage) { logger.debug("JSSTrustManager: extended key usage found: " + keyUsage); } else if (allowedToSkip) { logger.debug("JSSTrustManager: configured to allow null extended key usages field"); } else { throw new CertificateException("Missing extended key usage: " + keyUsage); } } } @Override public void checkClientTrusted(X509Certificate[] certChain, String authType) throws CertificateException { logger.debug("JSSTrustManager: checkClientTrusted(" + authType + "):"); try { checkCertChain(certChain, CLIENT_AUTH_OID); logger.debug("JSSTrustManager: SSL client certificate is valid"); } catch (CertificateException e) { logger.warn("JSSTrustManager: Invalid SSL client certificate: " + e); throw e; } catch (Exception e) { logger.warn("JSSTrustManager: Unable to validate certificate: " + e); throw new CertificateException(e); } } @Override public void checkServerTrusted(X509Certificate[] certChain, String authType) throws CertificateException { logger.debug("JSSTrustManager: checkServerTrusted(" + certChain.length + ", " + authType + "):"); try { checkCertChain(certChain, SERVER_AUTH_OID); logger.debug("JSSTrustManager: SSL server certificate is valid"); } catch (CertificateException e) { logger.warn("JSSTrustManager: Invalid SSL server certificate: " + e); throw e; } catch (Exception e) { logger.warn("JSSTrustManager: Unable to validate SSL server certificate: " + e); throw new CertificateException(e); } } @Override public X509Certificate[] getAcceptedIssuers() { logger.debug("JSSTrustManager: getAcceptedIssuers():"); Collection caCerts = new ArrayList<>(); try { CryptoManager manager = CryptoManager.getInstance(); for (org.mozilla.jss.crypto.X509Certificate cert : manager.getCACerts()) { logger.debug("JSSTrustManager: - " + cert.getSubjectDN()); try { PK11Cert caCert = (PK11Cert) cert; caCert.checkValidity(); caCerts.add(caCert); } catch (Exception e) { logger.debug("JSSTrustManager: invalid CA certificate: " + e); } } } catch (NotInitializedException e) { logger.error("JSSTrustManager: Unable to get CryptoManager: " + e, e); throw new RuntimeException(e); } return caCerts.toArray(new X509Certificate[caCerts.size()]); } } jss-4.6.3/org/mozilla/jss/provider/javax/crypto/JSSTrustManagerFactory.java000066400000000000000000000010461362106420000270250ustar00rootroot00000000000000package org.mozilla.jss.provider.javax.crypto; import java.security.*; import javax.net.ssl.*; public class JSSTrustManagerFactory extends TrustManagerFactorySpi { protected void engineInit(KeyStore ks) { // There is nothing we can do here. } protected void engineInit(ManagerFactoryParameters spec) { // There is nothing we can do here. } protected TrustManager[] engineGetTrustManagers() { TrustManager[] tms = new TrustManager[1]; tms[0] = new JSSTrustManager(); return tms; } } jss-4.6.3/org/mozilla/jss/ssl/000077500000000000000000000000001362106420000161535ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/ssl/CipherPolicy.java000066400000000000000000000012511362106420000214070ustar00rootroot00000000000000/* 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 class CipherPolicy { public static final CipherPolicy DOMESTIC = new CipherPolicy(SocketBase.SSL_POLICY_DOMESTIC); public static final CipherPolicy EXPORT = new CipherPolicy(SocketBase.SSL_POLICY_EXPORT); public static final CipherPolicy FRANCE = new CipherPolicy(SocketBase.SSL_POLICY_FRANCE); private int _enum; private CipherPolicy(int _enum) { } int getEnum() { return _enum; } } jss-4.6.3/org/mozilla/jss/ssl/PrintOutputStreamWriter.java000066400000000000000000000013221362106420000237020ustar00rootroot00000000000000/* 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/. */ // // // // $Id$ package org.mozilla.jss.ssl; import java.io.*; class PrintOutputStreamWriter extends java.io.OutputStreamWriter { public PrintOutputStreamWriter(OutputStream out) { super(out); } public void print(String x) throws java.io.IOException { write(x, 0, x.length()); } public void println(String x) throws java.io.IOException { // String line = new String(x + "\n"); String line = x + "\n"; write(line, 0, line.length()); flush(); } } jss-4.6.3/org/mozilla/jss/ssl/SSLAlertDescription.java000066400000000000000000000070721362106420000226610ustar00rootroot00000000000000/* 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 javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLProtocolException; public enum SSLAlertDescription { // see lib/ssl/ssl3prot.h in NSS CLOSE_NOTIFY (0), END_OF_EARLY_DATA (1), // TLS 1.3 UNEXPECTED_MESSAGE (10, SSLProtocolException.class), BAD_RECORD_MAC (20, SSLProtocolException.class), DECRYPTION_FAILED (21, SSLProtocolException.class), // RFC 5246 RECORD_OVERFLOW (22, SSLProtocolException.class), // TLS only DECOMPRESSION_FAILURE (30, SSLProtocolException.class), HANDSHAKE_FAILURE (40, SSLHandshakeException.class), NO_CERTIFICATE (41, SSLPeerUnverifiedException.class), // SSL3 only, NOT TLS BAD_CERTIFICATE (42, SSLPeerUnverifiedException.class), UNSUPPORTED_CERTIFICATE (43, SSLPeerUnverifiedException.class), CERTIFICATE_REVOKED (44, SSLPeerUnverifiedException.class), CERTIFICATE_EXPIRED (45, SSLPeerUnverifiedException.class), CERTIFICATE_UNKNOWN (46, SSLPeerUnverifiedException.class), ILLEGAL_PARAMETER (47, SSLProtocolException.class), // All alerts below are TLS only. UNKNOWN_CA (48, SSLPeerUnverifiedException.class), ACCESS_DENIED (49, SSLHandshakeException.class), DECODE_ERROR (50, SSLProtocolException.class), DECRYPT_ERROR (51, SSLProtocolException.class), EXPORT_RESTRICTION (60, SSLHandshakeException.class), PROTOCOL_VERSION (70, SSLHandshakeException.class), INSUFFICIENT_SECURITY (71, SSLHandshakeException.class), INTERNAL_ERROR (80, SSLProtocolException.class), INAPPROPRIATE_FALLBACK (86, SSLProtocolException.class), // could also be sent for SSLv3 USER_CANCELED (90, SSLProtocolException.class), NO_RENEGOTIATION (100, SSLHandshakeException.class), // Alerts for client hello extensions MISSING_EXTENSION (109, SSLHandshakeException.class), UNSUPPORTED_EXTENSION (110, SSLHandshakeException.class), CERTIFICATE_UNOBTAINABLE (111, SSLPeerUnverifiedException.class), UNRECOGNIZED_NAME (112, SSLHandshakeException.class), BAD_CERTIFICATE_STATUS_RESPONSE (113, SSLPeerUnverifiedException.class), BAD_CERTIFICATE_HASH_VALUE (114, SSLPeerUnverifiedException.class), NO_APPLICATION_PROTOCOL (120, SSLHandshakeException.class); private int id; private Class exception; private SSLAlertDescription(int id) { this.id = id; } private SSLAlertDescription(int id, Class exception) { this(id); this.exception = exception; } public int getID() { return id; } public Class getExceptionClass() { return exception; } public static SSLAlertDescription valueOf(int id) { for (SSLAlertDescription description : SSLAlertDescription.class.getEnumConstants()) { if (description.id == id) return description; } return null; } } jss-4.6.3/org/mozilla/jss/ssl/SSLAlertEvent.java000066400000000000000000000066211362106420000214560ustar00rootroot00000000000000/* 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; import javax.net.ssl.SSLException; import org.mozilla.jss.nss.SSLFDProxy; public class SSLAlertEvent extends EventObject { private static final long serialVersionUID = 1L; int level; int description; SSLAlertLevel levelEnum; SSLAlertDescription descriptionEnum; public SSLAlertEvent(SSLSocket socket) { super(socket); } public SSLAlertEvent(SSLSocket socket, int level, int description) { super(socket); setLevel(level); setDescription(description); } public SSLAlertEvent(SSLSocket socket, SSLAlertLevel level, SSLAlertDescription description) { super(socket); setLevel(level); setDescription(description); } public SSLAlertEvent(SSLFDProxy proxy) { super(proxy); } public SSLAlertEvent(SSLFDProxy proxy, int level, int description) { super(proxy); setLevel(level); setDescription(description); } public SSLAlertEvent(SSLFDProxy proxy, SSLAlertLevel level, SSLAlertDescription description) { super(proxy); setLevel(level); setDescription(description); } public SSLSocket getSocket() { return (SSLSocket)getSource(); } public SSLFDProxy getFileDesc() { return (SSLFDProxy)getSource(); } public int getLevel() { return level; } public SSLAlertLevel getLevelEnum() { return levelEnum; } public void setLevel(int level) { this.level = level; this.levelEnum = SSLAlertLevel.valueOf(level); } public void setLevel(SSLAlertLevel level) { this.levelEnum = level; this.level = level.getID(); } public int getDescription() { return description; } public SSLAlertDescription getDescriptionEnum() { return descriptionEnum; } public void setDescription(int description) { this.description = description; this.descriptionEnum = SSLAlertDescription.valueOf(description); } public void setDescription(SSLAlertDescription description) { this.descriptionEnum = description; this.description = description.getID(); } public SSLException toException() { if (levelEnum == SSLAlertLevel.FATAL) { Class exception_class = descriptionEnum.getExceptionClass(); SSLException exception; try { exception = exception_class.getConstructor(String.class).newInstance(this.toString()); } catch (Exception e) { // When we fail to construct an exception of type // exception_class, usually that means that we've gotten // a null exception_class. In which case, because this is // a fatal exception, throw it as a generic SSLException. exception = new SSLException(this.toString()); } return exception; } return null; } public void throwException() throws SSLException { throw this.toException(); } public String toString() { return this.levelEnum + ": " + this.descriptionEnum; } } jss-4.6.3/org/mozilla/jss/ssl/SSLAlertLevel.java000066400000000000000000000012561362106420000214430ustar00rootroot00000000000000/* 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; } } jss-4.6.3/org/mozilla/jss/ssl/SSLCertificateApprovalCallback.java000066400000000000000000000140421362106420000247450ustar00rootroot00000000000000/* 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/. */ /* * SSLSecurityStatus.java * */ package org.mozilla.jss.ssl; import java.util.Enumeration; import java.util.Vector; import org.mozilla.jss.pkcs11.PK11Cert; /** * This interface is what you should implement if you want to * be able to decide whether or not you want to approve the peer's cert, * instead of having NSS do that. */ public interface SSLCertificateApprovalCallback { /** * This method is called when the server sends it's certificate to * the client. * * The 'status' argument passed to this method is constructed by * NSS. It's a list of things 'wrong' with the certificate (which * you can see by calling the status.getReasons() method. So, * if there are problems regarding validity or trust of any of the * certificates in the chain, you can present this info to the user. * * If there are no items in the Enumeration returned by getReasons(), * you can assume that the certificate is trustworthy, and return * true, or you can continue to make further tests of your own * to determine trustworthiness. * * @param cert the peer's server certificate * @param status the ValidityStatus object containing a list * of all the problems with the cert * * @return true allow the connection to continue
* false terminate the connection (Expect an IOException * on the outstanding read()/write() on the socket) */ public boolean approve(org.mozilla.jss.crypto.X509Certificate cert, ValidityStatus status); /** * This class holds details about the errors for each cert in * the chain that the server presented * * To use this class, getReasons(), then iterate over the enumeration */ class ValidityStatus { public static final int EXPIRED_CERTIFICATE = -8192 + 11; public static final int REVOKED_CERTIFICATE = -8192 + 12; public static final int INADEQUATE_KEY_USAGE = -8192 + 90; public static final int INADEQUATE_CERT_TYPE = -8192 + 91; public static final int UNTRUSTED_CERT = -8192 + 21; public static final int CERT_STATUS_SERVER_ERROR = -8192 +115; public static final int UNKNOWN_ISSUER = -8192 + 13; public static final int UNTRUSTED_ISSUER = -8192 + 20; public static final int CERT_NOT_IN_NAME_SPACE = -8192 + 112; public static final int CA_CERT_INVALID = -8192 + 36; public static final int PATH_LEN_CONSTRAINT_INVALID = -8192 + 37; public static final int BAD_KEY = -8192 + 14; public static final int BAD_SIGNATURE = -8192 + 10; public static final int EXPIRED_ISSUER_CERTIFICATE = -8192 +30; public static final int INVALID_TIME = -8192 + 8; public static final int UNKNOWN_SIGNER = -8192 + 116; public static final int SEC_ERROR_CRL_EXPIRED = -8192 + 31; public static final int SEC_ERROR_CRL_BAD_SIGNATURE = -8192 + 32; public static final int SEC_ERROR_CRL_INVALID = -8192 + 33; public static final int CERT_BAD_ACCESS_LOCATION = -8192 + 117; public static final int OCSP_UNKNOWN_RESPONSE_TYPE = -8192 + 118; public static final int OCSP_BAD_HTTP_RESPONSE = -8192 + 119; public static final int OCSP_MALFORMED_REQUEST = -8192 + 120; public static final int OCSP_SERVER_ERROR = -8192 + 121; public static final int OCSP_TRY_SERVER_LATER = -8192 + 122; public static final int OCSP_REQUEST_NEEDS_SIG = -8192 + 123; public static final int OCSP_UNAUTHORIZED_REQUEST = -8192 + 124; public static final int OCSP_UNKNOWN_RESPONSE_STATUS= -8192 + 125; public static final int OCSP_UNKNOWN_CERT = -8192 + 126; public static final int OCSP_NOT_ENABLED = -8192 + 127; public static final int OCSP_NO_DEFAULT_RESPONDER = -8192 + 128; public static final int OCSP_MALFORMED_RESPONSE = -8192 + 129; public static final int OCSP_UNAUTHORIZED_RESPONSE = -8192 + 130; public static final int OCSP_FUTURE_RESPONSE = -8192 + 131; public static final int OCSP_OLD_RESPONSE = -8192 + 132; /** this indicates common-name mismatch */ public static final int BAD_CERT_DOMAIN = -12288 + 12; private Vector reasons = new Vector<>(); /** * add a new failure reason to this enumeration. This is called from the * native code callback when it does a verify on the cert chain * * @param newReason sslerr.h error code - see constants defined above; * @param cert a reference to the cert - so you can see the subject name, etc * @param depth the index of this cert in the chain. 0 is the server cert. */ public void addReason(int newReason, PK11Cert cert, int depth) { ValidityItem status = new ValidityItem(newReason,cert,depth); reasons.addElement(status); } /** * returns an enumeration. The elements in the enumeration are * all of type 'ValidityItem' */ public Enumeration getReasons() { return reasons.elements(); } } class ValidityItem { private int reason; private int depth; private PK11Cert cert; public ValidityItem(int reason, PK11Cert cert, int depth) { this.reason = reason; this.cert = cert; this.depth = depth; } /** * @return the NSS error code which caused the error - see the list of * error codes above for those which could be returned */ public int getReason() { return reason; } /** * @return the index into the cert chain of the certificate which caused * this error. In a chain 5-certs long, 0 is the server-cert. * 1,2,3 would be the intermediates, and 4 would be the root */ public int getDepth() { return depth; } /** * @return the certificate associated with this error. You can use * the X509Certificate functions to get details such as issuer/subject * name, serial number, etc. */ public PK11Cert getCert() { return cert; } } } jss-4.6.3/org/mozilla/jss/ssl/SSLCipher.c000066400000000000000000000114371362106420000201210ustar00rootroot00000000000000#include #include #include #include #include #include "_jni/org_mozilla_jss_ssl_SSLCipher.h" /* Copied from NSS's ssl3con.c. */ static const CK_MECHANISM_TYPE auth_alg_defs[] = { CKM_INVALID_MECHANISM, /* ssl_auth_null */ CKM_RSA_PKCS, /* ssl_auth_rsa_decrypt */ CKM_DSA, /* ? _SHA1 */ /* ssl_auth_dsa */ CKM_INVALID_MECHANISM, /* ssl_auth_kea (unused) */ CKM_ECDSA, /* ssl_auth_ecdsa */ CKM_ECDH1_DERIVE, /* ssl_auth_ecdh_rsa */ CKM_ECDH1_DERIVE, /* ssl_auth_ecdh_ecdsa */ CKM_RSA_PKCS, /* ssl_auth_rsa_sign */ CKM_RSA_PKCS_PSS, /* ssl_auth_rsa_pss */ CKM_NSS_HKDF_SHA256, /* ssl_auth_psk (just check for HKDF) */ CKM_INVALID_MECHANISM /* ssl_auth_tls13_any */ }; PR_STATIC_ASSERT(PR_ARRAY_SIZE(auth_alg_defs) == ssl_auth_size); /* Copied from NSS's ssl3con.c. */ static const CK_MECHANISM_TYPE kea_alg_defs[] = { CKM_INVALID_MECHANISM, /* ssl_kea_null */ CKM_RSA_PKCS, /* ssl_kea_rsa */ CKM_DH_PKCS_DERIVE, /* ssl_kea_dh */ CKM_INVALID_MECHANISM, /* ssl_kea_fortezza (unused) */ CKM_ECDH1_DERIVE, /* ssl_kea_ecdh */ CKM_ECDH1_DERIVE, /* ssl_kea_ecdh_psk */ CKM_DH_PKCS_DERIVE, /* ssl_kea_dh_psk */ CKM_INVALID_MECHANISM, /* ssl_kea_tls13_any */ }; PR_STATIC_ASSERT(PR_ARRAY_SIZE(kea_alg_defs) == ssl_kea_size); #if (NSS_VMAJOR >= 3) && (NSS_VMINOR >= 43) /* Not present in ssl3con.c. */ static const CK_MECHANISM_TYPE hash_alg_defs[] = { CKM_INVALID_MECHANISM, /* ssl_hash_none */ CKM_MD5, /* ssl_hash_md5 */ CKM_SHA_1, /* ssl_hash_sha1 */ CKM_SHA224, /* ssl_hash_sha224 */ CKM_SHA256, /* ssl_hash_sha256 */ CKM_SHA384, /* ssl_hash_sha384 */ CKM_SHA512, /* ssl_hash_sha512 */ }; #endif JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLCipher_checkSupportedStatus(JNIEnv *env, jclass clazz, jint cipher_suite) { PRInt32 allowed; SSLCipherSuiteInfo info = { 0 }; /* Fetch information about whether or not this cipher is allowed by local * policy. */ if (SSL_CipherPolicyGet(cipher_suite, &allowed) != SECSuccess) { /* When the previous call fails, it means that the specified cipher * suite wasn't found; calls to enable it will also fail. Mark it as * unsupported. */ return JNI_FALSE; } if (allowed != SSL_ALLOWED) { /* If the cipher suite isn't allowed by policy, reject it early. */ return JNI_FALSE; } /* Fetch extended information about this particular cipher suite. */ if (SSL_GetCipherSuiteInfo(cipher_suite, &info, sizeof(info)) != SECSuccess) { /* Since we know the cipher suite is good (because the call to * SSL_CipherPolicyGet(...) succeeded), we know that this is because * the size of SSLCipherSuiteInfo in the version of NSS that we * were compiled with exceeds the size of the SSLCipherSuiteInfo * struct available to NSS at runtime. * * This happens *only* when the version of NSS we were compiled with * is *newer* than what is on the system. * * This is a "soft" failure and means that we have to rely only on * cipher policy to tell if this cipher is supported. Since it was * allowed, return JNI_TRUE here. */ return JNI_TRUE; } /* Our NSS DB or application could've configured FIPS mode explicitly, * even though the system might not be in FIPS mode. In that case, * explicitly check that this allowed cipher is available in FIPS mode. */ if (PK11_IsFIPS() && info.isFIPS == 0) { return JNI_FALSE; } /* Our last checks are to make sure that, for all related mechanisms, we * have a token with this function. This is similar to the code in NSS's * ssl3_config_match_init(...). Note that this doesn't finish the work * of that function (by checking that the certificate matches the cipher * suite). */ if (info.authType != ssl_auth_tls13_any && info.authType != ssl_auth_null && !PK11_TokenExists(auth_alg_defs[info.authType])) { return JNI_FALSE; } if (info.keaType != ssl_kea_null && info.keaType != ssl_kea_tls13_any && !PK11_TokenExists(kea_alg_defs[info.keaType])) { return JNI_FALSE; } /* Only check if NSS >= 3.43. Note that when this condition holds at * compile time, and we're executing under an older NSS version, we'd * have exited due to the check in SSL_GetCipherSuiteInfo(...). */ #if (NSS_VMAJOR >= 3) && (NSS_VMINOR >= 43) if (info.kdfHash != ssl_hash_none && !PK11_TokenExists(hash_alg_defs[info.kdfHash])) { return JNI_FALSE; } #endif return JNI_TRUE; } jss-4.6.3/org/mozilla/jss/ssl/SSLCipher.java000066400000000000000000000613531362106420000206220ustar00rootroot00000000000000/* 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, SSLVersion.SSL_2_0), SSL2_RC4_128_EXPORT40_WITH_MD5 (0xFF02, SSLVersion.SSL_2_0), SSL2_RC2_128_CBC_WITH_MD5 (0xFF03, SSLVersion.SSL_2_0), SSL2_RC2_128_CBC_EXPORT40_WITH_MD5 (0xFF04, SSLVersion.SSL_2_0), SSL2_IDEA_128_CBC_WITH_MD5 (0xFF05, SSLVersion.SSL_2_0), SSL2_DES_64_CBC_WITH_MD5 (0xFF06, SSLVersion.SSL_2_0), SSL2_DES_192_EDE3_CBC_WITH_MD5 (0xFF07, SSLVersion.SSL_2_0), TLS_NULL_WITH_NULL_NULL (0x0000, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), /** * @deprecated Replaced with TLS_RSA_WITH_NULL_MD5. */ @Deprecated SSL3_RSA_WITH_NULL_MD5 (0x0001, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_RSA_WITH_NULL_MD5 (0x0001, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), /** * @deprecated Replaced with TLS_RSA_WITH_NULL_SHA. */ @Deprecated SSL3_RSA_WITH_NULL_SHA (0x0002, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_RSA_WITH_NULL_SHA (0x0002, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), SSL3_RSA_EXPORT_WITH_RC4_40_MD5 (0x0003, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_RSA_EXPORT_WITH_RC4_40_MD5 (0x0003, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), /** * @deprecated Replaced with TLS_RSA_WITH_RC4_128_MD5. */ @Deprecated SSL3_RSA_WITH_RC4_128_MD5 (0x0004, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_RSA_WITH_RC4_128_MD5 (0x0004, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), /** * @deprecated Replaced with TLS_RSA_WITH_RC4_128_SHA. */ @Deprecated SSL3_RSA_WITH_RC4_128_SHA (0x0005, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_RSA_WITH_RC4_128_SHA (0x0005, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (0x0006, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (0x0006, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), /** * @deprecated Replaced with TLS_RSA_WITH_IDEA_CBC_SHA. */ @Deprecated SSL3_RSA_WITH_IDEA_CBC_SHA (0x0007, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), TLS_RSA_WITH_IDEA_CBC_SHA (0x0007, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), SSL3_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0008, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0008, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), /** * @deprecated Replaced with TLS_RSA_WITH_DES_CBC_SHA. */ @Deprecated SSL3_RSA_WITH_DES_CBC_SHA (0x0009, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), TLS_RSA_WITH_DES_CBC_SHA (0x0009, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), /** * @deprecated Replaced with TLS_RSA_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_RSA_WITH_3DES_EDE_CBC_SHA (0x000a, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), SSL3_DH_DSS_EXPORT_WITH_DES40_CBC_SHA (0x000b, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA (0x000b, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), /** * @deprecated Replaced with TLS_DH_DSS_WITH_DES_CBC_SHA. */ @Deprecated SSL3_DH_DSS_WITH_DES_CBC_SHA (0x000c, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), TLS_DH_DSS_WITH_DES_CBC_SHA (0x000c, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), /** * @deprecated Replaced with TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_DH_DSS_WITH_3DES_EDE_CBC_SHA (0x000d, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA (0x000d, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), SSL3_DH_RSA_EXPORT_WITH_DES40_CBC_SHA (0x000e, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA (0x000e, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), /** * @deprecated Replaced with TLS_DH_RSA_WITH_DES_CBC_SHA. */ @Deprecated SSL3_DH_RSA_WITH_DES_CBC_SHA (0x000f, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), TLS_DH_RSA_WITH_DES_CBC_SHA (0x000f, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), /** * @deprecated Replaced with TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_DH_RSA_WITH_3DES_EDE_CBC_SHA (0x0010, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA (0x0010, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), SSL3_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA (0x0011, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA (0x0011, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), /** * @deprecated Replaced with TLS_DHE_DSS_WITH_DES_CBC_SHA. */ @Deprecated SSL3_DHE_DSS_WITH_DES_CBC_SHA (0x0012, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), TLS_DHE_DSS_WITH_DES_CBC_SHA (0x0012, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), /** * @deprecated Replaced with TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), SSL3_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0014, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0014, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), /** * @deprecated Replaced with TLS_DHE_RSA_WITH_DES_CBC_SHA. */ @Deprecated SSL3_DHE_RSA_WITH_DES_CBC_SHA (0x0015, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), TLS_DHE_RSA_WITH_DES_CBC_SHA (0x0015, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), /** * @deprecated Replaced with TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA (0x0016, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (0x0016, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), SSL3_DH_ANON_EXPORT_WITH_RC4_40_MD5 (0x0017, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 (0x0017, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), /** * @deprecated Replaced with TLS_DH_anon_WITH_RC4_128_MD5. */ @Deprecated SSL3_DH_ANON_WITH_RC4_128_MD5 (0x0018, SSLVersion.SSL_3_0), TLS_DH_anon_WITH_RC4_128_MD5 (0x0018, SSLVersion.SSL_3_0), SSL3_DH_ANON_EXPORT_WITH_DES40_CBC_SHA (0x0019, SSLVersion.SSL_3_0), TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA (0x0019, SSLVersion.SSL_3_0), /** * @deprecated Replaced with TLS_DH_anon_WITH_DES_CBC_SHA. */ @Deprecated SSL3_DH_ANON_WITH_DES_CBC_SHA (0x001a, SSLVersion.SSL_3_0), TLS_DH_anon_WITH_DES_CBC_SHA (0x001a, SSLVersion.SSL_3_0), /** * @deprecated Replaced with TLS_DH_anon_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_DH_ANON_WITH_3DES_EDE_CBC_SHA (0x001b, SSLVersion.SSL_3_0), TLS_DH_anon_WITH_3DES_EDE_CBC_SHA (0x001b, SSLVersion.SSL_3_0), /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. */ @Deprecated SSL3_FORTEZZA_DMS_WITH_NULL_SHA (0x001c, SSLVersion.SSL_3_0), /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. */ @Deprecated SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA (0x001d, SSLVersion.SSL_3_0), /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. */ @Deprecated SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA (0x001e, SSLVersion.SSL_3_0), SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA (0xfeff, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), SSL_RSA_FIPS_WITH_DES_CBC_SHA (0xfefe, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA (0x0062, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_RSA_EXPORT1024_WITH_RC4_56_SHA (0x0064, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA (0x0063, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA (0x0065, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_DHE_DSS_WITH_RC4_128_SHA (0x0066, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067, new SSLVersion[] { SSLVersion.TLS_1_2 }), TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 (0x006A, new SSLVersion[] { SSLVersion.TLS_1_2 }), TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x006B, new SSLVersion[] { SSLVersion.TLS_1_2 }), // New TLS cipher suites in NSS 3.4 TLS_RSA_WITH_AES_128_CBC_SHA (0x002F, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_DSS_WITH_AES_128_CBC_SHA (0x0030, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_RSA_WITH_AES_128_CBC_SHA (0x0031, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), /** * @deprecated Replaced with TLS_DH_anon_WITH_AES_128_CBC_SHA. */ @Deprecated TLS_DH_ANON_WITH_AES_128_CBC_SHA (0x0034, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), TLS_DH_anon_WITH_AES_128_CBC_SHA (0x0034, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), TLS_RSA_WITH_AES_256_CBC_SHA (0x0035, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_DSS_WITH_AES_256_CBC_SHA (0x0036, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_RSA_WITH_AES_256_CBC_SHA (0x0037, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), /** * @deprecated Replaced with TLS_DH_anon_WITH_AES_256_CBC_SHA. */ @Deprecated TLS_DH_ANON_WITH_AES_256_CBC_SHA (0x003A, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_anon_WITH_AES_256_CBC_SHA (0x003A, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_RSA_WITH_NULL_SHA256 (0x003B, new SSLVersion[] { SSLVersion.TLS_1_2 }), TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003C, new SSLVersion[] { SSLVersion.TLS_1_2 }), TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003D, new SSLVersion[] { SSLVersion.TLS_1_2 }), TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 (0x0041, new SSLVersion[] { SSLVersion.TLS_1_2 }), TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0041, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA (0x0042, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0043, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA (0x0044, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0045, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), /** * @deprecated Replaced with TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA. */ @Deprecated TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA (0x0046, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA (0x0046, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0084, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA (0x0085, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0086, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA (0x0087, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0088, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), /** * @deprecated Replaced with TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA. */ @Deprecated TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA (0x0089, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA (0x0089, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_RSA_WITH_SEED_CBC_SHA (0x0096, new SSLVersion[] { SSLVersion.SSL_3_0, SSLVersion.TLS_1_0 }), TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009C, SSLVersion.TLS_1_2), TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009D, SSLVersion.TLS_1_2), TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009E, SSLVersion.TLS_1_2), TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009F, SSLVersion.TLS_1_2), TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 (0x00A2, SSLVersion.TLS_1_2), TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 (0x00A3, SSLVersion.TLS_1_2), TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 (0x00AA, SSLVersion.TLS_1_2), TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 (0x00AB, SSLVersion.TLS_1_2), TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00FF), TLS_FALLBACK_SCSV (0x5600), TLS_ECDH_ECDSA_WITH_NULL_SHA (0xc001, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_ECDSA_WITH_RC4_128_SHA (0xc002, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc003, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA (0xc004, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA (0xc005, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDHE_ECDSA_WITH_NULL_SHA (0xc006, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (0xc007, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc008, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1 }), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_RSA_WITH_NULL_SHA (0xc00b, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_RSA_WITH_RC4_128_SHA (0xc00c, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA (0xc00d, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_RSA_WITH_AES_128_CBC_SHA (0xc00e, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_RSA_WITH_AES_256_CBC_SHA (0xc00f, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDHE_RSA_WITH_NULL_SHA (0xc010, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_anon_WITH_NULL_SHA (0xc015, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_anon_WITH_RC4_128_SHA (0xc016, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA (0xc017, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_anon_WITH_AES_128_CBC_SHA (0xc018, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDH_anon_WITH_AES_256_CBC_SHA (0xc019, true, new SSLVersion[] { SSLVersion.TLS_1_0, SSLVersion.TLS_1_1, SSLVersion.TLS_1_2 }), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023, true, SSLVersion.TLS_1_2), TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024, true, SSLVersion.TLS_1_2), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027, true, SSLVersion.TLS_1_2), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028, true, SSLVersion.TLS_1_2), TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02B, true, SSLVersion.TLS_1_2), TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02C, true, SSLVersion.TLS_1_2), TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02D, true, SSLVersion.TLS_1_2), TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02F, true, SSLVersion.TLS_1_2), TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030, true, SSLVersion.TLS_1_2), TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 (0xc031, true, SSLVersion.TLS_1_2), /* * TLS 1.3 */ /* draft-ietf-tls-chacha20-poly1305-04 */ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xCCA8, true, SSLVersion.TLS_1_2), TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xCCA9, true, SSLVersion.TLS_1_2), TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xCCAA, SSLVersion.TLS_1_2), TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xCCAC, true, SSLVersion.TLS_1_2), TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xCCAD, SSLVersion.TLS_1_2), TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 (0xD001, true, SSLVersion.TLS_1_2), TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 (0xD002, true, SSLVersion.TLS_1_2), /* Special TLS 1.3 cipher suites that really just specify AEAD */ TLS_AES_128_GCM_SHA256 (0x1301, false, SSLVersion.TLS_1_3), TLS_AES_256_GCM_SHA384 (0x1302, false, SSLVersion.TLS_1_3), TLS_CHACHA20_POLY1305_SHA256 (0x1303, false, SSLVersion.TLS_1_3); private int id; private boolean ecc; private SSLVersion[] versions; private boolean supported; private SSLCipher(int id) { /* Should only be used with TLS_EMPTY_RENEGOTIATION_INFO_SCSV and * TLS_FALLBACK_SCSV. */ this(id, false, null, true); } private SSLCipher(int id, SSLVersion version) { this(id, false, new SSLVersion[] { version }); } private SSLCipher(int id, SSLVersion[] versions) { this(id, false, versions); } private SSLCipher(int id, boolean ecc, SSLVersion version) { this(id, ecc, new SSLVersion[] { version }); } private SSLCipher(int id, boolean ecc, SSLVersion[] versions) { this(id, ecc, versions, checkSupportedStatus(id)); } private SSLCipher(int id, boolean ecc, SSLVersion[] versions, boolean supported) { this.id = id; this.ecc = ecc; this.versions = versions; this.supported = supported; } private static native boolean checkSupportedStatus(int id); public int getID() { return id; } public boolean isECC() { return ecc; } public boolean supportsTLSVersion(SSLVersion v) { if (versions == null) { return false; } for (SSLVersion version : versions) { if (version == v) { return true; } } return false; } public boolean isTLSv12() { return supportsTLSVersion(SSLVersion.TLS_1_2); } public boolean isTLSv13() { return supportsTLSVersion(SSLVersion.TLS_1_3); } public boolean isSupported() { return supported; } public boolean requiresRSACert() { return this.name().contains("_RSA_") && !this.name().contains("ECDH_RSA"); } public boolean requiresECDSACert() { return this.name().contains("_ECDSA_") || this.name().contains("ECDH_RSA"); } public static SSLCipher valueOf(int id) { for (SSLCipher cipher : SSLCipher.class.getEnumConstants()) { if (cipher.id == id) return cipher; } return null; } } jss-4.6.3/org/mozilla/jss/ssl/SSLClient.java000066400000000000000000000277151362106420000206320ustar00rootroot00000000000000/* 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/. */ // This demonstrates the SSL client-side support // package org.mozilla.jss.ssl; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.net.InetAddress; import java.net.Socket; import java.util.Hashtable; import org.mozilla.jss.CertDatabaseException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.InitializationValues; import org.mozilla.jss.KeyDatabaseException; import org.mozilla.jss.crypto.AlreadyInitializedException; /** * Parameters supported by this socket test: * * filename file to be read from https server (default: /index.html) * port port to connect to (default: 443) * ipaddr address to connect to (overrides hostname, no default) * hostname host to connect to (no default) * clientauth do client-auth or not (default: no client-auth) * * The following parameters are used for regression testing, so * we can print success or failure of the test. * * filesize size of file to be read * status security status of connection - this has to be an integer * cipher * sessionKeySize * sessionSecretSize * issuer * subject * certSerialNum * */ public class SSLClient { boolean handshakeEventHappened = false; boolean doClientAuth = false; Hashtable args; PrintStream results; String versionStr; String argNames[] = { "filename", "port", "ipaddr", "hostname", "filesize", "status", "sessionKeySize", "sessionSecretSize", "cipher", "issuer", "subject", "certSerialNum", }; String values[] = { "/index", // filename "443", // port to connect to "", // ipaddr (use hostname instead) "trading.etrade.com", // hostname to connect to "1024", // filesize "2", // status, 2 means ??? "128", // expected session key size "128", // expected session key secret bits "RC48", // expected cipher "CN=Hardcore Certificate Server II, OU=Hardcore, O=Netscape Communications Corporation, C=US", // expected issuer DN of server "CN=hbombsgi.mcom.com, OU=Hardcore, C=US", // expected subject DN of server "00C3", // serial number }; String okay = "okay"; String failed = "FAILED"; private static String htmlHeader = "SSL Client Tester"; private static String htmlTail = "\n"; /* simple helper functions */ private boolean isInvalid(String s) { return (s == null) || s.equals(""); } private String getArgument(String key) { return args.get(key); } /* * return "okay" or "FAILED" based on equality of * the argument strings */ private String cmp(String s1, String s2) { if(s1 == s2) return okay; if(s1 == null) return failed; if(s1.equals(s2)) return okay; return failed; } private String cmp(String s1, int s2) { return cmp(s1, Integer.valueOf(s2).toString()); } public void run(boolean printHeader, boolean testRegression) { try { SSLHandshakeCompletedListener listener = null; if(printHeader) results.println(htmlHeader); results.println("SSL Client Tester"); results.println( "$Id$ " + versionStr ); SSLSocket s; String hostname; int port; String filename = getArgument("filename"); if(isInvalid(filename)) { filename = "/index.html"; } String msg = "GET " + filename; String portstr = getArgument("port"); if(isInvalid(portstr)) { port = 443; } else { port = Integer.valueOf(portstr).intValue(); } String addrstr = getArgument("ipaddr"); hostname = addrstr; // unless it gets changed String tmpStr = getArgument("clientauth"); if(isInvalid(tmpStr)) doClientAuth = false; else { tmpStr = tmpStr.toLowerCase(); doClientAuth = !(tmpStr.equals("off") || tmpStr.equals("false") || tmpStr.equals("0")); } if(isInvalid(addrstr)) { // check for a host name hostname = getArgument("hostname"); if(isInvalid(hostname)) { throw new Exception("hostname not specified"); } } results.println("Connecting to " + hostname + " on port " + port ); SSLCertificateApprovalCallback approvalCallback = new TestCertApprovalCallback(); SSLClientCertificateSelectionCallback certSelectionCallback = new TestClientCertificateSelectionCallback(); Socket js = new Socket(InetAddress.getByName(hostname), port); //s = new SSLSocket(hostname, port, null, 0, s = new SSLSocket(js, hostname, approvalCallback, certSelectionCallback ); s.forceHandshake(); results.println("Connected."); // select the cert for client auth // You will have to provide a certificate with this // name if you expect client auth to work. //s.setClientCertNickname("JavaSSLTestClientCert"); // Setup a handshake callback. This listener will get invoked // When the SSL handshake is completed on this socket. listener = new ClientHandshakeCB(this); s.addHandshakeCompletedListener(listener); //s.forceHandshake(); OutputStream o = s.getOutputStream(); PrintOutputStreamWriter out = new PrintOutputStreamWriter(o); results.println("Sending: " + msg + " to " + hostname + ", " + port ); // send HTTP GET message across SSL connection out.println(msg + "\r"); InputStream in = s.getInputStream(); byte[] bytes = new byte[4096]; int totalBytes = 0; int numReads = 0; String lastBytes = null; // now try to read data back from the SSL connection try { for(;;) { results.println("Calling Read."); int n = in.read(bytes, 0, bytes.length); if(n == -1) { results.println("EOF found."); break; } if(n == 0) { results.println("Zero bytes read?"); break; } numReads++; if(totalBytes == 0) { // don't print forever... String data = new String(bytes, 0, 30, "8859_1"); results.println("Read " + n + " bytes of data"); results.println("First 30 bytes: " + escapeHTML(data)); } totalBytes += n; lastBytes = new String(bytes, n-31, 30, "8859_1"); } } catch (IOException e) { results.println( "IOException while reading from pipe? Actually got " + totalBytes + " bytes total"); e.printStackTrace(results); results.println(""); throw e; } finally { results.println("Last 30 bytes: " + lastBytes); results.println("Number of read() calls: " + numReads ); /* * if you want to test sslimpl.c's nsn_ThrowError(), try * uncommenting the following line. This will cause the * getStatus() call to fail. */ // in.close(); results.println("Diagnostics"); String tmp; SSLSecurityStatus status = s.getStatus(); results.println("Total bytes read: " + totalBytes ); results.println("Security status of session:"); results.println(status.toString()); // now, for the regression testing stuff if (testRegression) { results.println("Regression Tests"); results.println("Handshake callback event happened: " + ((handshakeEventHappened) ? okay : failed)); if(!isInvalid(tmp = getArgument("filesize"))) { results.println("filesize: " + cmp(tmp, totalBytes)); } if(!isInvalid(tmp = getArgument("status"))) { results.println("status: " + cmp(tmp, status.getSecurityStatus())); } if(!isInvalid(tmp = getArgument("sessionKeySize"))) { results.println("sessionKeySize: " + cmp(tmp, status.getSessionKeySize())); } if(!isInvalid(tmp = getArgument("sessionSecretSize"))) { results.println("sessionSecretSize: " + cmp(tmp, status.getSessionSecretSize())); } if(!isInvalid(tmp = getArgument("cipher"))) { results.println("cipher: " + cmp(tmp, status.getCipher())); } if(!isInvalid(tmp = getArgument("issuer"))) { results.println("issuer: " + cmp(tmp, status.getRemoteIssuer())); } if(!isInvalid(tmp = getArgument("subject"))) { results.println("subject: " + cmp(tmp, status.getRemoteSubject())); } if(!isInvalid(tmp = getArgument("certSerialNum"))) { String serialNum = status.getSerialNumber(); results.println("certSerialNum: " + cmp(tmp, serialNum)); } } // if false } // Got here, so no exception thrown above. // Try to clean up. o.close(); o = null; in.close(); in = null; if (listener != null) { s.removeHandshakeCompletedListener(listener); listener = null; } s.close(); s = null; } catch(Exception e) { results.println("***** TEST FAILED *****"); e.printStackTrace(results); results.println("If there is no stack trace, try disabling the JIT and trying again."); } results.println("END OF TEST"); } /** * given an input string, convert less-than, greater-than, and ampersand * from raw characters to escaped characters * (< becomes `&lt;', etc.) */ private String escapeHTML(String s) { StringBuffer result = new StringBuffer(); // this is inefficient, but I don't care for(int i=0; i': result.append(">"); break; case '&': result.append("&"); break; default: result.append(c); break; } } return result.toString(); } public SSLClient( PrintStream ps, String verStr, String[] argv) { this.args = new Hashtable<>(); this.results = ps; this.versionStr = verStr; for(int i=0; i nicknames); } jss-4.6.3/org/mozilla/jss/ssl/SSLHandshakeCompletedEvent.java000066400000000000000000000020741362106420000241300ustar00rootroot00000000000000/* 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/. */ /* * SSLHandshakeCompletedEvent.java * * */ package org.mozilla.jss.ssl; import java.net.*; import java.util.*; /* * right now, this only extends EventObject, but it will eventually * extend javax.net.ssl.HandshakeCompletedEvent */ /** * This class represents the event telling you a handshake * operation is complete. */ public class SSLHandshakeCompletedEvent extends EventObject { private static final long serialVersionUID = 1L; public SSLHandshakeCompletedEvent(SSLSocket socket) { super(socket); } /** * get security information about this socket, including * cert data */ public SSLSecurityStatus getStatus() throws SocketException { return getSocket().getStatus(); } /** * get socket on which the event occured */ public SSLSocket getSocket() { return (SSLSocket)getSource(); } } jss-4.6.3/org/mozilla/jss/ssl/SSLHandshakeCompletedListener.java000066400000000000000000000010471362106420000246330ustar00rootroot00000000000000/* 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/. */ /* * SSLHandshakeCompletedListener.java * * */ package org.mozilla.jss.ssl; import java.util.*; /** * This interface is used when you want to know that a security * handshake is complete. */ public interface SSLHandshakeCompletedListener extends EventListener { public void handshakeCompleted(SSLHandshakeCompletedEvent event); } jss-4.6.3/org/mozilla/jss/ssl/SSLInputStream.java000066400000000000000000000027211362106420000216550ustar00rootroot00000000000000/* 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.io.IOException; class SSLInputStream extends java.io.InputStream { SSLInputStream(SSLSocket sock) { this.sock = sock; } public int available() throws IOException { return sock.socketAvailable(); } public void close() throws IOException { sock.close(); } public int read() throws IOException { byte[] b = new byte[1]; int nread = read(b, 0, 1); if( nread == -1 ) { return nread; } else { return ((int) b[0]) & (0xff); } } public int read(byte[] b) throws IOException { return read(b, 0, b.length); } public int read(byte[] b, int off, int len) throws IOException { return sock.read(b, off, len); } public long skip(long n) throws IOException { long numSkipped = 0; int size = (int) (n < 2048 ? n : 2048); byte[] trash = new byte[size]; while( n > 0) { size = (int) (n < 2048 ? n : 2048); int nread = read(trash, 0, size); if( nread <= 0 ) { break; } numSkipped += nread; n -= nread; } return numSkipped; } private SSLSocket sock; } jss-4.6.3/org/mozilla/jss/ssl/SSLOutputStream.java000066400000000000000000000014461362106420000220610ustar00rootroot00000000000000/* 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.io.IOException; class SSLOutputStream extends java.io.OutputStream { SSLOutputStream(SSLSocket sock) { this.sock = sock; } public void write(int b) throws IOException { write( new byte[] {(byte)b}, 0, 1 ); } public void write(byte[] b) throws IOException { write( b, 0, b.length); } public void write(byte[] b, int off, int len) throws IOException { sock.write(b, off, len); } public void close() throws IOException { sock.close(); } private SSLSocket sock; } jss-4.6.3/org/mozilla/jss/ssl/SSLProtocolVariant.java000066400000000000000000000011641362106420000225300ustar00rootroot00000000000000/* 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 class SSLProtocolVariant { public static final SSLProtocolVariant STREAM = new SSLProtocolVariant(SocketBase.SSL_Variant_Stream); public static final SSLProtocolVariant DATA_GRAM = new SSLProtocolVariant(SocketBase.SSL_Variant_Datagram); private int _enum; private SSLProtocolVariant(int val) { _enum = val; } int getEnum() { return _enum; } } jss-4.6.3/org/mozilla/jss/ssl/SSLSecurityStatus.java000066400000000000000000000101701362106420000224120ustar00rootroot00000000000000/* 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 org.mozilla.jss.crypto.X509Certificate; /** * This class represents the known state of an SSL connection: what cipher * is being used, how secure it is, and who's on the other end. */ public class SSLSecurityStatus { int status; String cipher; int sessionKeySize; int sessionSecretSize; String issuer; String subject; String serialNumber; X509Certificate certificate; // Certificate may be null if client does not present certificate final public int STATUS_NOOPT = -1; final public int STATUS_OFF = 0; final public int STATUS_ON_HIGH = 1; final public int STATUS_ON_LOW = 2; /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. * STATUS_FORTEZZA is a placeholder for backward compatibility. */ @Deprecated final public int STATUS_FORTEZZA = 3; /** * This constructor is called from the native SSL code * It's not necessary for you to call this. */ public SSLSecurityStatus(int status, String cipher, int sessionKeySize, int sessionSecretSize, String issuer, String subject, String serialNumber, X509Certificate certificate) { String noCert = "no certificate"; this.status = status; this.cipher = cipher; this.sessionKeySize = sessionKeySize; this.sessionSecretSize = sessionSecretSize; this.certificate = certificate; if(noCert.equals(issuer)) this.issuer = null; else this.issuer = issuer; if(noCert.equals(subject)) this.subject = null; else this.subject = subject; this.serialNumber = serialNumber; } /** * Query if security is enabled on this socket. */ public boolean isSecurityOn() { return status > 0; } /** * Get exact security status of socket. */ public int getSecurityStatus() { return status; } /** * Query which cipher is being used in this session. */ public String getCipher() { return cipher; } /** * Query how many bits long the session key is. More bits are better. */ public int getSessionKeySize() { return sessionKeySize; } /** * To satisfy export restrictions, some of the session key may * be revealed. This function tells you how many bits are * actually secret. */ public int getSessionSecretSize() { return sessionSecretSize; } /** * Get the distinguished name of the remote certificate's issuer */ public String getRemoteIssuer() { return issuer; } /** * Get the distinguished name of the subject of the remote certificate */ public String getRemoteSubject() { return subject; } /** * Get the serial number of the remote certificate */ public String getSerialNumber() { return serialNumber; } /** * Retrieve certificate presented by the other other end * of the socket

Not Supported in NSS 2.0 Beta release. *

Can be null if peer did not present a certificate. */ public X509Certificate getPeerCertificate() { return certificate; } /** * Get a pretty string to show to a user, summarizing the contents * of this object */ public String toString() { String statusString; switch(status) { case STATUS_NOOPT: statusString = "NOOPT"; break; case STATUS_OFF: statusString = "OFF"; break; case STATUS_ON_HIGH: statusString = "ON HIGH"; break; case STATUS_ON_LOW: statusString = "ON LOW"; break; case STATUS_FORTEZZA: statusString = "FORTEZZA"; break; default: statusString = "unknown"; break; } return "Status: " + statusString + "\n" + "Cipher: " + cipher + "\n" + "Session key size: " + sessionKeySize + "\n" + "Session secret size: " + sessionSecretSize + "\n" + "Issuer: " + issuer + "\n" + "Subject: " + subject + "\n" + "Serial number: " + serialNumber + "\n"; } } jss-4.6.3/org/mozilla/jss/ssl/SSLServer.java000066400000000000000000000200671362106420000206530ustar00rootroot00000000000000/* 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/. */ // This program demonstrates SSL server-side support. It expects // (HTTP) clients to connect to it, and will respond to HTTP // GET requests // // tabstops: 4 package org.mozilla.jss.ssl; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.util.Hashtable; import org.mozilla.jss.CertDatabaseException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.KeyDatabaseException; /** * Parameters supported by this socket test: * * filename file to be read from https server (default: /index.html) * port port to connect to (default: 443) * clientauth do client-auth or not (default: no client-auth) * * The following parameters are used for regression testing, so * we can print success or failure of the test. * * filesize size of file to be read * status security status of connection - this has to be an integer * */ public class SSLServer { boolean handshakeEventHappened = false; boolean doClientAuth = false; Hashtable args; PrintStream results; String versionStr; String argNames[] = { "filename", "port", "filesize", "clientauth", "nickname" }; String values[] = { "data1k.txt", // filename "2000", // port "1024", // filesize "false", // request client auth "SSLServer" // nickname of cert to use }; private static String htmlHeader = "SSL Server Tester"; private static String htmlTail = "\n"; /* simple helper functions */ private boolean isInvalid(String s) { return (s == null) || s.equals(""); } private String getArgument(String key) { return args.get(key); } String okay = "okay"; String failed = "FAILED"; public void run() { try { SSLServerSocket l; SSLSocket s; int port; String tmpStr; String portStr; String nickname; results.println(htmlHeader); portStr = getArgument("port"); if(isInvalid(portStr)) { port = 443; } else { port = Integer.valueOf(portStr).intValue(); } results.println("here"); tmpStr = getArgument("clientauth"); if(!isInvalid(tmpStr)) { tmpStr = tmpStr.toLowerCase(); doClientAuth = !(tmpStr.equals("off") || tmpStr.equals("false") || tmpStr.equals("0")); } l = new SSLServerSocket(port); results.println("Listening " + l.toString()); // select the server's cert/key nickname = getArgument("nickname"); results.println("Getting Cert:"+nickname+""); l.setServerCertNickname(nickname); if (doClientAuth) { l.requestClientAuth(true); } // wait for and accept a connection. s = (SSLSocket)l.accept(); results.println("Accepted."); handleConnection(s); // handleConnection will close s, as appropriate. s = null; l.close(); l = null; } catch(Exception e) { results.println("***** TEST FAILED *****"); e.printStackTrace(results); results.println( "If there is no stack trace, try disabling the JIT and trying again."); } results.println("END OF TEST"); } public void handleConnection(SSLSocket s) throws Exception { SSLHandshakeCompletedListener listener = null; listener = new ServerHandshakeCB(this); s.addHandshakeCompletedListener(listener); results.println("Connected to " + s.toString()); InputStream in = s.getInputStream(); byte[] bytes = new byte[4096]; int totalBytes = 0; int numReads = 0; // now try to read data from the SSL connection try { boolean endFound = false; while(! endFound && totalBytes < bytes.length) { results.println("Calling Read."); int n = in.read(bytes, totalBytes, bytes.length - totalBytes); if(n == -1) { results.println("EOF found."); break; } if(n == 0) { results.println("Zero bytes read?"); break; } numReads++; results.println("Read " + n + " bytes of data"); totalBytes += n; for (int i = 0; i + 3 < bytes.length; ++i) { if (bytes[i] == 0x0D && bytes[i+1] == 0x0A && bytes[i+2] == 0x0D && bytes[i+3] == 0x0A ) { results.println("Empty line found."); endFound = true; break; } } } } catch (IOException e) { results.println( "IOException while reading from pipe? Actually got " + totalBytes + " bytes total"); e.printStackTrace(results); results.println(""); throw e; } results.println("Number of read() calls: " + numReads ); results.println("Total bytes read: " + totalBytes ); String msg = null; if (totalBytes > 0) { msg = new String(bytes, 0, totalBytes, "8859_1"); results.println("Request received:"); results.println(msg); results.println(""); } SSLSecurityStatus status = s.getStatus(); results.println("Security status of session:"); results.println(status.toString()); results.println("Handshake callback event happened: " + ((handshakeEventHappened) ? okay : failed)); OutputStream os = s.getOutputStream(); PrintOutputStreamWriter out = new PrintOutputStreamWriter(os); os = null; // don't keep this reference lying around String reply = "HTTP/1.0 200 OK\r\n" + "Server: Netscape-Enterprise/2.0a\r\n" + "Date: Tue, 01 Apr 1998 22:10:05 GMT\r\n" + "Content-type: text/plain\r\n" + "\r\n" + msg; out.println(reply); // Got here, so no exception thrown above. // Try to clean up. in.close(); in = null; if (listener != null) { s.removeHandshakeCompletedListener(listener); listener = null; } out.close(); out = null; s.close(); s = null; } public SSLServer( PrintStream ps, String verStr) { this.args = new Hashtable<>(); this.results = ps; this.versionStr = verStr; for(int i=0; i #include #include #include #include #include #include #include #include #include #include "jssl.h" #ifdef WINNT #include #endif JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_socketListen (JNIEnv *env, jobject self, jint backlog) { JSSL_SocketData *sock; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; if( PR_Listen(sock->fd, backlog) != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "Failed to set listen backlog on socket"); goto finish; } finish: return; } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_socketAccept (JNIEnv *env, jobject self, jobject newSock, jint timeout, jboolean handshakeAsClient) { JSSL_SocketData *sock; PRNetAddr addr; PRFileDesc *newFD=NULL; PRIntervalTime ivtimeout; JSSL_SocketData *newSD=NULL; jbyteArray sdArray = NULL; SECStatus status; PRThread *me; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; ivtimeout = (timeout > 0) ? PR_MillisecondsToInterval(timeout) : PR_INTERVAL_NO_TIMEOUT; if( handshakeAsClient ) { status = SSL_OptionSet(sock->fd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Failed to set option to handshake as client"); goto finish; } } /* Set the current thread doing the accept. */ me = PR_GetCurrentThread(); PR_Lock(sock->lock); if ( sock->closePending ) { PR_Unlock(sock->lock); JSSL_throwSSLSocketException(env, "Accept operation failed: socket is closing"); goto finish; } PR_ASSERT(sock->accepter == NULL); sock->accepter = me; PR_Unlock(sock->lock); newFD = PR_Accept(sock->fd, &addr, ivtimeout); PR_Lock(sock->lock); PR_ASSERT(sock->accepter == me); sock->accepter = NULL; PR_Unlock(sock->lock); if( newFD == NULL ) { PRErrorCode err = PR_GetError(); if( err == PR_PENDING_INTERRUPT_ERROR ) { #ifdef WINNT /* Clean up after PR_interrupt. */ PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Accept operation interrupted"); } else if( err == PR_IO_TIMEOUT_ERROR ) { #ifdef WINNT PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Accept operation timed out"); } else if( err == PR_IO_ERROR ) { JSSL_throwSSLSocketException(env, "Accept operation received IO error"); } else { JSSL_throwSSLSocketException(env, "Accept operation failed"); } goto finish; } newSD = JSSL_CreateSocketData(env, newSock, newFD, NULL /* priv */); if( newSD == NULL ) { goto finish; } newFD = NULL; /* setup the handshake callback */ status = SSL_HandshakeCallback(newSD->fd, JSSL_HandshakeCallback, newSD); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Unable to install handshake callback"); goto finish; } /* pass the pointer back to Java */ sdArray = JSS_ptrToByteArray(env, (void*) newSD); if( sdArray == NULL ) { /* exception was thrown */ goto finish; } finish: if( (*env)->ExceptionOccurred(env) != NULL ) { if( newSD != NULL ) { JSSL_DestroySocketData(env, newSD); } if( newFD != NULL ) { PR_Close(newFD); } } return sdArray; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_abortAccept( JNIEnv *env, jobject self) { JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; /* * The java layer prevents I/O once close has been * called but if an accept is in progress then abort it. * For WINNT the accept method must check for * PR_PENDING_INTERRUPT_ERROR and call PR_NT_CancelIo. */ PR_Lock(sock->lock); if ( sock->accepter ) { PR_Interrupt(sock->accepter); } sock->closePending = PR_TRUE; /* socket is to be closed */ PR_Unlock(sock->lock); finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_clearSessionCache( JNIEnv *env, jclass clazz) { SSL_ClearSessionCache(); } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_configServerSessionIDCache( JNIEnv *env, jclass myClass, jint maxEntries, jint ssl2Timeout, jint ssl3Timeout, jstring nameString) { const char* dirName = NULL; SECStatus status; dirName = JSS_RefJString(env, nameString); status = SSL_ConfigServerSessionIDCache( maxEntries, ssl2Timeout, ssl3Timeout, dirName); if (status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to configure server session ID cache"); goto finish; } finish: JSS_DerefJString(env, nameString, dirName); } /* * This is here for backwards binary compatibility: I didn't want to remove * the symbol from the DLL. This would only get called if someone were using * a pre-3.2 version of the JSS classes with this post-3.2 library. Using * different versions of the classes and the C code is not supported. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_setServerCertNickname( JNIEnv *env, jobject self, jstring nick) { PR_ASSERT(0); JSS_throwMsg(env, SOCKET_EXCEPTION, "JSS JAR/DLL version mismatch"); } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_setServerCert( JNIEnv *env, jobject self, jobject certObj) { JSSL_SocketData *sock; CERTCertificate* cert=NULL; PK11SlotInfo* slot=NULL; SECKEYPrivateKey* privKey=NULL; SECStatus status; if( certObj == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; if( JSS_PK11_getCertPtr(env, certObj, &cert) != PR_SUCCESS ) { goto finish; } PR_ASSERT(cert!=NULL); /* shouldn't happen */ if( JSS_PK11_getCertSlotPtr(env, certObj, &slot) != PR_SUCCESS ) { goto finish; } PR_ASSERT(slot!=NULL); /* shouldn't happen */ privKey = PK11_FindPrivateKeyFromCert(slot, cert, NULL); if (privKey != NULL) { status = SSL_ConfigServerCert(sock->fd, cert, privKey, NULL, 0); if( status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to configure secure server certificate and key"); goto finish; } } else { JSSL_throwSSLSocketException(env, "Failed to locate private key"); goto finish; } finish: if(privKey!=NULL) { SECKEY_DestroyPrivateKey(privKey); } } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_setReuseAddress( JNIEnv *env, jobject self, jboolean reuse) { JSSL_SocketData *sock; PRStatus status; PRSocketOptionData sockOptData; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; sockOptData.option = PR_SockOpt_Reuseaddr; sockOptData.value.reuse_addr = ((reuse == JNI_TRUE) ? PR_TRUE : PR_FALSE ); status = PR_SetSocketOption(sock->fd, &sockOptData); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: return; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_getReuseAddress( JNIEnv *env, jobject self) { JSSL_SocketData *sock; PRStatus status; PRSocketOptionData sockOptData; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; sockOptData.option = PR_SockOpt_Reuseaddr; status = PR_GetSocketOption(sock->fd, &sockOptData); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: /* If we got here via failure, reuse_addr might be uninitialized. But in * that case we're throwing an exception, so the return value doesn't * matter. */ return ((sockOptData.value.reuse_addr == PR_TRUE) ? JNI_TRUE : JNI_FALSE); } jss-4.6.3/org/mozilla/jss/ssl/SSLServerSocket.java000066400000000000000000000471361362106420000220320ustar00rootroot00000000000000/* 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.net.InetAddress; import java.io.IOException; import java.net.Socket; import java.net.SocketException; import java.net.SocketTimeoutException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.TokenException; /** * SSL server socket. */ public class SSLServerSocket extends java.net.ServerSocket { /* * Locking rules of SSLServerSocket * * isClosed and inAccept must be accessed with the object locked. * * acceptLock must be locked throughout the accept method. It is * used to serialize accept calls on the object. */ private SocketProxy sockProxy = null; private boolean handshakeAsClient = false; private SocketBase base = new SocketBase(); private boolean isClosed = false; private boolean inAccept = false; private java.lang.Object acceptLock = new java.lang.Object(); /** * The default size of the listen queue. */ public static final int DEFAULT_BACKLOG = 50; /** * Creates a server socket listening on the given port. * The listen queue will be of size DEFAULT_BACKLOG. */ public SSLServerSocket(int port) throws IOException { this(port, DEFAULT_BACKLOG, null); } /** * Creates a server socket listening on the given port. * @param backlog The size of the socket's listen queue. */ public SSLServerSocket(int port, int backlog) throws IOException { this(port, backlog, null); } /** * Creates a server socket listening on the given port. * @param backlog The size of the socket's listen queue. * @param bindAddr The local address to which to bind. If null, an * unspecified local address will be bound to. */ public SSLServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException { this(port, backlog, bindAddr, null); } /** * Creates a server socket listening on the given port. * @param backlog The size of the socket's listen queue. * @param bindAddr The local address to which to bind. If null, an * unspecified local address will be bound to. * @param certApprovalCallback Will get called to approve any certificate * presented by the client. */ public SSLServerSocket(int port, int backlog, InetAddress bindAddr, SSLCertificateApprovalCallback certApprovalCallback) throws IOException { this(port,backlog, bindAddr, certApprovalCallback, false); } /** * Creates a server socket listening on the given port. * @param backlog The size of the socket's listen queue. * @param bindAddr The local address to which to bind. If null, an * unspecified local address will be bound to. * @param certApprovalCallback Will get called to approve any certificate * presented by the client. * @param reuseAddr Reuse the local bind port; this parameter sets * the SO_REUSEADDR option on the socket before calling * bind(). The default is false for backward * compatibility. */ public SSLServerSocket(int port, int backlog, InetAddress bindAddr, SSLCertificateApprovalCallback certApprovalCallback, boolean reuseAddr) throws IOException { // Dance the dance of fools. The superclass doesn't have a default // constructor, so we have to trick it here. This is an example // of WHY WE SHOULDN'T BE EXTENDING SERVERSOCKET. super(0); super.close(); // create the socket int socketFamily = SocketBase.SSL_AF_INET; if(SocketBase.supportsIPV6()) { socketFamily = SocketBase.SSL_AF_INET6; } sockProxy = new SocketProxy( base.socketCreate(this, certApprovalCallback, null,socketFamily) ); base.setProxy(sockProxy); setReuseAddress(reuseAddr); byte[] bindAddrBA = null; if( bindAddr != null ) { bindAddrBA = bindAddr.getAddress(); } base.socketBind(bindAddrBA, port); String hostName = null; if(bindAddr != null) { hostName = bindAddr.getCanonicalHostName(); } socketListen(backlog); } private native void socketListen(int backlog) throws SocketException; /** * Accepts a connection. This call will block until a connection is made * or the timeout is reached. * * @return java.net.Socket Local socket for client communication * * @throws IOException If an input or output exception occurred * @throws SocketTimeoutException If the socket times out trying to connect * @throws SSLSocketException JSS subclass of java.net.SocketException */ public Socket accept() throws IOException { synchronized (acceptLock) { synchronized (this) { if (isClosed) { throw new IOException( "SSLServerSocket has been closed, and cannot be reused."); } inAccept = true; } SSLSocket s = new SSLSocket(); try { /* * socketAccept can throw an exception for timeouts, * IO errors, or PR_Interrupt called by abortAccept. * So first get a socket pointer, and if successful * create the SocketProxy. */ byte[] socketPointer = null; socketPointer = socketAccept(s, base.getTimeout(), handshakeAsClient); SocketProxy sp = new SocketProxy(socketPointer); s.setSockProxy(sp); } finally { synchronized (this) { inAccept=false; } } return s; } } /** * Sets the SO_TIMEOUT socket option. * @param timeout The timeout time in milliseconds. */ public void setSoTimeout(int timeout) { base.setTimeout(timeout); } /** * Returns the current value of the SO_TIMEOUT socket option. * @return The timeout time in milliseconds. */ public int getSoTimeout() { return base.getTimeout(); } public native void setReuseAddress(boolean reuse) throws SocketException; public native boolean getReuseAddress() throws SocketException; private native void abortAccept() throws SocketException; private native byte[] socketAccept(SSLSocket s, int timeout, boolean handshakeAsClient) throws SocketException, SocketTimeoutException; /** * Empties the SSL client session ID cache. */ public static native void clearSessionCache(); /** * @deprecated finalize() in Object has been deprecated */ @Deprecated protected void finalize() throws Throwable { close(); /* in case user never called close */ } /** * @return The local port. */ public int getLocalPort() { return base.getLocalPort(); } /** * Closes this socket. */ public void close() throws IOException { synchronized (this) { if( isClosed ) { /* finalize calls close or user calls close more than once */ return; } isClosed = true; if( sockProxy == null ) { /* nothing to do */ return; } if( inAccept ) { abortAccept(); } } /* Lock acceptLock to ensure that accept has been aborted. */ synchronized (acceptLock) { base.close(); sockProxy = null; base.setProxy(null); } } // This directory is used as the default for the Session ID cache private final static String UNIX_TEMP_DIR = "/tmp"; private final static String WINDOWS_TEMP_DIR = "\\temp"; /** * Configures the session ID cache. * @param maxSidEntries The maximum number of entries in the cache. If * 0 is passed, the default of 10,000 is used. * @param ssl2EntryTimeout The lifetime in seconds of an SSL2 session. * The minimum timeout value is 5 seconds and the maximum is 24 hours. * Values outside this range are replaced by the server default value * of 100 seconds. * @param ssl3EntryTimeout The lifetime in seconds of an SSL3 session. * The minimum timeout value is 5 seconds and the maximum is 24 hours. * Values outside this range are replaced by the server default value * of 100 seconds. * @param cacheFileDirectory The pathname of the directory that * will contain the session cache. If null is passed, the server default * is used: /tmp on Unix and \\temp on Windows. */ public static native void configServerSessionIDCache(int maxSidEntries, int ssl2EntryTimeout, int ssl3EntryTimeout, String cacheFileDirectory) throws SocketException; /** * Sets the certificate to use for server authentication. */ public void setServerCertNickname(String nick) throws SocketException { try { setServerCert( CryptoManager.getInstance().findCertByNickname(nick) ); } catch(NotInitializedException nie) { throw new SocketException("CryptoManager not initialized: " + nie); } catch(ObjectNotFoundException onfe) { throw new SocketException("Object not found: " + onfe); } catch(TokenException te) { throw new SocketException("Token Exception: " + te); } } /** * Sets the certificate to use for server authentication. */ public native void setServerCert( org.mozilla.jss.crypto.X509Certificate certnickname) throws SocketException; /** * Enables/disables the request of client authentication. 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. * @see org.mozilla.jss.ssl.SSLServerSocket#requireClientAuth */ public void requestClientAuth(boolean b) throws SocketException { base.requestClientAuth(b); } /** * @deprecated As of JSS 3.0. This method is misnamed. Use * requestClientAuth instead. */ @Deprecated public void setNeedClientAuth(boolean b) throws SocketException { base.requestClientAuth(b); } /** * Enables/disables the request of client authentication. 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. *

In addition, the client certificate's expiration will not * prevent it from being accepted. * @see org.mozilla.jss.ssl.SSLServerSocket#requireClientAuth public void requestClientAuthNoExpiryCheck(boolean b) throws SocketException { base.requestClientAuthNoExpiryCheck(b); } /** * @deprecated As of JSS 3.0. This method is misnamed. Use * requestClientAuthNoExpiryCheck instead. */ @Deprecated public void setNeedClientAuthNoExpiryCheck(boolean b) throws SocketException { base.requestClientAuthNoExpiryCheck(b); } /** * Enables SSL v2 on this socket. It is enabled by default, unless the * default has been changed with SSLSocket.enableSSL2Default. */ public void enableSSL2(boolean enable) throws SocketException { base.enableSSL2(enable); } /** * Enables SSL v3 on this socket. It is enabled by default, unless the * default has been changed with SSLSocket.enableSSL3Default. */ public void enableSSL3(boolean enable) throws SocketException { base.enableSSL3(enable); } /** * Enables TLS on this socket. It is enabled by default, unless the * default has been changed with SSLSocket.enableTLSDefault. */ public void enableTLS(boolean enable) throws SocketException { base.enableTLS(enable); } /** * Enables Session tickets on this socket. It is disabled by default, * unless the default has been changed with * SSLSocket.enableSessionTicketsDefault. */ public void enableSessionTickets(boolean enable) throws SocketException { base.enableSessionTickets(enable); } /** * Enables the mode of renegotiation that the peer must use. * The default is never renegotiate at all unless the default * has been changed with SSLSocket.enableRenegotiationDefault. * * @param mode One of: * SSLSocket.SSL_RENEGOTIATE_NEVER - Never renegotiate at all. * * SSLSocket.SSL_RENEGOTIATE_UNRESTRICTED - Renegotiate without * restriction, whether or not the peer's hello bears the TLS * renegotiation info extension. Vulnerable, as in the past. * * SSLSocket.SSL_RENEGOTIATE_REQUIRES_XTN - Only renegotiate if the * peer's hello bears the TLS renegotiation_info extension. This is * safe renegotiation. * * SSLSocket.SSL_RENEGOTIATE_TRANSITIONAL - Disallow unsafe * renegotiation in server sockets only, but allow clients * to continue to renegotiate with vulnerable servers. * This value should only be used during the transition period * when few servers have been upgraded. */ public void enableRenegotiation(int mode) throws SocketException { if (mode >= SocketBase.SSL_RENEGOTIATE_NEVER && mode <= SocketBase.SSL_RENEGOTIATE_TRANSITIONAL) { base.enableRenegotiation(mode); } else { throw new SocketException("Incorrect input value."); } } /** * For this socket require that the peer must send * Signaling Cipher Suite Value (SCSV) or Renegotiation Info (RI) * extension in ALL handshakes. It is disabled by default, * unless the default has been changed with * SSLSocket.enableRequireSafeNegotiationDefault. */ public void enableRequireSafeNegotiation(boolean enable) throws SocketException { base.enableRequireSafeNegotiation(enable); } /** * Enable rollback detection for this socket. * It is enabled by default, unless the default has been changed * with SSLSocket.enableRollbackDetectionDefault. */ public void enableRollbackDetection(boolean enable) throws SocketException { base.enableRollbackDetection(enable); } /** * 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 * need to be generated. * If the server cert's public key is more than 512 bits, * this option has the following effect: * enable=true: generate step-down keys * enable=false: don't generate step-down keys; disable * export cipher suites * * This option is enabled by default; unless the default has * been changed with SSLSocket.enableStepDownDefault. */ public void enableStepDown(boolean enable) throws SocketException { base.enableStepDown(enable); } /** * 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 * with SSLSocket.enableFDXDefault. */ public void enableFDX(boolean enable) throws SocketException { base.enableFDX(enable); } /** * Enable sending v3 client hello in v2 format for this socket. * It is enabled by default, unless the default has been changed * with SSLSocket.enableV2CompatibleHelloDefault. */ public void enableV2CompatibleHello(boolean enable) throws SocketException { base.enableV2CompatibleHello(enable); } /** * @return a String listing the current SSLOptions for this socket. */ public String getSSLOptions() { return base.getSSLOptions(); } /** * @return the local address of this server socket. */ public InetAddress getInetAddress() { return base.getLocalAddress(); } /** * 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. * @deprecated use requireClientAuth(int) */ @Deprecated public void requireClientAuth(boolean require, boolean onRedo) throws SocketException { base.requireClientAuth(require, onRedo); } /** * 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. * @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 && mode <= SocketBase.SSL_REQUIRE_NO_ERROR) { base.requireClientAuth(mode); } else { throw new SocketException("Incorrect input value."); } } /** * Sets the nickname of the certificate to use for client authentication. */ public void setClientCertNickname(String nick) throws SocketException { base.setClientCertNickname(nick); } /** * Sets the certificate to use for client authentication. */ public void setClientCert(org.mozilla.jss.crypto.X509Certificate cert) throws SocketException { base.setClientCert(cert); } /** * Determines whether this end of the socket is the client or the server * for purposes of the SSL protocol. By default, it is the server. * @param b true if this end of the socket is the SSL slient, false * if it is the SSL server. */ public void setUseClientMode(boolean b) { handshakeAsClient = b; } /** * Enables/disables the session cache. By default, the session cache * is enabled. */ public void useCache(boolean b) throws SocketException { base.useCache(b); } /** * Returns the addresses and ports of this socket * or an error message if the socket is not in a valid state. */ public String toString() { try { InetAddress inetAddr = getInetAddress(); int localPort = getLocalPort(); StringBuffer buf = new StringBuffer(); buf.append("SSLServerSocket[addr="); buf.append(inetAddr); buf.append(",localport="); buf.append(localPort); buf.append("]"); return buf.toString(); } catch (Exception e) { return "Exception caught in toString(): " + e.getMessage(); } } } jss-4.6.3/org/mozilla/jss/ssl/SSLSocket.c000066400000000000000000001014201362106420000201270ustar00rootroot00000000000000/* 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/. */ #include #include #include #include #include #include #include #include #include #include "_jni/org_mozilla_jss_ssl_SSLSocket.h" #include "jssl.h" #include #ifdef WINNT #include #define AF_INET6 23 #endif #ifdef WIN32 #include #define AF_INET6 23 #endif #include "SSLVersionRange.h" /* * support TLS v1.1, v1.2, and v1.3 * returns SSL version range bound by the version range provided by the system. * Doesn't change the defaults. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_ssl_SSLSocket_boundSSLVersionRange(JNIEnv *env, jclass clazz, jint ssl_variant, jint min, jint max) { SECStatus status; SSLVersionRange vrange; SSLVersionRange supported_range; jobject versionRange = NULL; if (ssl_variant <0 || ssl_variant >= JSSL_enums_size|| min <0 || min >= JSSL_enums_size || max <0 || max >= JSSL_enums_size) { char buf[128]; PR_snprintf(buf, 128, "JSS checkSSLVersionRangeDefault(): for variant=%d min=%d max=%d failed - out of range for array JSSL_enums size: %d", JSSL_enums[ssl_variant], min, max, JSSL_enums_size); JSSL_throwSSLSocketException(env, buf); goto finish; } vrange.min = JSSL_enums[min]; vrange.max = JSSL_enums[max]; /* get supported range */ status = SSL_VersionRangeGetSupported(JSSL_enums[ssl_variant], &supported_range); if( status != SECSuccess ) { char buf[128]; PR_snprintf(buf, 128, "SSL_VersionRangeGetSupported() for variant=%d failed: %d", JSSL_enums[ssl_variant], PR_GetError()); JSSL_throwSSLSocketException(env, buf); goto finish; } /* bind the min and max */ supported_range.min = MAX(supported_range.min, vrange.min); supported_range.max = MIN(supported_range.max, vrange.max); /* wrap NSS's SSLVersionRange into a org.mozilla.jss.ssl.SSLVersionRange */ versionRange = JSS_SSL_wrapVersionRange(env, supported_range); finish: return versionRange; } /* * support TLS v1.1, v1.2, and v1.3 * sets default SSL version range for sockets created after this call */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setSSLVersionRangeDefault(JNIEnv *env, jclass clazz, jint ssl_variant, jint min, jint max) { SECStatus status; SSLVersionRange vrange; SSLVersionRange supported_range; if (ssl_variant <0 || ssl_variant >= JSSL_enums_size|| min <0 || min >= JSSL_enums_size || max <0 || max >= JSSL_enums_size) { char buf[128]; PR_snprintf(buf, 128, "JSS setSSLVersionRangeDefault(): for variant=%d min=%d max=%d failed - out of range for array JSSL_enums size: %d", JSSL_enums[ssl_variant], min, max, JSSL_enums_size); JSSL_throwSSLSocketException(env, buf); goto finish; } vrange.min = JSSL_enums[min]; vrange.max = JSSL_enums[max]; /* get supported range */ status = SSL_VersionRangeGetSupported(JSSL_enums[ssl_variant], &supported_range); if( status != SECSuccess ) { char buf[128]; PR_snprintf(buf, 128, "SSL_VersionRangeGetSupported() for variant=%d failed: %d", JSSL_enums[ssl_variant], PR_GetError()); JSSL_throwSSLSocketException(env, buf); goto finish; } /* now check the min and max */ if (vrange.min < supported_range.min || vrange.max > supported_range.max) { char buf[128]; PR_snprintf(buf, 128, "JSS setSSLVersionRangeDefault() for variant=%d with min=%d max=%d out of range (%d:%d): %d", JSSL_enums[ssl_variant], vrange.min, vrange.max, supported_range.min, supported_range.max, PR_GetError()); JSSL_throwSSLSocketException(env, buf); goto finish; } /* set the default SSL Version Range */ status = SSL_VersionRangeSetDefault(JSSL_enums[ssl_variant], &vrange); if( status != SECSuccess ) { char buf[128]; PR_snprintf(buf, 128, "SSL_VersionRangeSetDefault() for variant=%d with min=%d max=%d failed: %d", JSSL_enums[ssl_variant], vrange.min, vrange.max, PR_GetError()); JSSL_throwSSLSocketException(env, buf); goto finish; } finish: return; } /* * support TLS v1.1, v1.2, and v1.3 * sets SSL version range for this socket */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_setSSLVersionRange (JNIEnv *env, jobject self, jint min, jint max) { SECStatus status; JSSL_SocketData *sock = NULL; SSLVersionRange vrange; if ( min <0 || min >= JSSL_enums_size || max <0 || max >= JSSL_enums_size) { char buf[128]; PR_snprintf(buf, 128, "JSS setSSLVersionRange(): for max=%d failed - out of range for array JSSL_enums size: %d", min, max, JSSL_enums_size); JSSL_throwSSLSocketException(env, buf); goto finish; } /* get my fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } vrange.min = JSSL_enums[min]; vrange.max = JSSL_enums[max]; /* * set the SSL Version Range * The validity of the range will be checked by this NSS call */ status = SSL_VersionRangeSet(sock->fd, &vrange); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_VersionRangeSet failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setSSLDefaultOption(JNIEnv *env, jclass clazz, jint joption, jint on) { SECStatus status; /* set the option */ status = SSL_OptionSetDefault(JSSL_enums[joption], on); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionSet failed"); goto finish; } finish: return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setSSLDefaultOptionMode(JNIEnv *env, jclass clazz, jint joption, jint mode) { SECStatus status; /* set the option */ status = SSL_OptionSetDefault(JSSL_enums[joption], JSSL_enums[mode]); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionSet failed"); goto finish; } finish: return; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLSocket_isFipsCipherSuiteNative(JNIEnv *env, jobject self, jint suite) { SECStatus status; PRBool bOption = PR_FALSE; SSLCipherSuiteInfo info; status = SSL_GetCipherSuiteInfo(suite, &info, sizeof info); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "ciphersuite invalid"); } if (info.isFIPS == 1) bOption = PR_TRUE; return bOption; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getSSLDefaultOption(JNIEnv *env, jobject self, jint joption) { SECStatus status; PRBool bOption; /* get the Default option */ status = SSL_OptionGetDefault(JSSL_enums[joption], &bOption); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionGetDefault failed"); } return bOption; } #if 0 #define EXCEPTION_CHECK(env, sock) \ if( sock != NULL && sock->jsockPriv!=NULL) { \ JSS_SSL_processExceptions(env, sock->jsockPriv); \ } #endif JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_forceHandshake(JNIEnv *env, jobject self) { JSSL_SocketData *sock = NULL; int rv; /* get my fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) goto finish; /* do the work */ rv = SSL_ForceHandshake(sock->fd); if( rv != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_ForceHandshake failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } /* * linger * The linger time, in seconds. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setSoLinger(JNIEnv *env, jobject self, jboolean on, jint linger) { PRSocketOptionData sockOptions; PRStatus status; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_Linger; sockOptions.value.linger.polarity = on; if(on) { sockOptions.value.linger.linger = PR_SecondsToInterval(linger); } status = PR_SetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getTcpNoDelay(JNIEnv *env, jobject self) { PRSocketOptionData sockOptions; JSSL_SocketData *sock = NULL; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_NoDelay; status = PR_GetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return sockOptions.value.no_delay; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setTcpNoDelay(JNIEnv *env, jobject self, jboolean on) { PRSocketOptionData sockOptions; PRStatus status; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_NoDelay; sockOptions.value.no_delay = on; status = PR_SetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getSendBufferSize(JNIEnv *env, jobject self) { PRSocketOptionData sockOptions; JSSL_SocketData *sock = NULL; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_SendBufferSize; status = PR_GetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return sockOptions.value.send_buffer_size; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setSendBufferSize(JNIEnv *env, jobject self, jint size) { PRSocketOptionData sockOptions; PRStatus status; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_SendBufferSize; sockOptions.value.send_buffer_size = size; status = PR_SetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getKeepAlive(JNIEnv *env, jobject self) { PRSocketOptionData sockOptions; JSSL_SocketData *sock = NULL; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_Keepalive; status = PR_GetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return sockOptions.value.keep_alive; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getReceiveBufferSize( JNIEnv *env, jobject self) { PRSocketOptionData sockOptions; JSSL_SocketData *sock = NULL; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_RecvBufferSize; status = PR_GetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return sockOptions.value.recv_buffer_size; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setReceiveBufferSize( JNIEnv *env, jobject self, jint size) { PRSocketOptionData sockOptions; PRStatus status; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_RecvBufferSize; sockOptions.value.recv_buffer_size = size; status = PR_SetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setKeepAlive(JNIEnv *env, jobject self, jboolean on) { PRSocketOptionData sockOptions; PRStatus status; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_Keepalive; sockOptions.value.keep_alive = on; status = PR_SetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getSoLinger(JNIEnv *env, jobject self) { PRSocketOptionData sockOptions; JSSL_SocketData *sock = NULL; jint retval=-1; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_Linger; status = PR_GetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSocketOption failed"); goto finish; } if( sockOptions.value.linger.polarity == PR_TRUE ) { retval = PR_IntervalToSeconds(sockOptions.value.linger.linger); } else { retval = -1; } finish: EXCEPTION_CHECK(env, sock) return retval; } /* * This function is only here for binary compatibility. See * http://bugzilla.mozilla.org/show_bug.cgi?id=143254 */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getLocalAddressNative(JNIEnv *env, jobject self) { PRNetAddr addr; if( JSSL_getSockAddr(env, self, &addr, LOCAL_SOCK) == PR_SUCCESS ) { return ntohl(addr.inet.ip); } else { return 0; } } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getPort(JNIEnv *env, jobject self) { PRNetAddr addr; if( JSSL_getSockAddr(env, self, &addr, PEER_SOCK) == PR_SUCCESS ) { return ntohs(addr.inet.port); } else { return 0; } } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_socketConnect (JNIEnv *env, jobject self, jbyteArray addrBA, jstring hostname, jint port) { JSSL_SocketData *sock; PRNetAddr addr; jbyte *addrBAelems = NULL; int addrBALen = 0; PRStatus status; int stat; const char *hostnameStr=NULL; jmethodID supportsIPV6ID; jclass socketBaseClass; jboolean supportsIPV6 = 0; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* * setup the PRNetAddr structure */ socketBaseClass = (*env)->FindClass(env, SOCKET_BASE_NAME); if( socketBaseClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } supportsIPV6ID = (*env)->GetStaticMethodID(env, socketBaseClass, SUPPORTS_IPV6_NAME, SUPPORTS_IPV6_SIG); if( supportsIPV6ID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } supportsIPV6 = (*env)->CallStaticBooleanMethod(env, socketBaseClass, supportsIPV6ID); if (!JSS_RefByteArray(env, addrBA, &addrBAelems, &addrBALen)) { ASSERT_OUTOFMEM(env); goto finish; } /* * Tell SSL the URL we think we want to connect to. * This prevents man-in-the-middle attacks. */ hostnameStr = JSS_RefJString(env, hostname); if( hostnameStr == NULL ) goto finish; stat = SSL_SetURL(sock->fd, (char*)hostnameStr); if( stat != 0 ) { JSSL_throwSSLSocketException(env, "Failed to set the SSL URL"); goto finish; } if(addrBALen != 4 && addrBALen != 16) { JSSL_throwSSLSocketException(env, "Invalid address in connect!"); goto finish; } if( addrBALen == 4) { addr.inet.family = AF_INET; addr.inet.port = PR_htons(port); memcpy(&addr.inet.ip, addrBAelems, 4); if(supportsIPV6) { addr.ipv6.family = AF_INET6; addr.ipv6.port = PR_htons(port); PR_ConvertIPv4AddrToIPv6(addr.inet.ip,&addr.ipv6.ip); } } else { /* Must be 16 and ipv6 */ if(supportsIPV6) { addr.ipv6.family = AF_INET6; addr.ipv6.port = PR_htons(port); memcpy(&addr.ipv6.ip,addrBAelems, 16); } else { JSSL_throwSSLSocketException(env, "Invalid address in connect!"); goto finish; } } /* * make the connect call */ status = PR_Connect(sock->fd, &addr, PR_INTERVAL_NO_TIMEOUT); if( status != PR_SUCCESS) { JSSL_throwSSLSocketException(env, "Unable to connect"); goto finish; } finish: /* This method should never be called on a Java socket wrapper. */ PR_ASSERT( sock==NULL || sock->jsockPriv==NULL); JSS_DerefJString(env, hostname, hostnameStr); JSS_DerefByteArray(env, addrBA, addrBAelems, JNI_ABORT); } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getStatus (JNIEnv *env, jobject self) { SECStatus secstatus; JSSL_SocketData *sock=NULL; int on; char *cipher=NULL; jobject cipherString; jint keySize; jint secretKeySize; char *issuer=NULL; jobject issuerString; char *subject=NULL; jobject subjectString; jobject statusObj = NULL; jclass statusClass; jmethodID statusCons; CERTCertificate *peerCert=NULL; jobject peerCertObj = NULL; char *serialNum = NULL; jobject serialNumObj = NULL; /* get the fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get the status */ secstatus = SSL_SecurityStatus( sock->fd, &on, &cipher, (int*)&keySize, (int*)&secretKeySize, &issuer, &subject); if(secstatus != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to retrieve socket security status"); goto finish; } /* * get the peer certificate */ peerCert = SSL_PeerCertificate(sock->fd); if( peerCert != NULL ) { /* the peer cert might be null, for example if this is the server * side and the client didn't auth. */ serialNum = CERT_Hexify(&peerCert->serialNumber, PR_FALSE /*do_colon*/); PR_ASSERT(serialNum != NULL); serialNumObj = (*env)->NewStringUTF(env, serialNum); if( serialNumObj == NULL ) { goto finish; } /* this call will wipe out peerCert */ peerCertObj = JSS_PK11_wrapCert(env, &peerCert); if( peerCertObj == NULL) { goto finish; } } /* * convert char*s to Java Strings */ cipherString = issuerString = subjectString = NULL; if( cipher != NULL ) cipherString = (*env)->NewStringUTF(env, cipher); if( issuer != NULL ) issuerString = (*env)->NewStringUTF(env, issuer); if( subject != NULL ) subjectString = (*env)->NewStringUTF(env, subject); /* * package the status into a new SSLSecurityStatus object */ statusClass = (*env)->FindClass(env, SSL_SECURITY_STATUS_CLASS_NAME); PR_ASSERT(statusClass != NULL); if( statusClass == NULL ) { /* exception was thrown */ goto finish; } statusCons = (*env)->GetMethodID(env, statusClass, SSL_SECURITY_STATUS_CONSTRUCTOR_NAME, SSL_SECURITY_STATUS_CONSTRUCTOR_SIG); PR_ASSERT(statusCons != NULL); if(statusCons == NULL ) { /* exception was thrown */ goto finish; } statusObj = (*env)->NewObject(env, statusClass, statusCons, on, cipherString, keySize, secretKeySize, issuerString, subjectString, serialNumObj, peerCertObj); finish: if( cipher != NULL ) { PR_Free(cipher); } if( issuer != NULL ) { PORT_Free(issuer); } if ( subject != NULL) { PORT_Free(subject); } if( peerCert != NULL ) { CERT_DestroyCertificate(peerCert); } if( serialNum != NULL ) { PR_Free(serialNum); } EXCEPTION_CHECK(env, sock) return statusObj; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setCipherPreference( JNIEnv *env, jobject sockObj, jint cipher, jboolean enable) { JSSL_SocketData *sock=NULL; SECStatus status; /* get the fd */ if( JSSL_getSockData(env, sockObj, &sock) != PR_SUCCESS) { /* exception was thrown */ goto finish; } status = SSL_CipherPrefSet(sock->fd, cipher, enable); if( status != SECSuccess ) { char buf[128]; PR_snprintf(buf, 128, "Failed to %s cipher 0x%lx\n", (enable ? "enable" : "disable"), cipher); JSSL_throwSSLSocketException(env, buf); goto finish; } finish: EXCEPTION_CHECK(env, sock); } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getCipherPreference( JNIEnv *env, jobject sockObj, jint cipher) { JSSL_SocketData *sock=NULL; SECStatus status; PRBool enabled = PR_FAILURE; /* get the fd */ if( JSSL_getSockData(env, sockObj, &sock) != PR_SUCCESS) { /* exception was thrown */ goto finish; } status = SSL_CipherPrefGet(sock->fd, cipher, &enabled); if( status != SECSuccess ) { char buf[128]; PR_snprintf(buf, 128, "Failed to get preference for cipher 0x%lx\n", cipher); JSSL_throwSSLSocketException(env, buf); goto finish; } finish: EXCEPTION_CHECK(env, sock); return enabled; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setCipherPreferenceDefault( JNIEnv *env, jclass clazz, jint cipher, jboolean enable) { SECStatus status; /* set the preference */ status = SSL_CipherPrefSetDefault(cipher, enable); if(status != SECSuccess) { char buf[128]; PR_snprintf(buf, 128, "Failed to %s cipher 0x%lx\n", (enable ? "enable" : "disable"), cipher); JSSL_throwSSLSocketException(env, buf); goto finish; } finish: return; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getCipherPreferenceDefault( JNIEnv *env, jclass clazz, jint cipher) { SECStatus status; PRBool enabled; /* get the preference */ status = SSL_CipherPrefGetDefault(cipher, &enabled); if(status != SECSuccess) { char buf[128]; PR_snprintf(buf, 128, "Failed to get default preference for " "cipher 0x%lx\n", cipher); JSSL_throwSSLSocketException(env, buf); goto finish; } finish: return enabled; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_socketRead(JNIEnv *env, jobject self, jbyteArray bufBA, jint off, jint len, jint timeout) { JSSL_SocketData *sock = NULL; jbyte *buf = NULL; jint size; PRIntervalTime ivtimeout; PRThread *me; jint nread = -1; if (!JSS_RefByteArray(env, bufBA, &buf, &size)) { goto finish; } if (off < 0 || len < 0 || (off+len) > size) { JSS_throw(env, INDEX_OUT_OF_BOUNDS_EXCEPTION); goto finish; } ivtimeout = (timeout > 0) ? PR_MillisecondsToInterval(timeout) : PR_INTERVAL_NO_TIMEOUT; /* get the socket */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* set the current thread doing the read */ me = PR_GetCurrentThread(); PR_Lock(sock->lock); if ( sock->closePending ) { PR_Unlock(sock->lock); JSSL_throwSSLSocketException(env, "Read operation interrupted"); goto finish; } PR_ASSERT(sock->reader == NULL); sock->reader = me; PR_Unlock(sock->lock); nread = PR_Recv(sock->fd, buf+off, len, 0 /*flags*/, ivtimeout); PR_Lock(sock->lock); PR_ASSERT(sock->reader == me); sock->reader = NULL; PR_Unlock(sock->lock); if( nread < 0 ) { PRErrorCode err = PR_GetError(); if( err == PR_PENDING_INTERRUPT_ERROR ) { #ifdef WINNT /* Clean up after PR_interrupt called by abortReadWrite. */ PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Read operation interrupted"); } else if( err == PR_IO_TIMEOUT_ERROR ) { #ifdef WINNT /* * if timeout was set, and the PR_Recv timed out, * then cancel the I/O on the socket, otherwise PR_Recv() * will always return PR_IO_PENDING_ERROR on subsequent * calls */ PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Operation timed out"); } else { JSSL_throwSSLSocketException(env, "Error reading from socket"); } goto finish; } if( nread == 0 ) { /* EOF in Java is -1 */ nread = -1; } finish: EXCEPTION_CHECK(env, sock) JSS_DerefByteArray(env, bufBA, buf, (nread>0) ? 0 /*copy and free*/ : JNI_ABORT /*free, no copy*/); return nread; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_socketAvailable( JNIEnv *env, jobject self) { jint available=0; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } available = SSL_DataPending(sock->fd); PR_ASSERT(available >= 0); finish: EXCEPTION_CHECK(env, sock) return available; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_socketWrite(JNIEnv *env, jobject self, jbyteArray bufBA, jint off, jint len, jint timeout) { JSSL_SocketData *sock = NULL; jbyte *buf = NULL; jint size; PRIntervalTime ivtimeout; PRThread *me; PRInt32 numwrit; if (!JSS_RefByteArray(env, bufBA, &buf, &size)) { goto finish; } if (off < 0 || len < 0 || (off+len) > size) { JSS_throw(env, INDEX_OUT_OF_BOUNDS_EXCEPTION); goto finish; } ivtimeout = (timeout > 0) ? PR_MillisecondsToInterval(timeout) : PR_INTERVAL_NO_TIMEOUT; /* get the socket */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* set the current thread doing the write */ me = PR_GetCurrentThread(); PR_Lock(sock->lock); if ( sock->closePending ) { PR_Unlock(sock->lock); JSSL_throwSSLSocketException(env, "Write operation interrupted"); goto finish; } PR_ASSERT(sock->writer == NULL); sock->writer = me; PR_Unlock(sock->lock); numwrit = PR_Send(sock->fd, buf+off, len, 0 /*flags*/, ivtimeout); PR_Lock(sock->lock); PR_ASSERT(sock->writer == me); sock->writer = NULL; PR_Unlock(sock->lock); if( numwrit < 0 ) { PRErrorCode err = PR_GetError(); if( err == PR_PENDING_INTERRUPT_ERROR ) { #ifdef WINNT /* clean up after PR_Interrupt called by abortReadWrite. */ PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Write operation interrupted"); } else if( err == PR_IO_TIMEOUT_ERROR ) { #ifdef WINNT /* * if timeout was set, and the PR_Send() timed out, * then cancel the I/O on the socket, otherwise PR_Send() * will always return PR_IO_PENDING_ERROR on subsequent * calls */ PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Operation timed out"); } else { JSSL_throwSSLSocketException(env, "Failed to write to socket"); } goto finish; } /* PR_Send is supposed to block until it sends everything */ PR_ASSERT(numwrit == len); finish: JSS_DerefByteArray(env, bufBA, buf, JNI_ABORT); EXCEPTION_CHECK(env, sock) } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_abortReadWrite( JNIEnv *env, jobject self) { JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) goto finish; /* * The java layer prevents I/O once close has been * called but if an I/O operation is in progress then abort it. * For WINNT the read and write methods must check for the * PR_PENDING_INTERRUPT_ERROR and call PR_NT_CancelIo. */ PR_Lock(sock->lock); if ( sock->reader ) { PR_Interrupt(sock->reader); } if ( sock->writer ) { PR_Interrupt(sock->writer); } sock->closePending = PR_TRUE; /* socket is to be closed */ PR_Unlock(sock->lock); finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_shutdownNative( JNIEnv *env, jobject self, jint how) { JSSL_SocketData *sock = NULL; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; status = PR_Shutdown(sock->fd, JSSL_enums[how]); if( status != PR_SUCCESS) { JSSL_throwSSLSocketException(env, "Failed to shutdown socket"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_invalidateSession(JNIEnv *env, jobject self) { JSSL_SocketData *sock = NULL; SECStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; status = SSL_InvalidateSession(sock->fd); if(status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to invalidate session"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_redoHandshake( JNIEnv *env, jobject self, jboolean flushCache) { JSSL_SocketData *sock = NULL; SECStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; status = SSL_ReHandshake(sock->fd, flushCache); if(status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to redo handshake"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_resetHandshakeNative( JNIEnv *env, jobject self, jboolean asClient) { JSSL_SocketData *sock = NULL; SECStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; status = SSL_ResetHandshake(sock->fd, !asClient); if(status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to redo handshake"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setCipherPolicyNative( JNIEnv *env, jobject self, jint policyEnum) { SECStatus status; switch(policyEnum) { case SSL_POLICY_DOMESTIC: status = NSS_SetDomesticPolicy(); break; case SSL_POLICY_EXPORT: status = NSS_SetExportPolicy(); break; case SSL_POLICY_FRANCE: status = NSS_SetFrancePolicy(); break; default: PR_ASSERT(PR_FALSE); status = SECFailure; } if(status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to set cipher policy"); goto finish; } finish: return; } JNIEXPORT jintArray JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getImplementedCipherSuites (JNIEnv *env, jclass clazz) { jintArray ciphArray = NULL; jint* arrayRegion = NULL; int i; ciphArray = (*env)->NewIntArray(env, SSL_NumImplementedCiphers); if( ciphArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } arrayRegion = (*env)->GetIntArrayElements(env, ciphArray, NULL/*isCopy*/); if( arrayRegion == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } for( i=0; i < SSL_NumImplementedCiphers; ++i) { arrayRegion[i] = SSL_ImplementedCiphers[i]; } finish: if( arrayRegion != NULL ) { (*env)->ReleaseIntArrayElements(env, ciphArray, arrayRegion, 0); } return ciphArray; } jss-4.6.3/org/mozilla/jss/ssl/SSLSocket.java000066400000000000000000001724261362106420000206440ustar00rootroot00000000000000/* 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.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; /** * SSL client socket. */ 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 TLS_NULL_WITH_NULL_NULL = 0x0000; /** * @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; public final static int TLS_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; public final static int TLS_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; public final static int TLS_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; public final static int TLS_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; public final static int TLS_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; public final static int TLS_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; public final static int TLS_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; public final static int TLS_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; public final static int TLS_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. */ @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; 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_DSS_WITH_AES_256_CBC_SHA256 = 0x006A; 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; /** * @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; public final static int TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040; 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; /** * @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; public final static int TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C; public final static int TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D; public final static int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E; public final static int TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F; public final static int TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2; public final static int TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3; public final static int TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA; public final static int TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB; public final static int TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF; public final static int TLS_FALLBACK_SCSV = 0x5600; 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_ECDSA_WITH_AES_256_CBC_SHA384 = 0xc024; public final static int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xc027; public final static int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xc028; public final static int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xc02B; public final static int TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xc02C; 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_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xc030; public final static int TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xc031; /* draft-ietf-tls-chacha20-poly1305-04 */ public final static int TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8; public final static int TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9; public final static int TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA; public final static int TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC; public final static int TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAD; public final static int TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 = 0xD001; public final static int TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 = 0xD002; /* Special TLS 1.3 cipher suites that really just specify AEAD */ public final static int TLS_AES_128_GCM_SHA256 = 0x1301; public final static int TLS_AES_256_GCM_SHA384 = 0x1302; public final static int TLS_CHACHA20_POLY1305_SHA256 = 0x1303; /* * Locking strategy of SSLSocket * * isClosed, inRead, and inWrite must be accessed with the object * locked. * * readLock must be locked throughout the read method. It is used * to serialize read calls. * * writeLock must be locked throughout the write method. It is used * to serialize write calls. */ private java.lang.Object readLock = new java.lang.Object(); private java.lang.Object writeLock = new java.lang.Object(); private boolean isClosed = false; private boolean inRead = false; private boolean inWrite = false; private InetAddress inetAddress; private int port; private SocketProxy sockProxy = null; private boolean open = false; private boolean handshakeAsClient = true; private SocketBase base = new SocketBase(); static final public int SSL_REQUIRE_NEVER = org.mozilla.jss.ssl.SocketBase.SSL_REQUIRE_NEVER; static final public int SSL_REQUIRE_ALWAYS = org.mozilla.jss.ssl.SocketBase.SSL_REQUIRE_ALWAYS; 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 = org.mozilla.jss.ssl.SocketBase.SSL_REQUIRE_NO_ERROR; static final public int SSL_RENEGOTIATE_NEVER = org.mozilla.jss.ssl.SocketBase.SSL_RENEGOTIATE_NEVER; static final public int SSL_RENEGOTIATE_REQUIRES_XTN = org.mozilla.jss.ssl.SocketBase.SSL_RENEGOTIATE_REQUIRES_XTN; static final public int SSL_RENEGOTIATE_UNRESTRICTED = org.mozilla.jss.ssl.SocketBase.SSL_RENEGOTIATE_UNRESTRICTED; static final public int SSL_RENEGOTIATE_TRANSITIONAL = org.mozilla.jss.ssl.SocketBase.SSL_RENEGOTIATE_TRANSITIONAL; private Collection socketListeners = new ArrayList<>(); private Collection handshakeCompletedListeners = new ArrayList<>(); /** * For sockets that get created by accept(). */ SSLSocket() throws IOException { } /** * Should only be called by SSLServerSocket after a successful * accept(). */ void setSockProxy(SocketProxy sp) { sockProxy = sp; base.setProxy(sp); } /** * Creates an SSL client socket and connects to the specified host and * port. * * @param host The hostname to connect to. * @param port The port to connect to. */ public SSLSocket(String host, int port) throws UnknownHostException, IOException { this(InetAddress.getByName(host), port, null, 0); } /** * Creates an SSL client socket and connects to the specified address and * port. * * @param address The IP address to connect to. * @param port The port to connect to. */ public SSLSocket(InetAddress address, int port) throws IOException { this(address, port, null, 0); } /** * Creates an SSL client socket and connects to the specified host and * port. Binds to the given local address and port. * * @param host The hostname to connect to. * @param port The port to connect to. * @param localAddr The local address to bind to. It can be null, in which * case an unspecified local address will be chosen. * @param localPort The local port to bind to. If 0, a random port will be * assigned to the socket. */ public SSLSocket(String host, int port, InetAddress localAddr, int localPort) throws IOException { this(InetAddress.getByName(host), port, localAddr, localPort); } /** * Creates an SSL client socket and connects to the specified address and * port. Binds to the given local address and port. * * @param address The IP address to connect to. * @param port The port to connect to. * @param localAddr The local address to bind to. It can be null, in which * case an unspecified local address will be chosen. * @param localPort The local port to bind to. If 0, a random port will be * assigned to the socket. */ public SSLSocket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException { this(address, port, localAddr, localPort, null, null); } /** * Creates an SSL client socket and connects to the specified host and * port. Binds to the given local address and port. Installs the given * callbacks for certificate approval and client certificate selection. * * @param host The hostname to connect to. * @param port The port to connect to. * @param localAddr The local address to bind to. It can be null, in which * case an unspecified local address will be chosen. * @param localPort The local port to bind to. If 0, a random port will be * assigned to the socket. * @param certApprovalCallback A callback that can be used to override * approval of the peer's certificate. * @param clientCertSelectionCallback A callback to select the client * certificate to present to the peer. */ public SSLSocket(String host, int port, InetAddress localAddr, int localPort, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback) throws IOException { this(InetAddress.getByName(host), port, localAddr, localPort, certApprovalCallback, clientCertSelectionCallback); } /** * Creates an SSL client socket and connects to the specified address and * port. Binds to the given local address and port. Installs the given * callbacks for certificate approval and client certificate selection. * * @param address The IP address to connect to. * @param port The port to connect to. * @param localAddr The local address to bind to. It can be null, in which * case an unspecified local address will be chosen. * @param localPort The local port to bind to. If 0, a random port will be * assigned to the socket. * @param stream This parameter is ignored. All SSLSockets are stream * sockets. * @param certApprovalCallback A callback that can be used to override * approval of the peer's certificate. * @param clientCertSelectionCallback A callback to select the client * certificate to present to the peer. * @deprecated As of JSS 3.0. The stream parameter is ignored, because * only stream sockets are supported. */ @Deprecated public SSLSocket(InetAddress address, int port, InetAddress localAddr, int localPort, boolean stream, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback) throws IOException { this(address, port, localAddr, localPort, certApprovalCallback, clientCertSelectionCallback); } /** * Creates an SSL client socket and connects to the specified address and * port. Binds to the given local address and port. Installs the given * callbacks for certificate approval and client certificate selection. * * @param address The IP address to connect to. * @param port The port to connect to. * @param localAddr The local address to bind to. It can be null, in which * case an unspecified local address will be chosen. * @param localPort The local port to bind to. If 0, a random port will be * assigned to the socket. * @param certApprovalCallback A callback that can be used to override * approval of the peer's certificate. * @param clientCertSelectionCallback A callback to select the client * certificate to present to the peer. */ public SSLSocket(InetAddress address, int port, InetAddress localAddr, int localPort, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback) throws IOException { this(address, address.getHostName(), port, localAddr, localPort, certApprovalCallback, clientCertSelectionCallback); } private SSLSocket(InetAddress address, String hostname, int port, InetAddress localAddr, int localPort, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback) throws IOException { int socketFamily = SocketBase.SSL_AF_INET; if(SocketBase.supportsIPV6()) { socketFamily = SocketBase.SSL_AF_INET6; } // create the socket sockProxy = new SocketProxy( base.socketCreate( this, certApprovalCallback, clientCertSelectionCallback,socketFamily) ); base.setProxy(sockProxy); // bind it to local address and port if( localAddr != null || localPort > 0 ) { // bind because they specified a local address byte[] addrBA = null; if( localAddr != null ) { addrBA = localAddr.getAddress(); } base.socketBind(addrBA, localPort); } /* connect to the remote socket */ socketConnect(address.getAddress(), hostname, port); } /** * Creates an SSL client socket using the given Java socket for underlying * I/O. Installs the given callbacks for certificate approval and * client certificate selection. * * @param s The Java socket to use for underlying I/O. * @param host The hostname of the remote side of the connection. * This name is used to verify the server's certificate. * @param certApprovalCallback A callback that can be used to override * approval of the peer's certificate. * @param clientCertSelectionCallback A callback to select the client * certificate to present to the peer. */ public SSLSocket(java.net.Socket s, String host, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback) throws IOException { // create the socket sockProxy = new SocketProxy( base.socketCreate( this, certApprovalCallback, clientCertSelectionCallback, s, host,SocketBase.SSL_AF_INET ) ); base.setProxy(sockProxy); resetHandshake(); } /** * @return The remote peer's IP address or null if the SSLSocket is closed. */ public InetAddress getInetAddress() { synchronized (this) { if( isClosed ) { return null; } else return base.getInetAddress(); } } /** * @return The local IP address or null if the SSLSocket is closed. */ public InetAddress getLocalAddress() { synchronized (this) { if( isClosed ) { return null; } else return base.getLocalAddress(); } } /** * @return The local port or -1 if the SSLSocket is closed. */ public int getLocalPort() { synchronized (this) { if( isClosed ) { return -1; } else return base.getLocalPort(); } } /** * @return The remote port. */ public native int getPort(); /** * Returns the input stream for reading from this socket. */ public InputStream getInputStream() throws IOException { return new SSLInputStream(this); } /** * Returns the output stream for writing to this socket. */ public OutputStream getOutputStream() throws IOException { return new SSLOutputStream(this); } /** * Enables or disables the TCP_NO_DELAY socket option. Enabling this * option will disable the Nagle algorithm. */ public native void setTcpNoDelay(boolean on) throws SocketException; /** * Returns the current setting of the TCP_NO_DELAY socket option. */ public native boolean getTcpNoDelay() throws SocketException; /** * Enables or disables the SO_KEEPALIVE socket option. */ public native void setKeepAlive(boolean on) throws SocketException; /** * Returns the current setting of the SO_KEEPALIVE socket option. */ public native boolean getKeepAlive() throws SocketException; /** * Shuts down the input side of the socket. */ public void shutdownInput() throws IOException { shutdownNative(SocketBase.PR_SHUTDOWN_RCV); } /** * Shuts down the output side of the socket. */ public void shutdownOutput() throws IOException { shutdownNative(SocketBase.PR_SHUTDOWN_SEND); } private native void shutdownNative(int how) throws IOException; private native void abortReadWrite() throws IOException; /** * Sets the SO_LINGER socket option. * param linger The time (in seconds) to linger for. */ public native void setSoLinger(boolean on, int linger) throws SocketException; /** * Returns the current value of the SO_LINGER socket option. */ public native int getSoLinger() throws SocketException; /** * Sets the SO_TIMEOUT socket option. * @param timeout The timeout time in milliseconds. */ public void setSoTimeout(int timeout) throws SocketException { base.setTimeout(timeout); } /** * Returns the current value of the SO_TIMEOUT socket option. * @return The timeout time in milliseconds. */ public int getSoTimeout() throws SocketException { return base.getTimeout(); } /** * Sets the size (in bytes) of the send buffer. */ public native void setSendBufferSize(int size) throws SocketException; /** * Returns the size (in bytes) of the send buffer. */ public native int getSendBufferSize() throws SocketException; /** * Sets the size (in bytes) of the receive buffer. */ 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 { synchronized (this) { if( isClosed ) { /* finalize calls close or user calls close more than once */ return; } isClosed = true; if( sockProxy == null ) { /* nothing to do */ return; } /* * If a read or write is occurring, abort the I/O. Any * further attempts to read/write will fail since isClosed * is true */ if ( inRead || inWrite ) { abortReadWrite(); } } /* * Lock readLock and writeLock to ensure that read and write * have been aborted. */ synchronized (readLock) { synchronized (writeLock) { base.close(); sockProxy = null; base.setProxy(null); } } } private native void socketConnect(byte[] addr, String hostname, int port) throws SocketException; //////////////////////////////////////////////////////////////////// // SSL-specific stuff //////////////////////////////////////////////////////////////////// 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 listener) { handshakeCompletedListeners.add(listener); } /** * Removes a previously registered listener for handshake completion. */ public void removeHandshakeCompletedListener(SSLHandshakeCompletedListener listener) { handshakeCompletedListeners.remove(listener); } private void notifyAllHandshakeListeners() { 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 enableSSL2Default. */ public void enableSSL2(boolean enable) throws SocketException { base.enableSSL2(enable); } /** * Sets the default for SSL v2 for all new sockets. */ static public void enableSSL2Default(boolean enable) throws SocketException{ setSSLDefaultOption(SocketBase.SSL_ENABLE_SSL2, enable); } /** * Enables SSL v3 on this socket. It is enabled by default, unless the * default has been changed with enableSSL3Default. */ public void enableSSL3(boolean enable) throws SocketException { base.enableSSL3(enable); } /** * Sets the default for SSL v3 for all new sockets. */ static public void enableSSL3Default(boolean enable) throws SocketException{ setSSLDefaultOption(SocketBase.SSL_ENABLE_SSL3, enable); } /** * Enables TLS on this socket. It is enabled by default, unless the * default has been changed with enableTLSDefault. */ public void enableTLS(boolean enable) throws SocketException { base.enableTLS(enable); } /** * Sets the default for TLS for all new sockets. */ 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 * enableSessionTicketsDefault. */ public void enableSessionTickets(boolean enable) throws SocketException { base.enableSessionTickets(enable); } /** * Sets the default for Session Tickets for all new sockets. */ static public void enableSessionTicketsDefault(boolean enable) throws SocketException{ setSSLDefaultOption(SocketBase.SSL_ENABLE_SESSION_TICKETS, enable); } /** * Enables the mode of renegotiation that the peer must use on this * socket. Default is never renegotiate at all. Unless the default has * been changed with SSLSocket.enableRenegotiationDefault. * * @param mode One of: * SSLSocket.SSL_RENEGOTIATE_NEVER - Never renegotiate at all. * * SSLSocket.SSL_RENEGOTIATE_UNRESTRICTED - Renegotiate without * restriction, whether or not the peer's hello bears the TLS * renegotiation info extension. Vulnerable, as in the past. * * SSLSocket.SSL_RENEGOTIATE_REQUIRES_XTN - Only renegotiate if the * peer's hello bears the TLS renegotiation_info extension. This is * safe renegotiation. * * SSLSocket.SSL_RENEGOTIATE_TRANSITIONAL - Disallow unsafe * renegotiation in server sockets only, but allow clients * to continue to renegotiate with vulnerable servers. * This value should only be used during the transition period * when few servers have been upgraded. */ public void enableRenegotiation(int mode) throws SocketException { if (mode >= SocketBase.SSL_RENEGOTIATE_NEVER && mode <= SocketBase.SSL_RENEGOTIATE_TRANSITIONAL) { base.enableRenegotiation(mode); } else { throw new SocketException("Incorrect input value."); } } /** * Set the mode of renegotiation that the peer must use for all new * sockets. The default is never renegotiate at all. * * @param mode One of: * SSLSocket.SSL_RENEGOTIATE_NEVER - Never renegotiate at all. * * SSLSocket.SSL_RENEGOTIATE_UNRESTRICTED - Renegotiate without * restriction, whether or not the peer's hello bears the TLS * renegotiation info extension. Vulnerable, as in the past. * * SSLSocket.SSL_RENEGOTIATE_REQUIRES_XTN - Only renegotiate if the * peer's hello bears the TLS renegotiation_info extension. This is * safe renegotiation. * * SSLSocket.SSL_RENEGOTIATE_TRANSITIONAL - Disallow unsafe * renegotiation in server sockets only, but allow clients * to continue to renegotiate with vulnerable servers. * This value should only be used during the transition period * when few servers have been upgraded. */ static public void enableRenegotiationDefault(int mode) throws SocketException { if (mode >= SocketBase.SSL_RENEGOTIATE_NEVER && mode <= SocketBase.SSL_RENEGOTIATE_TRANSITIONAL) { setSSLDefaultOptionMode(SocketBase.SSL_ENABLE_RENEGOTIATION, mode); } else { throw new SocketException("Incorrect input value."); } } /** * For this socket require that the peer must send * Signaling Cipher Suite Value (SCSV) or Renegotiation Info (RI) * extension in ALL handshakes. It is disabled by default, * unless the default has been changed with * SSLSocket.enableRequireSafeNegotiationDefault. */ public void enableRequireSafeNegotiation(boolean enable) throws SocketException { base.enableRequireSafeNegotiation(enable); } /** * For this socket require that the peer must send * Signaling Cipher Suite Value (SCSV) or Renegotiation Info (RI) * extension in ALL handshakes. It is disabled by default. */ static public void enableRequireSafeNegotiationDefault(boolean enable) throws SocketException { setSSLDefaultOption(SocketBase.SSL_REQUIRE_SAFE_NEGOTIATION, enable); } /** * Enable rollback detection for this socket. * It is enabled by default, unless the default has been changed * with enableRollbackDetectionDefault. */ 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 { setSSLDefaultOption(SocketBase.SSL_ROLLBACK_DETECTION, enable); } /** * 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 * need to be generated. * If the server cert's public key is more than 512 bits, * this option has the following effect: * enable=true: generate step-down keys * enable=false: don't generate step-down keys; disable * export cipher suites * * This option is enabled by default; unless the default has * been changed with SSLSocket.enableStepDownDefault. */ 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 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 * need to be generated. * If the server cert's public key is more than 512 bits, * this option has the following effect: * enable=true: generate step-down keys * enable=false: don't generate step-down keys; disable * export cipher suites * * This option is enabled by default for all sockets. */ static void enableStepDownDefault(boolean enable) throws SocketException { setSSLDefaultOption(SocketBase.SSL_NO_STEP_DOWN, enable); } /** * 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 * with enableFDXDefault. */ public void enableFDX(boolean enable) throws SocketException { base.enableFDX(enable); } /** * 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 { 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 * with enableV2CompatibleHelloDefault. */ 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 { 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. */ 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" + ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SSL2) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_SSL3" + ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SSL3) != 0) ? "=on" : "=off")); 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"); switch (getSSLDefaultOption(SocketBase.SSL_REQUIRE_CERTIFICATE)) { case 0: buf.append("=Never"); break; case 1: buf.append("=Always"); break; case 2: buf.append("=First Handshake"); break; case 3: buf.append("=No Error"); break; default: buf.append("=Report JSS Bug this option has a status."); break; } //end switch buf.append("\nSSL_REQUEST_CERTIFICATE" + ((getSSLDefaultOption(SocketBase.SSL_REQUEST_CERTIFICATE) != 0) ? "=on" : "=off")); buf.append("\nSSL_NO_CACHE" + ((getSSLDefaultOption(SocketBase.SSL_NO_CACHE) != 0) ? "=on" : "=off")); buf.append("\nSSL_ROLLBACK_DETECTION" + ((getSSLDefaultOption(SocketBase.SSL_ROLLBACK_DETECTION) != 0) ? "=on" : "=off")); buf.append("\nSSL_NO_STEP_DOWN" + ((getSSLDefaultOption(SocketBase.SSL_NO_STEP_DOWN) != 0) ? "=on" : "=off")); 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) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_SESSION_TICKETS" + ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SESSION_TICKETS) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_RENEGOTIATION"); switch (getSSLDefaultOption(SocketBase.SSL_ENABLE_RENEGOTIATION)) { case 0: buf.append("=SSL_RENEGOTIATE_NEVER"); break; case 1: buf.append("=SSL_RENEGOTIATE_UNRESTRICTED"); break; case 2: buf.append("=SSL_RENEGOTIATE_REQUIRES_XTN"); break; case 3: buf.append("=SSL_RENEGOTIATE_TRANSITIONAL"); break; default: buf.append("=Report JSS Bug this option has a status."); break; } //end switch buf.append("\nSSL_REQUIRE_SAFE_NEGOTIATION" + ((getSSLDefaultOption(SocketBase.SSL_REQUIRE_SAFE_NEGOTIATION) != 0) ? "=on" : "=off")); } catch (SocketException e) { buf.append("\ngetSSLDefaultOptions exception " + e.getMessage()); } return buf.toString(); } /** * 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. * @deprecated use requireClientAuth(int) */ @Deprecated public void requireClientAuth(boolean require, boolean onRedo) throws SocketException { base.requireClientAuth(require, onRedo); } /** * 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 * 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, * SSLSocket.SSL_REQUIRE_NO_ERROR */ public void requireClientAuth(int mode) throws SocketException { if (mode >= SocketBase.SSL_REQUIRE_NEVER && mode <= SocketBase.SSL_REQUIRE_NO_ERROR) { base.requireClientAuth(mode); } else { throw new SocketException("Incorrect input value."); } } /** * Sets the default setting for requiring client authorization. * All subsequently created sockets will use this default setting. * @deprecated use requireClientAuthDefault(int) */ @Deprecated public void requireClientAuthDefault(boolean require, boolean onRedo) throws SocketException { setSSLDefaultOption(SocketBase.SSL_REQUIRE_CERTIFICATE, require ? (onRedo ? 1 : 2) : 0); } /** * Sets the default setting for requiring client authorization. * 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, * SSLSocket.SSL_REQUIRE_NO_ERROR */ static public void requireClientAuthDefault(int mode) throws SocketException { if (mode >= SocketBase.SSL_REQUIRE_NEVER && mode <= SocketBase.SSL_REQUIRE_NO_ERROR) { setSSLDefaultOption(SocketBase.SSL_REQUEST_CERTIFICATE, true); setSSLDefaultOptionMode(SocketBase.SSL_REQUIRE_CERTIFICATE,mode); } else { throw new SocketException("Incorrect input value."); } } /** * Force an already started SSL handshake to complete. * This method should block until the handshake has completed. */ 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 * if it is the SSL server. */ public void setUseClientMode(boolean b) { handshakeAsClient = b; } /** * @return true if this end of the socket is the SSL client, false * if it is the SSL server. */ public boolean getUseClientMode() { return handshakeAsClient; } /** * Resets the handshake state. */ public void resetHandshake() throws SocketException { resetHandshakeNative(handshakeAsClient); } private native void resetHandshakeNative(boolean asClient) throws SocketException; /** * Returns the security status of this socket. */ public native SSLSecurityStatus getStatus() throws SocketException; /** * Sets the nickname of the certificate to use for client authentication. * Alternately, you can specify an SSLClientCertificateSelectionCallback, * which will receive a list of certificates that are valid for client * authentication. * @see org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback */ public void setClientCertNickname(String nick) throws SocketException { base.setClientCertNickname(nick); } /** * Sets the certificate to use for client authentication. * Alternately, you can specify an SSLClientCertificateSelectionCallback, * which will receive a list of certificates that are valid for client * authentication. * @see org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback */ public void setClientCert( org.mozilla.jss.crypto.X509Certificate cert) throws SocketException { base.setClientCert(cert); } /** * Enables/disables the request of client authentication. 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. * @see org.mozilla.jss.ssl.SSLSocket#requireClientAuth */ public void requestClientAuth(boolean b) throws SocketException { base.requestClientAuth(b); } /** * @deprecated As of JSS 3.0. This method is misnamed. Use * requestClientAuth instead. */ @Deprecated public void setNeedClientAuth(boolean b) throws SocketException { base.requestClientAuth(b); } /** * Enables/disables the request of client authentication. 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. *

In addition, the client certificate's expiration will not * prevent it from being accepted. * @see org.mozilla.jss.ssl.SSLSocket#requireClientAuth public void requestClientAuthNoExpiryCheck(boolean b) throws SocketException { base.requestClientAuthNoExpiryCheck(b); } /** * @deprecated As of JSS 3.0. This method is misnamed. Use * requestClientAuthNoExpiryCheck instead. */ @Deprecated public void setNeedClientAuthNoExpiryCheck(boolean b) throws SocketException { base.requestClientAuthNoExpiryCheck(b); } /** * Enables/disables the session cache. By default, the session cache * is enabled. */ public void useCache(boolean b) throws SocketException { base.useCache(b); } /** * Sets the default setting for use of the session cache. */ public void useCacheDefault(boolean b) throws SocketException { setSSLDefaultOption(SocketBase.SSL_NO_CACHE, !b); } public static void setSSLVersionRangeDefault(SSLProtocolVariant ssl_variant, SSLVersionRange range) throws SocketException { if (range == null) throw new SocketException("setSSLVersionRangeDefault: range null"); setSSLVersionRangeDefault( ssl_variant.getEnum(), range.getMinVersion().value(), range.getMaxVersion().value()); } public static SSLVersionRange boundSSLVersionRange(SSLProtocolVariant ssl_variant, SSLVersionRange range) throws SocketException { if (range == null) throw new SocketException("setSSLVersionRangeDefault: range null"); return boundSSLVersionRange( ssl_variant.getEnum(), range.getMinVersion().value(), range.getMaxVersion().value()); } /** * Sets SSL Version Range Default */ private static native void setSSLVersionRangeDefault(int ssl_variant, int min, int max) throws SocketException; /** * Checks SSL Version Range against Default */ private static native SSLVersionRange boundSSLVersionRange(int ssl_variant, int min, int max) throws SocketException; private static void setSSLDefaultOption(int option, boolean on) throws SocketException { 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) throws SocketException; /** * Enables/disables the cipher on this socket. */ public native void setCipherPreference(int cipher, boolean enable) throws SocketException; /** * Returns whether this cipher is enabled or disabled on this socket. */ public native boolean getCipherPreference( int cipher) throws SocketException; /** * Sets the default for whether this cipher is enabled or disabled. */ public static native void setCipherPreferenceDefault(int cipher, boolean enable) throws SocketException; /** * Returns the default for whether this cipher is enabled or disabled. */ public static native boolean getCipherPreferenceDefault(int cipher) throws SocketException; native int socketAvailable() throws IOException; 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."); } inRead = true; } int iRet; try { iRet = socketRead(b, off, len, base.getTimeout()); } catch (SocketTimeoutException ste) { throw new SocketTimeoutException( "SocketTimeoutException cannot read on socket: " + ste); } catch (IOException ioe) { throw new IOException( "SocketException cannot read on socket: " + ioe.getMessage(), ioe); } finally { synchronized (this) { inRead = false; } } return iRet; } } 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."); } inWrite = true; } try { socketWrite(b, off, len, base.getTimeout()); } catch (SocketTimeoutException ste) { throw new SocketTimeoutException( "SocketTimeoutException cannot write on socket: " + ste); } catch (IOException ioe) { throw new IOException( "SocketException cannot write on socket: " + ioe.getMessage(), ioe); } finally { synchronized (this) { inWrite = false; } } } } private native int socketRead(byte[] b, int off, int len, int timeout) throws IOException; private native void socketWrite(byte[] b, int off, int len, int timeout) throws IOException; /** * Removes the current session from the session cache. */ public native void invalidateSession() throws SocketException; /** * Causes SSL to begin a full, new SSL 3.0 handshake from scratch * on a connection that has already completed one handshake. *

Does not flush the SSL3 cache entry first, so a full handshake * will not take place. Instead only the symmetric session keys will * be regenerated. */ public void redoHandshake() throws SocketException { redoHandshake(false); } /** * Causes SSL to begin a full, new SSL 3.0 handshake from scratch * on a connection that has already completed one handshake. * @param flushCache If true, this session will be flushed from the cache. * This will force a complete SSL handshake with a private key operation. * If false, only the session key will be regenerated. */ public native void redoHandshake(boolean flushCache) throws SocketException; /** * @deprecated finalize() in Object has been deprecated */ @Deprecated protected void finalize() throws Throwable { close(); /* in case user did not call close */ } /** * Sets the SSL cipher policy. This must be called before creating any * SSL sockets. */ public static void setCipherPolicy(CipherPolicy cp) throws SocketException { setCipherPolicyNative(cp.getEnum()); } private static native void setCipherPolicyNative(int policyEnum) throws SocketException; /** * Returns the addresses and ports of this socket * or an error message if the socket is not in a valid state. */ public String toString() { try { InetAddress inetAddr = getInetAddress(); InetAddress localAddr = getLocalAddress(); int port = getPort(); int localPort = getLocalPort(); StringBuffer buf = new StringBuffer(); buf.append("SSLSocket[addr="); buf.append(inetAddr); buf.append(",localaddr="); buf.append(localAddr); buf.append(",port="); buf.append(port); buf.append(",localport="); buf.append(localPort); buf.append("]"); return buf.toString(); } catch (Exception e) { return "Exception caught in toString(): " + e.getMessage(); } } /** * isFipsCipherSuite * *@return true if the ciphersuite isFIPS, false otherwise */ public static boolean isFipsCipherSuite(int ciphersuite) throws SocketException { return isFipsCipherSuiteNative(ciphersuite); } private static native boolean isFipsCipherSuiteNative(int ciphersuite) throws SocketException; /** * Returns a list of cipher suites that are implemented by NSS. * Each element in the array will be one of the cipher suite constants * defined in this class (for example, * TLS_RSA_WITH_AES_128_CBC_SHA). */ public static native int[] getImplementedCipherSuites(); } jss-4.6.3/org/mozilla/jss/ssl/SSLSocketException.java000066400000000000000000000021411362106420000225050ustar00rootroot00000000000000/* 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; /** * A subclass of java.net.SocketException that contains an error code * from the native (NSS/NSPR) code. These error codes are defined in the * class org.mozilla.jss.util.NativeErrcodes. * @see org.mozilla.jss.util.NativeErrcodes */ public class SSLSocketException extends java.net.SocketException { private static final long serialVersionUID = 1L; private int errcode = -1; public SSLSocketException() { super(); } public SSLSocketException(String msg) { super(msg); } public SSLSocketException(String msg, int errcode) { super(msg); this.errcode = errcode; } /** * Returns an error code, as defined in class * org.mozilla.jss.util.NativeErrcodes. * @see org.mozilla.jss.util.NativeErrcodes */ public int getErrcode() { return errcode; } } jss-4.6.3/org/mozilla/jss/ssl/SSLSocketListener.java000066400000000000000000000006361362106420000223430ustar00rootroot00000000000000/* 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); } jss-4.6.3/org/mozilla/jss/ssl/SSLTest.java000066400000000000000000000063031362106420000203210ustar00rootroot00000000000000/* 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.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Enumeration; import java.util.Hashtable; import org.mozilla.jss.CryptoManager; public class SSLTest { public static void main(String[] args) { new SSLTest(args); } private Hashtable params = new Hashtable<>(); private String[] defaults = { "port", "443", "host", "www.amazon.com", "remotehost", "www.amazon.com" }; private void initParams() { processArgs(defaults); } private void processArgs(String[] args) { int i; for(i=0; i < args.length; i+=2) { System.out.flush(); params.put(args[i], args[i+1]); } } private void dumpParams() { Enumeration _enum = params.keys(); System.out.println("Parameters:"); while (_enum.hasMoreElements() ) { String key = _enum.nextElement(); System.out.println(key + "=" + params.get(key)); } } public SSLTest(String[] args) { try { initParams(); processArgs(args); dumpParams(); CryptoManager.initialize("."); int port = Integer.valueOf(params.get("port")); Socket s = new Socket(params.get("host"), port); SSLSocket ss = new SSLSocket(s, params.get("remotehost"), null, null); ss.setSoTimeout(5000); OutputStream os = ss.getOutputStream(); String writeString = "GET / HTTP/1.0\n\n"; byte[] writeBytes = writeString.getBytes("8859_1"); os.write(writeBytes); InputStream is = ss.getInputStream(); int numRead = 0; byte[] inbuf = new byte[256]; while( (numRead = is.read(inbuf)) != -1 ) { System.out.print( new String(inbuf, 0, numRead, "UTF-8")); } ss.setKeepAlive(true); ss.setReceiveBufferSize(32000); ss.setSendBufferSize(8000); ss.setSoLinger(true, 10); ss.setTcpNoDelay(true); System.out.println("remote addr is " + ss.getInetAddress().toString()); System.out.println("remote port is " + ss.getPort()); System.out.println("local addr is " + ss.getLocalAddress().toString()); System.out.println("local port is " + ss.getLocalPort()); System.out.println("keepalive is " + ss.getKeepAlive()); System.out.println("receive buffer size is " + ss.getReceiveBufferSize()); System.out.println("send buffer size is " + ss.getSendBufferSize()); System.out.println("solinger is " + ss.getSoLinger()); System.out.println("sotimeout is " + ss.getSoTimeout()); System.out.println("tcpNoDelay is " + ss.getTcpNoDelay()); ss.shutdownInput(); ss.shutdownOutput(); ss.close(); } catch(Exception e) { e.printStackTrace(); } try { Runtime.getRuntime().gc(); }catch(Exception e) { e.printStackTrace(); } } } jss-4.6.3/org/mozilla/jss/ssl/SSLVersion.java000066400000000000000000000051251362106420000210300ustar00rootroot00000000000000/* 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 SSLVersion { /** Aliases ordering is as follows: * [0] - JSS name * [1] - JDK name */ SSL_2_0(new String[] {"SSL2", "SSLv2"}, SocketBase.SSL_LIBRARY_VERSION_2), SSL_3_0(new String[] {"SSL3", "SSLv3"}, SocketBase.SSL_LIBRARY_VERSION_3_0), TLS_1_0(new String[] {"TLS1_0", "TLSv1"}, SocketBase.SSL_LIBRARY_VERSION_TLS_1_0), TLS_1_1(new String[] {"TLS1_1", "TLSv1.1"}, SocketBase.SSL_LIBRARY_VERSION_TLS_1_1), TLS_1_2(new String[] {"TLS1_2", "TLSv1.2"}, SocketBase.SSL_LIBRARY_VERSION_TLS_1_2), TLS_1_3(new String[] {"TLS1_3", "TLSv1.3"}, SocketBase.SSL_LIBRARY_VERSION_TLS_1_3); private String[] aliases; private int value; private SSLVersion(String alias, int value) { this.aliases = new String[] {alias}; this.value = value; } private SSLVersion(String[] aliases, int value) { this.aliases = aliases; this.value = value; } public String alias() { return aliases[0]; } public String jdkAlias() { return aliases[1]; } public String[] aliases() { return aliases; } public int value() { return value; } public static SSLVersion valueOf(int value) { for (SSLVersion version : SSLVersion.values()) { if (version.value == value) return version; } throw new IllegalArgumentException("Invalid SSLVersion value: " + value); } public boolean matchesAlias(String value) { for (String alias : aliases) { if (alias != null && alias.equalsIgnoreCase(value)) { return true; } } return false; } public static SSLVersion findByAlias(String alias) { alias = alias.toUpperCase(); // find by alias for (SSLVersion version : SSLVersion.values()) { if (version.matchesAlias(alias)) { return version; } } // find by name return SSLVersion.valueOf(alias); } public static SSLVersion maxSupported() { SSLVersion result = null; for (SSLVersion v : SSLVersion.values()) { if (result == null || v.compareTo(result) > 0) { result = v; } } return result; } public static SSLVersion minSupported() { return SSLVersion.TLS_1_0; } } jss-4.6.3/org/mozilla/jss/ssl/SSLVersionRange.c000066400000000000000000000025541362106420000213110ustar00rootroot00000000000000#include #include #include #include "SSLVersionRange.h" #include "java_ids.h" #include "jssl.h" jobject JSS_SSL_wrapVersionRange(JNIEnv *env, SSLVersionRange vrange) { jobject versionRange = NULL; jclass versionRangeClass = NULL; jmethodID versionRangeCons = NULL; /* * Package the status into a new SSLVersionRange object. */ versionRangeClass = (*env)->FindClass(env, SSL_VERSION_RANGE_CLASS_NAME); PR_ASSERT(versionRangeClass != NULL); if (versionRangeClass == NULL) { /* exception was thrown */ goto finish; } /* * Get a reference to the constructor so we can call it. */ versionRangeCons = (*env)->GetMethodID(env, versionRangeClass, SSL_VERSION_RANGE_CONSTRUCTOR_NAME, SSL_VERSION_RANGE_CONSTRUCTOR_SIG); PR_ASSERT(versionRangeCons != NULL); if (versionRangeCons == NULL) { /* exception was thrown */ goto finish; } /* * Try constructing the new object; returns NULL when construction fails. */ versionRange = (*env)->NewObject(env, versionRangeClass, versionRangeCons, JSSL_enums_reverse(vrange.min), JSSL_enums_reverse(vrange.max)); finish: return versionRange; } jss-4.6.3/org/mozilla/jss/ssl/SSLVersionRange.h000066400000000000000000000007251362106420000213140ustar00rootroot00000000000000#include #include #include #pragma once /* Wrap a NSS SSLVersionRange object into a org.mozilla.jss.ssl.SSLVersionRange object. */ jobject JSS_SSL_wrapVersionRange(JNIEnv *env, SSLVersionRange vrange); // Not implemented: easier to do in Java /* Unwrap a org.mozilla.jss.ssl.SSLVersionRange object and return a NSS SSLVersionRange. */ /* PRStatus JSS_SSL_unwrapVersionRange(JNIEnv *env, jobject range_proxy, SSLVersionRange *vrange); */ jss-4.6.3/org/mozilla/jss/ssl/SSLVersionRange.java000066400000000000000000000054101362106420000220020ustar00rootroot00000000000000/* 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.ArrayList; public class SSLVersionRange { private SSLVersion minVersion; private SSLVersion maxVersion; /** * @deprecated Replaced with SSLVersion.SSL_3_0. */ @Deprecated public static final int ssl3 = SocketBase.SSL_LIBRARY_VERSION_3_0; /** * @deprecated Replaced with SSLVersion.TLS_1_0. */ @Deprecated public static final int tls1_0 = SocketBase.SSL_LIBRARY_VERSION_TLS_1_0; /** * @deprecated Replaced with SSLVersion.TLS_1_1. */ @Deprecated public static final int tls1_1 = SocketBase.SSL_LIBRARY_VERSION_TLS_1_1; /** * @deprecated Replaced with SSLVersion.TLS_1_2. */ @Deprecated public static final int tls1_2 = SocketBase.SSL_LIBRARY_VERSION_TLS_1_2; /** * @deprecated Replaced with SSLVersion.TLS_1_3. */ @Deprecated public static final int tls1_3 = SocketBase.SSL_LIBRARY_VERSION_TLS_1_3; public SSLVersionRange(SSLVersion minVersion, SSLVersion maxVersion) throws IllegalArgumentException { if (minVersion.value() > maxVersion.value()) { throw new IllegalArgumentException("Arguments out of range"); } this.minVersion = minVersion; this.maxVersion = maxVersion; } /** * Used by the C code, do not use it directly * @deprecated Replaced with SSLVersionRange(SSLVersion minVersion, SSLVersion maxVersion). * @param min_enum * @param max_enum * @throws IllegalArgumentException */ @Deprecated public SSLVersionRange(int min_enum, int max_enum) throws IllegalArgumentException { this(SSLVersion.valueOf(min_enum), SSLVersion.valueOf(max_enum)); } public SSLVersion getMinVersion() { return minVersion; } public SSLVersion getMaxVersion() { return maxVersion; } /** * @return enumeration value */ public int getMinEnum() { return minVersion.value(); } /** * @return enumeration value */ public int getMaxEnum() { return maxVersion.value(); } /** * Gets all of the SSLVersions in this range, including endpoints. * * @return All SSLVersions in this range */ public SSLVersion[] getAllInRange() { ArrayList result = new ArrayList(); for (SSLVersion v : SSLVersion.values()) { if (v.compareTo(this.minVersion) >= 0 && v.compareTo(this.maxVersion) <= 0) { result.add(v); } } return result.toArray(new SSLVersion[result.size()]); } } jss-4.6.3/org/mozilla/jss/ssl/SocketBase.java000066400000000000000000000402511362106420000210430ustar00rootroot00000000000000/* 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.io.IOException; import java.lang.reflect.Constructor; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Enumeration; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.X509Certificate; class SocketBase { // This is just another reference to the same proxy object // that is held by the SSLSocket or SSLServerSocket. private SocketProxy sockProxy; private int timeout; int getTimeout() { return timeout; } void setTimeout(int timeout) { this.timeout = timeout; } void setProxy(SocketProxy sockProxy) { this.sockProxy = sockProxy; } native byte[] socketCreate(Object socketObject, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback, java.net.Socket javaSock, String host, int family) throws SocketException; byte[] socketCreate(Object socketObject, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback, int family) throws SocketException { return socketCreate(socketObject, certApprovalCallback, clientCertSelectionCallback, null, null, family); } native void socketBind(byte[] addrBA, int port) throws SocketException; /** * Enums. These must match the enums table in common.c. This is * safer than copying the values of the C constants, which are subject * to change, into Java code. * Note to developer these constants are not all related! i.e. you cannot * pass in PR_SHUTDOWN_RCV to setSSLOption etc! Check their usage * in NSS and NSPR before using. */ static final int SSL_ENABLE_SSL2 = 0; static final int SSL_ENABLE_SSL3 = 1; static final int SSL_ENABLE_TLS = 2; static final int TCP_NODELAY = 3; static final int SO_KEEPALIVE = 4; static final int PR_SHUTDOWN_RCV = 5; static final int PR_SHUTDOWN_SEND = 6; static final int SSL_REQUIRE_CERTIFICATE = 7; static final int SSL_REQUEST_CERTIFICATE = 8; static final int SSL_NO_CACHE = 9; static final int SSL_POLICY_DOMESTIC = 10; static final int SSL_POLICY_EXPORT = 11; static final int SSL_POLICY_FRANCE = 12; static final int SSL_ROLLBACK_DETECTION = 13; static final int SSL_NO_STEP_DOWN = 14; static final int SSL_ENABLE_FDX = 15; static final int SSL_V2_COMPATIBLE_HELLO = 16; static final int SSL_REQUIRE_NEVER = 17; static final int SSL_REQUIRE_ALWAYS = 18; static final int SSL_REQUIRE_FIRST_HANDSHAKE = 19; static final int SSL_REQUIRE_NO_ERROR = 20; static final int SSL_ENABLE_SESSION_TICKETS = 21; static final int SSL_ENABLE_RENEGOTIATION = 22; static final int SSL_RENEGOTIATE_NEVER = 23; static final int SSL_RENEGOTIATE_UNRESTRICTED = 24; static final int SSL_RENEGOTIATE_REQUIRES_XTN = 25; static final int SSL_RENEGOTIATE_TRANSITIONAL = 26; static final int SSL_REQUIRE_SAFE_NEGOTIATION = 27; /* ssl/sslproto.h for supporting SSLVersionRange */ static final int SSL_LIBRARY_VERSION_2 = 28; static final int SSL_LIBRARY_VERSION_3_0 = 29; static final int SSL_LIBRARY_VERSION_TLS_1_0 = 30; static final int SSL_LIBRARY_VERSION_TLS_1_1 = 31; static final int SSL_LIBRARY_VERSION_TLS_1_2 = 32; static final int SSL_LIBRARY_VERSION_TLS_1_3 = 35; /* ssl/sslt.h */ static final int SSL_Variant_Stream = 33; static final int SSL_Variant_Datagram = 34; static final int SSL_AF_INET = 50; static final int SSL_AF_INET6 = 51; void close() throws IOException { socketClose(); } // SSLServerSocket and SSLSocket close methods // have their own synchronization control that // protects SocketBase.socketClose. native void socketClose() throws IOException; private boolean requestingClientAuth = false; void requestClientAuth(boolean b) throws SocketException { requestingClientAuth = b; setSSLOption(SSL_REQUEST_CERTIFICATE, b); } public void requestClientAuthNoExpiryCheck(boolean b) throws SocketException { requestingClientAuth = b; requestClientAuthNoExpiryCheckNative(b); } private native void requestClientAuthNoExpiryCheckNative(boolean b) throws SocketException; void enableSSL2(boolean enable) throws SocketException { setSSLOption(SSL_ENABLE_SSL2, enable); } void enableSSL3(boolean enable) throws SocketException { setSSLOption(SSL_ENABLE_SSL3, enable); } void enableTLS(boolean enable) throws SocketException { setSSLOption(SSL_ENABLE_TLS, enable); } void enableSessionTickets(boolean enable) throws SocketException { setSSLOption(SSL_ENABLE_SESSION_TICKETS, enable); } void enableRenegotiation(int mode) throws SocketException { setSSLOptionMode(SocketBase.SSL_ENABLE_RENEGOTIATION, mode); } void enableRequireSafeNegotiation(boolean enable) throws SocketException { setSSLOption(SSL_REQUIRE_SAFE_NEGOTIATION, enable); } void enableRollbackDetection(boolean enable) throws SocketException { setSSLOption(SSL_ROLLBACK_DETECTION, enable); } void enableStepDown(boolean enable) throws SocketException { setSSLOption(SSL_NO_STEP_DOWN, enable); } void enableFDX(boolean enable) throws SocketException { setSSLOption(SSL_ENABLE_FDX, enable); } void enableV2CompatibleHello(boolean enable) throws SocketException { setSSLOption(SSL_V2_COMPATIBLE_HELLO, enable); } void setSSLOption(int option, boolean on) throws SocketException { setSSLOption(option, on ? 1 : 0); } /** * Sets SSL options for this socket that have simple * enable/disable values. */ native void setSSLOption(int option, int on) throws SocketException; void setSSLVersionRange(SSLVersionRange range) throws SocketException { setSSLVersionRange(range.getMinVersion().value(), range.getMaxVersion().value()); } /** * Sets SSL Version Range for this socket to support TLS v1.1 to v1.3 */ native void setSSLVersionRange(int min, int max) throws SocketException; /** * Sets the SSL option setting mode value use for options * that have more values than just enable/disable. */ native void setSSLOptionMode(int option, int option2) throws SocketException; /* return 0 for option disabled 1 for option enabled. */ native int getSSLOption(int option) throws SocketException; public String getSSLOptions() { StringBuffer buf = new StringBuffer(); try { buf.append("SSL Options configured for this SSLSocket:"); buf.append("\nSSL_ENABLE_SSL2" + ((getSSLOption(SocketBase.SSL_ENABLE_SSL2) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_SSL3" + ((getSSLOption(SocketBase.SSL_ENABLE_SSL3) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_TLS" + ((getSSLOption(SocketBase.SSL_ENABLE_TLS) != 0) ? "=on" : "=off")); buf.append("\nSSL_REQUIRE_CERTIFICATE"); switch (getSSLOption(SocketBase.SSL_REQUIRE_CERTIFICATE)) { case 0: buf.append("=Never"); break; case 1: buf.append("=Always"); break; case 2: buf.append("=First Handshake"); break; case 3: buf.append("=No Error"); break; default: buf.append("=Report JSS Bug this option has a status."); break; } //end switch buf.append("\nSSL_REQUEST_CERTIFICATE" + ((getSSLOption(SocketBase.SSL_REQUEST_CERTIFICATE) != 0) ? "=on" : "=off")); buf.append("\nSSL_NO_CACHE" + ((getSSLOption(SocketBase.SSL_NO_CACHE) != 0) ? "=on" : "=off")); buf.append("\nSSL_ROLLBACK_DETECTION" + ((getSSLOption(SocketBase.SSL_ROLLBACK_DETECTION) != 0) ? "=on" : "=off")); buf.append("\nSSL_NO_STEP_DOWN" + ((getSSLOption(SocketBase.SSL_NO_STEP_DOWN) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_FDX" + ((getSSLOption(SocketBase.SSL_ENABLE_FDX) != 0) ? "=on" : "=off")); buf.append("\nSSL_V2_COMPATIBLE_HELLO" + ((getSSLOption(SocketBase.SSL_V2_COMPATIBLE_HELLO) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_SESSION_TICKETS" + ((getSSLOption(SocketBase.SSL_ENABLE_SESSION_TICKETS) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_RENEGOTIATION"); switch (getSSLOption(SocketBase.SSL_ENABLE_RENEGOTIATION)) { case 0: buf.append("=SSL_RENEGOTIATE_NEVER"); break; case 1: buf.append("=SSL_RENEGOTIATE_UNRESTRICTED"); break; case 2: buf.append("=SSL_RENEGOTIATE_REQUIRES_XTN"); break; case 3: buf.append("=SSL_RENEGOTIATE_TRANSITIONAL"); break; default: buf.append("=Report JSS Bug this option has a status."); break; } //end switch buf.append("\nSSL_REQUIRE_SAFE_NEGOTIATION" + ((getSSLOption(SocketBase.SSL_REQUIRE_SAFE_NEGOTIATION) != 0) ? "=on" : "=off")); } catch (SocketException e) { buf.append("\ngetSSLOptions exception " + e.getMessage()); } return buf.toString(); } /** * Converts a host-ordered 4-byte internet address into an InetAddress. * Unfortunately InetAddress provides no more efficient means * of construction than getByName(), and it is final. * * @return The InetAddress corresponding to the given integer, * or null if the InetAddress could not be constructed. */ private static InetAddress convertIntToInetAddress(int intAddr) { InetAddress in; int[] addr = new int[4]; addr[0] = ((intAddr >>> 24) & 0xff); addr[1] = ((intAddr >>> 16) & 0xff); addr[2] = ((intAddr >>> 8) & 0xff); addr[3] = ((intAddr) & 0xff); try { in = InetAddress.getByName( addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3]); } catch (java.net.UnknownHostException e) { in = null; } return in; } private native byte[] getLocalAddressByteArrayNative() throws SocketException; private native byte[] getPeerAddressByteArrayNative() throws SocketException; /** * @return the InetAddress of the peer end of the socket. */ InetAddress getInetAddress() { try { byte[] address = getPeerAddressByteArrayNative(); InetAddress iAddr = null; try { iAddr = InetAddress.getByAddress(address); } catch (UnknownHostException e) { } return iAddr; } catch (SocketException e) { return null; } } private native int getPeerAddressNative() throws SocketException; /** * @return The local IP address. */ InetAddress getLocalAddress() { try { byte[] address = getLocalAddressByteArrayNative(); InetAddress lAddr = null; try { lAddr = InetAddress.getByAddress(address); } catch (UnknownHostException e) { } return lAddr; } catch (SocketException e) { return null; } } private native int getLocalAddressNative() throws SocketException; public int getLocalPort() { try { return getLocalPortNative(); } catch (SocketException e) { return 0; } } private native int getLocalPortNative() throws SocketException; void requireClientAuth(boolean require, boolean onRedo) throws SocketException { if (require && !requestingClientAuth) { requestClientAuth(true); } setSSLOption(SSL_REQUIRE_CERTIFICATE, require ? (onRedo ? 1 : 2) : 0); } void requireClientAuth(int mode) throws SocketException { if (mode > 0 && !requestingClientAuth) { requestClientAuth(true); } setSSLOptionMode(SocketBase.SSL_REQUIRE_CERTIFICATE, mode); } /** * Sets the nickname of the certificate to use for client authentication. */ public void setClientCertNickname(String nick) throws SocketException { try { CryptoManager cm = CryptoManager.getInstance(); X509Certificate cert = cm.findCertByNickname(nick); setClientCert(cert); } catch (NotInitializedException nie) { throw new RuntimeException(nie); } catch (ObjectNotFoundException onfe) { throw new RuntimeException(onfe); } catch (TokenException te) { throw new RuntimeException(te); } } native void setClientCert(org.mozilla.jss.crypto.X509Certificate cert) throws SocketException; void useCache(boolean b) throws SocketException { setSSLOption(SSL_NO_CACHE, !b); } static Throwable processExceptions(Throwable topException, Throwable bottomException) { try { StringBuffer strBuf; strBuf = new StringBuffer(topException.toString()); if (bottomException != null) { strBuf.append(" --> "); strBuf.append(bottomException.toString()); } Class excepClass = topException.getClass(); Class stringClass = java.lang.String.class; Constructor cons = excepClass.getConstructor(new Class[] { stringClass }); return (Throwable) cons.newInstance(new Object[] { strBuf.toString() }); } catch (Exception e) { throw new RuntimeException("Problem constructing exception container: " + e.getMessage(), e); //return topException; } } static private int supportsIPV6 = -1; static boolean supportsIPV6() { if (supportsIPV6 >= 0) { if (supportsIPV6 > 0) { return true; } else { return false; } } Enumeration netInter; try { netInter = NetworkInterface.getNetworkInterfaces(); } catch (SocketException e) { return false; } while (netInter.hasMoreElements()) { NetworkInterface ni = netInter.nextElement(); Enumeration addrs = ni.getInetAddresses(); while (addrs.hasMoreElements()) { InetAddress o = addrs.nextElement(); if (o.getClass() == Inet6Address.class) { supportsIPV6 = 1; return true; } } } supportsIPV6 = 0; return false; } } jss-4.6.3/org/mozilla/jss/ssl/SocketProxy.java000066400000000000000000000007721362106420000213160ustar00rootroot00000000000000/* 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; class SocketProxy extends org.mozilla.jss.util.NativeProxy { public SocketProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); } } jss-4.6.3/org/mozilla/jss/ssl/TestCertApprovalCallback.java000066400000000000000000000045261362106420000237040ustar00rootroot00000000000000/* 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.Enumeration; import org.mozilla.jss.crypto.InternalCertificate; /** * This is a test implementation of the certificate approval callback which * gets invoked when the server presents a certificate which is not * trusted by the client */ public class TestCertApprovalCallback implements SSLCertificateApprovalCallback { public boolean approve( org.mozilla.jss.crypto.X509Certificate servercert, SSLCertificateApprovalCallback.ValidityStatus status) { SSLCertificateApprovalCallback.ValidityItem item; System.out.println("in TestCertApprovalCallback.approve()"); /* dump out server cert details */ System.out.println("Peer cert details: "+ "\n subject: "+servercert.getSubjectDN().toString()+ "\n issuer: "+servercert.getIssuerDN().toString()+ "\n serial: "+servercert.getSerialNumber().toString() ); /* iterate through all the problems */ boolean trust_the_server_cert=false; Enumeration errors = status.getReasons(); int i=0; while (errors.hasMoreElements()) { i++; item = errors.nextElement(); System.out.println("item "+i+ " reason="+item.getReason()+ " depth="+item.getDepth()); org.mozilla.jss.crypto.X509Certificate cert = item.getCert(); if (item.getReason() == SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER) { trust_the_server_cert = true; } System.out.println(" cert details: "+ "\n subject: "+cert.getSubjectDN().toString()+ "\n issuer: "+cert.getIssuerDN().toString()+ "\n serial: "+cert.getSerialNumber().toString() ); } if (trust_the_server_cert) { System.out.println("importing certificate."); try { InternalCertificate newcert = org.mozilla.jss.CryptoManager.getInstance(). importCertToPerm(servercert,"testnick"); newcert.setSSLTrust(InternalCertificate.TRUSTED_PEER | InternalCertificate.VALID_PEER); } catch (Exception e) { System.out.println("thrown exception: "+e); } } /* allow the connection to continue. returning false here would abort the connection */ return true; } } jss-4.6.3/org/mozilla/jss/ssl/TestClientCertificateSelectionCallback.java000066400000000000000000000032661362106420000265310ustar00rootroot00000000000000/* 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.Enumeration; import java.util.Vector; /** * This interface is what you should implement if you want to * be able to decide whether or not you want to approve the peer's cert, * instead of having NSS do that. */ public class TestClientCertificateSelectionCallback implements SSLClientCertificateSelectionCallback { /** * this method will be called form the native callback code * when a certificate is requested. You must return a String * which is the nickname of the certificate you wish to present. * * @param nicknames A Vector of Strings. These strings are an * aid to the user to select the correct nickname. This list is * made from the list of all certs which are valid, match the * CA's trusted by the server, and which you have the private * key of. If nicknames.length is 0, you should present an * error to the user saying 'you do not have any unexpired * certificates'. * @return You must return the nickname of the certificate you * wish to use. You can return null if you do not wish to send * a certificate. */ public String select(Vector nicknames) { Enumeration e = nicknames.elements(); String s="",first=null; System.out.println("in TestClientCertificateSelectionCallback.select() "+s); while (e.hasMoreElements()) { s = e.nextElement(); if (first == null) { first = s; } System.out.println(" "+s); } return first; } } jss-4.6.3/org/mozilla/jss/ssl/callbacks.c000066400000000000000000000603251362106420000202440ustar00rootroot00000000000000/* 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/. */ #include #include #include #include #include #include #include #include #include #include #include #include "jssl.h" #include #include #include #include int JSSL_getOCSPPolicy() { JNIEnv *env; jint policy = -1; jmethodID getOCSPPolicyID; jclass cryptoManagerClass; /* get the JNI environment */ if((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != 0){ PR_ASSERT(PR_FALSE); goto finish; } cryptoManagerClass = (*env)->FindClass(env, CRYPTO_MANAGER_NAME); if( cryptoManagerClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } getOCSPPolicyID = (*env)->GetStaticMethodID(env, cryptoManagerClass, GET_OCSP_POLICY_NAME,GET_OCSP_POLICY_SIG); if( getOCSPPolicyID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } policy = (*env)->CallStaticIntMethod(env, cryptoManagerClass, getOCSPPolicyID); finish: return (int) policy; } static SECStatus secCmpCertChainWCANames(CERTCertificate *cert, CERTDistNames *caNames) { SECItem * caname; CERTCertificate * curcert; CERTCertificate * oldcert; PRUint32 contentlen; int j; int headerlen; int depth; SECStatus rv; SECItem issuerName; SECItem compatIssuerName; depth=0; curcert = CERT_DupCertificate(cert); while( curcert ) { issuerName = curcert->derIssuer; /* compute an alternate issuer name for compatibility with 2.0 * enterprise server, which send the CA names without * the outer layer of DER header */ rv = DER_Lengths(&issuerName, &headerlen, &contentlen); if ( rv == SECSuccess ) { compatIssuerName.data = &issuerName.data[headerlen]; compatIssuerName.len = issuerName.len - headerlen; } else { compatIssuerName.data = NULL; compatIssuerName.len = 0; } for (j = 0; j < caNames->nnames; j++) { caname = &caNames->names[j]; if (SECITEM_CompareItem(&issuerName, caname) == SECEqual) { rv = SECSuccess; CERT_DestroyCertificate(curcert); goto done; } else if (SECITEM_CompareItem(&compatIssuerName, caname) == SECEqual) { rv = SECSuccess; CERT_DestroyCertificate(curcert); goto done; } } if ( ( depth <= 20 ) && ( SECITEM_CompareItem(&curcert->derIssuer, &curcert->derSubject) != SECEqual ) ) { oldcert = curcert; curcert = CERT_FindCertByName(curcert->dbhandle, &curcert->derIssuer); CERT_DestroyCertificate(oldcert); depth++; } else { CERT_DestroyCertificate(curcert); curcert = NULL; } } rv = SECFailure; done: return rv; } /* * This callback is called when the peer has request you to send you * client-auth certificate. You get to pick which one you want * to send. * * Expected return values: * 0 SECSuccess * -1 SECFailure - No suitable certificate found. * -2 SECWouldBlock (we're waiting while we ask the user). */ SECStatus JSSL_CallCertSelectionCallback( void * arg, PRFileDesc * fd, CERTDistNames * caNames, CERTCertificate ** pRetCert, SECKEYPrivateKey ** pRetKey) { CERTCertificate * cert; PK11SlotInfo * slot; SECKEYPrivateKey * privkey; jobject nicknamecallback = (jobject)arg; SECStatus rv = SECFailure; CERTCertNicknames * names; int i; int count =0; jclass vectorclass; jmethodID vectorcons; jobject vector; jmethodID vector_add; jstring nickname_string; jstring chosen_nickname; const char *chosen_nickname_for_c; jclass clientcertselectionclass; jmethodID clientcertselectionclass_select; JNIEnv *env; int debug_cc=0; if((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != 0){ PR_ASSERT(PR_FALSE); return SECFailure; } PR_ASSERT(env != NULL); clientcertselectionclass = (*env)->GetObjectClass(env,nicknamecallback); clientcertselectionclass_select = (*env)->GetMethodID( env, clientcertselectionclass, "select", "(Ljava/util/Vector;)Ljava/lang/String;" ); /* get java bits and piece ready to create a new vector */ vectorclass = (*env)->FindClass( env, "java/util/Vector"); if (debug_cc) { PR_fprintf(PR_STDOUT," got vectorclass: %lx\n",vectorclass); } vectorcons = (*env)->GetMethodID( env, vectorclass,"","()V"); if (debug_cc) { PR_fprintf(PR_STDOUT," got vectorcons: %lx\n",vectorcons); } vector_add = (*env)->GetMethodID( env, vectorclass, "addElement", "(Ljava/lang/Object;)V"); if (debug_cc) { PR_fprintf(PR_STDOUT," got vectoradd: %lx\n",vector_add); } /* create new vector */ vector = (*env)->NewObject( env, vectorclass, vectorcons); if (debug_cc) { PR_fprintf(PR_STDOUT," got new vector: %lx\n",vector); } /* next, get a list of all the valid nicknames */ names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(), SEC_CERT_NICKNAMES_USER, NULL /*pinarg*/); if (names != NULL) { for (i = 0; i < names->numnicknames; i++) { if (debug_cc) { PR_fprintf(PR_STDOUT,"checking nn: %s\n",names->nicknames[i]); } cert = JSS_PK11_findCertAndSlotFromNickname( names->nicknames[i], NULL /*pinarg*/, &slot); if ( !cert ) continue; /* Only check unexpired certs */ if ( CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE /*allowOverride*/) != secCertTimeValid ) { if (debug_cc) { PR_fprintf(PR_STDOUT," not valid\n"); } CERT_DestroyCertificate(cert); PK11_FreeSlot(slot); continue; } rv = secCmpCertChainWCANames(cert, caNames); if ( rv == SECSuccess ) { if (debug_cc) { PR_fprintf(PR_STDOUT," matches ca name\n"); } privkey = PK11_FindPrivateKeyFromCert(slot, cert, NULL /*pinarg*/); /* just test if we have the private key */ if ( privkey ) { count++; if (debug_cc) { PR_fprintf(PR_STDOUT," found privkey\n"); } SECKEY_DestroyPrivateKey(privkey); /* if we have, then this nickname has passed all the tests necessary to put it in the list */ nickname_string = (*env)->NewStringUTF(env, names->nicknames[i]); if (debug_cc) { PR_fprintf(PR_STDOUT," calling vector_add\n"); } (*env)->CallVoidMethod(env,vector,vector_add, nickname_string ); if (debug_cc) { PR_fprintf(PR_STDOUT," back from vector_add\n"); } } } CERT_DestroyCertificate(cert); PK11_FreeSlot(slot); } CERT_FreeNicknames(names); } /* okay - so we made a vector of the certs - now call the java class to figure out which one to send */ chosen_nickname = (*env)->CallObjectMethod(env,nicknamecallback, clientcertselectionclass_select, vector ); chosen_nickname_for_c = JSS_RefJString(env, chosen_nickname); if (chosen_nickname_for_c == NULL) { return SECFailure; } if (debug_cc) { PR_fprintf(PR_STDOUT," chosen nickname: %s\n",chosen_nickname_for_c); } cert = JSS_PK11_findCertAndSlotFromNickname(chosen_nickname_for_c, NULL /*pinarg*/, &slot); if (debug_cc) { PR_fprintf(PR_STDOUT," found certificate\n"); } JSS_DerefJString(env, chosen_nickname, chosen_nickname_for_c); if (cert == NULL) { return SECFailure; } privkey = PK11_FindPrivateKeyFromCert(slot, cert, NULL /*pinarg*/); PK11_FreeSlot(slot); if ( privkey == NULL ) { CERT_DestroyCertificate(cert); return SECFailure; } if (debug_cc) { PR_fprintf(PR_STDOUT," found privkey. returning\n"); } *pRetCert = cert; *pRetKey = privkey; rv = SECSuccess; 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; 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); /* Fast return when assumptions are incorrect. */ if (socket == NULL || socket->socketObject == NULL || rc != JNI_OK || env == NULL) { return; } /* 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, "", "(L" SSLSOCKET_CLASS ";II)V"); PR_ASSERT(eventConstructor != NULL); event = (*env)->NewObject(env, eventClass, eventConstructor, socket->socketObject, (int)alert->level, (int)alert->description); PR_ASSERT(event != NULL); /* 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); /* Fast return when assumptions are incorrect. */ if (socket == NULL || socket->socketObject == NULL || rc != JNI_OK || env == NULL) { return; } /* 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, "", "(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) { JSSL_SocketData *sock = (JSSL_SocketData*) arg; jclass sockClass; jmethodID notifierID; JNIEnv *env; PR_ASSERT(sock!=NULL); /* get the JNI environment */ if((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != 0){ PR_ASSERT(PR_FALSE); goto finish; } PR_ASSERT(env != NULL); /* get the handshake notification method ID */ PR_ASSERT(sock->socketObject!=NULL); sockClass = (*env)->GetObjectClass(env, sock->socketObject); notifierID = (*env)->GetMethodID(env, sockClass, SSLSOCKET_HANDSHAKE_NOTIFIER_NAME, SSLSOCKET_HANDSHAKE_NOTIFIER_SIG); if(notifierID == NULL) goto finish; /* call the handshake notification method */ (*env)->CallVoidMethod(env, sock->socketObject, notifierID); finish: return; } /* * Callback from SSL for checking certificate the peer (other end of * the socket) presents. */ SECStatus JSSL_DefaultCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) { char * hostname = NULL; SECStatus rv = SECFailure; SECCertUsage certUsage; CERTCertificate *peerCert=NULL; int ocspPolicy = JSSL_getOCSPPolicy(); certUsage = isServer ? certUsageSSLClient : certUsageSSLServer; /* PKIX call needs a SECCertificate usage, convert */ SECCertificateUsage certificateUsage = (SECCertificateUsage)1 << certUsage; /* SSL_PeerCertificate() returns a shallow copy of the cert, so we must destroy it before we exit this function */ peerCert = SSL_PeerCertificate(fd); if (peerCert) { if( ocspPolicy == OCSP_LEAF_AND_CHAIN_POLICY) { rv = JSSL_verifyCertPKIX( peerCert, certificateUsage, NULL /* pin arg */, ocspPolicy, NULL, NULL); } else { rv = CERT_VerifyCertNow(CERT_GetDefaultCertDB(), peerCert, checkSig, certUsage, NULL /*pinarg*/); } } /* if we're a server, then we don't need to check the CN of the certificate, so we can just return whatever returncode we have now */ if ( rv != SECSuccess || isServer ) { if (peerCert) { CERT_DestroyCertificate(peerCert); } return (int)rv; } /* cert is OK. This is the client side of an SSL connection. * Now check the name field in the cert against the desired hostname. * NB: This is our only defense against Man-In-The-Middle (MITM) attacks! */ hostname = SSL_RevealURL(fd); /* really is a hostname, not a URL */ if (hostname && hostname[0]) { rv = CERT_VerifyCertName(peerCert, hostname); PORT_Free(hostname); } else rv = SECFailure; if (peerCert) CERT_DestroyCertificate(peerCert); return rv; } static void addToVerifyLog(JNIEnv *env, CERTVerifyLog *log, CERTCertificate *cert, unsigned long error, unsigned int depth) { CERTVerifyLogNode *node, *tnode; PR_ASSERT(log != NULL); PL_ARENA_ALLOCATE(node, log->arena, sizeof(CERTVerifyLogNode)); if ( node == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); return; } node->cert = CERT_DupCertificate(cert); node->error = error; node->depth = depth; node->arg = NULL; if ( log->tail == NULL ) { /* empty list */ log->head = log->tail = node; node->prev = NULL; node->next = NULL; } else if ( depth >= log->tail->depth ) { /* add to tail */ node->prev = log->tail; log->tail->next = node; log->tail = node; node->next = NULL; } else if ( depth < log->head->depth ) { /* add at head */ node->prev = NULL; node->next = log->head; log->head->prev = node; log->head = node; } else { /* add in middle */ tnode = log->tail; while ( tnode != NULL ) { if ( depth >= tnode->depth ) { /* insert after tnode */ node->prev = tnode; node->next = tnode->next; tnode->next->prev = node; tnode->next = node; break; } tnode = tnode->prev; } } log->count++; } /* * Callback from SSL for checking a (possibly) expired * certificate the peer presents. * * obj - a jobject -> instance of a class implementing * the SSLCertificateApprovalCallback interface */ SECStatus JSSL_JavaCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) { CERTCertificate *peerCert=NULL; CERTVerifyLog log; JNIEnv *env; jobject validityStatus; jmethodID addReasonMethod; int certUsage; int checkcn_rv; jmethodID approveMethod; jboolean result; char *hostname=NULL; SECStatus retval = SECFailure; SECStatus verificationResult; PR_ASSERT(arg != NULL); PR_ASSERT(fd != NULL); /* initialize logging structures */ log.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if( log.arena == NULL ) return SECFailure; log.head = NULL; log.tail = NULL; log.count = 0; int ocspPolicy = JSSL_getOCSPPolicy(); /* get the JNI environment */ if((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != 0){ PR_ASSERT(PR_FALSE); goto finish; } /* First, get a handle on the cert that the peer presented */ peerCert = SSL_PeerCertificate(fd); /* if peer didn't present a cert, why am I called? */ if (peerCert == NULL) goto finish; certUsage = isServer ? certUsageSSLClient : certUsageSSLServer; /* PKIX call needs a SECCertificate usage, convert */ SECCertificateUsage certificateUsage = (SECCertificateUsage)1 << certUsage; /* * verify it against current time - (can't use * CERT_VerifyCertNow() since it doesn't allow passing of * logging parameter) */ if( ocspPolicy == OCSP_LEAF_AND_CHAIN_POLICY) { verificationResult = JSSL_verifyCertPKIX( peerCert, certificateUsage, NULL /* pin arg */, ocspPolicy, &log, NULL); } else { verificationResult = CERT_VerifyCert( CERT_GetDefaultCertDB(), peerCert, checkSig, certUsage, PR_Now(), NULL /*pinarg*/, &log); } if (verificationResult == SECSuccess && log.count > 0) { verificationResult = SECFailure; } /* * Verify the domain name of the cert. */ hostname = SSL_RevealURL(fd); /* really is a hostname, not a URL */ if (hostname && hostname[0]) { checkcn_rv = CERT_VerifyCertName(peerCert, hostname); PORT_Free(hostname); } else { checkcn_rv = SECFailure; } if (checkcn_rv != SECSuccess) { addToVerifyLog(env, &log,peerCert,SSL_ERROR_BAD_CERT_DOMAIN,0); if((*env)->ExceptionOccurred(env) != NULL) goto finish; verificationResult = SECFailure; } /* * create a new ValidityStatus object */ { jclass clazz; jmethodID cons; clazz = (*env)->FindClass(env, SSLCERT_APP_CB_VALIDITY_STATUS_CLASS); if( clazz == NULL ) goto finish; cons = (*env)->GetMethodID(env, clazz, PLAIN_CONSTRUCTOR, PLAIN_CONSTRUCTOR_SIG); if( cons == NULL ) goto finish; validityStatus = (*env)->NewObject(env, clazz, cons); if( validityStatus == NULL ) { goto finish; } /* get the addReason methodID while we're at it */ addReasonMethod = (*env)->GetMethodID(env, clazz, SSLCERT_APP_CB_VALIDITY_STATUS_ADD_REASON_NAME, SSLCERT_APP_CB_VALIDITY_STATUS_ADD_REASON_SIG); if( addReasonMethod == NULL ) { goto finish; } } /* * Load up the ValidityStatus object with all the reasons for failure */ if (verificationResult == SECFailure) { CERTVerifyLogNode *node; int error; CERTCertificate *errorcert=NULL; int depth; jobject ninjacert; node = log.head; while (node) { error = node->error; errorcert = node->cert; node->cert = NULL; depth = node->depth; ninjacert = JSS_PK11_wrapCert(env,&errorcert); (*env)->CallVoidMethod(env, validityStatus, addReasonMethod, error, ninjacert, depth ); node = node->next; } } /* * Call the approval callback */ { jobject approvalCallbackObj; jclass approvalCallbackClass; jobject peerninjacert; approvalCallbackObj = (jobject) arg; approvalCallbackClass = (*env)->GetObjectClass(env,approvalCallbackObj); approveMethod = (*env)->GetMethodID( env, approvalCallbackClass, SSLCERT_APP_CB_APPROVE_NAME, SSLCERT_APP_CB_APPROVE_SIG); if( approveMethod == NULL ) { PR_ASSERT(PR_FALSE); goto finish; } peerninjacert = JSS_PK11_wrapCert(env,&peerCert); if( peerninjacert == NULL) { PR_ASSERT(PR_FALSE); goto finish; } result = (*env)->CallBooleanMethod(env, approvalCallbackObj, approveMethod, peerninjacert, validityStatus); if( result == JNI_TRUE ) { retval = SECSuccess; } } finish: if( peerCert != NULL ) { CERT_DestroyCertificate(peerCert); } PORT_FreeArena(log.arena, PR_FALSE); return retval; } SECStatus JSSL_GetClientAuthData( void * arg, PRFileDesc * fd, CERTDistNames * caNames, CERTCertificate ** pRetCert, SECKEYPrivateKey ** pRetKey) { SECKEYPrivateKey * privkey; JSSL_SocketData * sock; SECStatus rv = SECFailure; PR_ASSERT(arg != NULL); sock = (JSSL_SocketData*) arg; if (sock->clientCert) { privkey = PK11_FindPrivateKeyFromCert(sock->clientCertSlot, sock->clientCert, NULL /*pinarg*/); if ( privkey ) { rv = SECSuccess; *pRetCert = CERT_DupCertificate(sock->clientCert); *pRetKey = privkey; } } return rv; } /* * Callback from SSL for checking a (possibly) expired * certificate the peer presents. */ SECStatus JSSL_ConfirmExpiredPeerCert(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) { SECStatus rv=SECFailure; SECCertUsage certUsage; CERTCertificate* peerCert=NULL; int64 notAfter, notBefore; certUsage = isServer ? certUsageSSLClient : certUsageSSLServer; peerCert = SSL_PeerCertificate(fd); if (peerCert) { rv = CERT_GetCertTimes(peerCert, ¬Before, ¬After); if (rv != SECSuccess) goto finish; /* * Verify the certificate based on it's expiry date. This should * always succeed, if the cert is trusted. It doesn't care if * the cert has expired. */ rv = CERT_VerifyCert(CERT_GetDefaultCertDB(), peerCert, checkSig, certUsage, notAfter, NULL /*pinarg*/, NULL /* log */); } if ( rv != SECSuccess ) goto finish; if( ! isServer ) { /* This is the client side of an SSL connection. * Now check the name field in the cert against the desired hostname. * NB: This is our only defense against Man-In-The-Middle (MITM) attacks! */ char* hostname = NULL; hostname = SSL_RevealURL(fd); /* really is a hostname, not a URL */ if (hostname && hostname[0]) { rv = CERT_VerifyCertName(peerCert, hostname); PORT_Free(hostname); } else { rv = SECFailure; } } finish: if (peerCert!=NULL) CERT_DestroyCertificate(peerCert); return rv; } jss-4.6.3/org/mozilla/jss/ssl/common.c000066400000000000000000001032601362106420000176110ustar00rootroot00000000000000/* 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/. */ #include #include #include #include #include #include #include #include #include #include #include "_jni/org_mozilla_jss_ssl_SSLSocket.h" #include "jssl.h" #include "cert.h" #ifdef WIN32 #include #endif #define SSL_AF_INET 50 #define SSL_AF_INET6 51 void JSSL_throwSSLSocketException(JNIEnv *env, char *message) { const char *errStr; PRErrorCode nativeErrcode; char *msg = NULL; int msgLen; jclass excepClass; jmethodID excepCons; jobject excepObj; jstring msgString; jint VARIABLE_MAY_NOT_BE_USED result; /* * get the error code and error string */ nativeErrcode = PR_GetError(); errStr = JSS_strerror(nativeErrcode); if( errStr == NULL ) { errStr = "Unknown error"; } /* * construct the message */ msgLen = strlen(message) + strlen(errStr) + 40; msg = PR_Malloc(msgLen); if( msg == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } PR_snprintf(msg, msgLen, "%s: (%ld) %s", message, nativeErrcode, errStr); /* * turn the message into a Java string */ msgString = (*env)->NewStringUTF(env, msg); if( msgString == NULL ) goto finish; /* * Create the exception object. Use java.net.SocketTimeoutException * for timeouts, org.mozilla.jss.ssl.SSLSocketException for everything * else. */ switch (nativeErrcode) { case PR_PENDING_INTERRUPT_ERROR : excepClass = (*env)->FindClass(env, INTERRUPTED_IO_EXCEPTION); break; case PR_IO_ERROR : excepClass = (*env)->FindClass(env, IO_EXCEPTION); break; case PR_IO_TIMEOUT_ERROR : case PR_CONNECT_TIMEOUT_ERROR : excepClass = (*env)->FindClass(env, SOCKET_TIMEOUT_EXCEPTION); break; default : /* for all other PR_ERRORs throw SocketException */ excepClass = (*env)->FindClass(env, SSLSOCKET_EXCEPTION); break; } PR_ASSERT(excepClass != NULL); if( excepClass == NULL ) goto finish; excepCons = (*env)->GetMethodID(env, excepClass, "", "(Ljava/lang/String;)V"); PR_ASSERT( excepCons != NULL ); if( excepCons == NULL ) goto finish; excepObj = (*env)->NewObject(env, excepClass, excepCons, msgString); PR_ASSERT(excepObj != NULL); if( excepObj == NULL ) goto finish; /* * throw the exception */ result = (*env)->Throw(env, excepObj); PR_ASSERT(result == 0); finish: if( msg != NULL ) { PR_Free(msg); } } /* * This is done for regular sockets that we connect() and server sockets, * but not for sockets that come from accept. */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_ssl_SocketBase_socketCreate(JNIEnv *env, jobject self, jobject sockObj, jobject certApprovalCallback, jobject clientCertSelectionCallback, jobject javaSock, jstring host,jint family) { jbyteArray sdArray = NULL; JSSL_SocketData *sockdata = NULL; SECStatus status; PRFileDesc *newFD = NULL; PRFileDesc *tmpFD = NULL; PRFilePrivate *priv = NULL; int socketFamily = 0; if (family != SSL_AF_INET6 && family != SSL_AF_INET) { JSSL_throwSSLSocketException(env, "socketCreate() Invalid family!"); goto finish; } if( family == SSL_AF_INET) socketFamily = PR_AF_INET; else socketFamily = PR_AF_INET6; if( javaSock == NULL ) { /* create a TCP socket */ newFD = PR_OpenTCPSocket(socketFamily); if( newFD == NULL ) { JSSL_throwSSLSocketException(env, "PR_NewTCPSocket() returned NULL"); goto finish; } } else { newFD = JSS_SSL_javasockToPRFD(env, javaSock); if( newFD == NULL ) { JSS_throwMsg(env, SOCKET_EXCEPTION, "failed to construct NSPR wrapper around java socket"); goto finish; } priv = newFD->secret; } /* enable SSL on the socket */ tmpFD = SSL_ImportFD(NULL, newFD); if( tmpFD == NULL ) { JSSL_throwSSLSocketException(env, "SSL_ImportFD() returned NULL"); goto finish; } newFD = tmpFD; sockdata = JSSL_CreateSocketData(env, sockObj, newFD, priv); if( sockdata == NULL ) { goto finish; } newFD = NULL; if( host != NULL ) { const char *chars; int retval; PR_ASSERT( javaSock != NULL ); chars = JSS_RefJString(env, host); retval = SSL_SetURL(sockdata->fd, chars); JSS_DerefJString(env, host, chars); if( retval ) { JSSL_throwSSLSocketException(env, "Failed to set SSL domain name"); goto finish; } } status = SSL_OptionSet(sockdata->fd, SSL_SECURITY, PR_TRUE); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Unable to enable SSL security on socket"); goto finish; } /* setup the handshake callback */ status = SSL_HandshakeCallback(sockdata->fd, JSSL_HandshakeCallback, sockdata); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Unable to install handshake callback"); goto finish; } /* setup the cert authentication callback */ if( certApprovalCallback != NULL ) { /* create global reference to the callback object */ sockdata->certApprovalCallback = (*env)->NewGlobalRef(env, certApprovalCallback); if( sockdata->certApprovalCallback == NULL ) goto finish; /* install the Java callback */ status = SSL_AuthCertificateHook( sockdata->fd, JSSL_JavaCertAuthCallback, (void*) sockdata->certApprovalCallback); } else { /* install the default callback */ status = SSL_AuthCertificateHook( sockdata->fd, JSSL_DefaultCertAuthCallback, NULL); } if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Unable to install certificate authentication callback"); goto finish; } /* setup the client cert selection callback */ if( clientCertSelectionCallback != NULL ) { /* create a new global ref */ sockdata->clientCertSelectionCallback = (*env)->NewGlobalRef(env, clientCertSelectionCallback); if(sockdata->clientCertSelectionCallback == NULL) goto finish; /* install the Java callback */ status = SSL_GetClientAuthDataHook( sockdata->fd, JSSL_CallCertSelectionCallback, (void*) sockdata->clientCertSelectionCallback); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Unable to install client certificate selection callback"); goto finish; } } /* pass the pointer back to Java */ sdArray = JSS_ptrToByteArray(env, (void*) sockdata); if( sdArray == NULL ) { /* exception was thrown */ goto finish; } finish: if( (*env)->ExceptionOccurred(env) != NULL ) { if( sockdata != NULL ) { JSSL_DestroySocketData(env, sockdata); } if( newFD != NULL ) { PR_Close(newFD); } } else { PR_ASSERT( sdArray != NULL ); } return sdArray; } JSSL_SocketData* JSSL_CreateSocketData(JNIEnv *env, jobject sockObj, PRFileDesc* newFD, PRFilePrivate *priv) { SECStatus status; JSSL_SocketData *sockdata = NULL; /* make a JSSL_SocketData structure */ sockdata = PR_Malloc( sizeof(JSSL_SocketData) ); if( sockdata == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } sockdata->fd = newFD; sockdata->socketObject = NULL; sockdata->certApprovalCallback = NULL; sockdata->clientCertSelectionCallback = NULL; sockdata->clientCert = NULL; sockdata->clientCertSlot = NULL; sockdata->jsockPriv = priv; sockdata->lock = NULL; sockdata->reader = NULL; sockdata->writer = NULL; sockdata->accepter = NULL; sockdata->closePending = PR_FALSE; sockdata->lock = PR_NewLock(); if( sockdata->lock == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* * Make a global ref to the socket. Since it is a weak reference, it will * get garbage collected if this is the only reference that remains. * We do this so that sockets will get closed when they go out of scope * in the Java layer. */ 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 ) { JSSL_DestroySocketData(env, sockdata); sockdata = NULL; } } return sockdata; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketProxy_releaseNativeResources (JNIEnv *env, jobject this) { /* SSLSocket.close and SSLServerSocket.close call */ /* SocketBase.close to destroy all native Resources */ /* attached to the socket. There is no native resource */ /* to release after close has been called. This method */ /* remains because SocketProxy extends org.mozilla.jss.util.NativeProxy*/ /* which defines releaseNativeResources as abstract and */ /* therefore must be implemented by SocketProxy */ } void JSSL_DestroySocketData(JNIEnv *env, JSSL_SocketData *sd) { PR_ASSERT(sd != NULL); PR_Close(sd->fd); if( sd->socketObject != NULL ) { DELETE_WEAK_GLOBAL_REF(env, sd->socketObject ); } if( sd->certApprovalCallback != NULL ) { (*env)->DeleteGlobalRef(env, sd->certApprovalCallback); } if( sd->clientCertSelectionCallback != NULL ) { (*env)->DeleteGlobalRef(env, sd->clientCertSelectionCallback); } if( sd->clientCert != NULL ) { CERT_DestroyCertificate(sd->clientCert); } if( sd->clientCertSlot != NULL ) { PK11_FreeSlot(sd->clientCertSlot); } if( sd->lock != NULL ) { PR_DestroyLock(sd->lock); } PR_Free(sd); } /* * These must match up with the constants defined in SocketBase.java. * Note to developer these constants are not all related! i.e. you cannot * pass in PR_SHUTDOWN_RCV to setSSLOption etc! Check their usage * in NSS and NSPR before using. */ PRInt32 JSSL_enums[] = { SSL_ENABLE_SSL2, /* 0 */ /* ssl.h */ SSL_ENABLE_SSL3, /* 1 */ /* ssl.h */ SSL_ENABLE_TLS, /* 2 */ /* ssl.h */ PR_SockOpt_NoDelay, /* 3 */ /* prio.h */ PR_SockOpt_Keepalive, /* 4 */ /* prio.h */ PR_SHUTDOWN_RCV, /* 5 */ /* prio.h */ PR_SHUTDOWN_SEND, /* 6 */ /* prio.h */ SSL_REQUIRE_CERTIFICATE, /* 7 */ /* ssl.h */ SSL_REQUEST_CERTIFICATE, /* 8 */ /* ssl.h */ SSL_NO_CACHE, /* 9 */ /* ssl.h */ SSL_POLICY_DOMESTIC, /* 10 */ /* ssl.h */ SSL_POLICY_EXPORT, /* 11 */ /* ssl.h */ SSL_POLICY_FRANCE, /* 12 */ /* ssl.h */ SSL_ROLLBACK_DETECTION, /* 13 */ /* ssl.h */ SSL_NO_STEP_DOWN, /* 14 */ /* ssl.h */ SSL_ENABLE_FDX, /* 15 */ /* ssl.h */ SSL_V2_COMPATIBLE_HELLO, /* 16 */ /* ssl.h */ SSL_REQUIRE_NEVER, /* 17 */ /* ssl.h */ SSL_REQUIRE_ALWAYS, /* 18 */ /* ssl.h */ SSL_REQUIRE_FIRST_HANDSHAKE,/* 19 */ /* ssl.h */ SSL_REQUIRE_NO_ERROR, /* 20 */ /* ssl.h */ SSL_ENABLE_SESSION_TICKETS, /* 21 */ /* ssl.h */ SSL_ENABLE_RENEGOTIATION, /* 22 */ /* ssl.h */ SSL_RENEGOTIATE_NEVER, /* 23 */ /* ssl.h */ SSL_RENEGOTIATE_UNRESTRICTED, /* 24 */ /* ssl.h */ SSL_RENEGOTIATE_REQUIRES_XTN, /* 25 */ /* ssl.h */ SSL_RENEGOTIATE_TRANSITIONAL, /* 26 */ /* ssl.h */ SSL_REQUIRE_SAFE_NEGOTIATION, /* 27 */ /* ssl.h */ SSL_LIBRARY_VERSION_2, /* 28 */ /* sslproto.h */ SSL_LIBRARY_VERSION_3_0, /* 29 */ /* sslproto.h */ SSL_LIBRARY_VERSION_TLS_1_0, /* 30 */ /* sslproto.h */ SSL_LIBRARY_VERSION_TLS_1_1, /* 31 */ /* sslproto.h */ SSL_LIBRARY_VERSION_TLS_1_2, /* 32 */ /* sslproto.h */ ssl_variant_stream, /* 33 */ /* sslt.h */ ssl_variant_datagram, /* 34 */ /* sslt.h */ SSL_LIBRARY_VERSION_TLS_1_3, /* 35 */ /* sslproto.h */ 0 }; /* * Reverses the above table mapping enum value -> NSS constant. */ int JSSL_enums_reverse(PRInt32 value) { int index = 0; for (index = 0; index < JSSL_enums_size; index++) { if (JSSL_enums[index] == value) { return index; } } return index; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_socketBind (JNIEnv *env, jobject self, jbyteArray addrBA, jint port) { JSSL_SocketData *sock; PRNetAddr addr; jbyte *addrBAelems = NULL; int addrBALen = 0; PRStatus status; jmethodID supportsIPV6ID; jclass socketBaseClass; jboolean supportsIPV6 = 0; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* * setup the PRNetAddr structure */ /* * Do we support IPV6? */ socketBaseClass = (*env)->FindClass(env, SOCKET_BASE_NAME); if( socketBaseClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } supportsIPV6ID = (*env)->GetStaticMethodID(env, socketBaseClass, SUPPORTS_IPV6_NAME, SUPPORTS_IPV6_SIG); if( supportsIPV6ID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } supportsIPV6 = (*env)->CallStaticBooleanMethod(env, socketBaseClass, supportsIPV6ID); memset( &addr, 0, sizeof( PRNetAddr )); if (addrBA != NULL) { if (!JSS_RefByteArray(env, addrBA, &addrBAelems, &addrBALen)) { ASSERT_OUTOFMEM(env); goto finish; } if (addrBALen != 4 && addrBALen != 16) { JSS_throwMsgPrErr(env, BIND_EXCEPTION, "Invalid address in bind!"); goto finish; } if( addrBALen == 4) { addr.inet.family = PR_AF_INET; addr.inet.port = PR_htons(port); memcpy(&addr.inet.ip, addrBAelems, 4); if(supportsIPV6) { addr.inet.family = PR_AF_INET6; addr.ipv6.port = PR_htons(port); PR_ConvertIPv4AddrToIPv6(addr.inet.ip,&addr.ipv6.ip); } } else { /* Must be 16 and ipv6 */ if(supportsIPV6) { addr.ipv6.family = PR_AF_INET6; addr.ipv6.port = PR_htons(port); memcpy(&addr.ipv6.ip,addrBAelems, 16); } else { JSS_throwMsgPrErr(env, BIND_EXCEPTION, "Invalid address in bind!"); goto finish; } } } else { if(supportsIPV6) { status = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, port, &addr); } else { status = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET, port, &addr); } } /* do the bind() call */ status = PR_Bind(sock->fd, &addr); if( status != PR_SUCCESS ) { JSS_throwMsgPrErr(env, BIND_EXCEPTION, "Could not bind to address"); goto finish; } finish: JSS_DerefByteArray(env, addrBA, addrBAelems, JNI_ABORT); } /* * SSLServerSocket and SSLSocket have their own synchronization * that protects SocketBase.socketClose. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_socketClose(JNIEnv *env, jobject self) { JSSL_SocketData *sock = NULL; /* get the FD */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) { /* exception was thrown */ return; } JSSL_DestroySocketData(env, sock); } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_requestClientAuthNoExpiryCheckNative (JNIEnv *env, jobject self, jboolean b) { JSSL_SocketData *sock = NULL; SECStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; /* * Set the option on the socket */ status = SSL_OptionSet(sock->fd, SSL_REQUEST_CERTIFICATE, b); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Failed to set REQUEST_CERTIFICATE option on socket"); goto finish; } if(b) { /* * Set the callback function */ status = SSL_AuthCertificateHook(sock->fd, JSSL_ConfirmExpiredPeerCert, NULL /*cx*/); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Failed to set certificate authentication callback"); goto finish; } } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_setSSLOption (JNIEnv *env, jobject self, jint option, jint on) { SECStatus status; JSSL_SocketData *sock = NULL; /* get my fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* set the option */ status = SSL_OptionSet(sock->fd, JSSL_enums[option], on); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionSet failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_setSSLOptionMode (JNIEnv *env, jobject self, jint option, jint mode) { SECStatus status; JSSL_SocketData *sock = NULL; /* get my fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* set the option */ status = SSL_OptionSet(sock->fd, JSSL_enums[option], JSSL_enums[mode]); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionSet failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SocketBase_getSSLOption(JNIEnv *env, jobject self, jint option) { JSSL_SocketData *sock = NULL; SECStatus status = SECSuccess; PRBool bOption = PR_FALSE; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* get the option */ status = SSL_OptionGet(sock->fd, JSSL_enums[option], &bOption); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionGet failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return bOption; } PRStatus JSSL_getSockAddr (JNIEnv *env, jobject self, PRNetAddr *addr, LocalOrPeer localOrPeer) { JSSL_SocketData *sock = NULL; PRStatus status=PR_FAILURE; /* get my fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* get the port */ if( localOrPeer == LOCAL_SOCK ) { status = PR_GetSockName(sock->fd, addr); } else { PR_ASSERT( localOrPeer == PEER_SOCK ); status = PR_GetPeerName(sock->fd, addr); } if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSockName failed"); } finish: EXCEPTION_CHECK(env, sock) return status; } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_ssl_SocketBase_getPeerAddressByteArrayNative (JNIEnv *env, jobject self) { jbyteArray byteArray=NULL; PRNetAddr addr; jbyte *address=NULL; int size=4; if( JSSL_getSockAddr(env, self, &addr, PEER_SOCK) != PR_SUCCESS) { goto finish; } if( PR_NetAddrFamily(&addr) == PR_AF_INET6) { size = 16; address = (jbyte *) &addr.ipv6.ip; } else { address = (jbyte *) &addr.inet.ip; } byteArray = JSS_ToByteArray(env, address, size); if (byteArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: return byteArray; } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_ssl_SocketBase_getLocalAddressByteArrayNative (JNIEnv *env, jobject self) { jbyteArray byteArray=NULL; PRNetAddr addr; jbyte *address=NULL; int size=4; if( JSSL_getSockAddr(env, self, &addr, LOCAL_SOCK) != PR_SUCCESS) { goto finish; } if( PR_NetAddrFamily(&addr) == PR_AF_INET6) { size = 16; address = (jbyte *) &addr.ipv6.ip; } else { address = (jbyte *) &addr.inet.ip; } byteArray = JSS_ToByteArray(env, address, size); if (byteArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: return byteArray; } /* Leave the original versions of these functions for compatibility */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SocketBase_getPeerAddressNative (JNIEnv *env, jobject self) { PRNetAddr addr; if( JSSL_getSockAddr(env, self, &addr, PEER_SOCK) == PR_SUCCESS) { return ntohl(addr.inet.ip); } else { return 0; } } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SocketBase_getLocalAddressNative(JNIEnv *env, jobject self) { PRNetAddr addr; if( JSSL_getSockAddr(env, self, &addr, LOCAL_SOCK) == PR_SUCCESS ) { return ntohl(addr.inet.ip); } else { return 0; } } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SocketBase_getLocalPortNative(JNIEnv *env, jobject self) { PRNetAddr addr; if( JSSL_getSockAddr(env, self, &addr, LOCAL_SOCK) == PR_SUCCESS ) { return ntohs(addr.inet.port); } else { return 0; } } /* * This is here for backwards binary compatibility: I didn't want to remove * the symbol from the DLL. This would only get called if someone were using * a pre-3.2 version of the JSS classes with this post-3.2 library. Using * different versions of the classes and the C code is not supported. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_setClientCertNicknameNative( JNIEnv *env, jobject self, jstring nick) { PR_ASSERT(0); JSS_throwMsg(env, SOCKET_EXCEPTION, "JSS JAR/DLL mismatch"); } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_setClientCert( JNIEnv *env, jobject self, jobject certObj) { JSSL_SocketData *sock = NULL; SECStatus status; CERTCertificate *cert = NULL; PK11SlotInfo *slot = NULL; if( certObj == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; /* * Store the cert and slot in the SocketData. */ if( JSS_PK11_getCertPtr(env, certObj, &cert) != PR_SUCCESS ) { goto finish; } if( JSS_PK11_getCertSlotPtr(env, certObj, &slot) != PR_SUCCESS ) { goto finish; } if( sock->clientCert != NULL ) { CERT_DestroyCertificate(sock->clientCert); } if( sock->clientCertSlot != NULL ) { PK11_FreeSlot(sock->clientCertSlot); } sock->clientCert = CERT_DupCertificate(cert); sock->clientCertSlot = PK11_ReferenceSlot(slot); /* * Install the callback. */ status = SSL_GetClientAuthDataHook(sock->fd, JSSL_GetClientAuthData, (void*)sock); if(status != SECSuccess) { JSSL_throwSSLSocketException(env, "Unable to set client auth data hook"); goto finish; } finish: EXCEPTION_CHECK(env, sock) } void JSS_SSL_processExceptions(JNIEnv *env, PRFilePrivate *priv) { jthrowable currentExcep; if( priv == NULL ) { return; } currentExcep = (*env)->ExceptionOccurred(env); (*env)->ExceptionClear(env); if( currentExcep != NULL ) { jmethodID processExcepsID; jclass socketBaseClass; jthrowable newException; socketBaseClass = (*env)->FindClass(env, SOCKET_BASE_NAME); if( socketBaseClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } processExcepsID = (*env)->GetStaticMethodID(env, socketBaseClass, PROCESS_EXCEPTIONS_NAME, PROCESS_EXCEPTIONS_SIG); if( processExcepsID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } newException = (*env)->CallStaticObjectMethod(env, socketBaseClass, processExcepsID, currentExcep, JSS_SSL_getException(priv)); if( newException == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } currentExcep = newException; } else { jthrowable excep = JSS_SSL_getException(priv); PR_ASSERT( excep == NULL ); if( excep != NULL ) { (*env)->DeleteGlobalRef(env, excep); } } finish: if( currentExcep != NULL && (*env)->ExceptionOccurred(env) == NULL) { int VARIABLE_MAY_NOT_BE_USED ret = (*env)->Throw(env, currentExcep); PR_ASSERT(ret == 0); } } /* Get the trusted anchor for pkix */ CERTCertificate *getRoot(CERTCertificate *cert, SECCertUsage certUsage) { CERTCertificate *root = NULL; CERTCertListNode *node = NULL; CERTCertList *certList = NULL; if (!cert) { goto finish; } certList = CERT_GetCertChainFromCert(cert, PR_Now(), certUsage); if (certList == NULL) { goto finish; } for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node)) { /* try to find the root */ if( node->cert && node->cert->isRoot ) { root = CERT_DupCertificate(node->cert) ; } } finish: CERT_DestroyCertList(certList); return root; } /* Internal helper for the below call. */ static SECStatus JSSL_verifyCertPKIXInternal(CERTCertificate *cert, SECCertificateUsage certificateUsage, secuPWData *pwdata, int ocspPolicy, CERTVerifyLog *log, SECCertificateUsage *usage, CERTCertList *trustedCertList) { /* Put the first set of possible flags internally here first. Later * there could be a more complete list to choose from; for now we only * support our hard core fetch AIA OCSP policy. Note that we disable * CRL fetching as Dogtag doesn't support it. Additionally, enable OCSP * checking on the chained CA certificates. Since NSS/PKIX's * CERT_GetClassicOCSPEnabledHardFailurePolicy doesn't do what we want, * we construct the policy ourselves. */ PRUint64 ocsp_Enabled_Hard_Policy_LeafFlags[2] = { /* crl */ CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD, /* ocsp */ CERT_REV_M_TEST_USING_THIS_METHOD | CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO }; PRUint64 ocsp_Enabled_Hard_Policy_ChainFlags[2] = { /* crl */ CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD, /* ocsp */ CERT_REV_M_TEST_USING_THIS_METHOD | CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO }; CERTRevocationMethodIndex ocsp_Enabled_Hard_Policy_Method_Preference[1] = { cert_revocation_method_ocsp }; CERTRevocationFlags ocsp_Enabled_Hard_Policy = { /* CERTRevocationTests - leafTests */ { /* number_of_defined_methods */ 2, /* cert_rev_flags_per_method */ ocsp_Enabled_Hard_Policy_LeafFlags, /* number_of_preferred_methods */ 1, /* preferred_methods */ ocsp_Enabled_Hard_Policy_Method_Preference, /* cert_rev_method_independent_flags */ 0 }, /* CERTRevocationTests - chainTests */ { /* number_of_defined_methods */ 2, /* cert_rev_flags_per_method */ ocsp_Enabled_Hard_Policy_ChainFlags, /* number_of_preferred_methods */ 1, /* preferred_methods */ ocsp_Enabled_Hard_Policy_Method_Preference, /* cert_rev_method_independent_flags */ 0 } }; /* The size of these objects are defined here based upon maximum possible * inputs. A dynamic allocation could reallocate based upon actual usage, * however this would affect the size by at most one or two. Note that, * due to the required usage of cert_pi_end/cert_po_end, these sizes are * inflated by one. */ CERTValOutParam cvout[3] = {{0}}; CERTValInParam cvin[6] = {{0}}; int usageIndex = -1; int inParamIndex = 0; int outParamIndex = 0; SECStatus res = SECFailure; if (cert == NULL) { goto finish; } if (ocspPolicy != OCSP_LEAF_AND_CHAIN_POLICY) { goto finish; } /* Enable live AIA fetching over the network. */ cvin[inParamIndex].type = cert_pi_useAIACertFetch; cvin[inParamIndex].value.scalar.b = PR_TRUE; inParamIndex++; /* By setting the time to zero, we choose the current time when the * check is performed. */ cvin[inParamIndex].type = cert_pi_date; cvin[inParamIndex].value.scalar.time = 0; inParamIndex++; /* Force the strict OCSP check on both the leaf and its chain. */ cvin[inParamIndex].type = cert_pi_revocationFlags; cvin[inParamIndex].value.pointer.revocation = &ocsp_Enabled_Hard_Policy; inParamIndex++; /* Establish a trust anchor if it is passed to us. NOTE: this trust anchor * must previously be validated before it is passed to us here. */ if (trustedCertList != NULL) { cvin[inParamIndex].type = cert_pi_trustAnchors; cvin[inParamIndex].value.pointer.chain = trustedCertList; inParamIndex++; } /* Done establishing input parameters. */ cvin[inParamIndex].type = cert_pi_end; /* When we need to log rationale for failure, pass it as an output * parameter. */ if (log != NULL) { cvout[outParamIndex].type = cert_po_errorLog; cvout[outParamIndex].value.pointer.log = log; outParamIndex ++; } /* When we need to inquire about the resulting certificate usage, pass it * here. */ if (usage != NULL) { usageIndex = outParamIndex; cvout[outParamIndex].type = cert_po_usages; cvout[outParamIndex].value.scalar.usages = 0; outParamIndex ++; } /* Done establishing output parameters. */ cvout[outParamIndex].type = cert_po_end; /* Call into NSS's PKIX library to validate our certificate. */ res = CERT_PKIXVerifyCert(cert, certificateUsage, cvin, cvout, &pwdata); finish: /* Clean up any certificates in the trusted certificate list. This was * a passed input parameter, but by taking ownership of it and clearing it, * we enable tail calls to this function. */ if (trustedCertList) { /* CERT_DestroyCertList destroys interior certs for us. */ CERT_DestroyCertList(trustedCertList); trustedCertList = NULL; } if (res == SECSuccess && usage && usageIndex != -1) { *usage = cvout[usageIndex].value.scalar.usages; } return res; } /* Verify a cert using an explicit PKIX call. For now only perform this call * when the OCSP policy is set to leaf and chain. Performs a blocking, online * OCSP status refresh. The result of this call will be a full-chain OCSP * validation. * * In the future, we'll use ocspPolicy to condition around additional policies * and handle them all with this method (and a call to PKIX). * * Note that this currently requires the certificate to be added directly * to the NSS DB. We can't otherwise validate against root certificates in * the default NSS DB. */ SECStatus JSSL_verifyCertPKIX(CERTCertificate *cert, SECCertificateUsage certificateUsage, secuPWData *pwdata, int ocspPolicy, CERTVerifyLog *log, SECCertificateUsage *usage) { SECCertUsage certUsage = certUsageSSLClient /* 0 */; /* We need to convert the SECCertificateUsage to a SECCertUsage to obtain * the root. */ SECCertificateUsage testUsage = certificateUsage; while (0 != (testUsage = testUsage >> 1)) { certUsage++; } CERTCertificate *root = getRoot(cert, certUsage); // Two cases: either the root is present, or it isn't. if (root == NULL) { /* In this case, we've had a hard time finding the root. In all * likelihood, the following call will fail to validate the end cert * as well and thus fail to validate. I don't believe there's a risk * in trying it however. */ return JSSL_verifyCertPKIXInternal(cert, certificateUsage, pwdata, ocspPolicy, log, usage, NULL); } else { /* In this case, we've found the root certificate. Before passing it * to the leaf, explicitly validate it with strict OCSP checking. Then * validate the leaf certificate with a known and trusted root * certificate. */ SECStatus ret = JSSL_verifyCertPKIXInternal(root, certificateUsageSSLCA, pwdata, ocspPolicy, log, usage, NULL); if (ret != SECSuccess) { return ret; } CERTCertList *rootList = CERT_NewCertList(); CERT_AddCertToListTail(rootList, root); return JSSL_verifyCertPKIXInternal(cert, certificateUsage, pwdata, ocspPolicy, log, usage, rootList); } } jss-4.6.3/org/mozilla/jss/ssl/javasock.c000066400000000000000000000620531362106420000201260ustar00rootroot00000000000000/* 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/. */ #include #include #include #include #include #include #include #include #include #include "jssutil.h" #include "java_ids.h" #include "jss_exceptions.h" static PRIntn invalidInt() { PR_ASSERT(!"invalidInt called"); return -1; } struct PRFilePrivate { JavaVM *javaVM; jobject sockGlobalRef; jthrowable exception; PRIntervalTime timeout; }; /* * exception should be a global ref */ void setException(JNIEnv *env, PRFilePrivate *priv, jthrowable excep) { PR_ASSERT(priv->exception == NULL); if( priv->exception != NULL) { (*env)->DeleteGlobalRef(env, priv->exception); } priv->exception = excep; } jthrowable JSS_SSL_getException(PRFilePrivate *priv) { jobject retval = priv->exception; priv->exception = NULL; return retval; } #define GET_ENV(vm, env) \ ( ((*(vm))->AttachCurrentThread((vm), (void**)&(env), NULL) == 0) ? 0 : 1 ) static PRInt32 writebuf(JNIEnv *env, PRFileDesc *fd, jobject sockObj, jbyteArray byteArray) { jmethodID getOutputStream, writeMethod; jclass sockClass, osClass; jobject outputStream; jint arrayLen=-1; PRInt32 retval; if( env == NULL ) { goto finish; } /* * get the OutputStream */ sockClass = (*env)->GetObjectClass(env, sockObj); PR_ASSERT(sockClass != NULL); getOutputStream = (*env)->GetMethodID(env, sockClass, SOCKET_GET_OUTPUT_STREAM_NAME, SOCKET_GET_OUTPUT_STREAM_SIG); if(getOutputStream == NULL) { ASSERT_OUTOFMEM(env); goto finish; } outputStream = (*env)->CallObjectMethod(env, sockObj, getOutputStream); if( outputStream == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* * get OutputStream.write */ osClass = (*env)->GetObjectClass(env, outputStream); writeMethod = (*env)->GetMethodID(env, osClass, OSTREAM_WRITE_NAME, OSTREAM_WRITE_SIG); if( writeMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } arrayLen = (*env)->GetArrayLength(env, byteArray); /* * Write bytes */ (*env)->CallVoidMethod(env, outputStream, writeMethod, byteArray, 0, arrayLen); /* this may have thrown an IO Exception */ finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = -1; PR_SetError(PR_IO_ERROR, 0); } else { retval = arrayLen; } } else { retval = -1; PR_SetError(PR_IO_ERROR, 0); } return retval; } static PRStatus processTimeout(JNIEnv *env, PRFileDesc *fd, jobject sockObj, PRIntervalTime timeout) { jclass socketClass; jmethodID setSoTimeoutMethod; jint javaTimeout; if( timeout == fd->secret->timeout ) { /* no need to change it */ goto finish; } /* * Call setSoTimeout on the Java socket */ socketClass = (*env)->GetObjectClass(env, sockObj); if( socketClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } setSoTimeoutMethod = (*env)->GetMethodID(env, socketClass, SET_SO_TIMEOUT_NAME, SET_SO_TIMEOUT_SIG); if( setSoTimeoutMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } if( timeout == PR_INTERVAL_NO_TIMEOUT ) { javaTimeout = 0; /* 0 means no timeout in Java */ } else if( timeout == PR_INTERVAL_NO_WAIT ) { PR_ASSERT(!"PR_INTERVAL_NO_WAIT not supported"); javaTimeout = 1; /* approximate with 1ms wait */ } else { javaTimeout = PR_IntervalToMilliseconds(timeout); } (*env)->CallVoidMethod(env, sockObj, setSoTimeoutMethod, javaTimeout); /* This may have thrown an exception */ fd->secret->timeout = timeout; finish: if( (*env)->ExceptionOccurred(env) ) { return PR_FAILURE; } else { return PR_SUCCESS; } } static PRInt32 jsock_write(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout) { jobject sockObj; JNIEnv *env; jbyteArray outbufArray; PRInt32 retval=-1; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); if( processTimeout(env, fd, sockObj, timeout) != PR_SUCCESS ) goto finish; /* * convert iov to java byte array */ { int iovi; jbyte *bytes; int outbufLen; for( iovi = 0, outbufLen = 0; iovi < iov_size; ++iovi) { outbufLen += iov[iovi].iov_len; } PR_ASSERT(outbufLen >= 0); outbufArray = (*env)->NewByteArray(env, outbufLen); if( outbufArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } if (!JSS_RefByteArray(env, outbufArray, &bytes, NULL)) { ASSERT_OUTOFMEM(env); goto finish; } for (iovi = 0, outbufLen = 0; iovi < iov_size; ++iovi) { memcpy(bytes+outbufLen,iov[iovi].iov_base, iov[iovi].iov_len); outbufLen += iov[iovi].iov_len; } PR_ASSERT(outbufLen == (*env)->GetArrayLength(env, outbufArray)); JSS_DerefByteArray(env, outbufArray, bytes, 0); } /* * Write bytes */ retval = writebuf(env, fd, sockObj, outbufArray); finish: /* nothing to free, nothing to return */ if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = -1; PR_SetError(PR_IO_ERROR, 0); } } else { retval = -1; PR_SetError(PR_IO_ERROR, 0); } return retval; } typedef enum { LOCAL_NAME, PEER_NAME } LocalOrPeer; static PRStatus getInetAddress(PRFileDesc *fd, PRNetAddr *addr, LocalOrPeer localOrPeer) { PRStatus status = PR_FAILURE; jobject sockObj; JNIEnv *env; jobject inetAddress; jbyteArray addrByteArray; jint port; int addrBALen = 0; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); /* * get the InetAddress and port */ { jclass sockClass = (*env)->GetObjectClass(env, sockObj); jmethodID getInetAddrMethod; jmethodID getPortMethod; const char *getAddrMethodName; const char *getPortMethodName; if( localOrPeer == LOCAL_NAME ) { getAddrMethodName = GET_LOCAL_ADDR_NAME; getPortMethodName = GET_LOCAL_PORT_NAME; } else { PR_ASSERT(localOrPeer == PEER_NAME); getAddrMethodName = GET_INET_ADDR_NAME; getPortMethodName = GET_PORT_NAME; } PR_ASSERT( sockClass != NULL ); getInetAddrMethod = (*env)->GetMethodID(env, sockClass, getAddrMethodName, GET_INET_ADDR_SIG); if( getInetAddrMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } inetAddress = (*env)->CallObjectMethod(env, sockObj, getInetAddrMethod); if( inetAddress == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } if( (*env)->ExceptionOccurred(env) ) goto finish; getPortMethod = (*env)->GetMethodID(env, sockClass, getPortMethodName, GET_PORT_SIG); if( getPortMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } port = (*env)->CallIntMethod(env, sockObj, getPortMethod); if( (*env)->ExceptionOccurred(env) ) goto finish; } /* * get the address as a byte array */ { jclass inetAddrClass = (*env)->GetObjectClass(env, inetAddress); jmethodID getAddressMethod; PR_ASSERT(inetAddrClass != NULL); getAddressMethod = (*env)->GetMethodID(env, inetAddrClass, GET_ADDR_NAME, GET_ADDR_SIG); if( getAddressMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } addrByteArray = (*env)->CallObjectMethod(env, inetAddress, getAddressMethod); if( addrByteArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } } /* * convert to a PRNetAddr */ { jbyte *addrBytes; memset(addr, 0, sizeof(PRNetAddr)); addrBALen = (*env)->GetArrayLength(env, addrByteArray); PR_ASSERT( (addrBALen == 4) || (addrBALen == 16 ) ); /* make sure you release them later */ if (!JSS_RefByteArray(env, addrByteArray, &addrBytes, NULL)) { ASSERT_OUTOFMEM(env); goto finish; } /* ip field is in network byte order */ if (addrBALen == 4) { memcpy( (void*) &addr->inet.ip, addrBytes, 4); addr->inet.family = PR_AF_INET; addr->inet.port = port; } else { memcpy( (void*) &addr->ipv6.ip,addrBytes, 16); addr->inet.family = PR_AF_INET6; addr->inet.port = port; } JSS_DerefByteArray(env, addrByteArray, addrBytes, JNI_ABORT); } status = PR_SUCCESS; finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); status = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } } else { status = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } return status; } static PRStatus jsock_getPeerName(PRFileDesc *fd, PRNetAddr *addr) { return getInetAddress(fd, addr, PEER_NAME); } static PRStatus jsock_getSockName(PRFileDesc *fd, PRNetAddr *addr) { return getInetAddress(fd, addr, LOCAL_NAME); } static PRInt32 jsock_send(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout) { JNIEnv *env; jobject sockObj; jbyteArray byteArray; PRInt32 retval = -1;; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); if( processTimeout(env, fd, sockObj, timeout) != PR_SUCCESS ) goto finish; /* * Turn buf into byte array */ byteArray = JSS_ToByteArray(env, buf, amount); if (byteArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } retval = writebuf(env, fd, sockObj, byteArray); finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = -1; PR_SetError(PR_IO_ERROR, 0); } } else { retval = -1; PR_SetError(PR_IO_ERROR, 0); } return retval; } static PRInt32 jsock_recv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout) { PRInt32 retval=-1; JNIEnv *env; jobject sockObj; jbyteArray byteArray; jobject inputStream; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); if( processTimeout(env, fd, sockObj, timeout) != PR_SUCCESS ) goto finish; /* * get InputStream */ { jclass sockClass = (*env)->GetObjectClass(env, sockObj); jmethodID getInputStreamMethod; if( sockClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } getInputStreamMethod = (*env)->GetMethodID(env, sockClass, SOCKET_GET_INPUT_STREAM_NAME, SOCKET_GET_INPUT_STREAM_SIG); if( getInputStreamMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } inputStream = (*env)->CallObjectMethod(env, sockObj, getInputStreamMethod); if( inputStream == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } } /* create new, empty byte array */ byteArray = (*env)->NewByteArray(env, amount); if( byteArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* * call read() */ { jclass isClass = (*env)->GetObjectClass(env, inputStream); jmethodID readMethod; if( isClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } readMethod = (*env)->GetMethodID(env, isClass, ISTREAM_READ_NAME, ISTREAM_READ_SIG); if( readMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } retval = (*env)->CallIntMethod(env, inputStream, readMethod, byteArray); if( (*env)->ExceptionOccurred(env) ) { goto finish; } else if( retval == -1 ) { /* Java EOF == -1, NSPR EOF == 0 */ retval = 0; } else if( retval == 0 ) { /* timeout */ PR_ASSERT( fd->secret->timeout != PR_INTERVAL_NO_TIMEOUT ); PR_SetError(PR_IO_TIMEOUT_ERROR, 0); retval = -1; } PR_ASSERT(retval <= amount); } /* * copy byte array to buf */ if( retval > 0 ) { jbyte *bytes; bytes = (*env)->GetByteArrayElements(env, byteArray, NULL); if (bytes != NULL) { memcpy(buf, bytes, retval); JSS_DerefByteArray(env, byteArray, bytes, JNI_ABORT); } else { JSS_throwMsg(env, OUT_OF_MEMORY_ERROR, "Unable to get byte array elements."); } } finish: if( env ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, excep); (*env)->ExceptionClear(env); retval = -1; PR_SetError(PR_IO_ERROR, 0); } } else { retval = -1; PR_SetError(PR_IO_ERROR, 0); } return retval; } static jboolean getBooleanProperty(JNIEnv *env, jobject sock, const char* methodName) { jclass sockClass; jmethodID method; jboolean retval = JNI_FALSE; sockClass = (*env)->GetObjectClass(env, sock); if( sockClass == NULL ) goto finish; method = (*env)->GetMethodID(env, sockClass, methodName, "()Z"); if( method == NULL ) goto finish; retval = (*env)->CallBooleanMethod(env, sock, method); finish: return retval; } static jint getIntProperty(JNIEnv *env, jobject sock, const char* methodName) { jclass sockClass; jmethodID method; jint retval=0; sockClass = (*env)->GetObjectClass(env, sock); if( sockClass == NULL ) goto finish; method = (*env)->GetMethodID(env, sockClass, methodName, "()I"); if( method == NULL ) goto finish; retval = (*env)->CallIntMethod(env, sock, method); finish: return retval; } static void setBooleanProperty(JNIEnv *env, jobject sock, const char* methodName, jboolean value) { jclass sockClass; jmethodID method; sockClass = (*env)->GetObjectClass(env, sock); if( sockClass == NULL ) goto finish; method = (*env)->GetMethodID(env, sockClass, methodName, "(Z)V"); if( method == NULL ) goto finish; (*env)->CallVoidMethod(env, sock, method, value); finish: return; } static void setIntProperty(JNIEnv *env, jobject sock, const char* methodName, jint value) { jclass sockClass; jmethodID method; sockClass = (*env)->GetObjectClass(env, sock); if( sockClass == NULL ) goto finish; method = (*env)->GetMethodID(env, sockClass, methodName, "(I)V"); if( method == NULL ) goto finish; (*env)->CallVoidMethod(env, sock, method, value); finish: return; } static void getSoLinger(JNIEnv *env, jobject sock, PRLinger *linger) { jint lingSecs; lingSecs = getIntProperty(env, sock, "getSoLinger"); if( (*env)->ExceptionOccurred(env) ) goto finish; if( lingSecs == -1 ) { linger->polarity = PR_FALSE; } else { linger->polarity = PR_TRUE; linger->linger = PR_SecondsToInterval(lingSecs); } finish: return; } static void setSoLinger(JNIEnv *env, jobject sock, PRLinger *linger) { jint lingSecs; jclass clazz; jmethodID methodID; jboolean onoff; if( linger->polarity == PR_FALSE ) { onoff = JNI_FALSE; lingSecs = 0; /* this should be ignored */ } else { onoff = JNI_TRUE; lingSecs = PR_IntervalToSeconds(linger->linger); } clazz = (*env)->GetObjectClass(env, sock); if( clazz == NULL ) goto finish; methodID = (*env)->GetMethodID(env, clazz, "setSoLinger", "(ZI)V"); if( methodID == NULL) goto finish; (*env)->CallVoidMethod(env, sock, methodID, onoff, lingSecs); finish: return; } static PRStatus jsock_getSockOpt(PRFileDesc *fd, PRSocketOptionData *data) { PRStatus retval = PR_SUCCESS; JNIEnv *env; jobject sockObj; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); switch(data->option) { case PR_SockOpt_Nonblocking: data->value.non_blocking = PR_FALSE; break; case PR_SockOpt_Keepalive: data->value.keep_alive = getBooleanProperty(env, sockObj, "getKeepAlive") == JNI_TRUE ? PR_TRUE : PR_FALSE; break; case PR_SockOpt_RecvBufferSize: data->value.send_buffer_size = getIntProperty(env, sockObj, "getReceiveBufferSize"); break; case PR_SockOpt_SendBufferSize: data->value.recv_buffer_size = getIntProperty(env, sockObj, "getSendBufferSize"); break; case PR_SockOpt_Linger: getSoLinger( env, sockObj, & data->value.linger ); break; case PR_SockOpt_NoDelay: data->value.no_delay = getBooleanProperty(env, sockObj,"getTcpNoDelay"); break; default: retval = PR_FAILURE; break; } finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } } else { retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } return retval; } static PRStatus jsock_setSockOpt(PRFileDesc *fd, PRSocketOptionData *data) { PRStatus retval = PR_SUCCESS; JNIEnv *env; jobject sockObj; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); switch(data->option) { case PR_SockOpt_Keepalive: setBooleanProperty(env, sockObj, "setKeepAlive",data->value.keep_alive); break; case PR_SockOpt_Linger: setSoLinger(env, sockObj, &data->value.linger); break; case PR_SockOpt_RecvBufferSize: setIntProperty(env, sockObj, "setReceiveBufferSize", data->value.recv_buffer_size); break; case PR_SockOpt_SendBufferSize: setIntProperty(env, sockObj, "setSendBufferSize", data->value.send_buffer_size); break; case PR_SockOpt_NoDelay: setBooleanProperty(env, sockObj, "setTcpNoDelay", data->value.no_delay); break; default: retval = PR_FAILURE; break; } finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } } else { retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } return retval; } static PRStatus jsock_close(PRFileDesc *fd) { PRStatus retval = PR_FAILURE; JNIEnv *env; jobject sockObj; jclass sockClass; jmethodID closeMethod; jthrowable excep; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); /* * Get the close method */ sockClass = (*env)->GetObjectClass(env, sockObj); if( sockClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } closeMethod = (*env)->GetMethodID(env, sockClass, SOCKET_CLOSE_NAME, SOCKET_CLOSE_SIG); if( closeMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* * call the close method */ (*env)->CallVoidMethod(env, sockObj, closeMethod); /* * Free the PRFilePrivate */ (*env)->DeleteGlobalRef(env, fd->secret->sockGlobalRef); if( (excep = JSS_SSL_getException(fd->secret)) != NULL ) { (*env)->DeleteGlobalRef(env, excep); } PR_Free(fd->secret); fd->secret = NULL; retval = PR_SUCCESS; finish: /* * If an exception was thrown, we can't put it in the fd because we * just deleted it. So instead, we're going to let it ride and check for * it up in socketClose(). */ if( env ) { if( (*env)->ExceptionOccurred(env) != NULL ) { retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } } else { retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } return retval; } static PRStatus jsock_shutdown(PRFileDesc *fd, PRShutdownHow how) { PRStatus retval = PR_FAILURE; JNIEnv *env; jobject sockObj; jmethodID methodID; jclass clazz; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); clazz = (*env)->GetObjectClass(env, sockObj); if( clazz == NULL ) goto finish; if( how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH ) { methodID = (*env)->GetMethodID(env, clazz, "shutdownOutput", "()V"); if( methodID == NULL ) goto finish; (*env)->CallVoidMethod(env, sockObj, methodID); } if( (*env)->ExceptionOccurred(env) ) goto finish; if( how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH ) { methodID = (*env)->GetMethodID(env, clazz, "shutdownInput", "()V"); if( methodID == NULL ) goto finish; (*env)->CallVoidMethod(env, sockObj, methodID); } retval = PR_SUCCESS; finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } } else { retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } return retval; } static const PRIOMethods jsockMethods = { PR_DESC_SOCKET_TCP, (PRCloseFN) jsock_close, (PRReadFN) invalidInt, (PRWriteFN) invalidInt, (PRAvailableFN) invalidInt, (PRAvailable64FN) invalidInt, (PRFsyncFN) invalidInt, (PRSeekFN) invalidInt, (PRSeek64FN) invalidInt, (PRFileInfoFN) invalidInt, (PRFileInfo64FN) invalidInt, (PRWritevFN) jsock_write, (PRConnectFN) invalidInt, (PRAcceptFN) invalidInt, (PRBindFN) invalidInt, (PRListenFN) invalidInt, (PRShutdownFN) jsock_shutdown, (PRRecvFN) jsock_recv, (PRSendFN) jsock_send, (PRRecvfromFN) invalidInt, (PRSendtoFN) invalidInt, (PRPollFN) invalidInt, (PRAcceptreadFN) invalidInt, (PRTransmitfileFN) invalidInt, (PRGetsocknameFN) jsock_getSockName, (PRGetpeernameFN) jsock_getPeerName, (PRReservedFN) invalidInt, (PRReservedFN) invalidInt, (PRGetsocketoptionFN) jsock_getSockOpt, (PRSetsocketoptionFN) jsock_setSockOpt, (PRSendfileFN) invalidInt, (PRConnectcontinueFN) invalidInt, (PRReservedFN) invalidInt, (PRReservedFN) invalidInt, (PRReservedFN) invalidInt, (PRReservedFN) invalidInt }; static void jsockDestructor(PRFileDesc *fd) { PR_ASSERT(!"This destructor shouldn't be called. close() does the work"); } PRFileDesc* JSS_SSL_javasockToPRFD(JNIEnv *env, jobject sockObj) { PRFileDesc *fd; JavaVM *vm; if( (*env)->GetJavaVM(env, &vm) != 0 ) { return NULL; } fd = PR_NEW(PRFileDesc); if( fd ) { fd->methods = &jsockMethods; fd->secret = PR_NEW(PRFilePrivate); fd->secret->sockGlobalRef = (*env)->NewGlobalRef(env, sockObj); fd->secret->javaVM = vm; fd->secret->exception = NULL; fd->secret->timeout = PR_INTERVAL_NO_TIMEOUT; fd->lower = fd->higher = NULL; fd->dtor = jsockDestructor; } else { /* OUT OF MEM */ } return fd; } jss-4.6.3/org/mozilla/jss/ssl/javax/000077500000000000000000000000001362106420000172645ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/ssl/javax/BufferPRFD.c000066400000000000000000000332571362106420000213270ustar00rootroot00000000000000#include /* Necessary for correctly propagating E_WOULDBLOCK. */ #include #include #include /* Ring buffer implementation to handle read/write calls. */ #include "j_buffer.h" #include "BufferPRFD.h" /* This struct stores all the private data we need access to from inside our * PRFileDesc calls. We store the following information: * * read_bytes -- raw buffer to read from for recv(...) calls * read_capacity -- size of read_bytes buffer * read_ptr -- location after the last character in the buffer; * i.e., location to place the next character if writing. * * write_bytes -- raw buffer to write to for send(...) calls * write_capacity -- size of write_bytes buffer * write_ptr -- location after the last character in the buffer; * i.e., location to place the next character if writing. * * peer_addr -- peer address info, truncated to 16 bytes * * As the read_* and write_* members should be provided by the creator, and * actors outside our PRFileDesc need access to this information (to add more * bytes to the read buffer when more data arrives for instance), we store * pointers and not the values themselves. * * The creator is responsible for ensuring that all data gets correctly freed * when the program exits; we will not free any of our pointers that were not * created by us. */ struct PRFilePrivate { j_buffer *read_buffer; j_buffer *write_buffer; uint8_t *peer_addr; }; // This function is provided as a stub for all unimplemented calls. static PRIntn invalidInternalCall(/* anything */) { // For debugging; any invalid calls are asserted, so we can get a full // backtrace from the debugger and _hopefully_ we can find out which call // was attempted. To enable asserts, define DEBUG or FORCE_PR_ASSERT // before loading the NSPR headers, e.g., by using the DEBUG release type // during CMake configuration time. PR_ASSERT(!"invalidInternalCall performed!"); return 0; } // This function mimics shutting down a buffer. static PRStatus PRBufferShutdown(PRFileDesc *fd, PRIntn how) { // This method has no functionality; we're a lower level under both // the SSLEngine and NSS's SSL context. When the application issues // a shutdown request, SSLEngine refuses to allow new writes (and only // reads until the remote party acknowledges the shutdown). All data // should be written into the NSS connection buffer and NSS's shutdown // should be called. At this point, there's nothing left for us to do: // there's no TCP socket we need to terminate, and we need to allow // any remaining buffered bytes to be written. So, the only thing we // can do is return success here. return PR_SUCCESS; } // This function mimics closing a buffer and frees our associated data. static PRStatus PRBufferClose(PRFileDesc *fd) { if (fd->secret != NULL) { // We intentionally don't free read_buffer or write_buffer; we assume // the caller has a copy of these data structures as well, and could // still be reading after the PRFileDesc is closed. fd->secret->read_buffer = NULL; fd->secret->write_buffer = NULL; // Free the peer address we allocated during initialiation. free(fd->secret->peer_addr); fd->secret->peer_addr = NULL; // Free our internal data structure. free(fd->secret); fd->secret = NULL; } fd->secret = NULL; return PR_SUCCESS; } // Fake getting the name of the remote peer static PRStatus PRBufferGetPeerName(PRFileDesc *fd, PRNetAddr *addr) { /* getPeerName takes a PRFileDesc and modifies the PRNetAddr with the * name of the peer. Because of the specifics of the NSS Implementation, * we return whatever name was passed to us on creation; we lack a real * TCP socket and thus a real TCP name. * * However, we have to provide the peer name as type IPv6, else it either * gets mangled by the IPv4 -> IPv6 translation or a * PR_ADDRESS_NOT_SUPPORTED_ERROR is thrown by ssl_GetPeerInfo(...). */ /* There are three main places this is called in a normal TLS connection: * * ssl_ImportFD(...) -- where the result of this function is compared * to PR_SUCCESS to see if it is connected * ssl_BeginClientHandshake(...) -- where this function sets local * values for session resumption on * the client * ssl3_HandleClientHello(...) -- where this function sets local * values for evaluating session * resumption from the client. * * Because these results have to be consistent for session resumption to * work, we must query the internal structure and return that value. * Note that it isn't a security risk if an incorrect peer_addr is * provided to us: the other party must _also_ know the session keys for * this to matter. */ // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSPR/Reference/PRNetAddr if (fd->secret == NULL || addr == NULL) { return PR_FAILURE; } PRFilePrivate *internal = fd->secret; addr->ipv6.family = PR_AF_INET6; addr->ipv6.port = 0xFFFF; addr->ipv6.flowinfo = 0x00000000; // We validate that strlen(peer_addr) <= 16 on creation by truncating // it to 16 bytes. Thus the memcpy with strlen(...) won't overflow the // size of ipv6.ip. memset(&addr->ipv6.ip, 0, 16); memcpy(&addr->ipv6.ip, internal->peer_addr, 16); return PR_SUCCESS; } // Respond to send requests static PRInt32 PRBufferSend(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout) { /* Send takes a PRFileDesc and attempts to send some amount of bytes from * the start of buf to the other party before timeout is reached. Because * we're implementing this as a buffer, copy into the buffer if there is * free space, else return EWOULDBLOCK. */ PRFilePrivate *internal = fd->secret; if (!jb_can_write(internal->write_buffer)) { /* Under correct Unix non-blocking socket semantics, if we lack data * to write, return a negative length and set EWOULDBLOCK. This is * documented in `man 2 recv`. */ PR_SetError(PR_WOULD_BLOCK_ERROR, EWOULDBLOCK); return -1; } /* By checking if we can write, we ensure we don't return 0 from * jb_write(...); otherwise, we'd violate non-blocking socket * semantics. */ return jb_write(internal->write_buffer, (const uint8_t *) buf, amount); } // Respond to write requests static PRInt32 PRBufferWrite(PRFileDesc *fd, const void *buf, PRInt32 amount) { /* Write is the same as Send except that it doesn't have a timeout or * understand flags. Since our implementation of Send is fake, pass * arbitrary data and use it to implement Write as well. */ return PRBufferSend(fd, buf, amount, 0, -1); } // Respond to recv requests static PRInt32 PRBufferRecv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout) { /* Recv takes a PRFileDesc and attempts to read some amount of bytes from * the start of buf to return to the caller before timeout is reached. * Because we're implementing this as a buffer, copy from the buffer when * there is something in it, else return EWOULDBLOCK. */ PRFilePrivate *internal = fd->secret; if (!jb_can_read(internal->read_buffer)) { /* See comment in PRBufferSend about EWOULDBLOCK. */ PR_SetError(PR_WOULD_BLOCK_ERROR, EWOULDBLOCK); return -1; } /* By checking if we can read, we ensure we don't return 0 from * jb_read(...); otherwise, we'd violate non-blocking socket * semantics. */ return jb_read(internal->read_buffer, (uint8_t *) buf, amount); } // Respond to read requests static PRInt32 PRBufferRead(PRFileDesc *fd, void *buf, PRInt32 amount) { /* Read is the same as Recv except that it doesn't have a timeout or * understand flags. Since our implementation of Recv is fake, pass * arbitrary data and use it to implement Read as well. */ return PRBufferRecv(fd, buf, amount, 0, -1); } // Fake responses to getSocketOption requests static PRStatus PRBufferGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data) { /* getSocketOption takes a PRFileDesc and modifies the value field of data * with socket option specified in the option field. We fake responses with * a couple of sane defaults here: * * non_blocking = true * reuse_addr = true * keep_alive = false * no_delay = true * * We return valid responses to three other options: * * max_segment = capacity of read_buffer * recv_buffer_size = capacity of read buffer * send_buffer_size = capacity of write buffer * * Note that all responses are "fake" in that calls to SetSocketOption will * not be reflected here. */ if (!data || !fd) { return PR_FAILURE; } PRFilePrivate *internal = fd->secret; switch (data->option) { case PR_SockOpt_Nonblocking: data->value.non_blocking = PR_TRUE; return PR_SUCCESS; case PR_SockOpt_Reuseaddr: data->value.reuse_addr = PR_TRUE; return PR_SUCCESS; case PR_SockOpt_Keepalive: data->value.keep_alive = PR_FALSE; return PR_SUCCESS; case PR_SockOpt_NoDelay: data->value.no_delay = PR_TRUE; return PR_SUCCESS; case PR_SockOpt_MaxSegment: data->value.max_segment = jb_capacity(internal->read_buffer); return PR_SUCCESS; case PR_SockOpt_RecvBufferSize: data->value.recv_buffer_size = jb_capacity(internal->read_buffer); return PR_SUCCESS; case PR_SockOpt_SendBufferSize: data->value.send_buffer_size = jb_capacity(internal->write_buffer); return PR_SUCCESS; default: return PR_FAILURE; } } // Fake responses to setSocketOption static PRStatus PRBufferSetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data) { /* This gives the caller control over setting socket options. It is the * equivalent of fcntl() with F_SETFL. In our case, O_NONBLOCK is the * only thing passed in, which we always return as true anyways, so * ignore the result. */ return PR_SUCCESS; } // Create a method table with all our implemented functions static const PRIOMethods PRIOBufferMethods = { PR_DESC_SOCKET_TCP, PRBufferClose, PRBufferRead, PRBufferWrite, (PRAvailableFN)invalidInternalCall, (PRAvailable64FN)invalidInternalCall, (PRFsyncFN)invalidInternalCall, (PRSeekFN)invalidInternalCall, (PRSeek64FN)invalidInternalCall, (PRFileInfoFN)invalidInternalCall, (PRFileInfo64FN)invalidInternalCall, (PRWritevFN)invalidInternalCall, (PRConnectFN)invalidInternalCall, (PRAcceptFN)invalidInternalCall, (PRBindFN)invalidInternalCall, (PRListenFN)invalidInternalCall, PRBufferShutdown, PRBufferRecv, PRBufferSend, (PRRecvfromFN)invalidInternalCall, (PRSendtoFN)invalidInternalCall, (PRPollFN)invalidInternalCall, (PRAcceptreadFN)invalidInternalCall, (PRTransmitfileFN)invalidInternalCall, (PRGetsocknameFN)invalidInternalCall, PRBufferGetPeerName, (PRReservedFN)invalidInternalCall, (PRReservedFN)invalidInternalCall, PRBufferGetSocketOption, PRBufferSetSocketOption, (PRSendfileFN)invalidInternalCall, (PRConnectcontinueFN)invalidInternalCall, (PRReservedFN)invalidInternalCall, (PRReservedFN)invalidInternalCall, (PRReservedFN)invalidInternalCall, (PRReservedFN)invalidInternalCall }; /* Free a Buffer-backed PRFileDesc. Note that it is usually sufficient to call * PR_Close(...) on the buffer instead. This is provided for completeness and * should not be called in a SSL context as the buffer PRFileDesc is wrapped * by the SSL PRFileDesc. Note that this only removes references to the * underlying j_buffers and does not free them; it is up to the caller to * do so. */ void freeBufferPRFileDesc(PRFileDesc *fd) { /* Leave it to the caller to free the bytes; they should maintain a * reference to it as well. */ /* If fd->secret is none, close() was called first so we can just exit. */ if (fd->secret == NULL) { return; } fd->secret->read_buffer = NULL; fd->secret->write_buffer = NULL; fd->secret = NULL; } /* Construct a new PRFileDesc backed by a pair of buffers. Note that these * should be separate buffers, but need not be unique to this PRFileDesc; * that is, a client and server could share (but be swapped) j_buffers. * The caller is expected to provide a peer_info to be used for optional * session resumption; this will be truncated at 16 bytes of data, and * extended with nulls if it is shorter. It is suggested that this be an IPv4 * or IPv6 address. Note that this value is not used to validate the hostname * in any way (see SSL_SetURL to validate the peer). */ PRFileDesc *newBufferPRFileDesc(j_buffer *read_buf, j_buffer *write_buf, uint8_t *peer_info, size_t peer_info_len) { PRFileDesc *fd; fd = PR_NEW(PRFileDesc); if (fd) { fd->methods = &PRIOBufferMethods; fd->secret = PR_NEW(PRFilePrivate); fd->secret->read_buffer = read_buf; fd->secret->write_buffer = write_buf; size_t len = peer_info_len; if (len > 16) { len = 16; } fd->secret->peer_addr = calloc(16, sizeof(uint8_t)); memcpy(fd->secret->peer_addr, peer_info, len); fd->lower = NULL; fd->higher = NULL; fd->dtor = freeBufferPRFileDesc; } return fd; } jss-4.6.3/org/mozilla/jss/ssl/javax/BufferPRFD.h000066400000000000000000000025731362106420000213310ustar00rootroot00000000000000#include /* Necessary for correctly propagating E_WOULDBLOCK. */ #include #include #include /* Ring buffer implementation to handle read/write calls. */ #include "j_buffer.h" /* Use a modern pragma guard... */ #pragma once /* Free a Buffer-backed PRFileDesc. Note that it is usually sufficient to call * PR_Close(...) on the buffer instead. This is provided for completeness and * should not be called in a SSL context as the buffer PRFileDesc is wrapped * by the SSL PRFileDesc. Note that this only removes references to the * underlying j_buffers and does not free them; it is up to the caller to * do so. */ void freeBufferPRFileDesc(PRFileDesc *fd); /* Construct a new PRFileDesc backed by a pair of buffers. Note that these * should be separate buffers, but need not be unique to this PRFileDesc; * that is, a client and server could share (but be swapped) j_buffers. * The caller is expected to provide a peer_info to be used for optional * session resumption; this will be truncated at 16 bytes of data, and * extended with nulls if it is shorter. It is suggested that this be an IPv4 * or IPv6 address. Note that this value is not used to validate the hostname * in any way (see SSL_SetURL to validate the peer). */ PRFileDesc *newBufferPRFileDesc(j_buffer *read_buf, j_buffer *write_buf, uint8_t *peer_info, size_t peer_info_len); jss-4.6.3/org/mozilla/jss/ssl/javax/JSSParameters.java000066400000000000000000000142251362106420000226160ustar00rootroot00000000000000package org.mozilla.jss.ssl.javax; import javax.net.ssl.*; import java.util.*; import org.mozilla.jss.ssl.*; /** * JSSParameters is an implementation of SSLParameters to interoperate * with NSS. * * In particular, we extend SSLParameters to provide cipher suites and * protocol versions as NSS constants. This aids with the JNI translation * layer. We also create a default set of SSLParameters which use a null * cipher suite list and null protocol version list to fall back on the * NSS default. On RHEL-like systems, this will default to CryptoPolicies. * * We also need to store the desired certificate alias; this contrasts to * the SNI functionality provided by SSLParameters in that it ties back * to a certificate in the NSS DB and works with client certificates. When * using the JSSEngine implementation of SSLEngine, only the alias will be * used to find the certificate. */ public class JSSParameters extends SSLParameters { private SSLCipher[] suites; private SSLVersionRange range; private String alias; private String hostname; public JSSParameters() { // Choose our default set of SSLParameters here; default to null // everywhere to rely on the default NSS policies. super(null, null); } public JSSParameters(SSLParameters downcast) { this(); if (downcast == null) { return; } // Copy data from downcast setCipherSuites(downcast.getCipherSuites()); setProtocols(downcast.getProtocols()); setAlgorithmConstraints(downcast.getAlgorithmConstraints()); setEndpointIdentificationAlgorithm(downcast.getEndpointIdentificationAlgorithm()); setServerNames(downcast.getServerNames()); setSNIMatchers(downcast.getSNIMatchers()); setUseCipherSuitesOrder(downcast.getUseCipherSuitesOrder()); if (downcast.getWantClientAuth()) { setWantClientAuth(downcast.getWantClientAuth()); } if (downcast.getNeedClientAuth()) { setNeedClientAuth(downcast.getNeedClientAuth()); } } public JSSParameters(String[] cipherSuites) { super(cipherSuites); } public JSSParameters(String[] cipherSuites, String[] protocols) { super(cipherSuites, protocols); } public void setCipherSuites(String[] cipherSuites) throws IllegalArgumentException { if (cipherSuites == null || cipherSuites.length == 0) { suites = null; return; } ArrayList converted = new ArrayList(); for (String cipherSuite : cipherSuites) { try { converted.add(SSLCipher.valueOf(cipherSuite)); } catch (Exception e) { throw new IllegalArgumentException("JSSParameters.setCipherSuites() - Unknown cipher suite (" + cipherSuite + "): " + e.getMessage(), e); } } suites = converted.toArray(new SSLCipher[0]); } public void setCipherSuites(SSLCipher[] cipherSuites) { if (cipherSuites == null || cipherSuites.length == 0) { suites = null; return; } // Perform a copy of cipherSuites in case it is modified later. suites = new SSLCipher[cipherSuites.length]; for (int index = 0; index < cipherSuites.length; index++) { suites[index] = cipherSuites[index]; } } public String[] getCipherSuites() { if (suites == null) { return null; } ArrayList ciphers = new ArrayList(); for (SSLCipher suite : suites) { ciphers.add(suite.name()); } return ciphers.toArray(new String[0]); } public SSLCipher[] getSSLCiphers() { return suites; } public void setProtocols(String[] protocols) throws IllegalArgumentException { if (protocols == null || protocols.length == 0) { range = null; return; } try { SSLVersion minProtocol = SSLVersion.findByAlias(protocols[0]); SSLVersion maxProtocol = minProtocol; for (String protocol : protocols) { SSLVersion version = SSLVersion.findByAlias(protocol); if (minProtocol.ordinal() > version.ordinal()) { minProtocol = version; } if (maxProtocol.ordinal() < version.ordinal()) { maxProtocol = version; } } range = new SSLVersionRange(minProtocol, maxProtocol); } catch (Exception e) { throw new IllegalArgumentException("JSSParameters.setProtocols() - unknown protocol: " + e.getMessage(), e); } } public void setProtocols(SSLVersion min, SSLVersion max) { range = new SSLVersionRange(min, max); } public void setProtocols(SSLVersionRange vrange) { range = vrange; } public String[] getProtocols() { if (range == null) { return null; } ArrayList enabledProtocols = new ArrayList(); for (SSLVersion v: SSLVersion.values()) { if (range.getMinVersion().ordinal() <= v.ordinal() && v.ordinal() <= range.getMaxVersion().ordinal()) { // We've designated the second alias as the standard Java name // for the protocol. However if one isn't provided, fall back // to the first alias. It currently is the case that all // elements in SSLVersion have two aliases. if (v.aliases().length >= 2) { enabledProtocols.add(v.aliases()[1]); } else { enabledProtocols.add(v.aliases()[0]); } } } return enabledProtocols.toArray(new String[0]); } public SSLVersionRange getSSLVersionRange() { return range; } public String getAlias() { return alias; } public void setAlias(String cert_alias) { alias = cert_alias; } public String getHostname() { return hostname; } public void setHostname(String server_hostname) { hostname = server_hostname; } } jss-4.6.3/org/mozilla/jss/ssl/javax/j_buffer.c000066400000000000000000000253531362106420000212220ustar00rootroot00000000000000#include "j_buffer.h" #include #include #include j_buffer *jb_alloc(size_t length) { j_buffer *buf = calloc(1, sizeof(j_buffer)); buf->contents = calloc(length, sizeof(uint8_t)); buf->capacity = length; // In the beginning, we can only write, not read. Hence, set our read_pos // to the sentinel value, buf->capacity. buf->write_pos = 0; buf->read_pos = length; return buf; } size_t jb_capacity(j_buffer *buf) { if (buf == NULL) { return 0; } return buf->capacity; } bool jb_can_read(j_buffer *buf) { /* buf->read_pos == buf->capacity <=> can't read from the buffer */ return buf != NULL && buf->read_pos != buf->capacity; } size_t jb_read_capacity(j_buffer *buf) { if (buf == NULL) { return 0; } /* Semantics: buf->read_pos == buf->capacity <=> can't read */ if (buf->read_pos == buf->capacity) { return 0; } /* Semantics: buf->write_pos == buf->capacity <=> buffer empty */ if (buf->write_pos == buf->capacity) { return buf->capacity; } /* When buf->read_pos < buf->write_pos, delta is what we can read */ if (buf->read_pos < buf->write_pos) { return buf->write_pos - buf->read_pos; } /* Lastly, we can read to the end of the buffer and back around to * write_pos when buf->read_pos > buf->write_pos. Note that it is * never true that buf->read_pos == buf->write_pos. */ return (buf->capacity - buf->read_pos) + buf->write_pos; } bool jb_can_write(j_buffer *buf) { /* buf->write_pos == buf->capacity <=> can't write to the buffer */ return buf != NULL && buf->write_pos != buf->capacity; } size_t jb_write_capacity(j_buffer *buf) { if (buf == NULL) { return 0; } /* Semantics: buf->write_pos == buf->capacity <=> can't write */ if (buf->write_pos == buf->capacity) { return 0; } /* Semantics: buf->read_pos == buf->capacity <=> can't read */ if (buf->read_pos == buf->capacity) { return buf->capacity; } /* When buf->write_pos < buf->read_pos, delta is what we can write */ if (buf->write_pos < buf->read_pos) { return buf->read_pos - buf->write_pos; } /* Lastly, we can write to the end of the buffer and back around to * write_pos when buf->write_pos > buf->read_pos */ return (buf->capacity - buf->write_pos) + buf->read_pos; } int jb_put(j_buffer *buf, uint8_t byte) { /* ret == EOF <=> can't write to the buffer */ /* ret = char written <=> can write to the buffer */ if (!jb_can_write(buf)) { return EOF; } buf->contents[buf->write_pos] = byte; if (buf->read_pos == buf->capacity) { // As we just performed a write, we can now read, starting at this // location. buf->read_pos = buf->write_pos; } buf->write_pos += 1; if (buf->write_pos == buf->capacity && buf->read_pos > 0) { // If we've incremented write_pos and reached the limit of our // capacity, when read_pos is not at the head of the buffer, we can // write another character, so set the write_pos to the head. buf->write_pos = 0; } if (buf->write_pos == buf->read_pos) { // If we've incremented buf->write_pos and hit buf->read_pos, then we // can't write any more bytes. This is because we've already reset // buf->read_pos when it was at capacity, so if the condition holds, // either buf->write_pos != buf->capacity or buf->read_pos != // buf->capacity. buf->write_pos = buf->capacity; } // Semantics of put. return byte; } size_t jb_write(j_buffer *buf, const uint8_t *input, size_t input_size) { /* ret == 0 <=> can't write to the buffer or input_size == 0 */ /* ret == amount written <=> can write to the buffer */ if (!jb_can_write(buf) || input_size == 0) { return 0; } // Quantity we should write in our first batch. size_t write_size = buf->capacity - buf->write_pos; // Location (offset from buf->contents) we should write to. uint8_t *write_ptr = buf->contents + buf->write_pos; if (buf->read_pos > buf->write_pos) { // When buf->read_pos > buf->write_pos, we know that we are limited // in the quantity we can write by buf->read_pos. (If buf->read_pos < // buf->write_pos, we are not limited and can read up to capacity). // Since we guarantee buf->read_pos <= buf->capacity, this subtraction // will not grow the size written and only shrink it. write_size = buf->read_pos - buf->write_pos; } if (write_size > input_size) { // Since we're limited by the amount we can ultimately write by the // quantity of bytes of input we have, shrink write_size since it was // previously greater than input_size. write_size = input_size; } // Note that, sometimes write_size is computed as being smaller than // input_size. This happens when write_pos is towards the end of the // buffer, but read_pos is not at the start. Thus we can write more // bytes than we computed above. To handle this, we call jb_write // again after this pass. In the above we ensure that we always write // at least one byte, so input_size shrinks and buf->write_pos moves. // This ensures we make at most two calls to jb_write and have a recursion // depth of at most two. // This copies the current byte window from the input to the buffer. memcpy(write_ptr, input, write_size); if (buf->read_pos == buf->capacity) { // Since we just wrote bytes, we can now read bytes again. buf->read_pos = buf->write_pos; } // Since write_size is bounded above by the difference between // buf->capacity and buf->write_pos, we guarantee that // buf->write_pos <= buf->capacity after adding write_size. buf->write_pos += write_size; if (buf->write_pos == buf->capacity && buf->read_pos != 0) { // If we're at capacity but buf->read_pos isn't the start of the // buffer, we can update write_pos to be the head. In this case, // when write_size < input_size, we can write again, hence why we // call jb_write at the end. buf->write_pos = 0; } if (buf->write_pos == buf->read_pos) { // In this case, we've written the most we can until we ran into // read_pos, so we lack space to write again, so update write_pos // to be the capacity of the buffer. buf->write_pos = buf->capacity; } // Since we can recurse, update input (the pointer to where we're // writing), by the write_size so that the next byte is placed correctly. // Also, update input_size by write_size such that the remaining capacity // of the input buffer (or, the offset input buffer) is reflected. input += write_size; input_size -= write_size; // Recurse, updating the return value by this write size. return write_size + jb_write(buf, input, input_size); } int jb_get(j_buffer *buf) { /* ret == EOF <=> can't read from the buffer */ if (!jb_can_read(buf)) { return EOF; } uint8_t result = buf->contents[buf->read_pos]; if (buf->write_pos == buf->capacity) { // Since we just read from the buffer, we now have a place to write // to since it wasn't possible before. buf->write_pos = buf->read_pos; } // Always increment read_pos since we read a byte. buf->read_pos += 1; if (buf->read_pos == buf->capacity && buf->write_pos != 0) { // When the read_pos is now at capacity, but write_pos is not at the // start of the buffer, we can wrap read_pos and read more bytes. buf->read_pos = 0; } if (buf->read_pos == buf->write_pos) { // If incrementing read_pos put it equal with write_pos, we can no // longer read more bytes, so set it to buf->capacity. buf->read_pos = buf->capacity; } // Return the byte we read. return result; } size_t jb_read(j_buffer *buf, uint8_t *output, size_t output_size) { /* ret == 0 <=> can't read from the buffer or output_size == 0 */ /* ret == amount written <=> can read from the buffer */ if (!jb_can_read(buf) || output_size == 0) { return 0; } // Location we should read from: buf->contents + the offset given by // buf->read_pos. uint8_t *read_ptr = buf->contents + buf->read_pos; // Size of the read we should perform. We're always bounded above by the // difference between buf->capacity and buf->read_pos. size_t read_size = buf->capacity - buf->read_pos; if (buf->write_pos > buf->read_pos) { // When the condition holds and since buf->write_pos <= buf->capacity, // update read_size to be the difference between buf->write_pos and // buf->read_pos. This will thus never grow read_size. read_size = buf->write_pos - buf->read_pos; } if (read_size > output_size) { // Bound read_size by output_size when read_size exceeds output_size. read_size = output_size; } // We perform the initial copy of bytes from buf->contents to the output // buffer. However, we might need another pass, hence the recursion at the // end of jb_read. For more discussion, see the documentation in memcpy(output, read_ptr, read_size); if (buf->write_pos == buf->capacity) { // Since we just read from the buffer, we can now write to the buffer // at the location we just read from. buf->write_pos = buf->read_pos; } buf->read_pos += read_size; if (buf->read_pos == buf->capacity && buf->write_pos != 0) { // When we've reached buf->capacity and buf->write_pos isn't at the // start, we can read more bytes, so set buf->read_pos to the start // of the buffer. buf->read_pos = 0; } if (buf->read_pos == buf->write_pos) { // When buf->read_pos is buf->write_pos, we can no longer read any // more bytes from the buffer, so set buf->read_pos to our sentinel, // buf->capacity. buf->read_pos = buf->capacity; } // Move our output array by read_size and decrease its given size to // handle the recursion into jb_read. output += read_size; output_size -= read_size; return read_size + jb_read(buf, output, output_size); } void jb_free(j_buffer *buf) { // Safely handle partial or invalid structures. if (buf == NULL) { return; } if (buf->contents == NULL || buf->capacity == 0) { return; } // We clear the contents of the buffer before freeing it in case any // sensitive information was stored. memset(buf->contents, 0, buf->capacity); free(buf->contents); // Safe guards to ensure we don't try and free buf again. buf->contents = NULL; buf->capacity = 0; free(buf); } jss-4.6.3/org/mozilla/jss/ssl/javax/j_buffer.h000066400000000000000000000045441362106420000212260ustar00rootroot00000000000000#include #include #include #pragma once /* * Opaque structure for buffers. Subject to change at any time. * * A j_buffer is a circular ring buffer creating a FIFO queue of bytes. */ typedef struct { /* Contents of the buffer. */ uint8_t *contents; /* Capacity is used as a sentinel value; when write_pos == capacity, can't * write. */ size_t capacity; /* Next position to write to, else capacity if unable to write. */ size_t write_pos; /* Next position to read from, else capacity if unable to read. */ size_t read_pos; } j_buffer; /* * Create a new buffer; must be freed with jb_free. The length parameter is * the number of uint8_t elements the new buffer can store. */ j_buffer *jb_alloc(size_t length); /* Get the original capacity (i.e., when empty) of the specified buffer. */ size_t jb_capacity(j_buffer *buf); /* Whether or not the buffer can be read from. */ bool jb_can_read(j_buffer *buf); /* Number of bytes which can be read. */ size_t jb_read_capacity(j_buffer *buf); /* Whether or not the buffer can be written to. */ bool jb_can_write(j_buffer *buf); /* Number of bytes which can be written. */ size_t jb_write_capacity(j_buffer *buf); /* * Store a character into the buffer. Returns the character if stored, * else EOF if unable to store the character (because the buffer is full). * When not EOF, can safely be casted to a uint8_t. */ int jb_put(j_buffer *buf, uint8_t byte); /* * Store many characters into the buffer from an array of characters. Returns * the number of characters written into the buffer; max of input_size. This * is zero when the buffer is already full. */ size_t jb_write(j_buffer *buf, const uint8_t *input, size_t input_size); /* * Get the next character from the buffer or EOF if the buffer is empty. If * not EOF, can safely be casted to uint8_t. */ int jb_get(j_buffer *buf); /* * Read several characters from the buffer in the order they were written. The * characters are placed in output and up to output_size characters are read. * Returns the number of characters read; zero if the buffer was empty. */ size_t jb_read(j_buffer *buf, uint8_t *output, size_t output_size); /* * Free a buffer allocated with jb_alloc. This includes zeroing the contents * of the buffer in case any sensitive material was stored. */ void jb_free(j_buffer *buf); jss-4.6.3/org/mozilla/jss/ssl/jssl.h000066400000000000000000000100271362106420000172770ustar00rootroot00000000000000/* 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/. */ #ifndef ORG_MOZILLA_JSS_SSL_JSSL_H #define ORG_MOZILLA_JSS_SSL_JSSL_H /* ocsp policy constants */ /* ocsp policy constants */ static const int OCSP_NO_POLICY = 0; static const int OCSP_NORMAL_POLICY = 1; static const int OCSP_LEAF_AND_CHAIN_POLICY = 2; #include typedef struct { enum { PW_NONE = 0, PW_FROMFILE = 1, PW_PLAINTEXT = 2, PW_EXTERNAL = 3 } source; char *data; } secuPWData; struct JSSL_SocketData { PRFileDesc *fd; jobject socketObject; /* weak global ref */ jobject certApprovalCallback; /* global ref */ jobject clientCertSelectionCallback; /* global ref */ CERTCertificate *clientCert; PK11SlotInfo *clientCertSlot; PRFilePrivate *jsockPriv; PRLock *lock; /* protects reader, writer, accepter, and closePending */ PRThread *reader; PRThread *writer; PRThread *accepter; PRBool closePending; }; typedef struct JSSL_SocketData JSSL_SocketData; SECStatus 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 JSSL_DefaultCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer); SECStatus JSSL_CallCertSelectionCallback( void * arg, PRFileDesc * fd, CERTDistNames * caNames, CERTCertificate ** pRetCert, SECKEYPrivateKey ** pRetKey); SECStatus JSSL_ConfirmExpiredPeerCert(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer); SECStatus JSSL_GetClientAuthData( void * arg, PRFileDesc * fd, CERTDistNames * caNames, CERTCertificate ** pRetCert, SECKEYPrivateKey ** pRetKey); #ifdef JDK1_2 /* JDK 1.2 and higher provide weak references in JNI. */ #define NEW_WEAK_GLOBAL_REF(env, obj) \ ((*env)->NewWeakGlobalRef((env), (obj))) #define DELETE_WEAK_GLOBAL_REF(env, obj) \ ((*env)->DeleteWeakGlobalRef((env), (obj))) #else /* JDK 1.1 doesn't have weak references, so we'll have to use regular ones */ #define NEW_WEAK_GLOBAL_REF(env, obj) \ ((*env)->NewGlobalRef((env), (obj))) #define DELETE_WEAK_GLOBAL_REF(env, obj) \ ((*env)->DeleteGlobalRef((env), (obj))) #endif #define JSSL_getSockData(env, sockObject, sdptr) \ JSS_getPtrFromProxyOwner(env, sockObject, SSLSOCKET_PROXY_FIELD, \ SSLSOCKET_PROXY_SIG, (void**)sdptr) void JSSL_DestroySocketData(JNIEnv *env, JSSL_SocketData *sd); extern PRInt32 JSSL_enums[]; #define JSSL_enums_size 36 int JSSL_enums_reverse(PRInt32 value); JSSL_SocketData* JSSL_CreateSocketData(JNIEnv *env, jobject sockObj, PRFileDesc* newFD, PRFilePrivate *priv); #define SSL_POLICY_DOMESTIC 0 #define SSL_POLICY_EXPORT 1 #define SSL_POLICY_FRANCE 2 typedef enum {LOCAL_SOCK, PEER_SOCK} LocalOrPeer; PRStatus JSSL_getSockAddr (JNIEnv *env, jobject self, PRNetAddr *addr, LocalOrPeer localOrPeer); PRFileDesc* JSS_SSL_javasockToPRFD(JNIEnv *env, jobject sockObj); jthrowable JSS_SSL_getException(PRFilePrivate *priv); void JSS_SSL_processExceptions(JNIEnv *env, PRFilePrivate *priv); #define EXCEPTION_CHECK(env, sock) \ if( sock != NULL && sock->jsockPriv!=NULL) { \ JSS_SSL_processExceptions(env, sock->jsockPriv); \ } void JSSL_throwSSLSocketException(JNIEnv *env, char *message); int JSSL_getOCSPPolicy(); SECStatus JSSL_verifyCertPKIX(CERTCertificate *cert, SECCertificateUsage certificateUsage, secuPWData *pwdata, int ocspPolicy, CERTVerifyLog *log,SECCertificateUsage *usage); #endif jss-4.6.3/org/mozilla/jss/ssl/package.html000066400000000000000000000003771362106420000204430ustar00rootroot00000000000000 SSL sockets. jss-4.6.3/org/mozilla/jss/tests/000077500000000000000000000000001362106420000165145ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/tests/BMPStringTest.java000066400000000000000000000215551362106420000220340ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.junit.Assert; import org.junit.Test; import org.mozilla.jss.netscape.security.util.DerValue; public class BMPStringTest { public byte tag = DerValue.tag_BMPString; @Test public void testEncodingEmptyString() throws Exception { String string = ""; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingEmptyString() throws Exception { String input = ""; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + input + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingNullCharacters() throws Exception { String string = StringTestUtil.NULL_CHARS; System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); actual = StringTestUtil.normalizeUnicode(actual); System.out.println(" - norm. : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingNullCharacters() throws Exception { String input = StringTestUtil.NULL_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingPrintableCharacters() throws Exception { String string = StringTestUtil.PRINTABLE_CHARS; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); actual = StringTestUtil.normalizeUnicode(actual); System.out.println(" - norm. : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingPrintableCharacters() throws Exception { String input = StringTestUtil.PRINTABLE_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + input + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingNonPrintableCharacters() throws Exception { String string = StringTestUtil.NON_PRINTABLE_CHARS; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); actual = StringTestUtil.normalizeUnicode(actual); System.out.println(" - norm. : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingNonPrintableCharacters() throws Exception { String input = StringTestUtil.NON_PRINTABLE_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + input + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingControlCharacters() throws Exception { String string = StringTestUtil.CONTROL_CHARS; System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); actual = StringTestUtil.normalizeUnicode(actual); System.out.println(" - norm. : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingControlCharacters() throws Exception { String input = StringTestUtil.CONTROL_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingMultibyteCharacters() throws Exception { String string = StringTestUtil.MULTIBYTE_CHARS; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); actual = StringTestUtil.normalizeUnicode(actual); System.out.println(" - norm. : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingMultibyteCharacters() throws Exception { String input = StringTestUtil.MULTIBYTE_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingTime() throws Exception { System.out.println("Encoding time:"); String string = StringTestUtil.NULL_CHARS + StringTestUtil.PRINTABLE_CHARS + StringTestUtil.NON_PRINTABLE_CHARS + StringTestUtil.CONTROL_CHARS + StringTestUtil.MULTIBYTE_CHARS; long t0 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) JSSUtil.encode(tag, string); long t1 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) StringTestUtil.encode(tag, string); long t2 = System.currentTimeMillis(); long time1 = t1 - t0; long time2 = t2 - t1; System.out.println(" - JSS : " + time1 + " ms"); System.out.println(" - Internal: " + time2 + " ms"); } @Test public void testDecodingTime() throws Exception { System.out.println("Decoding time:"); String string = StringTestUtil.NULL_CHARS + StringTestUtil.PRINTABLE_CHARS + StringTestUtil.NON_PRINTABLE_CHARS + StringTestUtil.CONTROL_CHARS + StringTestUtil.MULTIBYTE_CHARS; byte[] data = JSSUtil.encode(tag, string); long t0 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) JSSUtil.decode(tag, data); long t1 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) StringTestUtil.decode(tag, data); long t2 = System.currentTimeMillis(); long time1 = t1 - t0; long time2 = t2 - t1; System.out.println(" - JSS : " + time1 + " ms"); System.out.println(" - Internal: " + time2 + " ms"); } } jss-4.6.3/org/mozilla/jss/tests/BadSSL.java000066400000000000000000000152541362106420000204360ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.ssl.SSLSocket; import org.mozilla.jss.ssl.SSLSocketException; import org.mozilla.jss.util.NativeErrcodes; /** * The BadSSL test case maintains an internal mapping from badssl.com * subdomains to expected exceptions and validates they occur. * * Since badssl.com offers no guaranteed SLA or availability, we likely * shouldn't add this site to automated tests. */ public class BadSSL { public static void main(String[] args) throws Exception { boolean ocsp = false; if (args.length < 1) { System.out.println("Usage: BadSSL nssdb [LEAF_AND_CHAIN]"); return; } if (args.length >= 2 && args[1].equals("LEAF_AND_CHAIN")) { System.out.println("Enabling leaf and chain policy..."); ocsp = true; } CryptoManager.initialize(args[0]); CryptoManager cm = CryptoManager.getInstance(); if (ocsp) { cm.setOCSPPolicy(CryptoManager.OCSPPolicy.LEAF_AND_CHAIN); } // Test cases which should fail due to various certificate errors. testExpired(); testWrongHost(); testSelfSigned(); testUntrustedRoot(); // The following test cases depend on crypto-policies or local NSS // configuration. testSHA1(); testRC4MD5(); testRC4(); test3DES(); testNULL(); // The following test cases depend on OCSP being enabled. if (ocsp) { testRevoked(); } // Test cases which should pass given the correct root certs. testSHA256(); testSHA384(); testSHA512(); testECC256(); testECC384(); testRSA2048(); testRSA4096(); testRSA8192(); testExtendedValidation(); } /* Test cases whose handshakes should fail below. */ public static void testExpired() throws Exception { testHelper("expired.badssl.com", 443, new String[]{ "(-8181)", "has expired" }); } public static void testWrongHost() throws Exception { testHelper("wrong.host.badssl.com", 443, new String[]{ "(-12276)", "domain name does not match" }); } public static void testSelfSigned() throws Exception { testHelper("self-signed.badssl.com", 443, new String[]{ "(-8101)", "(-8156)", "type not approved", "issuer certificate is invalid" }); } public static void testUntrustedRoot() throws Exception { testHelper("untrusted-root.badssl.com", 443, new String[]{ "(-8172)", "certificate issuer has been marked as not trusted" }); } public static void testRevoked() throws Exception { testHelper("revoked.badssl.com", 443, new String[]{ "(-8180)", "has been revoked" }); } public static void testSHA1() throws Exception { try { testHelper("sha1-intermediate.badssl.com", 443, new String[] { "(-12286)", "Cannot communicate securely" }); } catch (Exception e) { } } public static void testRC4MD5() throws Exception { try { testHelper("rc4-md5.badssl.com", 443, new String[] { "(-12286)", "Cannot communicate securely" }); } catch (Exception e) { } } public static void testRC4() throws Exception { try { testHelper("rc4.badssl.com", 443, new String[] { "(-12286)", "Cannot communicate securely" }); } catch (Exception e) { } } public static void test3DES() throws Exception { try { testHelper("3des.badssl.com", 443, new String[] { "(-12286)", "Cannot communicate securely" }); } catch (Exception e) { } } public static void testNULL() throws Exception { try { testHelper("null.badssl.com", 443, new String[] { "(-12286)", "Cannot communicate securely" }); } catch (Exception e) { } } /* Test cases which should handshake successfully below. */ public static void testSHA256() throws Exception { testHelper("sha256.badssl.com", 443); } public static void testSHA384() throws Exception { testHelper("sha384.badssl.com", 443); } public static void testSHA512() throws Exception { testHelper("sha512.badssl.com", 443); } public static void testECC256() throws Exception { testHelper("ecc256.badssl.com", 443); } public static void testECC384() throws Exception { testHelper("ecc384.badssl.com", 443); } public static void testRSA2048() throws Exception { testHelper("rsa2048.badssl.com", 443); } public static void testRSA4096() throws Exception { testHelper("rsa4096.badssl.com", 443); } public static void testRSA8192() throws Exception { testHelper("rsa8192.badssl.com", 443); } public static void testExtendedValidation() throws Exception { testHelper("extended-validation.badssl.com", 443); } /* Test case helpers. */ public static void testHelper(String host, int port) throws Exception { testSite(host, port); System.out.println("\t...ok"); } public static void testHelper(String host, int port, String[] substrs) throws Exception { try { testSite(host, port); } catch (SSLSocketException sse) { String actual = sse.getMessage().toLowerCase(); for (String expected : substrs) { if (actual.contains(expected.toLowerCase())) { System.out.println("\t...got expected error message."); return; } } System.err.println("\tUnexpected error message: " + actual); throw sse; } throw new RuntimeException("Expected to get an exception, but didn't!"); } public static void testHelper(String host, int port, int[] codes) throws Exception { try { testSite(host, port); } catch (SSLSocketException sse) { int actual = sse.getErrcode(); for (int expected : codes) { if (actual == expected) { System.out.println("\t...got expected error code."); return; } } System.err.println("\tUnexpected error code: " + actual); throw sse; } throw new RuntimeException("Expected to get an exception, but didn't!"); } public static void testSite(String host, int port) throws Exception { System.out.println("Testing connection to " + host + ":" + port); SSLSocket sock = new SSLSocket(host, 443); sock.forceHandshake(); sock.shutdownOutput(); sock.shutdownInput(); sock.close(); } } jss-4.6.3/org/mozilla/jss/tests/BigObjectIdentifier.java000066400000000000000000000041731362106420000232170ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.io.IOException; import java.math.BigInteger; import org.mozilla.jss.netscape.security.util.*; public class BigObjectIdentifier { public static void main(String[] args) throws Exception { long[] oid_components_long = { 1L, 3L,6L,1L,4L,1L,5000L,9L,1L,1L,1526913300628L, 1L}; int[] oid_components_int = { 1, 3,6,1,4,1,2312,9,1,1,15269, 1, 1}; BigInteger[] oid_components_big_int = { new BigInteger("1"), new BigInteger("3"), new BigInteger("6"), new BigInteger("1"), new BigInteger("4"), new BigInteger("1"), new BigInteger("2312"), new BigInteger("9"), new BigInteger("1"), new BigInteger("152691330062899999999999997777788888888888888889999999999999999"), new BigInteger("1") }; String oidIn = "1.3.6.1.4.1.2312.9.1.152691330062899999999999997777788888888888888889999999999999999.1"; ObjectIdentifier oid = new ObjectIdentifier(oidIn); ObjectIdentifier fromDer = null; ObjectIdentifier fromStaticMethod = null; ObjectIdentifier fromComponentList = null; ObjectIdentifier fromComponentListInt = null; ObjectIdentifier fromComponentListBigInt = null; System.out.println("oid: " + oid.toString()); DerOutputStream out = new DerOutputStream(); oid.encode(out); DerInputStream in = new DerInputStream(out.toByteArray()); fromDer = new ObjectIdentifier(in); System.out.println("fromDer: " + fromDer.toString()); fromStaticMethod = ObjectIdentifier.getObjectIdentifier(oidIn); System.out.println("fromStaticMethod: " + fromStaticMethod.toString()); fromComponentList = new ObjectIdentifier(oid_components_long); System.out.println("fromComponentList: " + fromComponentList.toString()); fromComponentListInt = new ObjectIdentifier(oid_components_int); System.out.println("fromComponentListInt: " + fromComponentListInt); fromComponentListBigInt = new ObjectIdentifier(oid_components_big_int); System.out.println("fromComponentListBigInt: " + fromComponentListBigInt); } } jss-4.6.3/org/mozilla/jss/tests/ChainSortingTest.java000066400000000000000000000262541362106420000226200ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.security.cert.X509Certificate; import java.util.Base64; import org.junit.Assert; import org.junit.Test; import org.mozilla.jss.netscape.security.util.Cert; import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ChainSortingTest { public static Logger logger = LoggerFactory.getLogger(ChainSortingTest.class); public X509Certificate rootCA; public X509Certificate subCA; public X509Certificate admin; public X509Certificate agent; public ChainSortingTest() throws Exception { // Subject DN: CN=Root CA Signing Certificate, O=EXAMPLE // Issuer DN: CN=Root CA Signing Certificate, O=EXAMPLE rootCA = new X509CertImpl(Base64.getDecoder().decode( "MIIDRjCCAi6gAwIBAgIJAMHiDXjnZ1J6MA0GCSqGSIb3DQEBCwUAMDgxEDAOBgNV" + "BAoMB0VYQU1QTEUxJDAiBgNVBAMMG1Jvb3QgQ0EgU2lnbmluZyBDZXJ0aWZpY2F0" + "ZTAeFw0xOTAzMDUxNzQzMjFaFw0yMDAzMDQxNzQzMjFaMDgxEDAOBgNVBAoMB0VY" + "QU1QTEUxJDAiBgNVBAMMG1Jvb3QgQ0EgU2lnbmluZyBDZXJ0aWZpY2F0ZTCCASIw" + "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMDv7ovkD+JVEdlLncYDnhzbLOz2" + "c3D37fobufnHHNwNOwfLZj8WdBCzwGJv+XGF+D2JIcKyYwYPR+HOg+xClhuuVleE" + "gMVvgxM+HcpM4heyBD2QczNo1dfXQRBy2AXvRn8Byh+Q6zbN7VoNu8ZaMQOxZx9m" + "EAiDZ7WxHVrEp2a4QrI6I9gKY6SyEHRzVT48JElLFokwhkMpF8vhgtj0Xxr5EEIY" + "yCMOzvZLtpeyH8PUri3Cv/hX1RZKjWqKLSJSKirnZLhZoEEzXtsOmoeeZBeRiabi" + "dPLsxqPfWFx4+BC7t5Vw5FaIt2mPh+q6bjZipO4uWz/p4a9wpqakuzgNsYUCAwEA" + "AaNTMFEwHQYDVR0OBBYEFCvlfY9OzAVsYpJEoqr7QfguO9v5MB8GA1UdIwQYMBaA" + "FCvlfY9OzAVsYpJEoqr7QfguO9v5MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + "AQELBQADggEBAHB1lWjT6bP1jAkk6eTVwBU2pGoGoYMGV3fWQGOmWQP5T7+nHKkU" + "jNMRACoC2hFlypwX8qQ70V5O4U+qrnxDP3EaT1zPsOB0x4DIIrpFgudL9EqnSbJ0" + "kvSz3awwO8x/Nvx7TatCncmTw9c14eqek2puhcQWvxHzWkaDHd9WxPrZJFftbSsn" + "ZGK2A/ybDCnUA5BDeCSDb5gufTd8gbS4wS1NwYcbbrQyHnLJlFcIF4aLkbYuX1bn" + "cYp8pQv3pZ3C/ofA+yBJvPELTaHjDC40MTdjFFfMQTPZswBX2iimoGQ/ProBGg7+" + "rLg2uk5AHff3oo/V1X0SSzo3IpvHh0jhg9I=" )); // Subject DN: CN=Subordinate CA Signing Certificate, O=EXAMPLE // Issuer DN: CN=Root CA Signing Certificate, O=EXAMPLE subCA = new X509CertImpl(Base64.getDecoder().decode( "MIIC8zCCAdsCCQCPJrl0/W/nMTANBgkqhkiG9w0BAQsFADA4MRAwDgYDVQQKDAdF" + "WEFNUExFMSQwIgYDVQQDDBtSb290IENBIFNpZ25pbmcgQ2VydGlmaWNhdGUwHhcN" + "MTkwMzA1MTg1MzMzWhcNMjAwMzA0MTg1MzMzWjA/MRAwDgYDVQQKDAdFWEFNUExF" + "MSswKQYDVQQDDCJTdWJvcmRpbmF0ZSBDQSBTaWduaW5nIENlcnRpZmljYXRlMIIB" + "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzop7/TcsWElVMjzjaaAcj5KH" + "c9H6rqhFmOsL/VYdbNzTkZD3i5DVB4sFFEHTMwEoKKpBKh9hkY8laRUWjtidDJu2" + "+NBPLJa+k0Q+KUWIQko1rtgSjmCN+oMZFh7Mo8fV1WLSBnNjwbUrMeRKxOaR/roa" + "YgIwH5Ra6cxsVHGngAfrjXPtiuFp7qjzUbbRBBRP2LpKDk45RzllSLhz09qgo135" + "by2zErfUsWoma+dzvfWVI27um2DEzHMMAHELZM6BSJEYaGUW+y4cHQuuhz6Bo1YY" + "L6RHp6RhuMzlILN7a/XznS6Zc8OV/hRlkZVUUha6tqSQ/uXNTaefa6sGrRWNdQID" + "AQABMA0GCSqGSIb3DQEBCwUAA4IBAQAKLJq6bCZ8f/bI1OAeRNE7eIZliDnTjLqM" + "M3sG9gkWCp1l7UD5CLAbCaL6jFEuBAvkr88LYS4A0vuMAmMVsiSsFRTZNLmazts7" + "NZARuOYmzuNb/SZzhOBgypo6G96cqLhslzFtxXs+zJic2lQEDu+5+pcZCyETWoBT" + "kD9sAM2dM1I9//05UTJ5mzuLFmW3rhSjsrOuYHJjwagUVVAYDrIqNgNb/XSlmWbu" + "d1t9sKHgHzN2H0DIsKaoupPhTDUABrDuG3mRn1gI2xu1RlluaXZB7ZpUZAB/hMTV" + "8JPbHZeV08qYlfWJqhnUAZ0YQOx0yi5D98uhYB6Is/msBQ/YIbEi" )); // Subject DN: UID=admin, O=EXAMPLE // Issuer DN: CN=Subordinate CA Signing Certificate, O=EXAMPLE admin = new X509CertImpl(Base64.getDecoder().decode( "MIIC5DCCAcwCCQCh59LykL9CDTANBgkqhkiG9w0BAQsFADA/MRAwDgYDVQQKDAdF" + "WEFNUExFMSswKQYDVQQDDCJTdWJvcmRpbmF0ZSBDQSBTaWduaW5nIENlcnRpZmlj" + "YXRlMB4XDTE5MDMwNTIwMDQxNloXDTIwMDMwNDIwMDQxNlowKTEQMA4GA1UECgwH" + "RVhBTVBMRTEVMBMGCgmSJomT8ixkAQEMBWFkbWluMIIBIjANBgkqhkiG9w0BAQEF" + "AAOCAQ8AMIIBCgKCAQEA7QR+I7nLeGFntCajqIETKZ2MtpXdnrU3nkJawKwi1xQp" + "lYhFoVIqGqiX1+LfopemmR1bv2hcLt9uce4FG8jtELEF5KuCdCT99BSi8iVU+w0z" + "s4kCfUj9HvIcFhUO0dhkyVI//ZDh16xOi5AS3jqB0PtjgYbdrmufxXQhnyoeY9CM" + "N/w8OmN7mx2xUIApFP2LldU21rNSvly2Q0JbVDN2q7EENViYovvELW7zALGT5l/u" + "wVUsdkdgKY2C0ZHCh+aUDvDogywIALJIRxjcCU3Udx8Vfq/+MZCNccj6CPeCxNFv" + "L/wNtu+MpboF1jwNZB5jK9FPr3lXaH1aDdxoBSDMVwIDAQABMA0GCSqGSIb3DQEB" + "CwUAA4IBAQApkTNJMiCOYi9MI79kHFbEESd/ae+TTvHAd7sBIe5u1v5yK5Ij2opK" + "orY+gCVwNQOUlR7P/FIaY4eLVfPswqr3pl6O/DyqcuMLZofOHAzPEIBPFV/Qxcu1" + "WB1SDnSW61Wx7khVnWJQPgbcPVHdgTSS4vmUOw3YAsFAqzczth6bw/5sD19WLVu6" + "OYTSFGiofFLZXkidxZ7DIP2TUsaFJUEOkdoXlAImaHGpsCB/NXj2bWRmbzxcnMxd" + "jxttLewQofszMM0extB95n1KFv/bzbD+m9NM+aqvLOrzOg5rlcE5cbU07DVIycYs" + "fszFfR+9FvzA/AOpUzHg8y+ZX1rUts5f" )); // Subject DN: UID=agent, O=EXAMPLE // Issuer DN: CN=Subordinate CA Signing Certificate, O=EXAMPLE agent = new X509CertImpl(Base64.getDecoder().decode( "MIIC5DCCAcwCCQCh59LykL9CDjANBgkqhkiG9w0BAQsFADA/MRAwDgYDVQQKDAdF" + "WEFNUExFMSswKQYDVQQDDCJTdWJvcmRpbmF0ZSBDQSBTaWduaW5nIENlcnRpZmlj" + "YXRlMB4XDTE5MDMwNTIwMzU1NVoXDTIwMDMwNDIwMzU1NVowKTEQMA4GA1UECgwH" + "RVhBTVBMRTEVMBMGCgmSJomT8ixkAQEMBWFnZW50MIIBIjANBgkqhkiG9w0BAQEF" + "AAOCAQ8AMIIBCgKCAQEA7c4d93Gw4c0eW88ALqlUP01qkTzwRFLGKExbeBAwAGIY" + "0c/c9sHFkRkEO5Fm+BeaX0qqdF5D7dk+yTJcnvbLa4YP0MC+iOBIAmRk9CZmfArM" + "GE6dmMtt2pmQb38VlyY+3Cmjhz779rfzepAkSdmeLFTUW1I1KUIZDUovuu58Ak6j" + "7V0Ri3V2iI8z5zLRqg1Ko517+vsr2nKeAUO+g2Zbcu8qb6uS3Qq7mrHaHg7ZZb+M" + "yyqdqmMmLW1SQnITyqVXV/KH3mbAfsdQPopODhdH1LpuEw9xU9hVG6tn+ihytPsU" + "7txSW2nFC3iSzL8FK1RSerWAN93hLHVf5q5XXVk87QIDAQABMA0GCSqGSIb3DQEB" + "CwUAA4IBAQCWPtQEoUMoSJY+gqnoJNqq7DzprBQOaBMV5KKA+Fo4mSn6MUetFLPl" + "/HD1Knub2DEEuALPq5H3O71Jfy1cscAq3sD9Zl2jPP4FvrC0ypQl/Q5bG/8QDM9p" + "1INSAdyzPsTY+Y/mKChF3HNCzssnDWWDzHr6gSI7wnlDrE2QQGdHIn2Znx4P47RH" + "MTFX3xumo1b8nTyjdJ2aW8T80i30SejDkmnN9XBp14D7fheGOlKeP2lCt5GDpkcF" + "mT4YgcaVtSxMQBn7QhWV3534BqAjE5a32DEuJ6SnZph1GaDFy/kMXbjV/n9igHDs" + "b5s4gPC9eTB38qG0y+8TDATxvJ7s2OOM" )); } @Test public void testNulLChain() throws Exception { logger.info("Testing null chain"); X509Certificate[] input = null; X509Certificate[] output = Cert.sortCertificateChain(input); X509Certificate[] expected = null; Assert.assertArrayEquals(expected, output); } @Test public void testEmptyChain() throws Exception { logger.info("Testing empty chain"); X509Certificate[] input = {}; X509Certificate[] output = Cert.sortCertificateChain(input); X509Certificate[] expected = {}; Assert.assertArrayEquals(expected, output); } @Test public void testOneLevelChain() throws Exception { logger.info("Testing one-level chain"); X509Certificate[] input = { rootCA }; X509Certificate[] output = Cert.sortCertificateChain(input); X509Certificate[] expected = { rootCA }; Assert.assertArrayEquals(expected, output); } @Test public void testTwoLevelOrderedChain() throws Exception { logger.info("Testing two-level ordered chain"); X509Certificate[] input = { rootCA, subCA }; X509Certificate[] output = Cert.sortCertificateChain(input); X509Certificate[] expected = { rootCA, subCA }; Assert.assertArrayEquals(expected, output); } @Test public void testTwoLevelUnorderedChain() throws Exception { logger.info("Testing two-level unordered chain"); X509Certificate[] input = { subCA, rootCA }; X509Certificate[] output = Cert.sortCertificateChain(input); X509Certificate[] expected = { rootCA, subCA }; Assert.assertArrayEquals(expected, output); } @Test public void testThreeLevelOrderedChain() throws Exception { logger.info("Testing three-level ordered chain"); X509Certificate[] input = { rootCA, subCA, admin }; X509Certificate[] output = Cert.sortCertificateChain(input); X509Certificate[] expected = { rootCA, subCA, admin }; Assert.assertArrayEquals(expected, output); } @Test public void testThreeLevelUnorderedChain() throws Exception { logger.info("Testing three-level unordered chain"); X509Certificate[] input = { admin, subCA, rootCA }; X509Certificate[] output = Cert.sortCertificateChain(input); X509Certificate[] expected = { rootCA, subCA, admin }; Assert.assertArrayEquals(expected, output); } @Test public void testThreeLevelReverseChain() throws Exception { logger.info("Testing three-level reverse chain"); X509Certificate[] input = { subCA, rootCA, admin }; X509Certificate[] output = Cert.sortCertificateChain(input, true); X509Certificate[] expected = { admin, subCA, rootCA }; Assert.assertArrayEquals(expected, output); } @Test public void testPartialChain() throws Exception { logger.info("Testing partial chain"); X509Certificate[] input = { admin, subCA }; X509Certificate[] output = Cert.sortCertificateChain(input); X509Certificate[] expected = { subCA, admin }; Assert.assertArrayEquals(expected, output); } @Test public void testDuplicateChain() throws Exception { logger.info("Testing chain with duplicate certificates"); X509Certificate[] input = { rootCA, subCA, subCA, admin }; try { Cert.sortCertificateChain(input); Assert.fail(); } catch (Exception e) { String message = e.getMessage(); String expected = "Duplicate certificate: " + subCA.getSubjectDN(); Assert.assertEquals(expected, message); } } @Test public void testBranchedChain() throws Exception { logger.info("Testing branched chain"); X509Certificate[] input = { rootCA, subCA, admin, agent}; try { Cert.sortCertificateChain(input); Assert.fail(); } catch (Exception e) { String message = e.getMessage(); String expected = "Branched chain: " + subCA.getSubjectDN(); Assert.assertEquals(expected, message); } } @Test public void testBrokenChain() throws Exception { logger.info("Testing broken chain"); X509Certificate[] input = { rootCA, admin }; try { Cert.sortCertificateChain(input); Assert.fail(); } catch (Exception e) { String message = e.getMessage(); String expected = "Multiple leaf certificates: [" + rootCA.getSubjectDN() + "], [" + admin.getSubjectDN() + "]"; Assert.assertEquals(expected, message); } } } jss-4.6.3/org/mozilla/jss/tests/ClassServer.java000077500000000000000000000075601362106420000216260ustar00rootroot00000000000000/* 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.tests; import java.io.BufferedReader; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import java.util.Vector; /* * ClassServer.java -- JSSE_SSLServer implements this * class. */ public abstract class ClassServer implements Runnable { private ServerSocket server = null; private Vector supportedCiphers = new Vector<>(); /** * Constructs a ClassServer based on ss */ protected ClassServer(ServerSocket ss) { server = ss; newListener(); } /** * The "listen" thread that accepts a connection to the * server, parses the header to obtain the file name * and sends back the bytes for the file (or error * if the file is not found or the response was malformed). */ public void run() { Socket socket = null; boolean socketListenStatus = true; // accept a connection while ( socketListenStatus ) { try { socket = server.accept(); } catch (Exception ex) { System.exit(1); } newListener(); //try to read some bytes, to allow the handshake to go through try { InputStream is = socket.getInputStream(); BufferedReader bir = new BufferedReader( new InputStreamReader(is)); String socketData = bir.readLine(); if ( socketData.equals("null") ) socketListenStatus = false; else if ( socketData != null ) supportedCiphers.add(socketData); socket.close(); } catch(EOFException e) { } catch(IOException ex) { } catch(NullPointerException npe) { socketListenStatus = false; } } try { server.close(); } catch (Exception ex) { System.exit(1); } System.out.println("Server exiting"); System.out.println("-------------------------------------------" + "-------------"); System.out.println("Summary of JSS client to JSSE server " + "communication test :"); System.out.println("-------------------------------------------" + "-------------"); System.out.println("supportedCiphers.size " + supportedCiphers.size()); System.out.println("Constants.jssCiphersSuites "+ Constants.jssCipherSuites.length); for ( int i=0; i<(supportedCiphers.size()-1); i++ ) { System.out.print(i + " SC " + new Integer(supportedCiphers.elementAt(i)).intValue()); for ( int j=0; j<(Constants.jssCipherSuites.length); j++ ) { if (new Integer(supportedCiphers.elementAt(i)).intValue() == Constants.jssCipherSuites[j].value ) { System.out.print(" JSSC "); System.out.println(" ["+ i +"]\t" + Constants.jssCipherSuites[j].name); System.out.flush(); } } } System.out.println("-------------------------------------------" + "-------------"); System.out.flush(); if( !socketListenStatus ) { System.exit(0); } } /** * Create a new thread to listen. */ private void newListener() { (new Thread(this)).start(); } } jss-4.6.3/org/mozilla/jss/tests/CloseDBs.java000066400000000000000000000043411362106420000210170ustar00rootroot00000000000000/* 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.tests; import java.math.BigInteger; import java.util.Enumeration; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoStore; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.X509Certificate; public final class CloseDBs extends org.mozilla.jss.DatabaseCloser { public CloseDBs() throws Exception { super(); } public static void main(String args[]) { int i; try { if(args.length != 1) { System.err.println("Usage: CloseDBs "); System.exit(0); } CryptoManager.initialize( args[0] ); CryptoManager manager = CryptoManager.getInstance(); Enumeration tokens = manager.getAllTokens(); CryptoStore store; X509Certificate certs[]; java.security.PrivateKey keys[]; while (tokens.hasMoreElements()) { CryptoToken token = tokens.nextElement(); store = token.getCryptoStore(); System.out.println("Token: "+token.getName()); certs = store.getCertificates(); System.out.println("Certs:"); for(i=0; i < certs.length; i++) { System.out.println( certs[i].getNickname() ); } keys = store.getPrivateKeys(); System.out.println("Keys:"); try { for(i=0; i < keys.length; i++) { System.out.println(new BigInteger(1, keys[i].getEncoded())); } } catch (Exception ex) { System.out.println(ex.getMessage()); } } System.out.println("Closing databases..."); try { (new CloseDBs()).closeDatabases(); } catch (Exception ex) { System.out.println(ex.getMessage()); System.exit(1); } System.out.println("Databases are closed."); System.exit(0); } catch(Exception e) { e.printStackTrace(); System.exit(1); } } } jss-4.6.3/org/mozilla/jss/tests/Constants.java000077500000000000000000000331471362106420000213460ustar00rootroot00000000000000/* 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.tests; import org.mozilla.jss.ssl.*; /** * Holds immutable values for JSS Tests. * */ public interface Constants { /** Debug level for all tests */ public static int debug_level = 1; public static final class cipher { int value; /* hex value */ String name; cipher(int v, String n) { value = v; name = n; } /* * returns the string representation of the ciphersuite OR * returns null if the ciphersuite is not found */ public static final String cipherToString(int aCipher ) { for (int i = 0; i < Constants.jssCipherSuites.length; i++) { if (aCipher == Constants.jssCipherSuites[i].value) { return Constants.jssCipherSuites[i].name; } } return null; } /* * returns the integer value of the ciphersuite OR * returns -1 if the ciphersuite is not found. */ public static final int stringToCipher(String sCipher ) { for (int i = 0; i < Constants.jssCipherSuites.length; i++) { if (sCipher.compareToIgnoreCase( Constants.jssCipherSuites[i].name) == 0) { return Constants.jssCipherSuites[i].value; } } return -1; } } /** * The following have been deprecated * * SSL3_RSA_WITH_RC4_128_MD5 * SSL3_RSA_WITH_RC4_128_SHA * SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA * SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA * SL3_RSA_WITH_3DES_EDE_CBC_SHA * SSL3_DHE_RSA_WITH_DES_CBC_SHA * SSL3_DHE_DSS_WITH_DES_CBC_SHA * SSL3_RSA_WITH_DES_CBC_SHA * SSL3_RSA_WITH_NULL_SHA * SSL3_RSA_WITH_NULL_MD5 * SSL3_RSA_WITH_RC4_128_MD5 * SSL3_RSA_WITH_3DES_EDE_CBC_SHA * SSL3_RSA_WITH_DES_CBC_SHA * SSL3_RSA_WITH_NULL_MD5 */ /* cipherSuites Supported by JSS */ public static final cipher jssCipherSuites[] = { /*0 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"), /*1 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"), /*2 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA"), /*3 */ new cipher(SSLSocket.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA"), /*4 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"), /*5 */ new cipher(SSLSocket.TLS_DHE_DSS_WITH_AES_256_CBC_SHA, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"), /*6 */ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"), /*7 */ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"), /*8 */ new cipher(SSLSocket.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA"), /*9 */ new cipher(SSLSocket.TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA"), /*10 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"), /*11 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"), /*12 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"), /*13 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"), /*14 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA"), /*15 */ new cipher(SSLSocket.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA"), /*16 */ new cipher(SSLSocket.TLS_DHE_DSS_WITH_RC4_128_SHA, "TLS_DHE_DSS_WITH_RC4_128_SHA"), /*17 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"), /*18 */ new cipher(SSLSocket.TLS_DHE_DSS_WITH_AES_128_CBC_SHA, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"), /*19 */ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS_ECDH_RSA_WITH_RC4_128_SHA"), /*20 */ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"), /*21 */ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"), /*22 */ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"), /*23 */ new cipher(SSLSocket.TLS_RSA_WITH_SEED_CBC_SHA, "TLS_RSA_WITH_SEED_CBC_SHA"), /*24 */ new cipher(SSLSocket.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA"), /*25 */ new cipher(SSLSocket.SSL3_RSA_WITH_RC4_128_MD5, "SSL3_RSA_WITH_RC4_128_MD5"), /*26 */ new cipher(SSLSocket.SSL3_RSA_WITH_RC4_128_SHA, "SSL3_RSA_WITH_RC4_128_SHA"), /*27 */ new cipher(SSLSocket.TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"), /*28 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"), /*29 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"), /*30 */ new cipher(SSLSocket.SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA"), /*31 */ new cipher(SSLSocket.SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA, "SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA"), /*32 */ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"), /*33 */ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"), /*34 */ new cipher(SSLSocket.SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"), /*35 */ new cipher(SSLSocket.SSL3_RSA_WITH_3DES_EDE_CBC_SHA, "SSL3_RSA_WITH_3DES_EDE_CBC_SHA"), /*36 */ new cipher(SSLSocket.SSL3_DHE_RSA_WITH_DES_CBC_SHA, "SSL3_DHE_RSA_WITH_DES_CBC_SHA"), /*37 */ new cipher(SSLSocket.SSL3_DHE_DSS_WITH_DES_CBC_SHA, "SSL3_DHE_DSS_WITH_DES_CBC_SHA"), /*38 */ new cipher(SSLSocket.SSL_RSA_FIPS_WITH_DES_CBC_SHA, "SSL_RSA_FIPS_WITH_DES_CBC_SHA"), /*39 */ new cipher(SSLSocket.SSL3_RSA_WITH_DES_CBC_SHA, "SSL3_RSA_WITH_DES_CBC_SHA"), /*40 */ new cipher(SSLSocket.TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA"), /*41 */ new cipher(SSLSocket.TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA"), /*42 */ new cipher(SSLSocket.SSL3_RSA_EXPORT_WITH_RC4_40_MD5, "SSL3_RSA_EXPORT_WITH_RC4_40_MD5"), /*43 */ new cipher(SSLSocket.SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5, "SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5"), /*44 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"), /*45 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS_ECDHE_RSA_WITH_NULL_SHA"), /*46 */ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_NULL_SHA, "TLS_ECDH_RSA_WITH_NULL_SHA"), /*47 */ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS_ECDH_ECDSA_WITH_NULL_SHA"), /*48 */ new cipher(SSLSocket.SSL3_RSA_WITH_NULL_SHA, "SSL3_RSA_WITH_NULL_SHA"), /*49 */ new cipher(SSLSocket.SSL3_RSA_WITH_NULL_MD5, "SSL3_RSA_WITH_NULL_MD5"), /*50 */ new cipher(SSLSocket.TLS_RSA_WITH_NULL_SHA256, "TLS_RSA_WITH_NULL_SHA256"), /*51 */ new cipher(SSLSocket.TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256"), /*52 */ new cipher(SSLSocket.TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS_RSA_WITH_AES_256_CBC_SHA256"), /*53*/ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"), /*54*/ new cipher(SSLSocket.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"), /*55*/ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"), /*56*/ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"), /*57*/ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"), /*58*/ new cipher(SSLSocket.TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256"), /*59*/ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"), /*60*/ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), /*61*/ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"), /** /* SSL2 ciphersuites are here for legacy purposes. * you should call SSLSocket.enableSSL2Default(false) during your setup. * to disable all SSL2 ciphersuites. **/ /*62*/ new cipher(SSLSocket.SSL2_RC4_128_WITH_MD5, "SSL2_RC4_128_WITH_MD5"), /*63*/ new cipher(SSLSocket.SSL2_RC2_128_CBC_WITH_MD5, "SSL2_RC2_128_CBC_WITH_MD5"), /*64*/ new cipher(SSLSocket.SSL2_DES_192_EDE3_CBC_WITH_MD5, "SSL2_DES_192_EDE3_CBC_WITH_MD5"), /*65*/ new cipher(SSLSocket.SSL2_DES_64_CBC_WITH_MD5, "SSL2_DES_64_CBC_WITH_MD5"), /*66*/ new cipher(SSLSocket.SSL2_RC4_128_EXPORT40_WITH_MD5, "SSL2_RC4_128_EXPORT40_WITH_MD5"), /*67*/ new cipher(SSLSocket.SSL2_RC2_128_CBC_EXPORT40_WITH_MD5, "SSL2_RC2_128_CBC_EXPORT40_WITH_MD5"), /*68*/ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"), /*69*/ new cipher(SSLSocket.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"), /*70*/ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"), /*71*/ new cipher(SSLSocket.TLS_RSA_WITH_NULL_SHA256, "TLS_RSA_WITH_NULL_SHA256"), /*72*/ new cipher(SSLSocket.TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256"), /*73*/ new cipher(SSLSocket.TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS_RSA_WITH_AES_256_CBC_SHA256"), /*74*/ new cipher(SSLSocket.TLS_RSA_WITH_SEED_CBC_SHA, "TLS_RSA_WITH_SEED_CBC_SHA"), /*75*/ new cipher(SSLSocket.TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256"), /*76*/ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"), /*77*/ new cipher(SSLSocket.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"), /*78*/ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"), /*79*/ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"), /*80*/ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), /*81*/ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"), /*82*/ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"), /*83*/ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"), /*84*/ new cipher(SSLSocket.TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384"), /*85*/ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"), /*86*/ new cipher(SSLSocket.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"), /*87*/ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"), /*88*/ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"), /*89*/ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"), /*90*/ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"), /*91*/ new cipher(SSLSocket.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"), /*92*/ new cipher(SSLSocket.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"), /*93*/ new cipher(SSLSocket.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"), // TLSv1_3 /*94*/ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"), /*95*/ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"), /*96*/ new cipher(SSLSocket.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"), /*97*/ new cipher(SSLSocket.TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"), /*98*/ new cipher(SSLSocket.TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"), /*99*/ new cipher(SSLSocket.TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"), /*100*/ new cipher(SSLSocket.TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256"), /*101*/ new cipher(SSLSocket.TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256"), /*102*/ new cipher(SSLSocket.TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256"), /*103*/ new cipher(SSLSocket.TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256") }; /** Cipher supported by JSSE (JDK 1.5.x) */ public static String [] sslciphersarray_jdk150 = { // These ciphers must always pass "SSL_RSA_WITH_RC4_128_MD5", "SSL_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "SSL_RSA_WITH_DES_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_EXPORT_WITH_RC4_40_MD5", "SSL_RSA_WITH_NULL_MD5", }; /** Cipher supported by JSSE (JDK 1.4.x) */ public static String [] sslciphersarray_jdk142 = { "SSL_RSA_WITH_RC4_128_MD5", "SSL_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "SSL_RSA_WITH_DES_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_EXPORT_WITH_RC4_40_MD5", "SSL_RSA_WITH_NULL_MD5", }; } jss-4.6.3/org/mozilla/jss/tests/ConverterTestUtil.java000066400000000000000000000012651362106420000230300ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.x509.AVAValueConverter; public class ConverterTestUtil { public static byte[] convert(AVAValueConverter converter, String string, byte[] tags) throws Exception { DerOutputStream os = new DerOutputStream(); DerValue value = converter.getValue(string, tags); value.encode(os); return os.toByteArray(); } public static byte[] convert(AVAValueConverter converter, String string) throws Exception { return convert(converter, string, null); } } jss-4.6.3/org/mozilla/jss/tests/CrossHMACTest.java000077500000000000000000000155131362106420000217510ustar00rootroot00000000000000/* 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.tests; import java.security.MessageDigest; import org.mozilla.jss.CryptoManager; import java.security.Security; import java.security.Provider; import javax.crypto.*; import javax.crypto.spec.*; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.util.PasswordCallback; /** * HMAC is a hash function based message authentication code. * CrossHMACTest compares the HMAC created by Mozilla, IBM and Sun JCE. * * @author Sandeep.Konchady@Sun.COM * @version 1.0 */ public class CrossHMACTest { private CryptoManager cm; /** * JSS crypto provider name. */ static final String MOZ_PROVIDER_NAME = "Mozilla-JSS"; /** * List all the HMAC Algorithms that JSS implements. */ static final String JSS_HMAC_Algs[] = {"HmacSHA1", "HmacSHA256", "HmacSHA384", "HmacSHA512" }; public CrossHMACTest(String[] argv) throws Exception { if (argv.length < 1) { System.out.println( "Usage: java org.mozilla.jss.tests.CrossHMACTest " + " [password file only needed in FIPS mode]"); System.exit(1); } CryptoManager.initialize(argv[0]); cm = CryptoManager.getInstance(); if (cm.FIPSEnabled() == true) { System.out.println("\n\t\tFIPS enabled.\n"); if (argv.length == 2) { CryptoToken tok = cm.getInternalCryptoToken(); System.out.println("logging in to token: " + tok.getName()); PasswordCallback cb = new FilePasswordCallback(argv[1]); tok.login(cb); } } } public boolean compareHMAC(String alg, SecretKeyFacade sk, String clearText) throws Exception { byte[] providerHmacOut; byte[] mozillaHmacOut; boolean bTested = false; //Get the Mozilla HMAC Mac mozillaHmac = Mac.getInstance(alg, MOZ_PROVIDER_NAME); mozillaHmac.init(sk); mozillaHmac.update(clearText.getBytes()); mozillaHmacOut = mozillaHmac.doFinal(); // loop through all configured providers; if they support the // algorithm compare the result to Mozilla's HMAC Provider[] providers = Security.getProviders("Mac." + alg); String provider = null; for (int i = 0; i < providers.length; ++i) { provider = providers[i].getName(); //System.out.println ("Testing provider " + provider); if (provider.equals(MOZ_PROVIDER_NAME)) { continue; } Mac providerHmac = Mac.getInstance(alg, provider); providerHmac.init(sk); providerHmac.update(clearText.getBytes()); providerHmacOut = providerHmac.doFinal(); if (MessageDigest.isEqual(mozillaHmacOut, providerHmacOut)) { System.out.println(provider + " and " + MOZ_PROVIDER_NAME + " give same " + alg); bTested = true; } else { throw new Exception("ERROR: " + provider + " and " + MOZ_PROVIDER_NAME + " give different " + alg); } } return bTested; } public void doHMAC(String alg, SecretKeyFacade sk, String clearText) throws Exception { byte[] mozillaHmacOut; //Get the Mozilla HMAC Mac mozillaHmac = Mac.getInstance(alg, MOZ_PROVIDER_NAME); mozillaHmac.init(sk); mozillaHmacOut = mozillaHmac.doFinal(clearText.getBytes()); if (mozillaHmacOut.length == mozillaHmac.getMacLength()) { System.out.println(MOZ_PROVIDER_NAME + " supports " + mozillaHmac.getAlgorithm() + " and the output size is " + mozillaHmac.getMacLength()); } else { throw new Exception("ERROR: hmac output size is " + mozillaHmacOut.length + ", should be " + mozillaHmac.getMacLength()); } } public boolean fipsMode() { return cm.FIPSEnabled(); } /** * Main test method. * @param argv */ public static void main(String[] argv) { try { CrossHMACTest hmacTest = new CrossHMACTest(argv); //The secret key must be a JSS key. That is, it must be an //instanceof org.mozilla.jss.crypto.SecretKeyFacade. //Generate the secret key using PKCS # 5 password Based Encryption //we have to specify a salt and an iteration count. PBEKeySpec pbeKeySpec; SecretKeyFactory keyFac; SecretKeyFacade sk; byte[] salt = { (byte) 0x0a, (byte) 0x6d, (byte) 0x07, (byte) 0xba, (byte) 0x1e, (byte) 0xbd, (byte) 0x72, (byte) 0xf1 }; int iterationCount = 7; pbeKeySpec = new PBEKeySpec("password".toCharArray(), salt, iterationCount); keyFac = SecretKeyFactory.getInstance("PBEWithSHA1AndDES3", "Mozilla-JSS"); sk = (SecretKeyFacade) keyFac.generateSecret(pbeKeySpec); ///////////////////////////////////////////////////////////// // Test all available algorithms ///////////////////////////////////////////////////////////// String clearText = new String("FireFox and Thunderbird rule"); for (int i = 0; i < JSS_HMAC_Algs.length; i++) { if (hmacTest.fipsMode()) { //In FIPS Mode only test JSS due to NSS prevents //key data from being extracted above the //NSS cryptographic boundary when FIPS mode //is enabled. //note there is a bug with HmacSHA512 in fipsmode. //https://bugzilla.mozilla.org/show_bug.cgi?id=436907 if (!JSS_HMAC_Algs[i].equals("HmacSHA512")) { hmacTest.doHMAC(JSS_HMAC_Algs[i], sk, clearText); } } else { // compare MOZ_PROVIDER_NAME implementation with all // providers that also support the given algorithm if (!hmacTest.compareHMAC( JSS_HMAC_Algs[i], sk, clearText)) { // no provider to compare results with so just test JSS hmacTest.doHMAC(JSS_HMAC_Algs[i], sk, clearText); } } } } catch (Exception e) { e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.6.3/org/mozilla/jss/tests/DEROutputStreamTests.java000066400000000000000000000047421362106420000234200ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.mozilla.jss.netscape.security.util.*; import java.math.*; public class DEROutputStreamTests { public static void assert_f(boolean expr, String location) { if (!expr) { System.err.println("Assertion: " + location); assert(expr); } } public static void testInteger(int value, byte[] expected) throws Exception { DerOutputStream out = new DerOutputStream(); BigInt num = new BigInt(value); out.putInteger(num); byte[] actual = out.toByteArray(); assert_f(actual.length == expected.length, "value=" + value); for (int i = 0; i < actual.length; i++) { assert_f(actual[i] == expected[i], "value=" + value + "|i=" + i); } } public static void testIntegers() throws Exception { int[] values = {0, 127, 128, 256}; byte[][] expected = {{0x02, 0x01, 0x00}, {0x02, 0x01, 0x7F}, {0x02, 0x02, 0x00, (byte) 0x80}, {0x02, 0x02, 0x01, 0x00}}; assert_f(values.length == expected.length, "testIntegers test cases"); for (int i = 0; i < values.length; i++ ) { testInteger(values[i], expected[i]); } } public static void testEnumeration(int value, byte[] expected) throws Exception { DerOutputStream out = new DerOutputStream(); out.putEnumerated(value); byte[] actual = out.toByteArray(); assert_f(actual.length == expected.length, "value=" + value); for (int i = 0; i < actual.length; i++ ) { assert_f(actual[i] == expected[i], "value=" + value + "|i=" + i); } } public static void testEnumerations() throws Exception { int[] values = {0, 1, 127, 128, 256, -128, -129}; byte[][] expected = {{0x0A, 0x01, 0x00}, {0x0A, 0x01, 0x01}, {0x0A, 0x01, 0x7F}, {0x0A, 0x02, 0x00, (byte) 0x80}, {0x0A, 0x02, 0x01, 0x00}, {0x0A, 0x01, (byte) 0x80}, {0x0A, 0x02, (byte) 0xFF, 0x7F}}; assert(values.length == expected.length); for (int i = 0; i < values.length; i++ ) { testEnumeration(values[i], expected[i]); } } public static void main(String[] args) throws Exception { testIntegers(); testEnumerations(); } } jss-4.6.3/org/mozilla/jss/tests/DigestTest.java000066400000000000000000000115431362106420000214420ustar00rootroot00000000000000/* 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.tests; import java.io.FileInputStream; import java.security.MessageDigest; import java.security.Provider; import java.security.Security; import org.mozilla.jss.CryptoManager; public class DigestTest { /** * This is the name of the JSS crypto provider for use with * MessageDigest.getInstance(). */ static final String MOZ_PROVIDER_NAME = "Mozilla-JSS"; /** * List all the Digest Algorithms that JSS implements. */ static final String JSS_Digest_Algs[] = { "MD2", "MD5", "SHA-1", "SHA-256", "SHA-384","SHA-512"}; public static boolean messageDigestCompare(String alg, byte[] toBeDigested) throws Exception { byte[] otherDigestOut; byte[] mozillaDigestOut; boolean bTested = false; // get the digest for the Mozilla-JSS provider java.security.MessageDigest mozillaDigest = java.security.MessageDigest.getInstance(alg, MOZ_PROVIDER_NAME); mozillaDigestOut = mozillaDigest.digest(toBeDigested); // loop through all the providers that support the algorithm // compare the result to Mozilla-JSS's digest Provider[] providers = Security.getProviders("MessageDigest." + alg); String provider = null; for (int i = 0; i < providers.length; ++i) { provider = providers[i].getName(); if (provider.equals(MOZ_PROVIDER_NAME)) { continue; } java.security.MessageDigest otherDigest = java.security.MessageDigest.getInstance(alg, provider); otherDigestOut = otherDigest.digest(toBeDigested); if( MessageDigest.isEqual(mozillaDigestOut, otherDigestOut) ) { System.out.println(provider + " and " + MOZ_PROVIDER_NAME + " give same " + alg + " message digests"); bTested = true; } else { throw new Exception("ERROR: " + provider + " and " + MOZ_PROVIDER_NAME + " give different " + alg + " message digests"); } } return bTested; } public static boolean testJSSDigest(String alg, byte[] toBeDigested) throws Exception { byte[] mozillaDigestOut; java.security.MessageDigest mozillaDigest = java.security.MessageDigest.getInstance(alg, MOZ_PROVIDER_NAME); mozillaDigestOut = mozillaDigest.digest(toBeDigested); if( mozillaDigestOut.length == mozillaDigest.getDigestLength() ) { System.out.println(mozillaDigest.getAlgorithm() + " " + " digest output size is " + mozillaDigestOut.length); } else { throw new Exception("ERROR: digest output size is "+ mozillaDigestOut.length + ", should be "+ mozillaDigest.getDigestLength() ); } return true; } public static void main(String []argv) { try { if( argv.length != 2 ) { System.out.println( "Usage: java org.mozilla.jss.tests.DigestTest " + " "); System.exit(1); } String dbdir = argv[0]; byte[] toBeDigested; int read; try (FileInputStream fis = new FileInputStream(argv[1])) { toBeDigested = new byte[fis.available()]; read = fis.read(toBeDigested); } System.out.println(read + " bytes to be digested"); CryptoManager.initialize(dbdir); ///////////////////////////////////////////////////////////// // Test all available algorithms ///////////////////////////////////////////////////////////// String javaVersion = System.getProperty("java.version"); System.out.println("The Java version is: " + javaVersion); for (int i = 0; i < JSS_Digest_Algs.length; i++) { // compare Mozilla-JSS implementation with all providers // that also support the given algorithm if (messageDigestCompare(JSS_Digest_Algs[i], toBeDigested) == false) { // no provider to compare results with testJSSDigest(JSS_Digest_Algs[i], toBeDigested); } } //HMAC examples in org.mozilla.jss.tests.HMACTest } catch( Exception e ) { e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.6.3/org/mozilla/jss/tests/DirStrConverterTest.java000066400000000000000000000105201362106420000233140ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.junit.Assert; import org.junit.Test; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.x509.DirStrConverter; public class DirStrConverterTest { @Test public void testEmptyString() throws Exception { String string = ""; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testNullCharacters() throws Exception { String string = StringTestUtil.NULL_CHARS; System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_T61String, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testPrintableCharacters() throws Exception { String string = StringTestUtil.PRINTABLE_CHARS; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testControlCharacters() throws Exception { String string = StringTestUtil.CONTROL_CHARS; System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_T61String, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testMultibyteCharacters() throws Exception { String string = StringTestUtil.MULTIBYTE_CHARS; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_UniversalString, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testPrintableCharactersWithTags() throws Exception { String string = StringTestUtil.PRINTABLE_CHARS; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string, new byte[] { DerValue.tag_IA5String, DerValue.tag_UTF8String }); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testMultibyteCharactersWithTags() throws Exception { String string = StringTestUtil.MULTIBYTE_CHARS; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_UTF8String, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string, new byte[] { DerValue.tag_IA5String, DerValue.tag_UTF8String }); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } } jss-4.6.3/org/mozilla/jss/tests/EmptyDerValue.java000066400000000000000000000011111362106420000220770ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.io.IOException; import org.mozilla.jss.netscape.security.util.DerValue; /* * Regression test: check that a zero-length derValue doesn't create a parsing * exception. * * Fixed by Fraser Tweedale in https://github.com/dogtagpki/jss/pull/89 * * Upstream Issue: https://pagure.io/dogtagpki/issue/3079 */ class EmptyDerValue { public static void main(String[] args) throws Exception { byte[] bytes = { 0x04, 0x00 }; DerValue derVal = new DerValue(bytes); System.out.println(derVal.getOctetString()); } } jss-4.6.3/org/mozilla/jss/tests/EnumerationZeroTest.java000066400000000000000000000200221362106420000233410ustar00rootroot00000000000000/** * Copyright (c) 2009 - 2018 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. * * Submitted by Alex Wood as an attachment to BZ#1582323. Used with * permission. */ package org.mozilla.jss.tests; import org.mozilla.jss.JSSProvider; import org.mozilla.jss.netscape.security.util.BitArray; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.x509.AuthorityKeyIdentifierExtension; import org.mozilla.jss.netscape.security.x509.CRLExtensions; import org.mozilla.jss.netscape.security.x509.CRLNumberExtension; import org.mozilla.jss.netscape.security.x509.CRLReasonExtension; import org.mozilla.jss.netscape.security.x509.Extension; import org.mozilla.jss.netscape.security.x509.KeyIdentifier; import org.mozilla.jss.netscape.security.x509.RevocationReason; import org.mozilla.jss.netscape.security.x509.RevokedCertImpl; import org.mozilla.jss.netscape.security.x509.RevokedCertificate; import org.mozilla.jss.netscape.security.x509.X500Name; import org.mozilla.jss.netscape.security.x509.X509CRLImpl; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Security; import java.security.cert.CertificateFactory; import java.security.cert.X509CRL; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; /** Class to demonstrate DER encoding failure when using an ASN.1 enumerated type with a value of zero. * * RFC 5280's section 5.3.1 lists the valid values for certificate revocation codes: * * CRLReason ::= ENUMERATED { * unspecified (0), * keyCompromise (1), * cACompromise (2), * affiliationChanged (3), * superseded (4), * cessationOfOperation (5), * certificateHold (6), * -- value 7 is not used * removeFromCRL (8), * privilegeWithdrawn (9), * aACompromise (10) } * */ public class EnumerationZeroTest { static { // Satellite 6 is only supported on 64 bit architectures Security.addProvider(new JSSProvider()); } private EnumerationZeroTest() { } public static String toHex(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 2); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); } /** * Calculate the KeyIdentifier for an RSAPublicKey and place it in an AuthorityKeyIdentifier extension. * * Java encodes RSA public keys using the SubjectPublicKeyInfo type described in RFC 5280. *

     * SubjectPublicKeyInfo  ::=  SEQUENCE  {
     *   algorithm            AlgorithmIdentifier,
     *   subjectPublicKey     BIT STRING  }
     *
     * AlgorithmIdentifier  ::=  SEQUENCE  {
     *   algorithm               OBJECT IDENTIFIER,
     *   parameters              ANY DEFINED BY algorithm OPTIONAL  }
     * 
* * A KeyIdentifier is a SHA-1 digest of the subjectPublicKey bit string from the ASN.1 above. * * @param key the RSAPublicKey to use * @return an AuthorityKeyIdentifierExtension based on the key * @throws IOException if we can't construct a MessageDigest object. */ public static AuthorityKeyIdentifierExtension buildAuthorityKeyIdentifier(RSAPublicKey key) throws IOException { try { MessageDigest d = MessageDigest.getInstance("SHA-1"); byte[] encodedKey = key.getEncoded(); DerInputStream s = new DerValue(encodedKey).toDerInputStream(); // Skip the first item in the sequence, AlgorithmIdentifier. // The parameter, startLen, is required for skipSequence although it's unused. s.skipSequence(0); // Get the subjectPublicKey bit string BitArray b = s.getUnalignedBitString(); byte[] digest = d.digest(b.toByteArray()); KeyIdentifier ki = new KeyIdentifier(digest); return new AuthorityKeyIdentifierExtension(ki, null, null); } catch (NoSuchAlgorithmException e) { throw new IOException("Could not find SHA1 implementation", e); } } /** * Output the DER encoding of a CRLExtension for examination */ public static void outputExtension(CRLReasonExtension ext) throws Exception { ByteArrayOutputStream resultBytesOut = new ByteArrayOutputStream(); ext.encode(resultBytesOut); byte[] encodedBytes = resultBytesOut.toByteArray(); System.out.print("Full encoded extension: " + toHex(encodedBytes)); Extension reasonExt = new Extension(new DerValue(encodedBytes)); System.out.print("\tEncoded CRL Reason: " + toHex(reasonExt.getExtensionValue())); DerValue reasonValue = new DerValue(reasonExt.getExtensionValue()); System.out.println("\tReason value: " + reasonValue.getEnumerated()); } /** * Build a CRL using JSS * @param useZero whether or not to try creating a CRLEntry with the reason set to "unspecified" * @return an X509CRL object * @throws Exception if anything goes wrong */ public static X509CRL buildCrl(boolean useZero) throws Exception { KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); generator.initialize(2048); KeyPair kp = generator.generateKeyPair(); List revokedCerts = new ArrayList<>(); for (int i = 0; i <= 10; i++) { // 7 is an unused value in the enumeration if (i == 7 || (i == 0 && !useZero)) { continue; } CRLReasonExtension reasonExt = new CRLReasonExtension(RevocationReason.fromInt(i)); outputExtension(reasonExt); CRLExtensions entryExtensions = new CRLExtensions(); entryExtensions.add(reasonExt); revokedCerts.add( new RevokedCertImpl(BigInteger.valueOf((long) i), new Date(), entryExtensions)); } CRLExtensions crlExtensions = new CRLExtensions(); crlExtensions.add(new CRLNumberExtension(BigInteger.ONE)); crlExtensions.add(buildAuthorityKeyIdentifier((RSAPublicKey) kp.getPublic())); X500Name issuer = new X500Name("CN=Test"); Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_MONTH, 365); Date until = calendar.getTime(); X509CRLImpl crlImpl = new X509CRLImpl( issuer, now, until, revokedCerts.toArray(new RevokedCertificate[] {}), crlExtensions ); crlImpl.sign(kp.getPrivate(), "SHA256withRSA"); CertificateFactory cf = CertificateFactory.getInstance("X.509"); byte[] data = crlImpl.getEncoded(); return (X509CRL) cf.generateCRL(new ByteArrayInputStream(data)); } public static void main(String[] args) { try { X509CRL crl = buildCrl(false); System.out.println(crl.toString()); buildCrl(true); // will throw exception } catch (Exception e) { e.printStackTrace(); } } } jss-4.6.3/org/mozilla/jss/tests/FilePasswordCallback.java000066400000000000000000000026211362106420000233770ustar00rootroot00000000000000/* 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.tests; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import org.mozilla.jss.util.Password; import org.mozilla.jss.util.PasswordCallback; import org.mozilla.jss.util.PasswordCallbackInfo; /** */ public class FilePasswordCallback implements PasswordCallback { private Properties passwords; public FilePasswordCallback(String filename) throws IOException { passwords = new Properties(); try (FileInputStream in = new FileInputStream(filename)) { passwords.load(in); } } /** */ public Password getPasswordFirstAttempt(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { String pw = passwords.getProperty(info.getName()); if( pw == null ) { throw new PasswordCallback.GiveUpException(); } else { System.out.println("***FilePasswordCallback returns " + pw); return new Password(pw.toCharArray()); } } /** */ public Password getPasswordAgain(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { throw new PasswordCallback.GiveUpException(); } } jss-4.6.3/org/mozilla/jss/tests/FipsTest.java000066400000000000000000000135331362106420000211250ustar00rootroot00000000000000/* 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.tests; import java.util.Enumeration; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.InitializationValues; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.pkcs11.PK11Module; import org.mozilla.jss.pkcs11.PK11Token; import org.mozilla.jss.util.PasswordCallback; public class FipsTest { public static void main(String args[]) { try { if( args.length < 2 ) { System.out.println("Usage: FipsTest "); return; } String dbdir = args[0]; String fipsmode = args[1]; String password = ""; if (args.length == 3) { password = args[2]; System.out.println("The password file " +password); } InitializationValues vals = new InitializationValues(dbdir); System.out.println("output of Initilization values "); System.out.println("Manufacturer ID: " + vals.getManufacturerID()); System.out.println("Library: " + vals.getLibraryDescription()); System.out.println("Internal Slot: " + vals.getInternalSlotDescription()); System.out.println("Internal Token: " + vals.getInternalTokenDescription()); System.out.println("Key Storage Slot: " + vals.getFIPSKeyStorageSlotDescription()); System.out.println("Key Storage Token: " + vals.getInternalKeyStorageTokenDescription()); System.out.println("FIPS Slot: " + vals.getFIPSSlotDescription()); System.out.println("FIPS Key Storage: " + vals.getFIPSKeyStorageSlotDescription()); if (fipsmode.equalsIgnoreCase("enable")) { vals.fipsMode = InitializationValues.FIPSMode.ENABLED; } else if (fipsmode.equalsIgnoreCase("disable")){ vals.fipsMode = InitializationValues.FIPSMode.DISABLED; } else { vals.fipsMode = InitializationValues.FIPSMode.UNCHANGED; } CryptoManager.initialize(vals); CryptoManager cm = CryptoManager.getInstance(); if (cm.FIPSEnabled() == true ) { System.out.println("\n\t\tFIPS enabled\n"); } else { System.out.println("\n\t\tFIPS not enabled\n"); } Enumeration modules = cm.getModules(); System.out.println("\nListing of Modules:"); while (modules.hasMoreElements()) { System.out.println("\t"+ modules.nextElement().getName() ); } CryptoToken tok; String tokenName; Enumeration tokens = cm.getAllTokens(); System.out.println("\nAll Tokens:"); while (tokens.hasMoreElements()) { tok = tokens.nextElement(); System.out.print("\t" + tok.getName()); if (tok.needsLogin() == true){ System.out.println("\t - Needs login.\n"); } else { System.out.println("\t - Does not need login.\n"); } } tokens = cm.getExternalTokens(); System.out.println("\nExternal Tokens:"); while(tokens.hasMoreElements()) { System.out.println("\t"+ tokens.nextElement().getName() ); } /* find the Internal Key Storage token */ if (cm.FIPSEnabled() == true ) { tokenName = vals.getFIPSSlotDescription(); } else { tokenName = vals.getInternalKeyStorageTokenDescription(); } /* truncate to 32 bytes and remove trailing white space*/ tokenName = tokenName.substring(0, 32); tokenName = tokenName.trim(); System.out.println("\nFinding the Internal Key Storage token: "+ tokenName); tok = cm.getTokenByName(tokenName); if( ((PK11Token)tok).isInternalKeyStorageToken() && tok.equals(cm.getInternalKeyStorageToken()) ) { System.out.println("Good, "+tok.getName()+", knows it is " + "the internal Key Storage Token"); } else { System.out.println("ERROR: "+tok.getName()+", doesn't know"+ " it is the internal key storage token"); } if (!password.equals("")) { System.out.println("logging in to the Token: " + tok.getName()); PasswordCallback cb = new FilePasswordCallback(password); tok.login(cb); System.out.println("logged in to the Token: " + tok.getName()); } /* find the Internal Crypto token */ if (cm.FIPSEnabled() == true ) { tokenName = vals.getFIPSSlotDescription(); } else { tokenName = vals.getInternalTokenDescription(); } /* truncate to 32 bytes and remove trailing white space*/ tokenName = tokenName.substring(0, 32); tokenName = tokenName.trim(); System.out.println("\nFinding the Internal Crypto token: " + tokenName); tok = cm.getTokenByName(tokenName); if( ((PK11Token)tok).isInternalCryptoToken() && tok.equals(cm.getInternalCryptoToken() )) { System.out.println("Good, "+tok.getName()+ ", knows it is the internal Crypto token"); } else { System.out.println("ERROR: "+tok.getName()+ ", doesn't know that it is the internal Crypto token"); } System.exit(0); } catch( Exception e ) { e.printStackTrace(); System.exit(1); } } } jss-4.6.3/org/mozilla/jss/tests/GenerateTestCert.java000077500000000000000000000301621362106420000225740ustar00rootroot00000000000000/* 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/. */ /** * GenerateTestCert is a class for generating SSL test certificates for * the JSS tests (all.pl). You should use certutil to create * your certificates. * */ package org.mozilla.jss.tests; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.*; import org.mozilla.jss.pkix.cert.Certificate; import org.mozilla.jss.util.PasswordCallback; import java.util.Calendar; import java.util.Date; import java.security.*; import java.security.PrivateKey; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.InternalCertificate; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.X509Certificate; public class GenerateTestCert { private X509Certificate nssServerCert, nssClientCert; static final private String CACERT_NICKNAME = "JSSCATestCert"; static final private String SERVERCERT_NICKNAME = "JSSTestServerCert"; static final private String CLIENTCERT_NICKNAME = "JSSTestClientCert"; private String keyType = "RSA"; private int keyLength = 4096; private SignatureAlgorithm sigAlg = SignatureAlgorithm.RSASignatureWithSHA256Digest; /** * Main method for testing and generating cert pairs. */ public static void main(String[] args) throws Exception { GenerateTestCert gtc = new GenerateTestCert(); if ( args.length > 0 ) { gtc.doIt(args); } else { gtc.usage(); } } public void usage() { System.out.println("USAGE: " + "java org.mozilla.jss.tests.GenerateTestCert " + " [hostname] " + "[Signature Alg] [CAcertNickname] " + "[ServerCertNickname] [ClientCertNickName]"); System.out.println("This program creates self signed Certificates." + "They are only meant for testing and should never be " + "used in production. " + "\nThe default nicknames:" + "\n\tCA certificate: " + CACERT_NICKNAME + "\n\tServer certificate: " + SERVERCERT_NICKNAME + "\n\tClient certificate: " + CLIENTCERT_NICKNAME); System.out.println("Signature algorithm values:\n" + "\tSHA-1/RSA" + "\tSHA-256/RSA" + "\tSHA-384/RSA" + "\tSHA-512/RSA" + "\tSHA-1/DSA" + "\tSHA-1/EC" + "\tSHA-256/EC" + "\tSHA-384/EC" + "\tSHA-512/EC"); System.exit(1); } private void setSigAlg(String alg) { if (alg.equalsIgnoreCase("SHA-1/RSA")) { sigAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest; } else if (alg.equalsIgnoreCase("SHA-256/RSA")) { sigAlg = SignatureAlgorithm.RSASignatureWithSHA256Digest; } else if (alg.equalsIgnoreCase("SHA-384/RSA")) { sigAlg = SignatureAlgorithm.RSASignatureWithSHA384Digest; } else if (alg.equalsIgnoreCase("SHA-512/RSA")) { sigAlg = SignatureAlgorithm.RSASignatureWithSHA512Digest; } else if (alg.equalsIgnoreCase("SHA-1/DSA")) { sigAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest; } else if (alg.equalsIgnoreCase("SHA-1/EC")) { sigAlg = SignatureAlgorithm.ECSignatureWithSHA1Digest; } else if (alg.equalsIgnoreCase("SHA-256/EC")) { sigAlg = SignatureAlgorithm.ECSignatureWithSHA256Digest; } else if (alg.equalsIgnoreCase("SHA-384/EC")) { sigAlg = SignatureAlgorithm.ECSignatureWithSHA384Digest; } else if (alg.equalsIgnoreCase("SHA-512/EC")) { sigAlg = SignatureAlgorithm.ECSignatureWithSHA512Digest; } else { usage(); } if (alg.endsWith("RSA")) { keyType = "RSA"; } else if (alg.endsWith("DSA")) { keyType = "DSA"; keyLength = 1024; } else if (alg.endsWith("EC")) { keyType = "EC"; keyLength = 256; } else { usage(); } } /** * Based on the input parameters, generate a cert * pair. */ private void doIt(String[] args) throws Exception { String caCertNick = CACERT_NICKNAME; String serverCertNick = SERVERCERT_NICKNAME; String clientCertNick = CLIENTCERT_NICKNAME; if ( args.length < 3 ) { usage(); } try { CryptoManager.initialize(args[0]); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(args[1]); tok.login(cb); int serialNum = new Integer(args[2]).intValue(); X509Certificate[] permCerts = cm.getPermCerts(); int originalPermCerts = permCerts.length; System.out.println("Number of certificates stored in the " + " database: " + originalPermCerts); String hostname = "localhost"; if (args.length > 4) { hostname = args[3]; } String alg = "SHA-256/RSA"; if (args.length > 5) { alg = args[4]; } setSigAlg(alg); X509Certificate[] certs; if (args.length > 6) { caCertNick = args[5]; } /* ensure certificate does not already exists */ certs = cm.findCertsByNickname(caCertNick); if (certs.length > 0) { System.out.println(caCertNick + " already exists!"); System.exit(1); } if (args.length > 7) { serverCertNick = args[6]; } certs = cm.findCertsByNickname(serverCertNick); if (certs.length > 0) { System.out.println(serverCertNick + " already exists!"); System.exit(1); } if (args.length == 8) { clientCertNick = args[7]; } certs = cm.findCertsByNickname(clientCertNick); if (certs.length > 0) { System.out.println(clientCertNick + " already exists!"); System.exit(1); } // generate CA cert java.security.KeyPairGenerator kpg = java.security.KeyPairGenerator.getInstance( keyType, "Mozilla-JSS"); kpg.initialize(keyLength); KeyPair caPair = kpg.genKeyPair(); SEQUENCE extensions = new SEQUENCE(); extensions.addElement(makeBasicConstraintsExtension()); Certificate caCert = makeCert("CACert", "CACert", serialNum, caPair.getPrivate(), caPair.getPublic(), serialNum, extensions); X509Certificate nssCaCert = cm.importUserCACertPackage( ASN1Util.encode(caCert), caCertNick); InternalCertificate intern = (InternalCertificate)nssCaCert; intern.setSSLTrust( InternalCertificate.TRUSTED_CA | InternalCertificate.TRUSTED_CLIENT_CA | InternalCertificate.VALID_CA); // generate server cert kpg.initialize(keyLength); KeyPair serverPair = kpg.genKeyPair(); Certificate serverCert = makeCert("CACert", hostname, serialNum+1, caPair.getPrivate(), serverPair.getPublic(), serialNum, null); nssServerCert = cm.importCertPackage( ASN1Util.encode(serverCert), serverCertNick); // generate client auth cert kpg.initialize(keyLength); KeyPair clientPair = kpg.genKeyPair(); Certificate clientCert = makeCert("CACert", "ClientCert", serialNum+2, caPair.getPrivate(), clientPair.getPublic(), serialNum, null); nssClientCert = cm.importCertPackage( ASN1Util.encode(clientCert), clientCertNick); System.out.println("\nThis program created certificates with \n" + "following cert nicknames:" + "\n\t" + caCertNick + "\n\t" + serverCertNick + "\n\t" + clientCertNick); permCerts = cm.getPermCerts(); if ( (originalPermCerts + 3) != permCerts.length) { System.out.println("Error there should be three more " + " certificates stored in the database"); System.exit(1); } else { System.out.println("Number of certificates stored in the " + " database: " + permCerts.length); } /* ensure certificates exists */ certs = cm.findCertsByNickname(caCertNick); if (certs.length == 0) { System.out.println(caCertNick + " should exist!"); System.exit(1); } certs = cm.findCertsByNickname(serverCertNick); if (certs.length == 0) { System.out.println(serverCertNick + " should exist!"); System.exit(1); } certs = cm.findCertsByNickname(clientCertNick); if (certs.length == 0) { System.out.println(clientCertNick + " should exist!"); System.exit(1); } } catch(Exception e) { e.printStackTrace(); System.exit(1); } System.exit(0); } /** * Make basic extension. */ private Extension makeBasicConstraintsExtension() throws Exception { SEQUENCE bc = new SEQUENCE(); bc.addElement( new BOOLEAN(true) ); // cA OBJECT_IDENTIFIER bcOID = new OBJECT_IDENTIFIER( new long[] {2, 5, 29, 19}); // from RFC 2459 OCTET_STRING enc = new OCTET_STRING(ASN1Util.encode(bc)); return new Extension(bcOID, true, enc); } /** * Method that generates a certificate for given credential * * @param issuerName * @param subjectName * @param serialNumber * @param privKey * @param pubKey * @param rand * @param extensions * @throws java.lang.Exception * @return */ private Certificate makeCert(String issuerName, String subjectName, int serialNumber, PrivateKey privKey, PublicKey pubKey, int rand, SEQUENCE extensions) throws Exception { AlgorithmIdentifier sigAlgID = new AlgorithmIdentifier(sigAlg.toOID()); Name issuer = new Name(); issuer.addCountryName("US"); issuer.addOrganizationName("Mozilla"); issuer.addOrganizationalUnitName("JSS Testing" + rand); issuer.addCommonName(issuerName); Name subject = new Name(); subject.addCountryName("US"); subject.addOrganizationName("Mozilla"); subject.addOrganizationalUnitName("JSS Testing" + rand); subject.addCommonName(subjectName); Calendar cal = Calendar.getInstance(); Date notBefore = cal.getTime(); cal.add(Calendar.YEAR, 1); Date notAfter = cal.getTime(); SubjectPublicKeyInfo.Template spkiTemp = new SubjectPublicKeyInfo.Template(); SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) ASN1Util.decode(spkiTemp, pubKey.getEncoded()); CertificateInfo info = new CertificateInfo( CertificateInfo.v3, new INTEGER(serialNumber), sigAlgID, issuer, notBefore, notAfter, subject, spki); if( extensions != null ) { info.setExtensions(extensions); } return new Certificate(info, privKey, sigAlg); } } jss-4.6.3/org/mozilla/jss/tests/GenericASN1ExtensionTest.java000066400000000000000000000047271362106420000241250ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.util.Hashtable; import org.junit.Assert; import org.junit.Test; import org.mozilla.jss.netscape.security.extensions.GenericASN1Extension; import org.mozilla.jss.netscape.security.x509.OIDMap; public class GenericASN1ExtensionTest { //@Test public void testConstructorArgs() throws Exception { String name1 = "testExtension1"; String oid1 = "1.2.3.4"; String pattern = ""; Hashtable config = new Hashtable(); GenericASN1Extension extension1 = new GenericASN1Extension(name1, oid1, pattern, false, config); Assert.assertEquals(name1, extension1.getName()); Assert.assertNotNull(OIDMap.getClass(name1)); String name2 = "testExtension2"; String oid2 = "2.4.6.8"; GenericASN1Extension extension2 = new GenericASN1Extension(name2, oid2, pattern, false, config); Assert.assertEquals(name2, extension2.getName()); Assert.assertNotNull(OIDMap.getClass(name2)); } @Test public void testConstructorJustConfig() throws Exception { String name1 = "testExtension1"; String oid1 = "1.2.3.4"; String pattern = ""; Hashtable config = new Hashtable(); config.put("oid", oid1); config.put("name", name1); config.put("pattern", pattern); config.put("critical", "true"); GenericASN1Extension extension1 = new GenericASN1Extension(config); Assert.assertEquals(name1, extension1.getName()); //Assert.assertNotNull(OIDMap.getClass(name1)); String name2 = "testExtension2"; String oid2 = "2.4.6.8"; config.put("oid", oid2); config.put("name", name2); GenericASN1Extension extension2 = new GenericASN1Extension(config); Assert.assertEquals(name2, extension2.getName()); //Assert.assertNotNull(OIDMap.getClass(name2)); OutputStream outputStream = new ByteArrayOutputStream(); extension1.encode(outputStream); extension2.encode(outputStream); } @Test public void testConstructorDER() throws Exception { byte[] value = new byte[0]; GenericASN1Extension extension = new GenericASN1Extension(true, value); OutputStream outputStream = new ByteArrayOutputStream(); extension.encode(outputStream); } } jss-4.6.3/org/mozilla/jss/tests/GenericValueConverterTest.java000066400000000000000000000110311362106420000244540ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.junit.Assert; import org.junit.Test; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.x509.GenericValueConverter; public class GenericValueConverterTest { @Test public void testEmptyString() throws Exception { String string = ""; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testNullCharacters() throws Exception { String string = StringTestUtil.NULL_CHARS; System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testPrintableCharacters() throws Exception { String string = StringTestUtil.PRINTABLE_CHARS; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testControlCharacters() throws Exception { String string = StringTestUtil.CONTROL_CHARS; System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testMultibyteCharacters() throws Exception { String string = StringTestUtil.MULTIBYTE_CHARS; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_BMPString, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); actual = StringTestUtil.normalizeUnicode(actual); System.out.println(" - norm. : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testPrintableCharactersWithTags() throws Exception { String string = StringTestUtil.PRINTABLE_CHARS; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_T61String, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string, new byte[] { DerValue.tag_T61String, DerValue.tag_UniversalString }); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testMultibyteCharactersWithTags() throws Exception { String string = StringTestUtil.MULTIBYTE_CHARS; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_UniversalString, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string, new byte[] { DerValue.tag_T61String, DerValue.tag_UniversalString }); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } } jss-4.6.3/org/mozilla/jss/tests/HmacTest.java000066400000000000000000000054051362106420000210730ustar00rootroot00000000000000 package org.mozilla.jss.tests; import java.security.Key; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.InitializationValues; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.SymmetricKey; public class HmacTest { private static final String INTERNAL_KEY_STORAGE_TOKEN = new InitializationValues("").getInternalKeyStorageTokenDescription().trim(); private static final String NSS_DATABASE_DIR = "sql:data"; private static final String PROVIDER = "Mozilla-JSS"; public static void main(String[] args) throws Exception { String algorithm = "hmac-sha1"; configureCrypto(args); Mac mac = Mac.getInstance(algorithm, PROVIDER); byte[] keyData = new byte[16]; Key key = importHmacSha1Key(keyData); mac.init(key); doHMAC(mac,"Dogtag rules!"); System.out.println("Done"); } private static void configureCrypto(String[] args) throws Exception { InitializationValues initializationValues = new InitializationValues(args[0]); CryptoManager.initialize(initializationValues); CryptoManager cryptoManager = CryptoManager.getInstance(); CryptoToken cryptoToken = cryptoManager.getTokenByName(INTERNAL_KEY_STORAGE_TOKEN); cryptoManager.setThreadToken(cryptoToken); } private static Key importHmacSha1Key(byte[] key) throws Exception { SecretKeyFactory factory = SecretKeyFactory.getInstance("HmacSHA1", "Mozilla-JSS"); return factory.generateSecret(new SecretKeySpec(key, "HmacSHA1")); } private static synchronized Key getWrappingKey() throws Exception { final String keyGenAlgorithm = "AES"; final int wrappingKeyLength = 256; KeyGenerator keyGen = KeyGenerator.getInstance(keyGenAlgorithm, PROVIDER); keyGen.init(wrappingKeyLength); return keyGen.generateKey(); } public static void doHMAC(Mac mozillaHmac, String clearText) throws Exception { byte[] mozillaHmacOut; //Get the Mozilla HMAC mozillaHmacOut = mozillaHmac.doFinal(clearText.getBytes()); if (mozillaHmacOut.length == mozillaHmac.getMacLength()) { System.out.println(PROVIDER + " supports " + mozillaHmac.getAlgorithm() + " and the output size is " + mozillaHmac.getMacLength()); } else { throw new Exception("ERROR: hmac output size is " + mozillaHmacOut.length + ", should be " + mozillaHmac.getMacLength()); } } } jss-4.6.3/org/mozilla/jss/tests/IA5StringConverterTest.java000066400000000000000000000062161362106420000236610ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.junit.Assert; import org.junit.Test; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.x509.IA5StringConverter; public class IA5StringConverterTest { @Test public void testEmptyString() throws Exception { String string = ""; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testNullCharacters() throws Exception { String string = StringTestUtil.NULL_CHARS; System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testPrintableCharacters() throws Exception { String string = StringTestUtil.PRINTABLE_CHARS; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testControlCharacters() throws Exception { String string = StringTestUtil.CONTROL_CHARS; System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testMultibyteCharacters() throws Exception { String string = StringTestUtil.MULTIBYTE_CHARS; System.out.println("Converting: [" + string + "]"); System.out.println(" - expected: IllegalArgumentException"); try { byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IllegalArgumentException); } } } jss-4.6.3/org/mozilla/jss/tests/IA5StringTest.java000066400000000000000000000210061362106420000217630ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.io.IOException; import org.junit.Assert; import org.junit.Test; import org.mozilla.jss.netscape.security.util.DerValue; public class IA5StringTest { public byte tag = DerValue.tag_IA5String; @Test public void testEncodingEmptyString() throws Exception { String string = ""; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingEmptyString() throws Exception { String input = ""; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + input + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingNullCharacters() throws Exception { String string = StringTestUtil.NULL_CHARS; System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); actual = StringTestUtil.normalizeUnicode(actual); System.out.println(" - norm. : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingNullCharacters() throws Exception { String input = StringTestUtil.NULL_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingPrintableCharacters() throws Exception { String string = StringTestUtil.PRINTABLE_CHARS; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingPrintableCharacters() throws Exception { String input = StringTestUtil.PRINTABLE_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + input + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingNonPrintableCharacters() throws Exception { String string = StringTestUtil.NON_PRINTABLE_CHARS; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingNonPrintableCharacters() throws Exception { String input = StringTestUtil.NON_PRINTABLE_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + input + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingControlCharacters() throws Exception { String string = StringTestUtil.CONTROL_CHARS; System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingControlCharacters() throws Exception { String input = StringTestUtil.CONTROL_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingMultibyteCharacters() throws Exception { String string = StringTestUtil.MULTIBYTE_CHARS; System.out.println("Encoding: [" + string + "]"); System.out.println(" - expected: IOException"); try { byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IOException); } } @Test public void testDecodingMultibyteCharacters() throws Exception { String input = StringTestUtil.MULTIBYTE_CHARS; byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: IOException"); try { String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IOException); } } @Test public void testEncodingTime() throws Exception { System.out.println("Encoding time:"); String string = StringTestUtil.NULL_CHARS + StringTestUtil.PRINTABLE_CHARS + StringTestUtil.NON_PRINTABLE_CHARS + StringTestUtil.CONTROL_CHARS; long t0 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) JSSUtil.encode(tag, string); long t1 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) StringTestUtil.encode(tag, string); long t2 = System.currentTimeMillis(); long time1 = t1 - t0; long time2 = t2 - t1; System.out.println(" - JSS : " + time1 + " ms"); System.out.println(" - Internal: " + time2 + " ms"); } @Test public void testDecodingTime() throws Exception { System.out.println("Decoding time:"); String string = StringTestUtil.NULL_CHARS + StringTestUtil.PRINTABLE_CHARS + StringTestUtil.NON_PRINTABLE_CHARS + StringTestUtil.CONTROL_CHARS; byte[] data = JSSUtil.encode(tag, string); long t0 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) JSSUtil.decode(tag, data); long t1 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) StringTestUtil.decode(tag, data); long t2 = System.currentTimeMillis(); long time1 = t1 - t0; long time2 = t2 - t1; System.out.println(" - JSS : " + time1 + " ms"); System.out.println(" - Internal: " + time2 + " ms"); } } jss-4.6.3/org/mozilla/jss/tests/JCAKeyWrap.java000077500000000000000000000426261362106420000212740ustar00rootroot00000000000000/* 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.tests; import java.io.IOException; import java.io.UnsupportedEncodingException; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.AlreadyInitializedException; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.Policy; import org.mozilla.jss.crypto.TokenException; import javax.crypto.SecretKey; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; import java.util.Arrays; import org.mozilla.jss.CertDatabaseException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.KeyDatabaseException; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.util.IncorrectPasswordException; import org.mozilla.jss.util.PasswordCallback; /** * Test Mozilla-JSS provider key wrap/unwrap * * JSS currently needs to compile with JDK 1.4.2.x * * This program tests wrapping/unwrapping on symmetric keys. * unwraping of private keys is not available at this time see * https://bugzilla.mozilla.org/show_bug.cgi?id=135328 * */ public class JCAKeyWrap { protected static final String MOZ_PROVIDER_NAME = "Mozilla-JSS"; public static void main(String args[]) { if (args.length != 2) { usage(); System.exit(1); } String dbdir = args[0]; String passwdfile = args[1]; try { JCAKeyWrap keyWrap = new JCAKeyWrap(dbdir, passwdfile); //If the IBMJCE provider exists tests with it otherwise //use the SunJCE provider. String otherProvider = new String("IBMJCE"); String otherRSAProvider = new String("IBMJCE"); Provider p = null; p = Security.getProvider(otherProvider); if (p == null) { otherProvider = new String("SunJCE"); otherRSAProvider = new String("SunRsaSign"); p = Security.getProvider(otherProvider); if (p == null) { System.out.println("unable to find IBMJCE or SunJCE " + "providers"); Provider[] providers = Security.getProviders(); for (int i = 0; i < providers.length; i++) { System.out.println("Provider " + i + ": " + providers[i].getName()); } System.exit(1); } } // Generate an RSA keypair KeyPairGenerator kpgen; kpgen = KeyPairGenerator.getInstance("RSA", MOZ_PROVIDER_NAME); kpgen.initialize(Policy.RSA_MINIMUM_KEY_SIZE); KeyPair rsaKeyPairNSS = kpgen.generateKeyPair(); kpgen = KeyPairGenerator.getInstance("RSA", otherRSAProvider); kpgen.initialize(Policy.RSA_MINIMUM_KEY_SIZE); KeyPair rsaKeyPairOtherProvider = kpgen.generateKeyPair(); javax.crypto.SecretKey tripleDESKey; KeyGenerator keyGen = KeyGenerator.getInstance("DESede", MOZ_PROVIDER_NAME); tripleDESKey = keyGen.generateKey(); keyWrap.wrapSymetricKeyWithRSA(tripleDESKey, rsaKeyPairNSS, MOZ_PROVIDER_NAME, MOZ_PROVIDER_NAME); if (!keyWrap.isBFipsMode()) { keyWrap.wrapSymetricKeyWithRSA(tripleDESKey, rsaKeyPairNSS, MOZ_PROVIDER_NAME, otherProvider); } keyGen = KeyGenerator.getInstance("AES", MOZ_PROVIDER_NAME); javax.crypto.SecretKey aesKeyToWrap; keyGen.init(128); aesKeyToWrap = keyGen.generateKey(); keyGen = KeyGenerator.getInstance("AES", MOZ_PROVIDER_NAME); int AESKeySize[] = {128, 192, 256}; for (int k = 0; k < AESKeySize.length; k++) { //create AES key javax.crypto.SecretKey aesKey; keyGen.init(AESKeySize[k]); aesKey = keyGen.generateKey(); keyGen = KeyGenerator.getInstance("AES", MOZ_PROVIDER_NAME); int keyStrength = (((SecretKeyFacade) aesKey).key.getStrength()); //JDK 1.4 and 1.5 only supports 128 keys for AES //therefore only do comparison testing of providers with //128 key strength if (keyStrength == 128 && !keyWrap.isBFipsMode()) { keyWrap.wrapSymetricKey(tripleDESKey, "AES/CBC/PKCS5Padding", aesKey, MOZ_PROVIDER_NAME, otherProvider); keyWrap.wrapSymetricKey(aesKeyToWrap, "AES/CBC/PKCS5Padding", aesKey, MOZ_PROVIDER_NAME, otherProvider); keyWrap.wrapSymetricKeyWithRSA(aesKey, rsaKeyPairNSS, MOZ_PROVIDER_NAME, otherProvider); } else { keyWrap.wrapSymetricKey(tripleDESKey, "AES/CBC/PKCS5Padding", aesKey); keyWrap.wrapSymetricKey(aesKeyToWrap, "AES/CBC/PKCS5Padding", aesKey); keyWrap.wrapSymetricKeyWithRSA(aesKey, rsaKeyPairNSS); } aesKeyToWrap = aesKey; } } catch (Exception e) { e.printStackTrace(); System.exit(1); } System.exit(0); } /** * */ public static void usage() { System.out.println( "Usage: java org.mozilla.jss.tests.JCAKeyWrap " + " "); } protected boolean bFipsMode = false; protected byte[] plainText = "Firefox rules!Firefox rules!Firefox rules!Firefox rules!Firefox rules!".getBytes(); protected byte[] plainTextPad = "Thunderbird rules!Thunderbird rules!Thunderbird rules!Thunderbird rules!Thunderbird rules!".getBytes(); /** * Default constructor to initialize Mozilla-JSS * @param certDbLoc * @param passwdFile */ public JCAKeyWrap(String certDbLoc, String passwdFile) { try { CryptoManager.initialize(certDbLoc); CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(passwdFile); token.login(cb); if (cm.FIPSEnabled()) { bFipsMode = true; System.out.println("in Fipsmode."); } } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } catch (KeyDatabaseException ex) { ex.printStackTrace(); System.exit(1); } catch (CertDatabaseException ex) { ex.printStackTrace(); System.exit(1); } catch (AlreadyInitializedException ex) { ex.printStackTrace(); System.exit(1); } catch (GeneralSecurityException ex) { ex.printStackTrace(); System.exit(1); } catch (IncorrectPasswordException ex) { ex.printStackTrace(); System.exit(1); } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } catch (NotInitializedException ex) { ex.printStackTrace(); System.exit(1); } } /** * * @return true when in FIPS mode false otherwise */ public boolean isBFipsMode() { return bFipsMode; } /** * Randomly selects a cipher transformation "algorithm/mode/padding". * @param symKeyType * @return a cipher transformation "algorithm/mode/padding" * @throws Exception */ public String testCipher(String symKeyType) throws Exception { String testCipher; String[] cipherDESede = {"DESede/ECB/NoPadding", "DESede/CBC/PKCS5Padding", "DESede/CBC/NoPadding"}; String[] cipherAES = {"AES/ECB/NoPadding", "AES/CBC/NoPadding", "AES/CBC/PKCS5Padding"}; SecureRandom r = SecureRandom.getInstance("pkcs11prng", MOZ_PROVIDER_NAME); if (symKeyType.equalsIgnoreCase("AES")) { return cipherAES[r.nextInt(cipherAES.length)]; } else if (symKeyType.equalsIgnoreCase("DESede")) { return cipherDESede[r.nextInt(cipherDESede.length)]; } else { throw new Exception("no support for " + symKeyType); } } /** * * both providers are Mozilla-JSS * * @param symKey * @param keyPair * @throws Exception */ public void wrapSymetricKeyWithRSA(Key symKey, KeyPair keyPair) throws Exception { wrapSymetricKeyWithRSA(symKey, keyPair, MOZ_PROVIDER_NAME, MOZ_PROVIDER_NAME); } /** * * @param symKey * @param keyPair * @param providerA * @param providerB * @throws Exception */ public void wrapSymetricKeyWithRSA( Key symKey, KeyPair keyPair, String providerA, String providerB) throws Exception { try { String symKeyType = new String(symKey.getAlgorithm()); System.out.print("Wrap " + symKeyType + " " + ((SecretKeyFacade) symKey).key.getStrength() + " with RSA. "); // wrap key Cipher cipher = Cipher.getInstance("RSA", providerA); cipher.init(Cipher.WRAP_MODE, keyPair.getPublic()); byte[] wrappedData = cipher.wrap(symKey); // unwrap key cipher = Cipher.getInstance("RSA", providerA); cipher.init(Cipher.UNWRAP_MODE, keyPair.getPrivate()); SecretKey unwrappedKey = (javax.crypto.SecretKey) cipher.unwrap(wrappedData, symKeyType, Cipher.SECRET_KEY); testKeys(symKey, unwrappedKey, providerA, providerB); } catch (BadPaddingException ex) { ex.printStackTrace(); System.exit(1); } catch (UnsupportedEncodingException ex) { ex.printStackTrace(); System.exit(1); } catch (IllegalBlockSizeException ex) { ex.printStackTrace(); System.exit(1); } catch (InvalidKeyException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchPaddingException ex) { ex.printStackTrace(); System.exit(1); } } /** * both providers used will be Mozilla-JSS * * @param symKey * @param wrapperAlg * @param wrapperKey * @throws Exception */ public void wrapSymetricKey(Key symKey, String wrapperAlg, Key wrapperKey) throws Exception { wrapSymetricKey(symKey, wrapperAlg, wrapperKey, MOZ_PROVIDER_NAME, MOZ_PROVIDER_NAME); } /** * compare two keys * * @param key1 * @param key2 * @return true if equal false otherwise */ static boolean keysEqual(Key key1, Key key2) { if (key1.equals(key2)) { return true; } if (Arrays.equals(key1.getEncoded(), key2.getEncoded())) { return true; } return false; } /** * * @param keyA * @param keyB * @param providerA * @param providerB * @throws java.lang.Exception */ protected void testKeys(Key keyA, Key keyB, String providerA, String providerB) throws Exception { //ensure keys are equal if (bFipsMode) { //bFipsMode providerA and providerB mozilla-JSS //Keys are not extractable so just check key length if (((SecretKeyFacade) keyA).key.getStrength() != ((SecretKeyFacade) keyB).key.getStrength()) { throw new Exception("unwrapped key strength does not " + "match orginal"); } } else if (!keysEqual(keyA, keyB)) { throw new Exception("unwrapped key " + "does not match original"); } //As an extra test encrypt with keyA using ProviderA //and decrypt with with keyB using ProviderB String cipherAlg = testCipher(keyA.getAlgorithm()); System.out.println("Test " + cipherAlg + " encrypt with " + providerA + " decrypt " + providerB); // if no padding is used plainText needs to be fixed length // block divisable by 8 bytes byte[] plaintext = plainText; if (cipherAlg.endsWith("PKCS5Padding")) { plaintext = plainTextPad; } //encrypt some text as a test with the key to be wrap Cipher cipher = Cipher.getInstance(cipherAlg, providerA); cipher.init(Cipher.ENCRYPT_MODE, keyA); byte[] encryptedText = cipher.doFinal(plaintext); //generate the algorithm Parameters; they need to be //the same for encrypt/decrypt if they are needed. AlgorithmParameters ap = null; byte[] encodedAlgParams = null; ap = cipher.getParameters(); if (ap != null) { //get parameters to store away as example. encodedAlgParams = ap.getEncoded(); } // use the unwrapped key for decryption cipher = Cipher.getInstance(cipherAlg, providerB); if (encodedAlgParams == null) { cipher.init(Cipher.DECRYPT_MODE, keyB); } else { //retrieve the algorithmParameters from the encoded array AlgorithmParameters aps = AlgorithmParameters.getInstance(keyB.getAlgorithm()); aps.init(encodedAlgParams); cipher.init(Cipher.DECRYPT_MODE, keyB, aps); } byte[] recovered = new byte[plaintext.length]; int rLen = cipher.update(encryptedText, 0, encryptedText.length, recovered, 0); rLen += cipher.doFinal(recovered, rLen); if (!java.util.Arrays.equals(plaintext, recovered)) { throw new Exception("key do not match. unable to encrypt/decrypt."); } } /** * * @param symKey * @param wrapperAlg * @param wrapperKey * @param providerA * @param providerB * @throws Exception */ public void wrapSymetricKey(Key symKey, String wrapperAlg, Key wrapperKey, String providerA, String providerB) throws Exception { try { System.out.print("Wrap " + symKey.getAlgorithm() + " " + ((SecretKeyFacade) symKey).key.getStrength() + " with " + wrapperKey.getAlgorithm() + " " + ((SecretKeyFacade) wrapperKey).key.getStrength() + " symmetric key. "); // wrap key Cipher cipher = Cipher.getInstance(wrapperAlg, providerA); cipher.init(Cipher.WRAP_MODE, wrapperKey); byte[] wrappedData = cipher.wrap(symKey); //generate the algorithm Parameters; they need to be //the same for encrypt/decrypt if they are needed. byte[] encodedKeyWrapAP = null; AlgorithmParameters ap = null; ap = cipher.getParameters(); if (ap != null) { //get parameters to store away as example. encodedKeyWrapAP = ap.getEncoded(); } // unwrap key cipher = Cipher.getInstance(wrapperAlg, providerA); if (encodedKeyWrapAP == null) { cipher.init(Cipher.UNWRAP_MODE, wrapperKey); } else { //retrieve the algorithmParameters from the encoded array AlgorithmParameters aps = AlgorithmParameters.getInstance( wrapperKey.getAlgorithm()); aps.init(encodedKeyWrapAP); cipher.init(Cipher.UNWRAP_MODE, wrapperKey, aps); } SecretKey unwrappedKey = (SecretKey) cipher.unwrap(wrappedData, symKey.getAlgorithm(), Cipher.SECRET_KEY); testKeys(symKey, unwrappedKey, providerA, providerB); } catch (BadPaddingException ex) { ex.printStackTrace(); System.exit(1); } catch (IllegalBlockSizeException ex) { ex.printStackTrace(); System.exit(1); } catch (UnsupportedEncodingException ex) { ex.printStackTrace(); System.exit(1); } catch (InvalidKeyException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchPaddingException ex) { ex.printStackTrace(); System.exit(1); } } } jss-4.6.3/org/mozilla/jss/tests/JCASigTest.java000066400000000000000000000132711362106420000212630ustar00rootroot00000000000000/* 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.tests; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.Provider; import java.security.Security; import java.security.Signature; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.InitializationValues; import org.mozilla.jss.crypto.Policy; public class JCASigTest { public static void usage() { System.out.println( "Usage: java org.mozilla.jss.tests.JCASigTest "); } public static void sigTest(String alg, KeyPair keyPair) { byte[] data = new byte[] {1,2,3,4,5,6,7,8,9}; byte[] signature; Signature signer; try { signer = Signature.getInstance(alg); System.out.println("Created a signing context"); Provider provider = signer.getProvider(); System.out.println("The provider used for the signer " + provider.getName() + " and the algorithm was " + alg); if (provider.getName().equalsIgnoreCase("Mozilla-JSS") == false) { System.out.println("Mozilla-JSS is supposed to be the " + "default provider for JCASigTest"); System.exit(1); } signer.initSign( keyPair.getPrivate()); System.out.println("initialized the signing operation"); signer.update(data); System.out.println("updated signature with data"); signature = signer.sign(); System.out.println("Successfully signed!"); signer.initVerify(keyPair.getPublic()); System.out.println("initialized verification"); signer.update(data); System.out.println("updated verification with data"); if ( signer.verify(signature) ) { System.out.println("Signature Verified Successfully!"); } else { System.out.println("ERROR: Signature failed to verify."); } } catch ( Exception e ) { e.printStackTrace(); System.exit(1); } } public static void main(String args[]) { CryptoManager manager; KeyPairGenerator kpgen; KeyPair keyPair; if ( args.length != 2 ) { usage(); System.exit(1); } String dbdir = args[0]; String file = args[1]; try { InitializationValues vals = new InitializationValues (dbdir ); vals.removeSunProvider = true; CryptoManager.initialize(vals); manager = CryptoManager.getInstance(); manager.setPasswordCallback( new FilePasswordCallback(file) ); Provider[] providers = Security.getProviders(); for ( int i=0; i < providers.length; i++ ) { System.out.println("Provider "+i+": "+providers[i].getName()); } // Generate an RSA keypair kpgen = KeyPairGenerator.getInstance("RSA"); kpgen.initialize(Policy.RSA_MINIMUM_KEY_SIZE); keyPair = kpgen.generateKeyPair(); Provider provider = kpgen.getProvider(); System.out.println("The provider used to Generate the Keys was " + provider.getName() ); System.out.println("provider info " + provider.getInfo() ); if (provider.getName().equalsIgnoreCase("Mozilla-JSS") == false) { System.out.println("Mozilla-JSS is supposed to be the " + "default provider for JCASigTest"); System.exit(1); } sigTest("MD5/RSA", keyPair); sigTest("MD2/RSA", keyPair); sigTest("SHA-1/RSA", keyPair); sigTest("SHA-256/RSA", keyPair); sigTest("SHA-384/RSA", keyPair); sigTest("SHA-512/RSA", keyPair); // Generate an DSA keypair kpgen = KeyPairGenerator.getInstance("DSA"); kpgen.initialize(1024); keyPair = kpgen.generateKeyPair(); provider = kpgen.getProvider(); System.out.println("The provider used to Generate the Keys was " + provider.getName() ); System.out.println("provider info " + provider.getInfo() ); if (provider.getName().equalsIgnoreCase("Mozilla-JSS") == false) { System.out.println("Mozilla-JSS is supposed to be the " + "default provider for JCASigTest"); System.exit(1); } sigTest("SHA-1/DSA", keyPair); kpgen = KeyPairGenerator.getInstance("EC"); kpgen.initialize(256); keyPair = kpgen.generateKeyPair(); provider = kpgen.getProvider(); System.out.println("The provider used to Generate the Keys was " + provider.getName() ); System.out.println("provider info " + provider.getInfo() ); if (provider.getName().equalsIgnoreCase("Mozilla-JSS") == false) { System.out.println("Mozilla-JSS is supposed to be the " + "default provider for JCASigTest"); System.exit(1); } sigTest("SHA-1/EC", keyPair); sigTest("SHA-256/EC", keyPair); sigTest("SHA-384/EC", keyPair); sigTest("SHA-512/EC", keyPair); } catch ( Exception e ) { e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.6.3/org/mozilla/jss/tests/JCASymKeyGen.java000066400000000000000000000517431362106420000215620ustar00rootroot00000000000000/* 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.tests; import java.io.IOException; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.RC2ParameterSpec; import org.mozilla.jss.CertDatabaseException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.KeyDatabaseException; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.crypto.AlreadyInitializedException; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.util.IncorrectPasswordException; import org.mozilla.jss.util.PasswordCallback; /** * */ public class JCASymKeyGen { static final String MOZ_PROVIDER_NAME = "Mozilla-JSS"; byte[] plainText = "Firefox rules!Firefox rules!Firefox rules!Firefox rules!Firefox rules!".getBytes(); byte[] plainTextPad = "Thunderbird rules!Thunderbird rules!Thunderbird rules!Thunderbird rules!Thunderbird rules!".getBytes(); byte[] plainTextB = "NSPR NSS JSS!NSPR NSS JSS!NSPR NSS JSS!".getBytes(); byte[] plainTextPadB = "Use Firefox and Thunderbird!".getBytes(); static boolean bFipsMode = false; /** * Default constructor */ public JCASymKeyGen( String certDbLoc, String passwdFile) { try { CryptoManager.initialize(certDbLoc); CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalCryptoToken(); if (cm.FIPSEnabled()) { try { bFipsMode=true; PasswordCallback cb = new FilePasswordCallback(passwdFile); token.login(cb); System.out.println("Logged in"); } catch (IncorrectPasswordException ex) { ex.printStackTrace(); System.exit(1); } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } } } catch (AlreadyInitializedException ex) { ex.printStackTrace(); System.exit(1); } catch (CertDatabaseException ex) { ex.printStackTrace(); System.exit(1); } catch (NotInitializedException ex) { ex.printStackTrace(); System.exit(1); } catch (GeneralSecurityException ex) { ex.printStackTrace(); System.exit(1); } catch (KeyDatabaseException ex) { ex.printStackTrace(); System.exit(1); } } /** * * @param keyType * @param provider * @return javax.crypto.SecretKey key */ public javax.crypto.SecretKey genSecretKey(String keyType, String provider){ javax.crypto.SecretKey key = null; javax.crypto.KeyGenerator kg = null; try { kg = KeyGenerator.getInstance(keyType, provider); if (keyType.equals("AES") || keyType.equals("RC2")) { kg.init(128); //JDK 1.4 and 1.5 only supports 128 keys for AES } System.out.println("Key " + keyType + " generation done by " + kg.getProvider().toString()); key = kg.generateKey(); if( !checkAlgorithm(key, keyType) ) { throw new Exception("Error: " + key.getAlgorithm() + " algorithm"); } //System.out.println("The length of the generated key in bits: " + // (key.getEncoded().length * 8) + // " " + key.getAlgorithm() ); } catch (NoSuchProviderException ex) { ex.printStackTrace(); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); } return key; } /** * * @param keyType * @param provider * @return javax.crypto.SecretKey key */ public javax.crypto.SecretKey genPBESecretKey(String keyType, String provider){ javax.crypto.SecretKey key = null; javax.crypto.SecretKeyFactory kf = null; try { char[] pw = "thunderbird".toCharArray(); byte[] salt = new byte[8]; SecureRandom random = SecureRandom.getInstance("pkcs11prng", MOZ_PROVIDER_NAME); random.nextBytes(salt); int iterationCount = 2; kf = SecretKeyFactory.getInstance(keyType, provider); PBEKeySpec keySpec = new PBEKeySpec(pw, salt, iterationCount); key = kf.generateSecret(keySpec); //todo this should work as well //PBEKeySpec pbeKeySpec = new PBEKeySpec(pw)); // key = kf.generateSecret(pbeKeySpec); System.out.println("Key " + keyType + " generation done by " + kf.getProvider().toString()); if (!bFipsMode) { System.out.println("The length of the generated key in bits: " + (key.getEncoded().length * 8) + " " + key.getAlgorithm() ); } } catch (NoSuchProviderException ex) { ex.printStackTrace(); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); } return key; } /** * * @param sKey * @param algFamily * @param algType * @param providerForEncrypt * @param providerForDecrypt */ public void testCipher(javax.crypto.SecretKey sKey, String algFamily, String algType, String providerForEncrypt, String providerForDecrypt) throws Exception { try { // if no padding is used plainText needs to be fixed length // block divisable by 8 bytes byte[] plaintext = plainText; if (algType.endsWith("PKCS5Padding")) { plaintext = plainTextPad; } //encypt Cipher cipher = Cipher.getInstance(algType, providerForEncrypt); AlgorithmParameters ap = null; byte[] encodedAlgParams = null; AlgorithmParameterSpec RC2ParSpec = null; if (algFamily.compareToIgnoreCase("RC2")==0) { //JDK 1.4 requires you to pass in generated algorithm //parameters for RC2 (JDK 1.5 does not). byte[] iv = new byte[8]; SecureRandom random = SecureRandom.getInstance("pkcs11prng", MOZ_PROVIDER_NAME); random.nextBytes(iv); RC2ParSpec = new RC2ParameterSpec(128, iv); cipher.init(Cipher.ENCRYPT_MODE, sKey, RC2ParSpec); } else { cipher.init(Cipher.ENCRYPT_MODE, sKey); //generate the algorithm Parameters; they need to be //the same for encrypt/decrypt if they are needed. ap = cipher.getParameters(); if (ap != null) { //get parameters to store away as example. encodedAlgParams = ap.getEncoded(); } } //System.out.print(plaintext.length + " plaintext size " + // providerForEncrypt + " encrypt outputsize: " + // cipher.getOutputSize(plaintext.length)); byte[] ciphertext = new byte[cipher.getOutputSize(plaintext.length)]; int cLen = cipher.update(plaintext, 0, plaintext.length, ciphertext, 0); cLen += cipher.doFinal(ciphertext, cLen); //decrypt cipher = Cipher.getInstance(algType, providerForDecrypt); if (encodedAlgParams == null) if (RC2ParSpec != null) // JDK 1.4 RC2 cipher.init(Cipher.DECRYPT_MODE, sKey, RC2ParSpec); else cipher.init(Cipher.DECRYPT_MODE, sKey); else { //retrieve the algorithmParameters from the encoded array AlgorithmParameters aps = AlgorithmParameters.getInstance(algFamily); aps.init(encodedAlgParams); cipher.init(Cipher.DECRYPT_MODE, sKey, aps); } byte[] recovered = new byte[cLen]; int rLen = cipher.update(ciphertext, 0, cLen, recovered, 0); rLen += cipher.doFinal(recovered, rLen); //ensure the recovered bytes equals the orginal plaintext boolean isEqual = true; for (int i = 0; i < plaintext.length; i++) { if (plaintext[i] != recovered[i]) { isEqual = false; break; } } if (isEqual) { //System.out.println(providerForEncrypt + " encrypted & " + // providerForDecrypt + " decrypted using " + // algType + " successful."); } else { throw new Exception("ERROR: " + providerForEncrypt + " and " + providerForDecrypt + " failed for " + algType ); } } catch (InvalidKeyException ex) { ex.printStackTrace(); } catch (javax.crypto.BadPaddingException ex) { ex.printStackTrace(); } catch (NoSuchProviderException ex) { ex.printStackTrace(); } catch (javax.crypto.NoSuchPaddingException ex) { ex.printStackTrace(); } catch (javax.crypto.IllegalBlockSizeException ex) { ex.printStackTrace(); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); } } /** * * @param sKey * @param algFamily * @param algType * @param providerForEncrypt * @param providerForDecrypt */ public void testMultiPartCipher(javax.crypto.SecretKey sKey, String algFamily, String algType, String providerForEncrypt, String providerForDecrypt) throws Exception { try { // if no padding is used plainText needs to be fixed length // block divisable by 8 bytes byte[] plaintext = plainText; byte[] plaintextB = plainTextB; if (algType.endsWith("PKCS5Padding")) { plaintext = plainTextPad; plaintextB = plainTextPadB; } //encypt Cipher cipher = Cipher.getInstance(algType, providerForEncrypt); AlgorithmParameters ap = null; byte[] encodedAlgParams = null; AlgorithmParameterSpec RC2ParSpec = null; if (algFamily.compareToIgnoreCase("RC2")==0) { //JDK 1.4 requires you to pass in generated algorithm //parameters for RC2 (JDK 1.5 does not). byte[] iv = new byte[8]; SecureRandom random = SecureRandom.getInstance("pkcs11prng", MOZ_PROVIDER_NAME); random.nextBytes(iv); RC2ParSpec = new RC2ParameterSpec(128, iv); cipher.init(Cipher.ENCRYPT_MODE, sKey, RC2ParSpec); } else { cipher.init(Cipher.ENCRYPT_MODE, sKey); //generate the algorithm Parameters; they need to be //the same for encrypt/decrypt if they are needed. ap = cipher.getParameters(); if (ap != null) { //get parameters to store away as example. encodedAlgParams = ap.getEncoded(); } } byte[] ciphertext = new byte[(cipher.getOutputSize(plaintext.length + plaintextB.length))]; int cLen = cipher.update(plaintext, 0, plaintext.length, ciphertext, 0); cLen += cipher.update(plaintextB, 0, plaintextB.length, ciphertext, cLen); cLen += cipher.doFinal(ciphertext, cLen); //decrypt cipher = Cipher.getInstance(algType, providerForDecrypt); if (encodedAlgParams == null) if (RC2ParSpec != null) // JDK 1.4 RC2 cipher.init(Cipher.DECRYPT_MODE, sKey, RC2ParSpec); else cipher.init(Cipher.DECRYPT_MODE, sKey); else { //retrieve the algorithmParameters from the encoded array AlgorithmParameters aps = AlgorithmParameters.getInstance(algFamily); aps.init(encodedAlgParams); cipher.init(Cipher.DECRYPT_MODE, sKey, aps); } byte[] recovered = new byte[cLen]; int rLen = cipher.update(ciphertext, 0, cLen, recovered, 0); rLen += cipher.doFinal(recovered, rLen); //ensure the recovered bytes equals the original plaintext boolean isEqual = true; for (int i = 0; i < plaintext.length; i++) { if (i [passwordFile]"); System.out.println("password file only required if in " + "FIPSMODE."); System.out.println("FIPSMODE requires Java 1.6 or higher!"); System.exit(1); } //If the IBMJCE provider exists tests with it otherwise //use the SunJCE provider. String otherProvider = new String("IBMJCE"); Provider p = null; p = Security.getProvider(otherProvider); if (p == null) { otherProvider = new String("SunJCE"); p = Security.getProvider(otherProvider); if (p == null){ System.out.println("unable to find IBMJCE or SunJCE providers"); System.exit(1); } } JCASymKeyGen skg = new JCASymKeyGen(certDbLoc, passwdFile); System.out.println(otherProvider + ": " + p.getInfo()); p = Security.getProvider(MOZ_PROVIDER_NAME); System.out.println(MOZ_PROVIDER_NAME + ": " + p.getInfo()); javax.crypto.SecretKey mozKey = null; try { for (int i = 0 ; i < symKeyTable.length; i++) { try { //generate the key using mozilla if (symKeyTable[i][0].startsWith("PBE") == true) { mozKey = skg.genPBESecretKey(symKeyTable[i][0], MOZ_PROVIDER_NAME); } else { mozKey = skg.genSecretKey(symKeyTable[i][0], MOZ_PROVIDER_NAME); } } catch(Exception e) { System.out.println("unable to generate key: " + symKeyTable[i][0] + " " + e.getMessage()); } //test the cipher algorithms for this keyType for (int a = 1 ; a < symKeyTable[i].length; a++){ //encrypt/decrypt with Mozilla Provider skg.testCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], MOZ_PROVIDER_NAME, MOZ_PROVIDER_NAME); skg.testMultiPartCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], MOZ_PROVIDER_NAME, MOZ_PROVIDER_NAME); try { //check to see if the otherProvider we are testing //against supports the algorithm. Cipher cipher = Cipher.getInstance(symKeyTable[i][a], otherProvider); } catch (Exception e) { System.out.println(MOZ_PROVIDER_NAME + " only supports " + symKeyTable[i][a]); //therefore don't try comparison continue; } //in FIPSMODE you can only use the Mozilla Provider if (!bFipsMode) { //encrypt with Mozilla, and Decrypt with otherProvider skg.testCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], MOZ_PROVIDER_NAME, otherProvider); skg.testMultiPartCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], MOZ_PROVIDER_NAME, otherProvider); //encrypt with otherProvider and decrypt with Mozilla skg.testCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], otherProvider, MOZ_PROVIDER_NAME); skg.testMultiPartCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], otherProvider, MOZ_PROVIDER_NAME); System.out.println(MOZ_PROVIDER_NAME + " and " + otherProvider + " tested " + symKeyTable[i][a]); } } } } catch(Exception e) { e.printStackTrace(); System.exit(1); } //end of main System.exit(0); } /** * Validate if the key algorithm of a given SecretKey * is the same as expected. * @param SecretKey k * @param String algorithm * @return boolean status */ private boolean checkAlgorithm(SecretKey k, String alg) { boolean status = false; if( k.getAlgorithm().equals(alg) ) { status = true; } return status; } } jss-4.6.3/org/mozilla/jss/tests/JSSE_SSLClient.java000077500000000000000000000452621362106420000220170ustar00rootroot00000000000000/* 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.tests; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchProviderException; import java.util.ArrayList; import java.util.Iterator; import java.lang.reflect.InvocationTargetException; import javax.net.ssl.HandshakeCompletedEvent; import javax.net.ssl.HandshakeCompletedListener; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This program connects to any SSL Server to exercise * all ciphers supported by JSSE for a given JDK/JRE * version. The result is listing of common ciphers * between the server and this JSSE client. * */ public class JSSE_SSLClient { public static Logger logger = LoggerFactory.getLogger(JSSE_SSLClient.class); // Local members private String sslRevision = "TLS"; private String host = null; private int port = -1; private String cipherName = null; private String path = null; private int debug_level = 0; private String EOF = "test"; private String keystoreLoc = "rsa.pfx"; private SSLSocketFactory factory = null; /* ciphersuites to test */ private ArrayList ciphersToTest = new ArrayList<>(); /* h_ciphers is for ciphersuite that were able to successfully * connect to the server */ private ArrayList h_ciphers = new ArrayList<>(); /* f_ciphers is for ciphersuite that failed to connect to the server */ private ArrayList f_ciphers = new ArrayList<>(); private boolean bVerbose = false; private boolean bFipsMode = false; /** * Set the protocol type and revision * @param fSslRevision */ public void setSslRevision(String fSslRevision) { if (!(fSslRevision.equals("TLS") || fSslRevision.equals("SSLv3"))) { logger.error("type must equal \'TLS\' or \'SSLv3\'\n"); System.exit(1); } this.sslRevision = fSslRevision; } /** * Set the host name to connect to. * @param fHost */ public void setHost(String fHost) { this.host = fHost; } /** * Set the port number to connect to. * @param fPort */ public void setPort(int fPort) { this.port = fPort; } /** * Set the cipher suite name to use. * @param fCipherSuite */ public void setCipherSuite(String fCipherSuite) { this.cipherName = fCipherSuite; } /** * Set the location of rsa.pfx * @param fKeystoreLoc */ public void setKeystoreLoc(String fKeystoreLoc) { keystoreLoc = fKeystoreLoc + "/" + keystoreLoc; } /** * Get the location of rsa.pfx * @return String fKeystoreLoc */ public String getKeystoreLoc() { return keystoreLoc; } /** * Default constructor. */ public JSSE_SSLClient() { //Do nothing. } public boolean isServerAlive() { boolean isServerAlive = false; SSLSocket socket = null; if (factory == null) { initSocketFactory(); } for (int i = 0 ; i < 20 ; i++) { try { Thread.sleep(1000); logger.info("Testing Connection:" + host + ":" + port); socket = (SSLSocket)factory.createSocket(host, port); socket.setEnabledCipherSuites(factory.getDefaultCipherSuites()); if (socket.isBound()) { logger.info("connect isBound"); isServerAlive = true; socket.close(); break; } } catch (java.net.ConnectException ex) { //not able to connect } catch (InterruptedException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } } return isServerAlive; } /** * Test communication with SSL server S */ public void testCiphersuites() { SSLSocket socket = null; int i = 0; if (factory == null) { initSocketFactory(); } if (!isServerAlive()) { logger.error("Unable to connect to " + host + ":" + port + " exiting."); System.exit(1); } Iterator iter = ciphersToTest.iterator(); while (iter.hasNext()) { String cs = iter.next(); String ciphers[] = {cs}; try { socket = (SSLSocket)factory.createSocket(host, port); socket.setEnabledCipherSuites(ciphers); testSSLSocket(socket, cs, i++); } catch (Exception ex) { logger.warn("failed ciphersuite" + ciphers[0]); f_ciphers.add(ciphers[0]); } } } public void configureCipherSuites(String server, String CipherSuite) { boolean testCipher = true; if (factory == null) { initSocketFactory(); } String ciphers[] = factory.getSupportedCipherSuites(); for (int i = 0; i < ciphers.length; ++i) { String ciphersuite = ciphers[i]; testCipher = true; if (bVerbose) { System.out.print(ciphersuite); } if (server.equalsIgnoreCase("JSS")) { //For JSS SSLServer don't test if ((ciphersuite.indexOf("_DHE_") != -1)|| (ciphersuite.indexOf("_DES40_") != -1) || (ciphersuite.indexOf("TLS_EMPTY_RENEGOTIATION_INFO_SCSV") != -1) || (ciphersuite.indexOf("SHA256") != -1) || // reenable in bug 776597 (ciphersuite.indexOf("_anon_") != -1) || (ciphersuite.indexOf("_KRB5_") != -1)) { if (bVerbose) System.out.print(" -"); testCipher = false; } } if (server.equalsIgnoreCase("JSSE")) { //For JSSE SSLServers don't test _DHE_, _EXPORT_, _anon_, _KRB5_ /* if ((ciphersuite.indexOf("_DHE_") != -1) || (ciphersuite.indexOf("_EXPORT_") != -1) || (ciphersuite.indexOf("_anon_") != -1) || (ciphersuite.indexOf("_KRB5_") != -1) ) { if (bVerbose) System.out.print(" -"); testCipher = false; } */ } if (testCipher) { ciphersToTest.add(ciphers[i]); if (bVerbose) System.out.print(" - Testing"); } } if (bVerbose) System.out.print("\n"); if(bVerbose) System.out.println("\nTesting " + ciphersToTest.size() + " ciphersuites."); } private void initSocketFactory() { SSLContext ctx = null; KeyManagerFactory kmf = null; TrustManagerFactory tmf = null; KeyStore ks = null; KeyStore ksTrust = null; String provider = "SunJCE"; /* * Set up a key manager for client authentication * if asked by the server. Use the implementation's * default TrustStore and secureRandom routines. */ char[] passphrase = "m1oZilla".toCharArray(); try { String javaVendor = System.getProperty("java.vendor"); logger.debug("JSSE_SSLClient: java.vendor: " + javaVendor); // Initialize the system if (javaVendor.equals("IBM Corporation")) { System.setProperty("java.protocol.handler.pkgs", "com.ibm.net.ssl.www.protocol.Handler"); java.security.Security.addProvider((java.security.Provider) Class.forName("com.ibm.jsse2.IBMJSSEProvider2").getConstructor().newInstance()); provider = "IBMJCE"; } else { System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); java.security.Security.addProvider((java.security.Provider) Class.forName("com.sun.crypto.provider.SunJCE").getConstructor().newInstance()); } // Load the keystore that contains the certificate String certificate = new String("SunX509"); ks = KeyStore.getInstance("PKCS12"); if (javaVendor.equals("IBM Corporation")) { certificate = new String("IbmX509"); ks = KeyStore.getInstance("PKCS12", provider); } try { kmf = KeyManagerFactory.getInstance(certificate); try (FileInputStream in = new FileInputStream(getKeystoreLoc())) { ks.load(in, passphrase); } } catch (Exception keyEx) { if (System.getProperty("java.vendor").equals("IBM Corporation")) { logger.error("Using IBM JDK: Cannot load keystore due "+ "to strong security encryption settings\nwith limited " + "Jurisdiction policy files :\n" + "http://www-1.ibm.com/support/docview.wss?uid=swg21169931"); System.exit(0); } else { logger.error(keyEx.getMessage(), keyEx); } throw keyEx; } kmf.init(ks, passphrase); // trust manager that trusts all certificates TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] chain, String authType) {} public void checkServerTrusted( java.security.cert.X509Certificate[] chain, String authType) {} } }; ctx = SSLContext.getInstance(sslRevision); ctx.init(kmf.getKeyManagers(), trustAllCerts, null); factory = ctx.getSocketFactory(); String[] JSSE_ciphers = factory.getSupportedCipherSuites(); } catch (KeyStoreException ex) { ex.printStackTrace(); } catch (NoSuchProviderException ex) { ex.printStackTrace(); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } catch (IllegalAccessException ex) { ex.printStackTrace(); } catch (InstantiationException ex) { ex.printStackTrace(); } catch (NoSuchMethodException ex) { ex.printStackTrace(); } catch (InvocationTargetException ex) { ex.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); } } /** * sendServerShutdownMsg */ public void sendServerShutdownMsg() { try { SSLSocket socket = null; if (factory == null) { initSocketFactory(); } socket = (SSLSocket)factory.createSocket(host, port); socket.setEnabledCipherSuites(factory.getDefaultCipherSuites()); if (bVerbose) { logger.info("Sending shutdown message to server."); } socket.startHandshake(); OutputStream os = socket.getOutputStream(); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); out.println("shutdown"); out.flush(); out.close(); socket.close(); } catch (Exception ex) { ex.printStackTrace(); } } private void testSSLSocket(SSLSocket socket, String ciphersuite, int socketID) { /* * register a callback for handshaking completion event */ try { socket.addHandshakeCompletedListener( new HandshakeCompletedListener() { public void handshakeCompleted( HandshakeCompletedEvent event) { h_ciphers.add(event.getCipherSuite()); logger.info(event.getCipherSuite()); logger.info("SessionId " + event.getSession() + " Test Status : PASS"); } } ); } catch (Exception handshakeEx) { logger.error(handshakeEx.getMessage(), handshakeEx); System.exit(1); } try { // Set socket timeout to 10 sec socket.setSoTimeout(10 * 1000); socket.startHandshake(); String outputLine = null; String inputLine = null; InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); BufferedReader bir = new BufferedReader( new InputStreamReader(is)); PrintWriter out; out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os))); //write then read on the connection once. outputLine = ciphersuite + ":" + socketID + "\n"; if (bVerbose) { logger.info("Sending: " + outputLine); } out.print(outputLine); out.flush(); inputLine = bir.readLine(); if (bVerbose) { logger.info("Received: " + inputLine + " on Client-" + socketID); } bir.close(); out.close(); } catch (SSLHandshakeException ex) { f_ciphers.add(ciphersuite); } catch (IOException ex) { logger.error(ex.getMessage(), ex); System.exit(1); } try { socket.close(); } catch (IOException ex) { ex.printStackTrace(); } } public void outputCipherResults() { String banner = new String ("\n----------------------------------------------------------\n"); logger.info(banner); logger.info("JSSE has " + factory.getSupportedCipherSuites().length + " ciphersuites and " + ciphersToTest.size() + " were configured and tested."); if (ciphersToTest.size() == h_ciphers.size()) { logger.info("All " + ciphersToTest.size() + " configured ciphersuites tested Successfully!\n"); } if (!h_ciphers.isEmpty()) { if (!f_ciphers.isEmpty()) { logger.info(banner); logger.info(h_ciphers.size() + " ciphersuites successfully connected to the "+ "server\n"); } Iterator iter = h_ciphers.iterator(); while (iter.hasNext()) { logger.info(iter.next()); } } if (bFipsMode) { logger.info("Note: ciphersuites that have the prefix " + "\"SSL\" or \"SSL3\" were used in TLS mode."); } if (ciphersToTest.size() != (h_ciphers.size() + f_ciphers.size())) { logger.warn("did not test all expected ciphersuites"); } if (!f_ciphers.isEmpty()) { logger.info(banner); logger.info(f_ciphers.size() + " ciphersuites that did not connect to the "+ "server\n\n"); Iterator iter = f_ciphers.iterator(); while (iter.hasNext()) { logger.info(iter.next()); } logger.error("we should have no failed ciphersuites!"); System.exit(1); } logger.info(banner); } /** * Main method for local unit testing. */ public static void main(String [] args) { String testCipher = null; String testHost = "localhost"; String keystoreLocation = "rsa.pfx"; int testPort = 29750; String serverType = "JSSE"; String usage = "java org.mozilla.jss.tests.JSSE_SSLClient" + "\n " + " "; try { if ( args[0].toLowerCase().equals("-h") || args.length < 1) { System.out.println(usage); System.exit(1); } if ( args.length >= 1 ) { keystoreLocation = args[0]; } if ( args.length >= 2) { testPort = new Integer(args[1]).intValue(); System.out.println("using port: " + testPort); } if ( args.length >= 3) { testHost = args[2]; } if ( args.length == 4) { serverType = args[3]; } if ( args.length == 5) { testCipher = args[4]; } } catch (Exception e) { System.out.println(usage); System.exit(1); } JSSE_SSLClient sslSock = new JSSE_SSLClient(); sslSock.setHost(testHost); sslSock.setPort(testPort); sslSock.setKeystoreLoc(keystoreLocation); sslSock.setCipherSuite(testCipher); sslSock.configureCipherSuites(serverType, testCipher); try { sslSock.testCiphersuites(); } catch (Exception e) { logger.error("Exception caught testing ciphersuites: " + e.getMessage(), e); System.exit(1); } sslSock.sendServerShutdownMsg(); sslSock.outputCipherResults(); System.exit(0); } } jss-4.6.3/org/mozilla/jss/tests/JSSE_SSLServer.java000077500000000000000000000323541362106420000220450ustar00rootroot00000000000000/* 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.tests; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.SocketTimeoutException; import java.security.KeyStore; import java.security.Provider; import java.security.Security; //note: SunPKCS11 requires JDK 1.5 or higher. //SunPKCS11 import sun.security.pkcs11.SunPKCS11; import java.util.Vector; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.InitializationValues; /** * JSSE SSLServer class that acts as SSL Server * * @author Sandeep.Konchady@Sun.COM * @version 1.0 */ public class JSSE_SSLServer { private int DefaultServerPort = 29753; private int port = DefaultServerPort; private String type = "SSLv3"; private String configDir = ""; private boolean bClientAuth = false; private boolean bVerbose = false; private Vector supportedCiphers = new Vector<>(); private CryptoManager manager; private String provider = "SunJCE"; /** * Constructs a JSSE_SSLServer. */ public JSSE_SSLServer() throws IOException { } /** * Set the provider to use. * @param p */ public void setProvider(String p) { provider = p; } /** * Get the configured provider. * @return String provider */ public String getProvider() { return provider; } /** * Set the location of keystore file. * @param fconfigDir */ public void setKeystore(String fconfigDir) { configDir = fconfigDir; } /** * Get the location of keystore file. * @return String configDir */ public String getKeystore() { return configDir; } /** * Main method to create the class server. This takes * one command line arguments, the port on which the * server accepts requests. */ public static void main(String args[]) { try { (new JSSE_SSLServer()).startSSLServer(args); } catch (Exception e) {} } /** * Start SSLServer and accept connections. * @param args */ public void startSSLServer(String[] args) throws Exception { String configDir = ""; String pwFile = ""; String nssConfig = ""; JSSE_SSLServer sslServer = new JSSE_SSLServer(); if ( args.length <= 1 ) { System.out.println( "USAGE: java JSSE_SSLServer [port] [TLS | SSLv3]" + "[ClientAuth = true | false]" + "[config directory] [keystore filename]" + "[NSS DB passwordFile]" + "[JCE || Mozilla-JSS || Sunpkcs11]"); System.out.println( "\nIf the second argument is TLS, it will start as a\n" + "TLS server, otherwise, it will be started in SSLv3 mode." + "\nIf the third argument is true,it will require\n" + "client authentication as well."); System.exit(1); } for (int i = 0; i < args.length; i++) { System.out.println(i + " = " + args[i]); } if (args.length >= 1) { port = Integer.parseInt(args[0]); } if (args.length >= 2) { type = args[1]; } if (args.length >= 3 && args[2].equals("true")) { bClientAuth = true; } if (args.length >= 4 && args.length >= 5) { configDir = args[3]; String keystore = configDir + "/" + args[4]; if ( keystore != null ) { sslServer.setKeystore(keystore); } } if (args.length >= 7 && args.length >=8 ) { if ((args[5].equalsIgnoreCase("Mozilla-JSS"))) { if (args.length >= 8) { pwFile = args[7]; } System.out.println("Initializing " + args[5]); InitializationValues vals = new InitializationValues(configDir); vals.removeSunProvider = false; CryptoManager.initialize(vals); manager = CryptoManager.getInstance(); manager.setPasswordCallback( new FilePasswordCallback(pwFile) ); } else if (args[5].equalsIgnoreCase("Sunpkcs11")) { System.out.println("Sunpkcs11 requires JDK 1.5" + "at this time JSS need to build with JDK 1.4.2"); //SunPKCS11 nssConfig = args[6]; //SunPKCS11 System.out.println("Initializing " + args[5] + "-NSS"); //SunPKCS11 Provider nss = null; //SunPKCS11 nss = new sun.security.pkcs11.SunPKCS11(nssConfig); //SunPKCS11 Security.insertProviderAt(nss, 1); //SunPKCS11 System.out.println("Initialized " + args[5] + "-NSS"); } else { //use default } } Provider[] providers = Security.getProviders(); for ( int i=0; i < providers.length; i++ ) { System.out.println("Provider "+i+": "+providers[i].getName()); } // System.out.println("using port: " + port); // System.out.println("mode type " + type + " ClientAuth " + // (bClientAuth ? "true" : "false")); // System.out.println("configDir " + configDir); try { System.out.println("creating SSLSockets:"); SSLServerSocketFactory ssf = sslServer.getServerSocketFactory(type); if ( ssf != null ) { SSLServerSocket ss = (SSLServerSocket)ssf.createServerSocket(port); // Set server socket timeout to 5 minutes ss.setSoTimeout(300 * 1000); System.out.println("Enable ciphers."); // Enable all the JSSE ciphersuites ss.setEnabledCipherSuites(ss.getSupportedCipherSuites()); System.out.println("Create JSSE SSLServer"); ss.setNeedClientAuth(bClientAuth); JSSE_SSLServer JSSEServ = new JSSE_SSLServer(); // accept an SSL connection int socketCntr = 0; while (true) { try { //The client will tell the server to shutdown Socket socket = ss.accept(); socket.setSoTimeout(300 * 1000); socketCntr ++; readWriteThread rwThread = new readWriteThread(socket, socketCntr); rwThread.start(); } catch (IOException ex) { System.out.println("Exception caught in " + "SSLServerSocket.accept():" + ex.getMessage()); try { ss.close(); } catch (Exception e) {} break; } } } else { if(System.getProperty("java.vendor").equals("IBM Corporation")){ System.out.println("Using IBM JDK: Cannot load keystore " + "due to strong security encryption settings\nwith " + "limited Jurisdiction policy files :\n http://" + "www-1.ibm.com/support/docview.wss?uid=swg21169931"); System.exit(0); } System.out.println("unable to initialize JSSE_SocketFactory " + "exiting!"); System.exit(1); } } catch (Exception e) { System.out.println("Unable to start JSSE_SSLServer: " + e.getMessage()); e.printStackTrace(); System.exit(1); } System.out.println("Main JSSE_SSLServer exiting."); // Exit gracefully System.exit(0); } /** * ReadWrite thread class that takes a * SSLSocket as input and read then writes * back to client. */ private class readWriteThread extends Thread { private Socket socket = null; private int socketCntr = 0; public readWriteThread(Socket sock, int cntr) { this.socket = sock; this.socketCntr = cntr; } public void run() { try { String inputLine = null; String outputLine = null; InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); BufferedReader bir = new BufferedReader( new InputStreamReader(is)); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); while (true) { try { if ((inputLine = bir.readLine()) != null) { if (inputLine.equalsIgnoreCase("shutdown")) { if (bVerbose) { System.out.println("Client told " + "JSSE_SSLServer to Shutdown!"); } is.close(); os.close(); socket.close(); System.exit(0); } outputLine = "ServerSSLSocket- " + socketCntr; if (bVerbose) { System.out.println("ServerSSLSocket-" + socketCntr + ": Received " + inputLine); System.out.println("Sending" + outputLine); } out.println(outputLine); out.flush(); } else { /* if you read null then quit. otherwise you * will be in endless loop with the socket * stuck in CLOSED_WAIT. */ if (bVerbose) { System.out.println("ServerSSLSocket-" + socketCntr + " read null aborting connection."); } break; } } catch (SocketTimeoutException ste) { System.out.println("ServerSSLSocket-" + socketCntr + " timed out: " + ste.toString()); break; } catch (IOException ex) { if (bVerbose) ex.printStackTrace(); break; } } /* close streams and close socket */ is.close(); os.close(); socket.close(); if (bVerbose) { System.out.println("ServerSSLSocket " + socketCntr + " has been Closed."); } } catch (IOException e) { e.printStackTrace(); } } } SSLServerSocketFactory getServerSocketFactory(String type) { // set up key manager to do server authentication SSLContext ctx = null; KeyManagerFactory kmf = null; KeyStore ks = null; char[] passphrase = "m1oZilla".toCharArray(); SSLServerSocketFactory ssf = null; System.setProperty("javax.net.ssl.trustStore", System.getProperty("java.home") + "/jre/lib/security/cacerts"); String certificate = "SunX509"; String javaVendor = System.getProperty("java.vendor"); if (javaVendor.equals("IBM Corporation")) certificate = "IbmX509"; System.out.println("keystore loc: " + getKeystore()); if (!(type.equals("TLS") || type.equals("SSLv3"))) { System.out.println("type must equal \'TLS\' or \'SSLv3\'\n"); System.exit(1); } try { ctx = SSLContext.getInstance(type); kmf = KeyManagerFactory.getInstance(certificate); ks = KeyStore.getInstance("PKCS12"); try (FileInputStream in = new FileInputStream(getKeystore())) { ks.load(in, passphrase); } kmf.init(ks, passphrase); ctx.init(kmf.getKeyManagers(), null, null); ssf = ctx.getServerSocketFactory(); return ssf; } catch (Exception e) { //if (Constants.debug_level > 3) e.printStackTrace(); } return ssf; } } jss-4.6.3/org/mozilla/jss/tests/JSSPackageTest.java000066400000000000000000000037521362106420000221410ustar00rootroot00000000000000/* 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.tests; public class JSSPackageTest { public static void main(String[] args) { try { Package pkg = Package.getPackage("org.mozilla.jss"); if (pkg != null) { System.out.println("\n---------------------------------------------------------"); System.out.println("Checking jss jar and library version"); System.out.println("---------------------------------------------------------"); System.out.println(" Introspecting jss jar file"); System.out.println("Package name:\t" + pkg.getName()); System.out.println("Spec title :\t" + pkg.getSpecificationTitle()); System.out.println("Spec vendor :\t" + pkg.getSpecificationVendor()); System.out.println("Spec version:\t" + pkg.getSpecificationVersion()); System.out.println("Impl title :\t" + pkg.getImplementationTitle()); System.out.println("Impl vendor :\t" + pkg.getImplementationVendor()); System.out.println("Impl version:\t" + pkg.getImplementationVersion()); } System.out.println("\n\tFetching version information " + "from CryptoManager"); System.out.println("\n\t" + org.mozilla.jss.CryptoManager.JAR_JSS_VERSION); System.out.println("\n\tTo check the JNI version in libjss4.so:"); System.out.println("\n\ttry: strings libjss4.so | grep -i header"); System.out.println("\n\tor : ident libjss4.so"); System.exit(0); } catch (Exception e) { System.out.println("Exception caught : " + e.getMessage()); e.printStackTrace(); System.exit(1); } } } jss-4.6.3/org/mozilla/jss/tests/JSSProvider.java000066400000000000000000000067261362106420000215440ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.util.*; import java.security.*; import javax.crypto.*; import javax.net.ssl.*; import org.mozilla.jss.*; import org.mozilla.jss.pkcs11.*; public class JSSProvider { public static String BASE_PACKAGE = "org.mozilla.jss.provider."; public static void shouldProvide(Provider p, String algo, String _type) { String item = (String) p.get(algo); assert(item != null); assert(item.startsWith(BASE_PACKAGE)); assert(item.endsWith("." + _type)); } public static void shouldNotProvide(Provider p, String algo) { assert(p.get(algo) == null); } public static void main(String[] args) throws Exception { // Before we initialize the CryptoManager, the JSS Provider shouldn't // exist. assert(Security.getProvider("Mozilla-JSS") == null); CryptoManager.initialize(args[0]); CryptoManager cm = CryptoManager.getInstance(); cm.setPasswordCallback(new FilePasswordCallback(args[1])); // Validate that the CryptoManager registers us as the // default/first provider. Provider p = Security.getProviders()[0]; assert(p.getName().equals("Mozilla-JSS")); assert(p instanceof org.mozilla.jss.JSSProvider); // Validate assumptions about how provider.get() works: // // Something which by no means should ever be implemented returns // null. shouldNotProvide(p, "Charlie's Chocolate Factory"); // Validate that our provider implements certain interfaces we care // about. In particular, ensure they're overriden as part of our // org.mozilla.jss.provider package, and that the class name matches // what we expect our implementation to be. shouldProvide(p, "KeyManagerFactory.NssX509", "JSSKeyManagerFactory"); // Validate that our provider is "default"; that is, when we get an // algorithm instance without explicitly providing the provider, we // end up with an instance from our provider. Mac m = Mac.getInstance("HmacSHA512"); assert(m.getProvider().getName().equals(p.getName())); // Our KeyManagerFactory and TrustMangerFactory should return KeyManagers // and TrustManagers from our class namespace. KeyManagerFactory kmf = KeyManagerFactory.getInstance("NssX509"); assert(kmf.getKeyManagers().length > 0); for (KeyManager km : kmf.getKeyManagers()) { System.out.println("got KeyManager: " + km); assert(km instanceof org.mozilla.jss.provider.javax.crypto.JSSKeyManager); } TrustManagerFactory tmf = TrustManagerFactory.getInstance("NssX509"); assert(tmf.getTrustManagers().length > 0); for (TrustManager tm : tmf.getTrustManagers()) { System.out.println("got TrustManager: " + tm); assert(tm instanceof org.mozilla.jss.provider.javax.crypto.JSSTrustManager); } // Our KeyStore should return instances or extensions of PK11Cert. KeyStore ks = KeyStore.getInstance("PKCS11"); ks.load(null, null); Enumeration aliases = ks.aliases(); while (aliases.hasMoreElements()) { String alias = aliases.nextElement(); java.security.cert.Certificate cert = ks.getCertificate(alias); if (cert == null) { continue; } assert(cert instanceof org.mozilla.jss.pkcs11.PK11Cert); } } } jss-4.6.3/org/mozilla/jss/tests/JSSUtil.java000066400000000000000000000047301362106420000206600ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BMPString; import org.mozilla.jss.asn1.IA5String; import org.mozilla.jss.asn1.PrintableString; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.asn1.TeletexString; import org.mozilla.jss.asn1.UTF8String; import org.mozilla.jss.asn1.UniversalString; import org.mozilla.jss.netscape.security.util.DerValue; public class JSSUtil { public static byte[] encode(byte tag, String string) throws Exception { ASN1Value value; switch (tag) { case DerValue.tag_BMPString: value = new BMPString(string); break; case DerValue.tag_IA5String: value = new IA5String(string); break; case DerValue.tag_PrintableString: value = new PrintableString(string); break; case DerValue.tag_T61String: value = new TeletexString(string); break; case DerValue.tag_UniversalString: value = new UniversalString(string); break; case DerValue.tag_UTF8String: value = new UTF8String(string); break; default: throw new Exception("Unsupported tag: " + tag); } return ASN1Util.encode(value); } public static String decode(byte tag, byte[] bytes) throws Exception { ASN1Template template; switch (tag) { case DerValue.tag_BMPString: template = new BMPString.Template(); break; case DerValue.tag_IA5String: template = new IA5String.Template(); break; case DerValue.tag_PrintableString: template = new PrintableString.Template(); break; case DerValue.tag_T61String: template = new TeletexString.Template(); break; case DerValue.tag_UniversalString: template = new UniversalString.Template(); break; case DerValue.tag_UTF8String: template = new UTF8String.Template(); break; default: throw new Exception("Unsupported tag: " + tag); } ASN1Value asnValue = ASN1Util.decode(new Tag(Tag.UNIVERSAL, tag), template, bytes); if (asnValue == null) { throw new Exception("Cannot decode the given bytes."); } return asnValue.toString(); } } jss-4.6.3/org/mozilla/jss/tests/JSS_FileUploadClient.java000077500000000000000000000310271362106420000232670ustar00rootroot00000000000000/* 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.tests; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback; import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent; import org.mozilla.jss.ssl.SSLHandshakeCompletedListener; import org.mozilla.jss.ssl.SSLSecurityStatus; import org.mozilla.jss.ssl.SSLSocket; import org.mozilla.jss.ssl.TestCertApprovalCallback; import org.mozilla.jss.ssl.TestClientCertificateSelectionCallback; import org.mozilla.jss.util.PasswordCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class JSS_FileUploadClient { public static Logger logger = LoggerFactory.getLogger(JSS_FileUploadClient.class); private String clientCertNick = null; private String serverHost = null; private boolean TestCertCallBack = false; private boolean success = true; private int fCipher = -1; private int port = 29755; private String EOF = "test"; private boolean handshakeCompleted = false; private CryptoManager cm = null; private CryptoToken tok = null; private PasswordCallback cb = null; private String fPasswordFile = "passwords"; private String fCertDbPath = "."; private String fUploadFile = "foo.in"; /** * Default Constructor, do not use. */ public JSS_FileUploadClient() { } /** * Initialize the desired cipher to be set * on the socket. * @param aCipher */ public void setCipher(int aCipher) { fCipher = aCipher; } /** * Initialize the hostname to run the server * @param aHostName */ public void setHostName(String aHostName) { serverHost = aHostName; } /** * Initialize the port to run the server * @param aPort */ public void setPort(int aPort) { port = aPort; } /** * Initialize the passwords file name * @param aPasswordFile */ public void setPasswordFile(String aPasswordFile) { fPasswordFile = aPasswordFile; } /** * Initialize the cert db path name * @param aCertDbPath */ public void setCertDbPath(String aCertDbPath) { fCertDbPath = aCertDbPath; } /** * Initialize the name of the file to * be used for testing along with full path. * @param aUploadFile */ public void setUploadFile(String aUploadFile) { fUploadFile = aUploadFile; } /** * Enable/disable Test Cert Callback. * @param aTestCertCallback */ public void setTestCertCallback(boolean aTestCertCallback) { TestCertCallBack = aTestCertCallback; } /** * Set client certificate * @param aClientCertNick Certificate Nick Name */ public void setClientCertNick(String aClientCertNick) { clientCertNick = aClientCertNick; } /** * Return true if handshake is completed * else return false; * @return boolean handshake status */ public boolean isHandshakeCompleted() { return this.handshakeCompleted; } /** * Set handshakeCompleted flag to indicate * that the socket handshake is coplete. */ public void setHandshakeCompleted() { this.handshakeCompleted = true; } /** * Clear handshakeCompleted flag to indicate * that the system is now ready for another * socket connection. */ public void clearHandshakeCompleted() { this.handshakeCompleted = false; } /** * Set EOF for closing server socket * @param fEof null for closing server socket */ public void setEOF(String fEof) { this.EOF = fEof; } /** * ReadWrite thread class that takes a * SSLSocket as input and sleeps * for 2 sec between sending some test * data and receiving. * NOTE: If bufferedStream.mark(Integer.MAX_VALUE); * method is invoked then fill method of * BufferedInputStream class copies lot of data using * System.arraycopy (which in-turn use memcpy). This * causes very high CPU usage. */ private class readWriteThread extends Thread { private SSLSocket clientSock = null; private int socketCntr = 0; public readWriteThread(SSLSocket sock, int cntr) { clientSock = sock; socketCntr = cntr; } public void run() { try { String socketData = null; char[] cbuf = null; int readLength = 0; String readString = null; OutputStream os = clientSock.getOutputStream(); System.out.println("Reading file foo.in"); BufferedReader in = new BufferedReader( new FileReader(fUploadFile)); System.out.println("Successfully got a handle to " + fUploadFile); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); while ((readString = in.readLine()) != null) { System.out.println("Read:" + readString); out.println(readString); out.flush(); } in.close(); out.close(); } catch (Exception e) { System.out.println("Exception caught" + e.getMessage()); e.printStackTrace(); System.exit(1); } } } /** * Initialize and create a socket connection to * SSLServer using the set parameters. */ public void doIt() throws Exception { try { CryptoManager.initialize(fCertDbPath); cm = CryptoManager.getInstance(); tok = cm.getInternalKeyStorageToken(); cb = new FilePasswordCallback(fPasswordFile); tok.login(cb); } catch (Exception e) { } // connect to the server logger.debug("client about to connect..."); String hostAddr = InetAddress.getByName(serverHost).getHostAddress(); logger.debug("the host " + serverHost + " and the address " + hostAddr); SSLCertificateApprovalCallback approvalCallback = new TestCertApprovalCallback(); SSLClientCertificateSelectionCallback certSelectionCallback = new TestClientCertificateSelectionCallback(); SSLSocket sock = null; if (TestCertCallBack) { logger.debug("calling approvalCallBack"); sock = new SSLSocket(InetAddress.getByName(hostAddr), port, null, 0, new TestCertApprovalCallback(), null); } else { logger.debug("NOT calling approvalCallBack"); sock = new SSLSocket(InetAddress.getByName(hostAddr), port); } logger.debug("clientCertNick=" + clientCertNick); sock.setClientCertNickname(clientCertNick); if ( fCipher != -1 ) { sock.setCipherPreference(fCipher, true); } logger.debug("Client specified cert by nickname"); logger.debug("client connected"); // Set socket timeout to 10 sec //sock.setSoTimeout(10 * 1000); //sock.setKeepAlive(true); sock.addHandshakeCompletedListener( new HandshakeListener("client",this)); sock.forceHandshake(); readWriteThread rwThread = new readWriteThread(sock, 0); rwThread.start(); } /** * SSL Handshake Listener implementation. */ public class HandshakeListener implements SSLHandshakeCompletedListener { private String who; private JSS_FileUploadClient boss; public HandshakeListener(String who, JSS_FileUploadClient boss) { this.who = who; this.boss = boss; } public void handshakeCompleted(SSLHandshakeCompletedEvent event) { try { String mesg = who + " got a completed handshake "; SSLSecurityStatus status = event.getStatus(); if( status.isSecurityOn() ) { mesg += "(security is ON)"; } else { mesg += "(security is OFF)"; } logger.debug(mesg); } catch(Exception e) { logger.error(e.getMessage(), e); boss.setFailure(); } setHandshakeCompleted(); } } /** * Set status return value to false. */ public synchronized void setFailure() { success = false; } /** * Set status return value to success. */ public synchronized boolean getSuccess() { return success; } /** * Main method. Used for unit testing. */ public static void main(String[] args) { String certnick = "JSSCATestCert"; String testCipher = "1"; String testhost = "localhost"; int testport = 29755; int socketCntr = 1; String certDbPath = null; String passwdFile = null; String uploadFile = "foo.in"; String usage = "\nUSAGE:\n" + "java org.mozilla.jss.tests.JSS_FileUploadClient" + " [# sockets] [JSS cipher integer]\n[certdb path]" + " [password file] [upload test file] " + " [server host] [server port]"; try { if (args.length <= 0 || args[0].toLowerCase().equals("-h")) { System.out.println(usage); System.exit(1); } else { socketCntr = new Integer(args[0]).intValue(); System.out.println("Socket Counter = " + socketCntr); } testCipher = args[1]; System.out.println("Test Cipher = " + testCipher); if ( args.length >= 3 ) { certDbPath = args[2]; passwdFile = args[3]; } if ( args.length >= 5 ) { uploadFile = args[4]; testhost = args[5]; testport = new Integer(args[6]).intValue(); } } catch (Exception e) { } System.out.println("Client connecting to server ..."); for ( int j=0; j jssSupportedCiphers = new Vector<>(); private static SSLServerSocket serverSock = null; private static SSLSocket sock = null; private String fServerCertNick = null; private String fServerHost = "localhost"; private String fPasswordFile = "passwords"; private String fCertDbPath = "."; private boolean TestInetAddress = false; private boolean success = true; public static int port = 29755; public static String usage = "\nUSAGE:\njava "+ "JSS_FileUploadServer "+ "[certdb path] [password file]"+ "\n[server_host_name] " + "[cert nickname]" + "[testInetAddress: true|false]"; public static void main(String[] args) throws Exception { try { (new JSS_FileUploadServer()).doIt(args); } catch (Exception e) { System.out.println("Exception caught: " + e.getMessage()); System.exit(1); } System.exit(0); } public void doIt(String[] args) throws Exception { if ( args.length < 1 || args[0].toLowerCase().indexOf("-h") != -1) { System.out.println(usage); System.exit(1); } int socketCntr = 0; try { if (args[0].length() > 0 && !args[0].equals(".")) fCertDbPath = args[0]; if (args[1].length() > 0 && !args[1].equals("passwords")) fPasswordFile = args[1]; if (args[2].length() > 0 && !args[2].equals("localhost")) fServerHost = args[2]; if (args[3].length() > 0) fServerCertNick = args[3]; } catch (Exception e) {} CryptoManager.initialize(fCertDbPath); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(fPasswordFile); tok.login(cb); if (args[4].equalsIgnoreCase("true") == true) { TestInetAddress = true; } // We have to configure the server session ID cache before // creating any server sockets. SSLServerSocket.configServerSessionIDCache(10, 100, 100, null); //Disable SSL2 SSLSocket.enableSSL2Default(false); //Note we will use the NSS default enabled ciphers suites // open the server socket and bind to the port logger.debug("Server about .... to create socket"); if (TestInetAddress) { logger.debug("the HostName " + fServerHost + " the Inet Address " + InetAddress.getByName(fServerHost)); serverSock = new SSLServerSocket(port, 5, InetAddress.getByName(fServerHost), null , true); } else { logger.debug("Inet set to Null"); serverSock = new SSLServerSocket(port, 5, null , null , true); } logger.debug("Server created socket"); //serverSock.setSoTimeout(120 * 1000); serverSock.requireClientAuth(SSLSocket.SSL_REQUIRE_NO_ERROR); serverSock.setServerCertNickname(fServerCertNick); logger.debug("Server specified cert by nickname"); System.out.println("Server ready to accept connections"); while ( true ) { // accept the connection sock = (SSLSocket) serverSock.accept(); //sock.setKeepAlive(true); sock.addHandshakeCompletedListener( new HandshakeListener("server", this)); socketCntr++; readWriteThread rwThread = new readWriteThread(sock, socketCntr); rwThread.start(); } } /** * ReadWrite thread class that takes a * SSLSocket as input and sleeps * for 2 sec between sending some test * data and receiving. */ private class readWriteThread extends Thread { private SSLSocket socket = null; private int socketCntr = 0; public readWriteThread(SSLSocket sock, int cntr) { this.socket = sock; this.socketCntr = cntr; } public void run() { try { String socketData = null; char[] cbuf = null; int readLength = 0; String readString = null; InputStream is = socket.getInputStream(); BufferedReader in = new BufferedReader( new InputStreamReader(is)); long timeInMs = new Date().getTime(); while ((readString = in.readLine()) != null) { long now = new Date().getTime(); System.out.print("Read " + readString.getBytes().length + "bytes in " + (now-timeInMs) + "\n"); timeInMs = now; } } catch (Exception e) { System.out.println("Exception caught in readWriteThread.run()\n"); e.printStackTrace(); System.exit(1); } } } public static class HandshakeListener implements SSLHandshakeCompletedListener { private String who; private JSS_FileUploadServer boss; public HandshakeListener(String who, JSS_FileUploadServer boss) { this.who = who; this.boss = boss; } public void handshakeCompleted(SSLHandshakeCompletedEvent event) { try { String mesg = who + " got a completed handshake "; SSLSecurityStatus status = event.getStatus(); if( status.isSecurityOn() ) { mesg += "(security is ON)"; } else { mesg += "(security is OFF)"; } logger.debug(mesg); } catch(Exception e) { logger.error(e.getMessage(), e); boss.setFailure(); } } } public synchronized void setFailure() { success = false; } public synchronized boolean getSuccess() { return success; } } jss-4.6.3/org/mozilla/jss/tests/JSS_SelfServClient.java000077500000000000000000001123141362106420000227730ustar00rootroot00000000000000/* 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.tests; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.Iterator; import org.mozilla.jss.CertDatabaseException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.InitializationValues; import org.mozilla.jss.KeyDatabaseException; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.crypto.AlreadyInitializedException; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent; import org.mozilla.jss.ssl.SSLHandshakeCompletedListener; import org.mozilla.jss.ssl.SSLSecurityStatus; import org.mozilla.jss.ssl.SSLSocket; import org.mozilla.jss.util.IncorrectPasswordException; import org.mozilla.jss.util.PasswordCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /************** * Note on how to use JSS_SelfServServer and JSS_SelfServerClient * * For debugging purposes you should modify Constant.java debug_level to 4. * * First create db's and certificates * java -cp jss4.jar org.mozilla.jss.tests.SetupDBs . ./passwords * java -cp jss4.jar org.mozilla.jss.tests.GenerateTestCert . /passwords * localhost SHA-256/RSA CA_RSA Client_RSA Server_RSA * * Start the server: * * java -cp ./jss4.jar org.mozilla.jss.tests.JSS_SelfServServer . passwords * localhost false 2921 verboseoff * * Start the client with 4 threads using ciphersuite 0x33. * Look at the file Constant.java for the ciphersuites values. * * java -cp jss4.jar org.mozilla.jss.tests.JSS_SelfServClient 2 0x33 * . localhost 2921 verboseoff JSS Client_RSA * * If you envoke the client with a ciphersuite value -1 * then all current JSS ciphersuites will be tested fox X number of * threads, and once all ciphersuites have been tested the client * will closed all client SSLSockets and then tell the server to * shutdown. This case is for the nightly automated tests. * * java -cp jss4.jar org.mozilla.jss.tests.JSS_SelfServClient 4 -1 * . passwords localhost 2921 verboseoff JSS */ interface ConstantsBase { // Test all implemented ciphersuites public static final int TEST_CIPHERS = -1; } public class JSS_SelfServClient implements ConstantsBase, Constants { public static Logger logger = LoggerFactory.getLogger(JSS_SelfServClient.class); private String clientCertNick = "default"; private String serverHost = "localhost"; private String ciphersuiteTested = null; private boolean TestCertCallBack = false; private boolean success = true; private int fCipher = TEST_CIPHERS; private int aWorkingCipher = 0; private boolean bTestCiphers = true; private String CipherName = null; private int port = 29754; private String EOF = "test"; private boolean handshakeCompleted = false; private boolean bVerbose = false; private boolean bFipsMode = false; /* ciphersuites to test */ private ArrayList ciphersToTest = new ArrayList<>(); private CryptoManager cm = null; private CryptoToken tok = null; private PasswordCallback cb = null; private String fPasswordFile = "passwords"; private String fCertDbPath = "."; private ArrayList sockList = new ArrayList<>(); /* h_ciphers is for ciphersuite that were able to successfully * connect to the server */ private ArrayList h_ciphers = new ArrayList<>(); /* f_ciphers is for ciphersuite that failed to connect to the server */ private ArrayList f_ciphers = new ArrayList<>(); private int sockID = 0; /* JSS only needs to be initailized for one instance */ private static boolean bJSS = false; private ThreadGroup socketThreads = new ThreadGroup("SSLSockets"); public void setTestCiphers(boolean t) { bTestCiphers = t; } public boolean getTestCiphers() { return bTestCiphers; } /** * Default Constructor. */ public JSS_SelfServClient() { if (logger.isDebugEnabled()) { bVerbose = true; } /* *if (bVerbose) { * for (int i = 0; i < jssCipherSuites.length; i++) { * System.out.println(jssCipherSuites[i].name + " " + * Integer.toHexString(jssCipherSuites[i].value) ); * } *} */ } public void setVerbose(boolean v) { bVerbose = v; } /** * returns true if JSS is sync with NSS ciphersuites. */ public boolean testJSSCiphersMatchNSS() { initJSS(); boolean cipherSuites = true; int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); for (int i = 0; i < ciphers.length; i++) { //if we do not find the ciphersuite than the JSS // table is out of date. if (Constants.cipher.cipherToString(ciphers[i]) == null) { cipherSuites = false; System.out.println("JSS does not support ciphersuite: " + Integer.toHexString(ciphers[i])); } } if (!cipherSuites) { System.out.println("ERROR: NSS has implemented " + "ciphersuites that JSS does not support!\n"); System.out.println("see http://mxr.mozilla.org/nss/" + "source/lib/ssl/sslproto.h"); System.out.println("Update org/mozilla/jss/ssl/" + "SSLSocket.java"); System.out.println("Update org/mozilla/jss/tests/" + "Constants.java"); System.out.println("NSS implemented ciphersuites " + "missing from JSS"); } return cipherSuites; } public void configureDefaultSSLOptions() { initJSS(); try { //Disable SSL2 SSLSocket.enableSSL2Default(false); //if in FIPS mode disable SSL3 if (bFipsMode) SSLSocket.enableSSL3Default(false); } catch (SocketException ex) { ex.printStackTrace(); System.exit(1); } } public void configureCipherSuites(String server) { int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); boolean testCipher; for (int i = 0; i < ciphers.length; ++i) { String ciphersuite = Constants.cipher.cipherToString(ciphers[i]); testCipher = true; if (bVerbose) { System.out.print(ciphersuite); } // This class uses the TLS versions that NSS enables by default. // Until NSS enables TLS 1.2 by default, don't test the cipher // suites that only work in TLS 1.2. if ((ciphersuite.indexOf("_SHA256") != -1) || (ciphersuite.indexOf("_SHA384") != -1) ) { if (bVerbose) System.out.print(" -"); testCipher = false; } if (server.equalsIgnoreCase("JSS")) { //For JSS SSLServer don't test if ((ciphersuite.indexOf("_DHE_") != -1) || (ciphersuite.indexOf("SSL2") != -1) || //Need to figure out why _ECDH_RSA don't work ( (ciphersuite.indexOf("RSA") != -1) && (ciphersuite.indexOf("_ECDH_") != -1)) ) { if (bVerbose) System.out.print(" -"); testCipher = false; } } if (server.equalsIgnoreCase("JSSE")) { //For JSSE SSLServers don't test if ((ciphersuite.indexOf("SSL2_") != -1) || (ciphersuite.indexOf("_ECDHE_") != -1) || (ciphersuite.indexOf("_ECDH_") != -1) || (ciphersuite.indexOf("_CAMELLIA_") != -1) || (ciphersuite.indexOf("_SEED_") != -1) || (ciphersuite.indexOf("_DHE_DSS_") != -1) || (ciphersuite.indexOf("_EXPORT1024_") != -1) || (ciphersuite.indexOf("_RSA_FIPS_") != -1) || (ciphersuite.indexOf("EXPORT_WITH_RC2") != -1) || (ciphersuite.indexOf("_ECDSA_") != -1) || (ciphersuite.indexOf("_256_") != -1) ) { if (bVerbose) System.out.print(" -"); testCipher = false; } } if (server.equalsIgnoreCase("Mozilla-JSS")) { //For JSSE Mozilla-JSS SSLServers don't test if ((ciphersuite.indexOf("SSL2_") != -1) || (ciphersuite.indexOf("_ECDHE_") != -1) || (ciphersuite.indexOf("_ECDH_") != -1) || (ciphersuite.indexOf("_CAMELLIA_") != -1) || (ciphersuite.indexOf("_SEED_") != -1) || (ciphersuite.indexOf("_DHE_DSS_") != -1)|| (ciphersuite.indexOf("_EXPORT1024_") != -1) || (ciphersuite.indexOf("_RSA_FIPS_") != -1) || (ciphersuite.indexOf("EXPORT_WITH_RC2") != -1) || (ciphersuite.indexOf("_ECDSA_") != -1) || (ciphersuite.indexOf( "SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA") != -1) || (ciphersuite.indexOf( "SSL3_RSA_WITH_3DES_EDE_CBC_SHA") != -1) || (ciphersuite.indexOf( "SSL3_DHE_RSA_WITH_DES_CBC_SHA") != -1)|| (ciphersuite.indexOf( "SSL3_RSA_WITH_DES_CBC_SHA") != -1) || (ciphersuite.indexOf( "SSL3_RSA_EXPORT_WITH_RC4_40_MD5") != -1) || (ciphersuite.indexOf("_256_") != -1) ) { if (bVerbose) System.out.print(" -"); testCipher = false; } } if (testCipher) { if (bFipsMode) { try { if (SSLSocket.isFipsCipherSuite(ciphers[i])) { ciphersToTest.add(new Integer(ciphers[i])); if (bVerbose) System.out.print(" - FIPS Testing"); } else if (bVerbose) System.out.print(" -"); } catch (SocketException ex) { ex.printStackTrace(); } } else { ciphersToTest.add(new Integer(ciphers[i])); if (bVerbose) System.out.print(" - Testing"); } } } if (bVerbose) System.out.print("\n"); if(bVerbose) System.out.println("\nTesting " + ciphersToTest.size() + " ciphersuites."); } /** *For every enabled ciphersuite created numOfThreads connections. */ public void testCiphersuites(int numOfThreads) { Iterator iter = ciphersToTest.iterator(); setTestCiphers(true); while (iter.hasNext()) { setCipher(iter.next().intValue()); try { createSSLConnections(numOfThreads); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } } } /** * Initialize the desired ciphersuite to be set * on the socket. * @param aCipher */ public void setCipher(int aCipher) { initJSS(); int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); ciphersuiteTested = Constants.cipher.cipherToString(aCipher); if (bVerbose || !bTestCiphers) { System.out.println("Testing " + Integer.toHexString(aCipher) + " " + ciphersuiteTested); } if (ciphersuiteTested != null) { fCipher = aCipher; } else { System.out.print("ciphersuite not supported"); System.exit(1); } try { if (cm.FIPSEnabled() && !SSLSocket.isFipsCipherSuite(aCipher)) { System.out.println("You are trying to test a non FIPS " + "ciphersuite when FIPS is enabled!"); System.exit(1); } } catch (SocketException ex) { ex.printStackTrace(); } //Disable all Ciphers we only want the one cipher //to be turned on for (int i = 0; i < ciphers.length; i++) { try { if (SSLSocket.getCipherPreferenceDefault(ciphers[i])) { // System.out.println("Implemented Cipher Suite: " + // Integer.toHexString(ciphers[i]) + " is ON"); SSLSocket.setCipherPreferenceDefault(ciphers[i], false); } } catch (SocketException ex) { ex.printStackTrace(); } } //note all ciphers are disabled but the ciphersuite to be tested //will only be enabled in the method createSSLSocket } /** * Initialize the hostname to run the server * @param aHostName */ public void setHostName(String aHostName) { serverHost = aHostName; } /** * Initialize the port to run the server * @param aPort */ public void setPort(int aPort) { port = aPort; } /** * Initialize the passwords file name * @param aPasswordFile */ public void setPasswordFile(String aPasswordFile) { fPasswordFile = aPasswordFile; } /** * Initialize the cert db path name * @param aCertDbPath */ public void setCertDbPath(String aCertDbPath) { fCertDbPath = aCertDbPath; } /** * Enable/disable Test Cert Callback. * @param aTestCertCallback */ public void setTestCertCallback(boolean aTestCertCallback) { TestCertCallBack = aTestCertCallback; } /** * Set client certificate * @param aClientCertNick Certificate Nick Name */ public void setClientCertNick(String aClientCertNick) { clientCertNick = aClientCertNick; X509Certificate certs[]; try { certs = cm.findCertsByNickname(clientCertNick); if (certs.length == 0) { System.out.println("unable to find cert nickname: " + clientCertNick); System.exit(1); } } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } } /** * Return true if handshake is completed * else return false; * @return handshake status */ public boolean isHandshakeCompleted() { return this.handshakeCompleted; } /** * Set handshakeCompleted flag to indicate * that the socket handshake is coplete. */ public void setHandshakeCompleted() { this.handshakeCompleted = true; } /** * Clear handshakeCompleted flag to indicate * that the system is now ready for another * socket connection. */ public void clearHandshakeCompleted() { this.handshakeCompleted = false; } /** * returns the total number SSLSockets created. */ public int getSockTotal() { return sockID; } /** * ReadWrite thread class that takes a * SSLSocket as input and sleeps * for 1 sec between sending some test * data and receiving. */ private class readWriteThread extends Thread { private SSLSocket clientSock = null; private String socketID = null; private String ciphersuite; public readWriteThread(ThreadGroup tgOb, String tName, String cs, SSLSocket sock) { super(tgOb, tName); if (bVerbose) { System.out.println("New thread: " + this); } ciphersuite = cs; clientSock = sock; socketID = tName; } public void run() { try { String outputLine = null; String inputLine = null; InputStream is = clientSock.getInputStream(); OutputStream os = clientSock.getOutputStream(); BufferedReader bir = new BufferedReader( new InputStreamReader(is)); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); while (true) { outputLine = ciphersuite + ":" + socketID + "\n"; if (bVerbose) { System.out.println("Sending: " + outputLine); } out.print(outputLine); out.flush(); inputLine = bir.readLine(); if (bVerbose) { System.out.println("Received: " + inputLine + " on Client-" + socketID); } Thread.sleep(50); } } catch (InterruptedException e) { e.printStackTrace(); } catch (java.net.SocketTimeoutException e) { e.printStackTrace(); } catch (IOException e) { if ((e.getMessage().equalsIgnoreCase( "SocketException cannot read on socket")) || (e.getMessage().equalsIgnoreCase( "Socket has been closed, and cannot be reused.")) ) { //System.out.println("SSLSocket " // + socketID + " has been closed."); } else e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } private void initJSS() { if (bJSS) { return; /* JSS already initialized */ } try { InitializationValues vals = new InitializationValues(fCertDbPath); CryptoManager.initialize(vals); cm = CryptoManager.getInstance(); if (cm.FIPSEnabled()) { System.out.println("The database is in FIPSMODE"); bFipsMode = true; } tok = cm.getInternalKeyStorageToken(); cb = new FilePasswordCallback(fPasswordFile); tok.login(cb); bJSS = true; }catch (KeyDatabaseException ex) { ex.printStackTrace(); System.exit(1); } catch (CertDatabaseException ex) { ex.printStackTrace(); System.exit(1); } catch (NotInitializedException ex) { ex.printStackTrace(); System.exit(1); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } catch (AlreadyInitializedException ex) { ex.printStackTrace(); System.exit(1); } catch (GeneralSecurityException ex) { ex.printStackTrace(); System.exit(1); } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } catch (IncorrectPasswordException ex) { ex.printStackTrace(); System.exit(1); } } public boolean isServerAlive() { boolean isServerAlive = false; try { SSLSocket s = null; if (bVerbose) System.out.println("Confirming Server is alive "); //TLS_RSA_WITH_AES_128_CBC_SHA works in FIPS and Non FIPS mode. //and with JSS and JSSE SSL servers. setCipher(SSLSocket.TLS_RSA_WITH_AES_128_CBC_SHA); System.out.println("Testing Connection:" + serverHost + ":" + port); for (int i = 0; i < 20; i++) { s = createSSLSocket(); if (s != null) break; Thread.sleep(1000); } if (s != null) { s.close(); isServerAlive = true; } } catch (InterruptedException ex) { ex.printStackTrace(); System.exit(1); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } return isServerAlive; } /** * sendServerShutdownMsg */ public void sendServerShutdownMsg() { try { SSLSocket s = null; if (bVerbose) System.out.println("Sending shutdown message " + "to server."); if (aWorkingCipher == 0) { System.out.println("no ciphersuite was able to connect to " + "the server!"); System.exit(1); } setCipher(aWorkingCipher); s = createSSLSocket(); if (s == null) throw new IOException("Unable to connect to server"); OutputStream os = s.getOutputStream(); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); out.println("shutdown"); out.flush(); out.close(); s.close(); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } } /** * closes the SSLSocket */ public void closeAllSockets() { try { SSLSocket s; long start = System.currentTimeMillis(); Iterator sIter = sockList.iterator(); while (sIter.hasNext()) { s = sIter.next(); s.close(); } System.out.println("Waiting till all threads are dead"); int i = 0; while (socketThreads.activeCount() > 0) { Thread.sleep(10); System.out.println("ActiveCount" + socketThreads.activeCount()); //This loop should always exit but it has the potential //to hang the QA tests so... if (i == 100) { // 100 x 10 System.out.println("It is taking too long for the " + "threads to die. Exiting the program"); System.out.println("Time taken: " + (System.currentTimeMillis() - start) + " Milliseconds"); /* while all the threads have not completed cleanup. */ /* the functional test of each configured cihpersuite */ /* successfully established a connection. */ /* Let remaining threads die when this application */ /* ends execution */ return; } i++; } System.out.println("All threads are dead. Time taken: " + (System.currentTimeMillis() - start) + " Milliseconds."); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } catch (InterruptedException ex) { ex.printStackTrace(); System.exit(1); } } /** * returns a connected SSLSocket or null if unable to connect. */ private SSLSocket createSSLSocket() { SSLSocket sock = null; try { // connect to the server if ( bVerbose ) System.out.println("client about to connect..."); String hostAddr = InetAddress.getByName(serverHost).getHostAddress(); if ( bVerbose ) System.out.println("the host " + serverHost + " and the address " + hostAddr); if (TestCertCallBack) { if ( bVerbose ) System.out.println("calling approvalCallBack"); sock = new SSLSocket(InetAddress.getByName(hostAddr), port, null, 0, new TestCertificateApprovalCallback(), null); } else { if ( bVerbose ) System.out.println("NOT calling approvalCallBack"); sock = new SSLSocket(InetAddress.getByName(hostAddr), port); } if (clientCertNick.equalsIgnoreCase("default")) { sock.setClientCertNickname("Client_RSA"); sock.setClientCertNickname("Client_ECDSA"); sock.setClientCertNickname("Client_DSS"); } else { sock.setClientCertNickname(clientCertNick); if ( bVerbose ) { System.out.println("Client specified cert by nickname"); } } //Ensure the ciphersuite is disable, then enabled only it. if (sock.getCipherPreference(fCipher)) { System.out.println("Ciphersuite should have been disabled?"); System.exit(1); } else { sock.setCipherPreference(fCipher, true); } sock.addHandshakeCompletedListener( new HandshakeListener("client",this)); sock.forceHandshake(); sock.setSoTimeout(10*1000); sockList.add(sock); sockID++; aWorkingCipher = fCipher; if ( bVerbose ) { System.out.println("client connected"); } } catch (SocketException ex) { if (bTestCiphers) { sock = null; } else { ex.printStackTrace(); System.exit(1); } } catch (UnknownHostException ex) { ex.printStackTrace(); System.exit(1); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } return sock; } public void outputCipherResults() { String banner = new String ("\n-------------------------------------------------------\n"); System.out.println(banner); System.out.println("JSS has " + org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites().length + " ciphersuites and " + ciphersToTest.size() + " were configured and tested."); if (ciphersToTest.size() == h_ciphers.size()) { System.out.println("All " + ciphersToTest.size() + " configured ciphersuites tested Successfully!\n"); } if (!h_ciphers.isEmpty()) { if (!f_ciphers.isEmpty()) { System.out.println(banner); System.out.println(h_ciphers.size() + " ciphersuites successfully connected to the "+ "server\n"); } Iterator iter = h_ciphers.iterator(); while (iter.hasNext()) { System.out.println(iter.next()); } } if (bFipsMode) { System.out.println("Note: ciphersuites that have the prefix " + "\"SSL\" or \"SSL3\" were used in TLS mode."); } if (ciphersToTest.size() != (h_ciphers.size() + f_ciphers.size())) { System.out.println("ERROR: did not test all expected ciphersuites"); } if (!f_ciphers.isEmpty()) { System.out.println(banner); System.out.println(f_ciphers.size() + " ciphersuites that did not connect to the "+ "server\n\n"); Iterator iter = f_ciphers.iterator(); while (iter.hasNext()) { System.out.println(iter.next()); } System.out.println("we should have no failed ciphersuites!"); System.exit(1); } System.out.println(banner); } /** * Initialize given number of SSLSocket client connection to the * SSLServer using the set parameters. Each Connection will have * a separate thread performing I/O to the Server. */ public void createSSLConnections(int numToCreate) throws Exception { SSLSocket sock = null; initJSS(); for (int i = 1; i <= numToCreate; i++) { sock = createSSLSocket(); if (sock != null) { String threadName = new String(sockID + "-" + i); readWriteThread rwThread = new readWriteThread(socketThreads, threadName, ciphersuiteTested, sock); rwThread.start(); if (i == 1) { h_ciphers.add(ciphersuiteTested); } } else { /* ciphersuite failed */ if (bTestCiphers) { f_ciphers.add(ciphersuiteTested); } break; } } if ( bVerbose ) { System.out.println("Active thread count: " + socketThreads.activeCount()); System.out.println("Total threads created: " + getSockTotal()); } } /** * SSL Handshake Listener implementation. */ public class HandshakeListener implements SSLHandshakeCompletedListener { private String who; private JSS_SelfServClient boss; public HandshakeListener(String who, JSS_SelfServClient boss) { this.who = who; this.boss = boss; } public void handshakeCompleted(SSLHandshakeCompletedEvent event) { try { String mesg = who + " got a completed handshake "; SSLSecurityStatus status = event.getStatus(); if( status.isSecurityOn() ) { mesg += "(security is ON)"; } else { mesg += "(security is OFF)"; } if ( bVerbose ) { System.out.println(mesg); } } catch(Exception e) { e.printStackTrace(); System.exit(1); } setHandshakeCompleted(); } } /** * Set status return value to false. */ public synchronized void setFailure() { success = false; } /** * Set status return value to success. */ public synchronized boolean getSuccess() { return success; } /** * Main method. Used for unit testing. */ public static void main(String[] args) { String certnick = "default"; int testCipher = TEST_CIPHERS; String testhost = "localhost"; int testport = 29754; int numOfThreads = 10; String certDbPath = null; String passwdFile = null; boolean bVerbose = false; String server = "JSS"; try { Thread.sleep(3*1000); } catch (InterruptedException ex) { ex.printStackTrace(); } String usage = "\nUSAGE:\n" + "java org.mozilla.jss.tests.JSS_SelfServClient" + " [# sockets] [JSS cipher hex code \"0xC013\" value or -1] " + "\n\nOptional:\n" + "[certdb path] [password file] [server host] [server port]" + "[verbose] [server = JSS or JSSE] [ClientCert]"; try { if (args.length <= 0 || args[0].toLowerCase().equals("-h")) { System.out.println(usage); System.exit(1); } else { numOfThreads = new Integer(args[0]).intValue(); System.out.println("Number of Threads to create: " + numOfThreads); } if (args.length >= 2) { if (args[1].startsWith("0x") || args[1].startsWith("0X")) { testCipher = Integer.decode(args[1]).intValue(); } else { testCipher = new Integer(args[1]).intValue(); } } if (args.length >= 3) { certDbPath = args[2]; } if (args.length >= 4) { passwdFile = args[3]; } if (args.length >= 5) { testhost = args[4]; } if (args.length >= 6) { testport = new Integer(args[5]).intValue(); } if ((args.length >= 7) && args[6].equalsIgnoreCase("verbose") == true) { System.out.println("verbose mode enabled."); bVerbose = true; } if (args.length >= 8) { server = args[7].toUpperCase(); } if (args.length >=9) { certnick = args[8]; System.out.println("certnickname: " + certnick); } } catch (Exception e) { System.out.println("Unknown exception : " + e.getMessage()); System.exit(1); } System.out.println("Client connecting to server: " + testhost + ":" + testport); JSS_SelfServClient jssTest = new JSS_SelfServClient(); try { if ( !testhost.equals("localhost") ) jssTest.setHostName(testhost); if ( testport != 29754 ) jssTest.setPort(testport); jssTest.setPasswordFile(passwdFile); jssTest.setCertDbPath(certDbPath); jssTest.setVerbose(bVerbose); jssTest.initJSS(); if (!jssTest.testJSSCiphersMatchNSS()) { System.out.println("JSS needs to update the ciphersuites!"); System.exit(1); } jssTest.setTestCertCallback(true); jssTest.configureDefaultSSLOptions(); if ( certDbPath != null ) jssTest.setCertDbPath(certDbPath); if ( passwdFile != null ) jssTest.setPasswordFile(passwdFile); if (!jssTest.isServerAlive()) { System.out.println("Server " + testhost + ":" + testport + " is not Alive.\nIf this test was ran by " + "all.pl look at the server invocation for failures " + "and check network issues."); System.exit(1); } if (testCipher != TEST_CIPHERS) { jssTest.setClientCertNick(certnick); jssTest.setTestCiphers(false); jssTest.setCipher(testCipher); jssTest.createSSLConnections(numOfThreads); } else { jssTest.configureCipherSuites(server); jssTest.testCiphersuites(numOfThreads); } } catch (Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace(); System.exit(1); } if (jssTest.getSockTotal() == 0 ) { System.out.println("No SSLSockets created check your " + "configuration."); System.exit(1); } // choose how to exit the program System.out.println(jssTest.getSockTotal() + " SSLSockets created."); System.out.println("Each created SSLSocket is reading/writing to" + " the SSLServer."); if (jssTest.getTestCiphers()) { try { //Sleep for 30 seconds Thread.sleep(30*1000); } catch (InterruptedException ex) { ex.printStackTrace(); System.exit(1); } jssTest.closeAllSockets(); jssTest.sendServerShutdownMsg(); jssTest.outputCipherResults(); System.exit(0); } System.out.println("You can choose to exit the program enter:" + "\n\t\'A\' to abort with out closing the sockets." + "\n\t\'C\' to close all client sockets (server will not quit)" + "\n\tor any other letter to close all sockets and tell the" + "server to quit."); try { BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); String p = stdin.readLine(); if (p.equalsIgnoreCase("a")) { System.out.println("Aborting with out closing SSLSockets."); } else { jssTest.closeAllSockets(); if (!p.equalsIgnoreCase("c")) { //shutdown the server jssTest.sendServerShutdownMsg(); } } } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.6.3/org/mozilla/jss/tests/JSS_SelfServServer.java000077500000000000000000000344571362106420000230360ustar00rootroot00000000000000/* 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.tests; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.SocketTimeoutException; import java.util.Vector; import java.lang.NumberFormatException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent; import org.mozilla.jss.ssl.SSLHandshakeCompletedListener; import org.mozilla.jss.ssl.SSLSecurityStatus; import org.mozilla.jss.ssl.SSLServerSocket; import org.mozilla.jss.ssl.SSLSocket; import org.mozilla.jss.util.PasswordCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /************** * Note on how to use JSS_SelfServServer and JSS_SelfServerClient * * For debugging purposes you should modify Constant.java debug_level to 4. * * First create db's and certificates * java -cp jss4.jar org.mozilla.jss.tests.SetupDBs . ./passwords * java -cp jss4.jar org.mozilla.jss.tests.GenerateTestCert . /passwords * localhost SHA-256/RSA CA_RSA Client_RSA Server_RSA * * Start the server: * * java -cp ./jss4.jar org.mozilla.jss.tests.JSS_SelfServServer . passwords localhost * false 2921 verboseoff * * Start the client with 4 threads using ciphersuite 0x33. * Look at the file Constant.java for the ciphersuites values. * * java -cp jss4.jar org.mozilla.jss.tests.JSS_SelfServClient 2 0x33 * . localhost 2921 verboseoff JSS Client_RSA * * If you envoke the client with a ciphersuite value -1 * then all current JSS ciphersuites will be tested fox X number of * threads, and once all ciphersuites have been tested the client * will closed all client SSLSockets and then tell the server to * shutdown. This case is for the nightly automated tests. * * java -cp jss4.jar org.mozilla.jss.tests.JSS_SelfServClient 4 -1 * . passwords localhost 2921 verboseoff JSS */ public class JSS_SelfServServer { public static Logger logger = LoggerFactory.getLogger(JSS_SelfServServer.class); private static Vector jssSupportedCiphers = new Vector<>(); private static SSLServerSocket serverSock = null; private static SSLSocket sock = null; public static void main(String[] args) throws Exception { try { (new JSS_SelfServServer()).doIt(args); } catch (Exception e) { System.out.println("JSS_SelfServServer exiting with Exception " + e.getMessage()); System.exit(1); } System.exit(0); } private String fServerCertNick = null; private String fServerHost = "localhost"; private String fPasswordFile = "passwords"; private String fCertDbPath = "."; private boolean TestInetAddress = false; private boolean success = true; private boolean bVerbose = false; public int port = 29754; public static String usage = "\nUSAGE:\njava JSS_SelfServServer"+ " [certdb path] [password file]\n"+ "[server_host_name] [testInetAddress: true|false]" + " "; public JSS_SelfServServer() { if (logger.isDebugEnabled()) { bVerbose = true; } } public void doIt(String[] args) throws Exception { if ( args.length < 5 || args[0].toLowerCase().equals("-h")) { System.out.println(usage); System.exit(1); } try { if (!args[0].equals(".")) fCertDbPath = args[0]; if (!args[1].equals("passwords")) fPasswordFile = args[1]; if (!args[2].equals("localhost")) fServerHost = args[2]; if (args[3].equalsIgnoreCase("true") == true) TestInetAddress = true; if (args.length >= 5) port = new Integer(Integer.valueOf(args[4])); if (args.length >=6 && args[5].equalsIgnoreCase("verbose")) { bVerbose = true; } if (args.length >=7 && !args[6].equalsIgnoreCase("default")) { fServerCertNick = args[6]; } } catch (NumberFormatException e) { System.out.println("Error parsing command line " + e.getMessage()); System.out.println(usage); System.exit(1); } if (bVerbose) System.out.println("initializing JSS"); CryptoManager.initialize(fCertDbPath); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(fPasswordFile); tok.login(cb); // We have to configure the server session ID cache before // creating any server sockets. SSLServerSocket.configServerSessionIDCache(10, 100, 100, null); if (cm.FIPSEnabled()) { /* turn on only FIPS ciphersuites */ /* Disable SSL2 and SSL3 ciphers */ SSLSocket.enableSSL2Default(false); SSLSocket.enableSSL3Default(false); //Enable only FIPS ciphersuites. int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); for (int i = 0; i < ciphers.length; ++i) { if (SSLSocket.isFipsCipherSuite(ciphers[i])) { /* enable the FIPS ciphersuite */ SSLSocket.setCipherPreferenceDefault(ciphers[i], true); } else if (SSLSocket.getCipherPreferenceDefault( ciphers[i])) { /* disable the non fips ciphersuite */ SSLSocket.setCipherPreferenceDefault(ciphers[i], false); } } } else { /* turn on all implemented ciphersuites the server certificate * will determine if the ciphersuites can be used. */ int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); for (int i = 0; i < ciphers.length; ++i) { try { SSLSocket.setCipherPreferenceDefault(ciphers[i], true); if (bVerbose) { System.out.println(Constants.cipher.cipherToString( ciphers[i]) + " " + Integer.toHexString(ciphers[i])); } } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } } //disable SSL2 ciphersuites SSLSocket.enableSSL2Default(false); } // open the server socket and bind to the port if (bVerbose) System.out.println("JSS_SelfServServ about .... to create socket"); if (TestInetAddress) { if (bVerbose) System.out.println("JSS_SelfServServ HostName " + fServerHost + " the Inet Address " + InetAddress.getByName(fServerHost)); serverSock = new SSLServerSocket(port, 5, InetAddress.getByName(fServerHost), null , true); } else { if (bVerbose) System.out.println("Inet set to Null"); serverSock = new SSLServerSocket(port, 5, null , null , true); } if (bVerbose) System.out.println("JSS_SelfServServ created socket"); serverSock.setSoTimeout(600*1000); // Set timeout for 10 minutes serverSock.requireClientAuth(SSLSocket.SSL_REQUIRE_NO_ERROR); serverSock.setServerCertNickname("Server_ECDSA"); serverSock.setServerCertNickname("Server_RSA"); serverSock.setServerCertNickname("Server_DSS"); if (bVerbose) System.out.println("JSS_SelfServServ specified cert by nickname"); System.out.println("JSS_SelfServServ " + fServerHost + " ready to accept connections on " + port); int socketCntr = 0; try { while ( true ) { // accept the connection sock = (SSLSocket) serverSock.accept(); sock.addHandshakeCompletedListener( new HandshakeListener("server", this)); socketCntr++; sock.setSoTimeout(300*1000); if (bVerbose) { System.out.println("Timeout value for SSL sockets: " + sock.getSoTimeout() + " milliseconds"); } readWriteThread rwThread = new readWriteThread(sock, socketCntr); rwThread.start(); } } catch (SocketTimeoutException ex) { if (socketCntr == 0) { System.out.println("JSS_SelfServServ No Client attempted to " + "connect! If " + "test ran from all.pl check the client execution " + "for errors."); } else { System.out.println("JSS_SelfServServ there has been " + socketCntr + " client " + " connections but the server Accept has timed out!"); } System.out.println("JSS_SelfServServ Timeout value: " + serverSock.getSoTimeout() + " milliseconds"); ex.printStackTrace(); System.out.println("JSS_SelfServServ exiting due to timeout."); System.exit(1); } catch (Exception ex) { System.out.println("JSS_SelfServServ Exception:"); ex.printStackTrace(); System.out.println("JSS_SelfServServ exiting."); System.exit(1); } } /** * ReadWrite thread class that takes a * SSLSocket as input and read then writes * back to client. */ private class readWriteThread extends Thread { private SSLSocket socket = null; private int socketCntr = 0; public readWriteThread(SSLSocket sock, int cntr) { this.socket = sock; this.socketCntr = cntr; } public void run() { try { String inputLine = null; String outputLine = null; InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); BufferedReader bir = new BufferedReader( new InputStreamReader(is)); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); while (true) { try { if ((inputLine = bir.readLine()) != null) { if (inputLine.equalsIgnoreCase("shutdown")) { if (bVerbose) { System.out.println("Client told " + " JSS_SelfServServer to Shutdown!"); } is.close(); os.close(); socket.close(); System.exit(0); } outputLine = "ServerSSLSocket- " + socketCntr; if (bVerbose) { System.out.println("ServerSSLSocket-" + socketCntr + ": Received " + inputLine); System.out.println("Sending" + outputLine); } out.println(outputLine); out.flush(); } else { /* if you read null then quit. otherwise you * will be in endless loop with the socket * stuck in CLOSED_WAIT. */ if (bVerbose) { System.out.println("ServerSSLSocket-" + socketCntr + " read null aborting connection."); } break; } } catch (SocketTimeoutException ste) { System.out.println("ServerSSLSocket-" + socketCntr + " timed out: " + ste.toString()); break; } catch (IOException ex) { break; } } /* close streams and close socket */ is.close(); os.close(); socket.close(); if (bVerbose) { System.out.println("ServerSSLSocket " + socketCntr + " has been Closed."); } } catch (IOException e) { e.printStackTrace(); } } } public static class HandshakeListener implements SSLHandshakeCompletedListener { private String who; private JSS_SelfServServer boss; public HandshakeListener(String who, JSS_SelfServServer boss) { this.who = who; this.boss = boss; } public void handshakeCompleted(SSLHandshakeCompletedEvent event) { try { String mesg = who + " got a completed handshake "; SSLSecurityStatus status = event.getStatus(); if( status.isSecurityOn() ) { mesg += "(security is ON)"; } else { mesg += "(security is OFF)"; } logger.debug(mesg); } catch(Exception e) { logger.error(e.getMessage(), e); boss.setFailure(); } } } public synchronized void setFailure() { success = false; } public synchronized boolean getSuccess() { return success; } } jss-4.6.3/org/mozilla/jss/tests/KeyFactoryTest.java000066400000000000000000000202421362106420000222770ustar00rootroot00000000000000/* 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.tests; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; import java.security.spec.KeySpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.util.PasswordCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; abstract class TestValues { protected TestValues(String keyGenAlg, String sigAlg, Class privateKeySpecClass, Class publicKeySpecClass, String provider) { this.keyGenAlg = keyGenAlg; this.sigAlg = sigAlg; this.privateKeySpecClass = privateKeySpecClass; this.publicKeySpecClass = publicKeySpecClass; this.provider = provider; } public final String keyGenAlg; public final String sigAlg; public final Class privateKeySpecClass; public final Class publicKeySpecClass; public final String provider; } class RSATestValues extends TestValues { public RSATestValues() { super("RSA", "SHA1withRSA", RSAPrivateCrtKeySpec.class, RSAPublicKeySpec.class, "SunRsaSign"); } public RSATestValues(String provider) { super("RSA", "SHA1withRSA", RSAPrivateCrtKeySpec.class, RSAPublicKeySpec.class, provider); } } class DSATestValues extends TestValues { public DSATestValues() { super("DSA", "SHA1withDSA", DSAPrivateKeySpec.class, DSAPublicKeySpec.class, "SUN"); } public DSATestValues(String provider) { super("DSA", "SHA1withDSA", DSAPrivateKeySpec.class, DSAPublicKeySpec.class, provider); } } public class KeyFactoryTest { public static Logger logger = LoggerFactory.getLogger(KeyFactoryTest.class); public static void main(String argv[]) { try { if( argv.length < 2 ) { System.out.println( "Usage: java org.mozilla.jss.tests.KeyFactoryTest " + " "); System.exit(1); } CryptoManager.initialize(argv[0]); CryptoToken tok = CryptoManager.getInstance().getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(argv[1]); tok.login(cb); /* This is just a huge amount of needless info for the tinderbox and nightly QA * Provider []provs = Security.getProviders(); * for( int i=0; i < provs.length; ++i) { * System.out.println("======"); * System.out.println(provs[i].getName()); * provs[i].list(System.out); * System.out.println("======"); * } */ (new KeyFactoryTest()).doTest(); } catch(Throwable e) { e.printStackTrace(); System.exit(1); } System.exit(0); } public void doTest() throws Throwable { String javaVendor = System.getProperty("java.vendor"); RSATestValues rsa = null; DSATestValues dsa = null; boolean exception = false; if ( javaVendor.equals("IBM Corporation") ) { rsa = new RSATestValues("IBMJCE"); dsa = new DSATestValues("IBMJCE"); } else { rsa = new RSATestValues(); dsa = new DSATestValues(); } // Generate RSA private key from spec try { genPrivKeyFromSpec(rsa); } catch (java.security.spec.InvalidKeySpecException ex) { logger.warn("InvalidKeySpecException caught " + "genPrivKeyFromSpec(rsa): " + ex.getMessage(), ex); if ( javaVendor.equals("IBM Corporation") ) { System.out.println("Could not generated a RSA private key from " + "a\njava.security.spec.RSAPrivateKeySpec. Not supported " + "IBMJCE"); } else { exception = true; } } catch (Exception ex) { logger.warn("Exception caught genPrivKeyFromSpec(rsa): " + ex.getMessage(), ex); } // Generate DSA private key from spec try { genPrivKeyFromSpec(dsa); } catch (java.security.spec.InvalidKeySpecException ex) { logger.warn("InvalidKeySpecException caught " + "genPrivKeyFromSpec(dsa): " + ex.getMessage(), ex); exception = true; } catch (Exception ex) { logger.warn("Exception caught genPrivKeyFromSpec(dsa): " + ex.getMessage(), ex); } // translate RSA key try { genPubKeyFromSpec(rsa); } catch (Exception ex) { logger.warn("Exception caught genPubKeyFromSpec(rsa): " + ex.getMessage(), ex); exception = true; } // translate key try { genPubKeyFromSpec(dsa); } catch (Exception ex) { logger.warn("Exception caught genPubKeyFromSpec(dsa): " + ex.getMessage(), ex); exception = true; } if (exception) System.exit(1); else System.exit(0); } void genPrivKeyFromSpec(TestValues vals) throws Throwable { // generate the key pair KeyPairGenerator kpg = KeyPairGenerator.getInstance(vals.keyGenAlg, vals.provider); kpg.initialize(512); KeyPair pair = kpg.generateKeyPair(); // get the private key spec KeyFactory sunFact = KeyFactory.getInstance(vals.keyGenAlg, vals.provider); KeySpec keySpec = sunFact.getKeySpec(pair.getPrivate(), vals.privateKeySpecClass); // import it into JSS KeyFactory jssFact = KeyFactory.getInstance(vals.keyGenAlg, "Mozilla-JSS"); PrivateKey jssPrivk = jssFact.generatePrivate(keySpec); signVerify(vals.sigAlg, jssPrivk, "Mozilla-JSS", pair.getPublic(), vals.provider); System.out.println("Successfully generated a " + vals.keyGenAlg + " private key from a " + vals.privateKeySpecClass.getName()); } public void signVerify(String sigAlg, PrivateKey privk, String signProv, PublicKey pubk, String verifyProv) throws Throwable { Signature signSig = Signature.getInstance(sigAlg, signProv); signSig.initSign(privk); String toBeSigned = "blah blah blah sign me"; signSig.update(toBeSigned.getBytes("UTF-8")); byte[] signature = signSig.sign(); Signature verSig = Signature.getInstance(sigAlg, verifyProv); verSig.initVerify(pubk); verSig.update(toBeSigned.getBytes("UTF-8")); if( ! verSig.verify(signature) ) { throw new Exception( "Private/public key mismatch: signing alg=" + sigAlg + ", signing provider=" + signProv + ", verifying provider = " + verifyProv); } } void genPubKeyFromSpec(TestValues vals) throws Throwable { // generate a key pair KeyPairGenerator kpg = KeyPairGenerator.getInstance(vals.keyGenAlg, vals.provider); kpg.initialize(512); KeyPair pair = kpg.generateKeyPair(); // get the public key spec KeyFactory sunFact = KeyFactory.getInstance(vals.keyGenAlg, vals.provider); KeySpec keySpec = sunFact.getKeySpec(pair.getPublic(), vals.publicKeySpecClass); // import it into JSS KeyFactory jssFact = KeyFactory.getInstance(vals.keyGenAlg, "Mozilla-JSS"); PublicKey jssPubk = jssFact.generatePublic(keySpec); signVerify(vals.sigAlg, pair.getPrivate(), vals.provider, jssPubk, "Mozilla-JSS"); System.out.println("Successfully generated a " + vals.keyGenAlg + " public key from a " + vals.publicKeySpecClass.getName()); } } jss-4.6.3/org/mozilla/jss/tests/KeyStoreTest.java000066400000000000000000000152361362106420000217730ustar00rootroot00000000000000/* 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.tests; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.util.Enumeration; import javax.crypto.SecretKey; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.pkcs11.PK11Token; import org.mozilla.jss.util.ConsolePasswordCallback; public class KeyStoreTest { public static void printUsage() { System.out.println("Usage: KeyStoreTest " + " [...]"); System.out.println("Operations:\n" + "getAliases\n" + "deleteEntry . . .\n" + "getCertByName . . .\n" + "getCertByDER \n" + "getKey \n" + "addKey \n" + "isTrustedCert \n"); } public static void main(String argv[]) throws Throwable { if( argv.length < 2 ) { printUsage(); System.exit(1); } String nss_db = argv[0]; String password_file = argv[1]; String op = argv[2]; int offset = 3; String[] args = new String[argv.length - offset]; for(int i = offset; i < argv.length; i++) { args[i - offset] = argv[i]; } CryptoManager.initialize(nss_db); CryptoManager cm = CryptoManager.getInstance(); // login to the token CryptoToken token = cm.getInternalKeyStorageToken(); //CryptoToken token = cm.getTokenByName("Builtin Object Token"); token.login(new FilePasswordCallback(password_file)); cm.setThreadToken(token); KeyStore ks = KeyStore.getInstance("PKCS11", "Mozilla-JSS"); ks.load(null, null); if( op.equalsIgnoreCase("getAliases") ) { dumpAliases(ks); } else if( op.equalsIgnoreCase("deleteEntry") ) { for(int j=0; j < args.length; ++j) { ks.deleteEntry(args[j]); } } else if( op.equalsIgnoreCase("getCertByName") ) { for(int j=0; j < args.length; ++j) { dumpCert(ks, args[j]); } } else if( op.equalsIgnoreCase("getCertByDER") ) { if( args.length < 1 ) { printUsage(); System.exit(1); } getCertByDER(ks, args[0]); } else if( op.equalsIgnoreCase("getKey") ) { if( args.length != 1 ) { printUsage(); System.exit(1); } getKey(ks, args[0]); } else if( op.equalsIgnoreCase("isTrustedCert") ) { if( args.length != 1 ) { printUsage(); System.exit(1); } isTrustedCert(ks, args[0]); } else if( op.equalsIgnoreCase("addKey") ) { if( args.length != 1 ) { printUsage(); System.exit(1); } addKey(ks, args[0]); } else { printUsage(); System.exit(1); } } public static void dumpCert(KeyStore ks, String alias) throws Throwable { Certificate cert = ks.getCertificate(alias); if( cert == null ) { System.out.println("Certificate with alias \"" + alias + "\" not found"); } else { System.out.println(cert.toString()); } } public static void dumpAliases(KeyStore ks) throws Throwable { Enumeration aliases = ks.aliases(); System.out.println("Aliases:"); while( aliases.hasMoreElements() ) { String alias = aliases.nextElement(); System.out.println( "\"" + alias + "\""); } System.out.println(); } public static void getCertByDER(KeyStore ks, String derCertFilename) throws Throwable { ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int numRead; try (FileInputStream fis = new FileInputStream(derCertFilename)) { while ((numRead = fis.read(buf)) != -1) { bos.write(buf, 0, numRead); } } ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); CertificateFactory fact = CertificateFactory.getInstance("X.509"); Certificate cert = fact.generateCertificate( bis ); String nick = ks.getCertificateAlias(cert); if( nick == null ) { System.out.println("No matching certificate was found."); } else { System.out.println("Found matching certificate \"" + nick + "\""); } } public static void getKey(KeyStore ks, String alias) throws Throwable { Key key = ks.getKey(alias, null); if( key == null ) { System.out.println("Could not find key for alias \"" + alias + "\""); System.exit(1); } else { String clazz = key.getClass().getName(); System.out.println("Found " + clazz + " for alias \"" + alias + "\""); } } public static void isTrustedCert(KeyStore ks, String alias) throws Throwable { if( ks.isCertificateEntry(alias) ) { System.out.println("\"" + alias + "\" is a trusted certificate" + " entry"); } else { System.out.println("\"" + alias + "\" is NOT a trusted certificate" + " entry"); } } public static void addKey(KeyStore ks, String alias) throws Throwable { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "Mozilla-JSS"); kpg.initialize(1024); KeyPair pair = kpg.genKeyPair(); Certificate [] certs = new Certificate[1]; ks.setKeyEntry(alias, pair.getPrivate(), null, certs); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); KeyGenerator kg = tok.getKeyGenerator( KeyGenAlgorithm.DES3 ); SecretKey key = new SecretKeyFacade(kg.generate()); ks.setKeyEntry(alias+"sym", key, null, null); } } jss-4.6.3/org/mozilla/jss/tests/KeyWrapping.java000066400000000000000000000133161362106420000216230ustar00rootroot00000000000000/* 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.tests; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import java.security.KeyPair; /** * Keywrapping tests.. * */ public class KeyWrapping { public static void main(String args[]) { try { CryptoManager.initialize("."); CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalCryptoToken(); CryptoToken keyToken = cm.getInternalKeyStorageToken(); KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES); KeyGenerator keyKg = keyToken.getKeyGenerator(KeyGenAlgorithm.DES3); SymmetricKey wrapped = kg.generate(); SymmetricKey wrapper = kg.generate(); SymmetricKey keyWrapper = keyKg.generate(); SymmetricKey keyWrapped = keyKg.clone(wrapped); // wrap a symmetric with a symmetric byte[] plaintextPre = new byte[] { (byte)0x73, (byte)0x24, (byte)0x51, (byte)0x48, (byte)0x32, (byte)0x87, (byte)0x23, (byte)0x33, (byte)0x65}; byte[] plaintext = Cipher.pad(plaintextPre, EncryptionAlgorithm.DES_ECB.getBlockSize()); System.out.println("plaintext length is " + plaintext.length); Cipher encryptor = token.getCipherContext(EncryptionAlgorithm.DES_ECB); encryptor.initEncrypt(wrapped); byte[] ciphertext = encryptor.doFinal(plaintext); System.out.println("ciphertext length is " + ciphertext.length); KeyWrapper keyWrap = token.getKeyWrapper(KeyWrapAlgorithm.DES_ECB); keyWrap.initWrap(wrapper,null); byte[] wrappedKey = keyWrap.wrap(wrapped); keyWrap.initUnwrap(wrapper, null); SymmetricKey unwrapped = keyWrap.unwrapSymmetric(wrappedKey, SymmetricKey.DES, SymmetricKey.Usage.DECRYPT, 0); Cipher decryptor = token.getCipherContext(EncryptionAlgorithm.DES_ECB); decryptor.initDecrypt(unwrapped); byte[] recoveredPre = decryptor.doFinal(ciphertext); System.out.println("Decrypted "+ recoveredPre.length+ " bytes"); byte[] recovered = Cipher.unPad(recoveredPre, EncryptionAlgorithm.DES_ECB.getBlockSize()); System.out.println("plaintext:"); displayByteArray(plaintextPre); System.out.println("ciphertext:"); displayByteArray(ciphertext); System.out.println("recovered:"); displayByteArray(recovered); // wrap a private with a symmetric keyWrap = keyToken.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD); IVParameterSpec iv = new IVParameterSpec(recovered); keyWrap.initWrap(keyWrapper, iv); KeyPairGenerator kpg = keyToken.getKeyPairGenerator(KeyPairAlgorithm.RSA); kpg.initialize(512); kpg.temporaryPairs(true); KeyPair kp = kpg.genKeyPair(); java.security.PublicKey pub = kp.getPublic(); PrivateKey privk = (org.mozilla.jss.crypto.PrivateKey)kp.getPrivate(); wrappedKey = keyWrap.wrap(privk); System.out.println("Original key:"); displayByteArray(privk.getUniqueID()); privk = null; kp = null; //keyToken.getCryptoStore().deletePrivateKey(privk); keyWrap.initUnwrap(keyWrapper,iv); PrivateKey newPrivk = keyWrap.unwrapTemporaryPrivate(wrappedKey, PrivateKey.RSA, pub ); // wrap a private with a symmetric using AES_KEY_WRAP_PAD keyWrap = keyToken.getKeyWrapper(KeyWrapAlgorithm.AES_KEY_WRAP_PAD); // IVParameterSpec iv = new IVParameterSpec(recovered); keyWrap.initWrap(keyWrapper,null /*iv*/); KeyPairGenerator kpg2 = keyToken.getKeyPairGenerator(KeyPairAlgorithm.RSA); kpg2.initialize(512); kpg2.temporaryPairs(true); KeyPair kp2 = kpg2.genKeyPair(); java.security.PublicKey pub2 = kp2.getPublic(); PrivateKey privk2 = (org.mozilla.jss.crypto.PrivateKey)kp2.getPrivate(); wrappedKey = keyWrap.wrap(privk2); System.out.println("Original key:"); displayByteArray(privk2.getUniqueID()); privk2 = null; kp2 = null; //keyToken.getCryptoStore().deletePrivateKey(privk); keyWrap.initUnwrap(keyWrapper,iv); PrivateKey newPrivk2 = keyWrap.unwrapTemporaryPrivate(wrappedKey, PrivateKey.RSA, pub ); System.out.println("New key:"); displayByteArray(newPrivk2.getUniqueID()); System.out.println("New key:"); displayByteArray(newPrivk2.getUniqueID()); // wrap a symmetric with a private keyWrap = keyToken.getKeyWrapper(KeyWrapAlgorithm.RSA); keyWrap.initWrap(pub,null); wrappedKey = keyWrap.wrap(keyWrapped); keyWrap.initUnwrap(newPrivk, null); unwrapped = keyWrap.unwrapSymmetric(wrappedKey, SymmetricKey.DES, SymmetricKey.Usage.DECRYPT, 0); unwrapped = kg.clone(unwrapped); decryptor = token.getCipherContext(EncryptionAlgorithm.DES_ECB); decryptor.initDecrypt(unwrapped); recovered = decryptor.doFinal(ciphertext); System.out.println("Recovered again:"); displayByteArray(Cipher.unPad(recovered, 8)); } catch(Exception e) { e.printStackTrace(); } } public static void displayByteArray(byte[] ba) { for(int i=0; i < ba.length; i++) { System.out.print( Integer.toHexString(ba[i]&0xff) + " " ); if( (i % 26) == 25 ) { System.out.println(""); } } System.out.println(""); } } jss-4.6.3/org/mozilla/jss/tests/ListCACerts.java000066400000000000000000000030251362106420000214770ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.*; public class ListCACerts { public static void main(String args[]) throws Exception { if( args.length > 2) { System.out.println( "Usage: java org.mozilla.jss.tests.ListCACerts [verbose]"); System.exit(1); } try { CryptoManager.initialize(args[0]); CryptoManager cm = CryptoManager.getInstance(); X509Certificate[] certs = cm.getCACerts(); //added verbose option to limited the output of the tinderbox // and nightly QA. System.out.println("Number of CA certs: " + certs.length); System.out.println("use option \"verbose\" if you want the CA " + "certs printed out"); if (args.length == 2 && args[1].equalsIgnoreCase("verbose")) { for(int i=0; i < certs.length; ++i ) { System.out.println(certs[i].getSubjectDN().toString()); InternalCertificate ic = (InternalCertificate) certs[i]; System.out.println("SSL: " + ic.getSSLTrust() + ", Email: " + ic.getEmailTrust() + ", Object Signing: " + ic.getObjectSigningTrust()); } } } catch(Throwable e) { e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.6.3/org/mozilla/jss/tests/ListCerts.java000066400000000000000000000105131362106420000212730ustar00rootroot00000000000000/* 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.tests; import java.io.ByteArrayInputStream; import java.security.cert.CertificateFactory; import java.util.Iterator; import java.util.Set; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.pkix.cert.Certificate; import org.mozilla.jss.pkix.cert.CertificateInfo; import org.mozilla.jss.pkix.cert.Extension; public class ListCerts { public static void main(String args[]) { try { if( args.length != 2 ) { System.out.println("Usage: ListCerts "); return; } String dbdir = args[0]; String nickname = args[1]; CryptoManager.initialize(dbdir); CryptoManager cm = CryptoManager.getInstance(); X509Certificate[] certs = cm.findCertsByNickname(nickname); System.out.println(certs.length + " certs found with this nickname."); for(int i=0; i < certs.length; i++) { System.out.println("\nSubject: "+certs[i].getSubjectDN()); Certificate cert = (Certificate)ASN1Util.decode(Certificate.getTemplate(), certs[i].getEncoded()); CertificateInfo info = cert.getInfo(); OBJECT_IDENTIFIER sigalg = info.getSignatureAlgId().getOID(); System.out.println("Signature oid " + info.getSignatureAlgId().getOID()); SEQUENCE extensions = info.getExtensions(); for (int j = 0; j < extensions.size(); j++) { Extension ext = (Extension)extensions.elementAt(i); OBJECT_IDENTIFIER oid = ext.getExtnId(); OCTET_STRING value = ext.getExtnValue(); System.out.println("Extension " + oid.toString()); if (ext.getCritical()) { System.out.println("Critical extension: " + oid.toString()); } else { System.out.println("NON Critical extension: " + oid.toString()); } } System.out.println("Convert to JDK cert"); //Convert to JDK certificate CertificateFactory cf = CertificateFactory.getInstance("X.509"); ByteArrayInputStream bais = new ByteArrayInputStream( certs[i].getEncoded()); java.security.cert.X509Certificate jdkCert = (java.security.cert.X509Certificate) cf.generateCertificate(bais); bais.close(); System.out.println("Subject " + jdkCert.getSubjectDN()); System.out.println("Signature oid " + jdkCert.getSigAlgName()); /* non critical extensions */ Set nonCritSet = jdkCert.getNonCriticalExtensionOIDs(); if (nonCritSet != null && !nonCritSet.isEmpty()) { for (Iterator j = nonCritSet.iterator(); j.hasNext();) { String oid = j.next(); System.out.println(oid); } } else { System.out.println("no NON Critical Extensions"); } /* critical extensions */ Set critSet = jdkCert.getCriticalExtensionOIDs(); if (critSet != null && !critSet.isEmpty()) { System.out.println("Set of critical extensions:"); for (Iterator j = critSet.iterator(); j.hasNext();) { String oid = j.next(); System.out.println(oid); } } else { System.out.println("no Critical Extensions"); } } System.out.println("END"); } catch( Exception e ) { e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.6.3/org/mozilla/jss/tests/PK10Gen.java000066400000000000000000000050641362106420000204710ustar00rootroot00000000000000/* 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.tests; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.util.Password; public class PK10Gen { public static void main(String args[]) { CryptoManager manager; Password pass1=null, pass2=null; char[] passchar1 = {'f', 'o', 'o', 'b', 'a', 'r'}; char[] passchar2 = {'n', 'e', 't', 's', 'c', 'a', 'p', 'e'}; if(args.length != 2) { System.err.println("Usage: java org.mozilla.jss.PK10Gen [rsa|dsa]"); return; } try { CryptoManager.initialize(args[0]); /* CryptoManager.initialize("secmod.db", "key3.db", "cert7.db"); CryptoManager cm = CryptoManager.getInstance(); PK11Token token = (PK11Token)cm.getInternalCryptoToken(); */ /* InitializationValues vals = new InitializationValues( args[0]+"/secmodule.db", args[0]+"/key3.db", args[0]+"/cert7.db"); CryptoManager.initialize(vals); */ try { manager = CryptoManager.getInstance(); } catch( NotInitializedException e ) { System.out.println("CryptoManager not initialized"); return; } CryptoToken token = manager.getInternalKeyStorageToken(); if(token.isLoggedIn() == false) { System.out.println("Good, isLoggedIn correctly says we're"+ " not logged in"); } else { System.out.println("ERROR: isLoggedIn incorrectly says we're"+ " logged in"); } pass1 = new Password( passchar1.clone()); pass2 = new Password( new char[]{0} ); token.initPassword(pass2, pass1); pass1.clear(); pass2.clear(); System.out.println("initialized PIN"); token.login(pass1); System.out.println("logged in"); String blob = token.generateCertRequest("cn=christina Fu", 512, args[1], (byte[]) null, (byte[]) null, (byte[]) null); System.out.println("pkcs#10 blob = \n" + blob); } catch(Exception e) { System.out.println("exception caught in PK10Gen: " + e.getMessage()); e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.6.3/org/mozilla/jss/tests/PrintableConverterTest.java000066400000000000000000000065521362106420000240370ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.junit.Assert; import org.junit.Test; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.x509.PrintableConverter; public class PrintableConverterTest { @Test public void testEmptyString() throws Exception { String string = ""; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testNullCharacters() throws Exception { String string = StringTestUtil.NULL_CHARS; System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]"); System.out.println(" - expected: IllegalArgumentException"); try { byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IllegalArgumentException); } } @Test public void testPrintableCharacters() throws Exception { String string = StringTestUtil.PRINTABLE_CHARS; System.out.println("Converting: [" + string + "]"); byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testControlCharacters() throws Exception { String string = StringTestUtil.CONTROL_CHARS; System.out.println("Converting: [" + StringTestUtil.toString(string.getBytes()) + "]"); System.out.println(" - expected: IllegalArgumentException"); try { byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IllegalArgumentException); } } @Test public void testMultibyteCharacters() throws Exception { String string = StringTestUtil.MULTIBYTE_CHARS; System.out.println("Converting: [" + string + "]"); System.out.println(" - expected: IllegalArgumentException"); try { byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IllegalArgumentException); } } } jss-4.6.3/org/mozilla/jss/tests/PrintableStringTest.java000066400000000000000000000214341362106420000233320ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.io.IOException; import org.junit.Assert; import org.junit.Test; import org.mozilla.jss.netscape.security.util.DerValue; public class PrintableStringTest { public byte tag = DerValue.tag_PrintableString; @Test public void testEncodingEmptyString() throws Exception { String string = ""; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingEmptyString() throws Exception { String input = ""; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + input + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingNullCharacters() throws Exception { String string = StringTestUtil.NULL_CHARS; System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]"); System.out.println(" - expected: IOException"); try { byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IOException); } } @Test public void testDecodingNullCharacters() throws Exception { byte[] data = { 0x13, 0x01, 0x00 }; System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); String expected = ""; // skip null chars (bug 359010) System.out.println(" - expected: [" + expected + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(expected, output); } @Test public void testEncodingPrintableCharacters() throws Exception { String string = StringTestUtil.PRINTABLE_CHARS; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingPrintableCharacters() throws Exception { String input = StringTestUtil.PRINTABLE_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + input + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingNonPrintableCharacters() throws Exception { String string = StringTestUtil.NON_PRINTABLE_CHARS; System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]"); System.out.println(" - expected: IOException"); try { byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IOException); } } @Test public void testDecodingNonPrintableCharacters() throws Exception { String input = StringTestUtil.NON_PRINTABLE_CHARS; byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: IOException"); try { String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IOException); } } @Test public void testEncodingControlCharacters() throws Exception { String string = StringTestUtil.CONTROL_CHARS; System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]"); System.out.println(" - expected: IOException"); try { byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IOException); } } @Test public void testDecodingControlCharacters() throws Exception { String input = StringTestUtil.CONTROL_CHARS; byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: IOException"); try { String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IOException); } } @Test public void testEncodingMultibyteCharacters() throws Exception { String string = StringTestUtil.MULTIBYTE_CHARS; System.out.println("Encoding: [" + string + "]"); System.out.println(" - expected: IOException"); try { byte[] actual = StringTestUtil.encode(tag, StringTestUtil.MULTIBYTE_CHARS); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IOException); } } @Test public void testDecodingMultibyteCharacters() throws Exception { String input = StringTestUtil.MULTIBYTE_CHARS; byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: IOException"); try { String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IOException); } } @Test public void testEncodingTime() throws Exception { System.out.println("Encoding time:"); String string = StringTestUtil.PRINTABLE_CHARS; long t0 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) JSSUtil.encode(tag, string); long t1 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) StringTestUtil.encode(tag, string); long t2 = System.currentTimeMillis(); long time1 = t1 - t0; long time2 = t2 - t1; System.out.println(" - JSS : " + time1 + " ms"); System.out.println(" - Internal: " + time2 + " ms"); } @Test public void testDecodingTime() throws Exception { System.out.println("Decoding time:"); String string = StringTestUtil.PRINTABLE_CHARS; byte[] data = JSSUtil.encode(tag, string); long t0 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) JSSUtil.decode(tag, data); long t1 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) StringTestUtil.decode(tag, data); long t2 = System.currentTimeMillis(); long time1 = t1 - t0; long time2 = t2 - t1; System.out.println(" - JSS : " + time1 + " ms"); System.out.println(" - Internal: " + time2 + " ms"); } } jss-4.6.3/org/mozilla/jss/tests/README_bbenv000066400000000000000000000043651362106420000205600ustar00rootroot00000000000000# This file has been renamed to "jss/org/mozilla/jss/tests/README_bbenv", and # the build/test procedure documented below has been replaced; the new build/test # procedure has been documented in top-level "jss/README". Procedure for building nspr/nss/jss and testing jss by using the provided sample run and bbenv scripts located in the jss/org/mozilla/jss/tests directory: 1. Create working directories: % mkdir -p work4jss/hg 2. Checkout all the needed sources: % cd work4jss/hg % hg clone https://hg.mozilla.org/projects/nspr % hg clone https://hg.mozilla.org/projects/nss % hg clone https://hg.mozilla.org/projects/jss % cd .. 3. Copy runSample.sh renaming it to run.sh: % cp hg/jss/org/mozilla/jss/tests/runSample.sh run.sh 4. Copy bbenvSample.sh renaming it to bbenv.sh: % cp hg/jss/org/mozilla/jss/tests/bbenvSample.sh bbenv.sh 5. Edit bbenv.sh to comply with the system that is being tested: (a) Set/reset the DOMSUF variable so that it can be resolved locally: NOTE: By default, DOMSUF=localdomain is set. (b) Set/reset the JAVA_HOME_64 variable in the bbenv script accordingly: On Linux (e. g. - Fedora 25), update java-1.8.0-openjdk to the latest and then run sudo /usr/sbin/alternatives --config java and hit enter. To check/select your Java version on Linux: % sudo /usr/sbin/alternatives --config java There is 1 program that provides 'java'. Selection Command ----------------------------------------------- *+ 1 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-3.b16.fc25.x86_64/jre/bin/java) Enter to keep the current selection[+], or type selection number: NOTE: You may have multiple entries (like on RHEl-7.x) or only one. Per this example, set: JAVA_HOME_64=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-3.b16.fc25.x86_64 Alternatively, on macOS, you'll have something like this: JAVA_HOME_64=/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home 6. Build nspr, nss, and jss and run the jss tests: % run.sh 1> run.log 2>&1 7. View the results captured in the various log files, for example: % less run.log % less output/all.log % less output/tmp.log jss-4.6.3/org/mozilla/jss/tests/SDR.java000066400000000000000000000036111362106420000200100ustar00rootroot00000000000000/* 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.tests; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.SecretDecoderRing; import org.mozilla.jss.util.ConsolePasswordCallback; public class SDR { public static void main(String[] args) { try { CryptoManager.initialize("."); String cmd = args[0]; String infile = args[1]; String outfile = args[2]; CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalKeyStorageToken(); token.login(new ConsolePasswordCallback()); SecretDecoderRing sdr = new SecretDecoderRing(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); int numread; byte[] data = new byte[1024]; try (FileInputStream fis = new FileInputStream(infile)) { while ((numread = fis.read(data)) != -1) { bos.write(data, 0, numread); } } byte[] inputBytes = bos.toByteArray(); byte[] outputBytes; if( cmd.equalsIgnoreCase("encrypt") ) { outputBytes = sdr.encrypt(inputBytes); } else { outputBytes = sdr.decrypt(inputBytes); } try (FileOutputStream fos = new FileOutputStream(outfile)) { fos.write(outputBytes); } } catch(Exception e) { e.printStackTrace(); System.exit(1); } System.exit(0); } private static char[] hex = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; } jss-4.6.3/org/mozilla/jss/tests/SSLClientAuth.java000066400000000000000000000417201362106420000220050ustar00rootroot00000000000000/* 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.tests; import java.security.cert.CertificateEncodingException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NicknameConflictException; import org.mozilla.jss.UserCertConflictException; import org.mozilla.jss.ssl.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.*; import org.mozilla.jss.pkix.cert.Certificate; import org.mozilla.jss.util.PasswordCallback; import java.util.Calendar; import java.util.Date; import java.security.*; import java.security.PrivateKey; import java.io.*; import java.net.SocketException; /** * SSLClientAuth Server/client test. */ public class SSLClientAuth implements Runnable { private CryptoManager cm; public static final SignatureAlgorithm sigAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest; /** * Method that generates a certificate for given credential * * @param issuerName * @param subjectName * @param serialNumber * @param privKey * @param pubKey * @param rand * @param extensions * @throws java.lang.Exception * @return Certificate */ public static Certificate makeCert(String issuerName, String subjectName, int serialNumber, PrivateKey privKey, PublicKey pubKey, int rand, SEQUENCE extensions) throws Exception { AlgorithmIdentifier sigAlgID = new AlgorithmIdentifier( sigAlg.toOID()); Name issuer = new Name(); issuer.addCountryName("US"); issuer.addOrganizationName("Mozilla"); issuer.addOrganizationalUnitName("JSS Testing" + rand); issuer.addCommonName(issuerName); Name subject = new Name(); subject.addCountryName("US"); subject.addOrganizationName("Mozilla"); subject.addOrganizationalUnitName("JSS Testing" + rand); subject.addCommonName(subjectName); Calendar cal = Calendar.getInstance(); Date notBefore = cal.getTime(); cal.add(Calendar.YEAR, 1); Date notAfter = cal.getTime(); SubjectPublicKeyInfo.Template spkiTemp = new SubjectPublicKeyInfo.Template(); SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) ASN1Util.decode(spkiTemp, pubKey.getEncoded()); CertificateInfo info = new CertificateInfo( CertificateInfo.v3, new INTEGER(serialNumber), sigAlgID, issuer, notBefore, notAfter, subject, spki); if( extensions != null ) { info.setExtensions(extensions); } return new Certificate(info, privKey, sigAlg); } /** * * @param args * @throws java.lang.Exception */ public static void main(String[] args) throws Exception { (new SSLClientAuth()).doIt(args); } private X509Certificate nssServerCert, nssClientCert; private String serverCertNick, clientCertNick; /** * * @param args * @throws java.lang.Exception */ public void doIt(String[] args) throws Exception { if ( args.length < 2 ) { System.out.println("Usage: java org.mozilla.jss.tests." + "SSLClientAuth [port]" + " [Certificate Serial Number]"); System.exit(1); } CryptoManager.initialize(args[0]); cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(args[1]); tok.login(cb); if (args.length >= 3) { port = new Integer(args[2]).intValue(); System.out.println("using port:" + port); } if (args.length >= 4) { serialNum = new Integer(args[3]).intValue(); } else { SecureRandom rng= SecureRandom.getInstance("pkcs11prng", "Mozilla-JSS"); serialNum = nextRandInt(rng); } X509Certificate[] certs; /* ensure certificate does not already exists */ /* we don't have to test all three */ serverCertNick = "SSLserver-"+serialNum; clientCertNick = "SSLclient-"+serialNum; certs = cm.findCertsByNickname(serverCertNick); if (certs.length == 0) { generateCerts(cm, serialNum); } else { try { nssServerCert = cm.findCertByNickname(serverCertNick); nssClientCert = cm.findCertByNickname(clientCertNick); } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } catch (ObjectNotFoundException ex) { ex.printStackTrace(); System.exit(1); } } configureDefaultSSLoptions(); testSpecificCiphers(); useNickname = false; testConnection(); useNickname = true; testConnection(); System.out.println("Exiting main()"); if( getSuccess() ) { System.exit(0); } else { System.exit(1); } } private boolean useNickname; private void generateCerts(CryptoManager cm, int serialNum) { // RSA Key with default exponent int keyLength = 4096; try { java.security.KeyPairGenerator kpg = java.security.KeyPairGenerator.getInstance("RSA", "Mozilla-JSS"); kpg.initialize(keyLength); KeyPair caPair = kpg.genKeyPair(); //Generate CA cert SEQUENCE extensions = new SEQUENCE(); extensions.addElement(makeBasicConstraintsExtension()); Certificate caCert = makeCert("CACert", "CACert", serialNum, caPair.getPrivate(), caPair.getPublic(), serialNum, extensions); X509Certificate nssCaCert = cm.importUserCACertPackage( ASN1Util.encode(caCert), "SSLCA-"+serialNum); InternalCertificate intern = (InternalCertificate)nssCaCert; intern.setSSLTrust( InternalCertificate.TRUSTED_CA | InternalCertificate.TRUSTED_CLIENT_CA | InternalCertificate.VALID_CA); // generate server cert kpg.initialize(keyLength); KeyPair serverPair = kpg.genKeyPair(); Certificate serverCert = makeCert("CACert", "localhost", serialNum+1, caPair.getPrivate(), serverPair.getPublic(), serialNum, null); nssServerCert = cm.importCertPackage( ASN1Util.encode(serverCert), serverCertNick); // generate client auth cert kpg.initialize(keyLength); KeyPair clientPair = kpg.genKeyPair(); Certificate clientCert = makeCert("CACert", "ClientCert", serialNum+2, caPair.getPrivate(), clientPair.getPublic(), serialNum, null); nssClientCert = cm.importCertPackage( ASN1Util.encode(clientCert), clientCertNick); } catch (CertificateEncodingException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchProviderException ex) { ex.printStackTrace(); System.exit(1); } catch (NicknameConflictException ex) { ex.printStackTrace(); System.exit(1); } catch (UserCertConflictException ex) { ex.printStackTrace(); System.exit(1); } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchItemOnTokenException ex) { ex.printStackTrace(); System.exit(1); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } } private void configureDefaultSSLoptions() { try { //Disable SSL2 and SSL3 ciphers SSLSocket.enableSSL2Default(false); SSLSocket.enableSSL3Default(false); /* TLS is enabled by default */ SSLSocket.setSSLVersionRangeDefault(SSLProtocolVariant.STREAM, new SSLVersionRange(SSLVersionRange.tls1_2, SSLVersionRange.tls1_2)); /* Enable Session tickets by default */ SSLSocket.enableSessionTicketsDefault(true); /* if FIPS is enabled, configure only FIPS ciphersuites */ if (cm.FIPSEnabled()) { System.out.println("The NSS database is configured in FIPS" + "mode."); System.out.println("Enable ony FIPS ciphersuites."); int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); for (int i = 0; i < ciphers.length; ++i) { if (SSLSocket.isFipsCipherSuite(ciphers[i])) { /* enable the FIPS ciphersuite */ SSLSocket.setCipherPreferenceDefault(ciphers[i], true); } else if (SSLSocket.getCipherPreferenceDefault( ciphers[i])) { /* disable the non fips ciphersuite */ SSLSocket.setCipherPreferenceDefault(ciphers[i], false); } } } } catch (SocketException ex) { System.out.println("Error configuring default SSL options."); ex.printStackTrace(); System.exit(1); } } // test one or more specific ciphers // -- normally for newly added ciphers private void testSpecificCiphers() { try { //Disable SSL2 and SSL3 ciphers SSLSocket.enableSSL2Default(false); SSLSocket.enableSSL3Default(false); /* TLS is enabled by default */ /* Enable Session tickets by default */ SSLSocket.enableSessionTicketsDefault(true); /* * when testing specific ciphers: * 1. flip this to true * 2. change the ciphers comparison (the code below was from * the latest test */ if (false) { System.out.println("testing new TLS_*SHA384 ciphers"); System.out.println("Enable ony two new ciphers."); int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); for (int i = 0; i < ciphers.length; ++i) { if (ciphers[i] == 157 || ciphers[i] == 159) { System.out.println("enabling cipher: " + ciphers[i]); /* enable a couple SHA384 ciphers */ SSLSocket.setCipherPreferenceDefault(ciphers[i], true); } else { System.out.println("disabling cipher: " + ciphers[i]); /* disable the non SHA384 ciphers */ SSLSocket.setCipherPreferenceDefault(ciphers[i], false); } } } } catch (SocketException ex) { System.out.println("Error configuring ciphers."); ex.printStackTrace(); System.exit(1); } } private void testConnection() throws Exception { serverReady = false; // spawn server Thread server = new Thread(this); server.start(); // wait for server to open its socket synchronized(this) { while(!serverReady) { this.wait(); } } // connect to the server System.out.println("client about to connect"); SSLSocket sock = new SSLSocket("localhost", port); if( useNickname ) { sock.setClientCertNickname(clientCertNick); System.out.println("Client specified cert by nickname"); } else { sock.setClientCert(nssClientCert); System.out.println("Client specified cert directly"); } System.out.println("client connected"); sock.addHandshakeCompletedListener( new HandshakeListener("client",this)); // force the handshake sock.forceHandshake(); String cipher = sock.getStatus().getCipher(); System.out.println("client forced handshake. ciphersuite: " + cipher); sock.close(); // wait for the server to finish server.join(); } public static class HandshakeListener implements SSLHandshakeCompletedListener { private String who; private SSLClientAuth boss; public HandshakeListener(String who, SSLClientAuth boss) { this.who = who; this.boss = boss; } public void handshakeCompleted(SSLHandshakeCompletedEvent event) { try { String mesg = who + " got a completed handshake "; SSLSecurityStatus status = event.getStatus(); if( status.isSecurityOn() ) { mesg += "(security is ON)"; } else { mesg += "(security is OFF)"; } System.out.println(mesg); } catch(Exception e) { e.printStackTrace(); boss.setFailure(); } } } public synchronized void setFailure() { success = false; } public synchronized boolean getSuccess() { return success; } private boolean success = true; public int port = 29752; public int serialNum = 0; public boolean serverReady = false; /** * Server run method. */ public void run() { try { // We have to configure the server session ID cache before // creating any server sockets. SSLServerSocket.configServerSessionIDCache(10, 100, 100, null); // open the server socket and bind to the port System.out.println("Server about to create socket"); SSLServerSocket serverSock = new SSLServerSocket(port, 5, null, null, true); System.out.println("Server created socket"); serverSock.requireClientAuth(SSLSocket.SSL_REQUIRE_NO_ERROR); if( useNickname ) { serverSock.setServerCertNickname(serverCertNick); System.out.println("Server specified cert by nickname"); } else { serverSock.setServerCert(nssServerCert); System.out.println("Server specified cert directly"); } // tell the client we're ready synchronized(this) { serverReady = true; this.notify(); } // accept the connection System.out.println("Server about to accept"); SSLSocket sock = (SSLSocket) serverSock.accept(); System.out.println("Server accepted"); sock.addHandshakeCompletedListener( new HandshakeListener("server", this)); // try to read some bytes, to allow the handshake to go through InputStream is = sock.getInputStream(); try { System.out.println("Server about to read"); is.read(); System.out.println("Server read successful"); } catch(EOFException e) { System.out.println("Server got EOF"); } sock.close(); serverSock.close(); } catch(Exception e) { synchronized(this) { serverReady = true; setFailure(); this.notify(); } e.printStackTrace(); } System.out.println("Server exiting"); } static Extension makeBasicConstraintsExtension() throws Exception { SEQUENCE bc = new SEQUENCE(); bc.addElement( new BOOLEAN(true) ); // cA OBJECT_IDENTIFIER bcOID = new OBJECT_IDENTIFIER( new long[] {2, 5, 29, 19}); // from RFC 2459 OCTET_STRING enc = new OCTET_STRING(ASN1Util.encode(bc)); return new Extension(bcOID, true, enc); } static int nextRandInt(SecureRandom rand) throws Exception { int i; byte[] bytes = new byte[4]; rand.nextBytes(bytes); i = ((int)bytes[0])<<24 | ((int)bytes[1])<<16 | ((int)bytes[2])<<8 | ((int)bytes[3]); System.out.println("generated random value:" + i); return i; } } jss-4.6.3/org/mozilla/jss/tests/SelfTest.java000066400000000000000000000173061362106420000211170ustar00rootroot00000000000000/* 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.tests; import java.util.Enumeration; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.InitializationValues; import org.mozilla.jss.NoSuchTokenException; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.crypto.AlreadyInitializedException; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.pkcs11.PK11Module; import org.mozilla.jss.pkcs11.PK11Token; import org.mozilla.jss.util.IncorrectPasswordException; import org.mozilla.jss.util.Password; public class SelfTest { public static void main(String[] args) throws Throwable { CryptoToken tok; CryptoToken intTok; CryptoManager manager; Password pass1=null, pass2=null; java.security.KeyPair keyPair; char[] passchar1 = {'f', 'o', 'o', 'b', 'a', 'r'}; char[] passchar2 = {'n', 'e', 't', 's', 'c', 'a', 'p', 'e'}; if(args.length != 1) { System.err.println("Usage: java ...SelfTest "); return; } InitializationValues vals = new InitializationValues( args[0] ); CryptoManager.initialize(vals); try { manager = CryptoManager.getInstance(); } catch( NotInitializedException e ) { System.out.println("CryptoManager not initialized"); return; } try { tok = manager.getTokenByName("asdffda"); System.out.println("ERROR: found a nonexistent token"); } catch (NoSuchTokenException e) { System.out.println("Good, could not find non-existent token"); } try { Enumeration modules = manager.getModules(); System.out.println("Modules:"); while(modules.hasMoreElements()) { System.out.println("\t"+ modules.nextElement().getName() ); } Enumeration tokens = manager.getAllTokens(); System.out.println("All Tokens:"); while(tokens.hasMoreElements()) { System.out.println("\t"+ tokens.nextElement().getName() ); } Enumeration extTokens = manager.getExternalTokens(); System.out.println("External Tokens:"); while(extTokens.hasMoreElements()) { System.out.println("\t"+ extTokens.nextElement().getName() ); } tok = manager.getTokenByName("Internal Key Storage Token"); System.out.println("Good, found internal DB token"); if( tok.equals(manager.getInternalKeyStorageToken()) ) { System.out.println("Good, it really is the key storage token"); } else { System.out.println("ERROR: it's not the same as the key "+ "storage token!"); } if( ((PK11Token)tok).isInternalKeyStorageToken() ) { System.out.println("Good, "+tok.getName()+" knows "+ "what it is"); } else { System.out.println("ERROR: "+tok.getName()+" doesn't know"+ " it is key storage token"); } intTok = manager.getInternalCryptoToken(); if( ((PK11Token)intTok).isInternalCryptoToken() ) { System.out.println("Good, "+tok.getName()+ " knows it is the internal token"); } else { System.out.println("ERROR: "+tok.getName()+ " doesn't know what that it is the internal token"); } if(tok.isLoggedIn() == false) { System.out.println("Good, isLoggedIn correctly says we're"+ " not logged in"); } else { System.out.println("ERROR: isLoggedIn incorrectly says we're"+ " logged in"); } System.out.println("Good, successfully opened token \""+ tok.getName()+"\""); pass1 = new Password( passchar1.clone()); pass2 = new Password( new char[]{0} ); tok.initPassword(pass2, pass1); pass1.clear(); pass2.clear(); System.out.println("Good, initialized PIN"); tok.logout(); try { pass1 = new Password( passchar2.clone()); tok.login(pass1); System.out.println("ERROR: Successfully logged in with wrong"+ " PIN"); } catch (IncorrectPasswordException e) { System.out.println("Good, unable to login with wrong PIN"); } finally { pass1.clear(); } pass1 = new Password( passchar1.clone()); tok.login(pass1); pass1.clear(); System.out.println("Good, logged in"); if(tok.isLoggedIn() == true) { System.out.println("Good, isLoggedIn correctly says we're"+ " logged in"); } else { System.out.println("ERROR: isLoggedIn incorrectly says we're"+ " not logged in"); } pass1 = new Password( passchar1.clone()); pass2 = new Password( passchar2.clone()); tok.changePassword(pass1, pass2); pass1.clear(); pass2.clear(); System.out.println("Good, changed PIN"); try { pass1 = new Password( passchar1.clone()); tok.login(pass1); // Should still be logged in System.out.println("Good, logging in with wrong PIN ok if "+ " already logged in"); } catch (IncorrectPasswordException e) { System.out.println("ERROR: logged in second time with wrong"+ "PIN, but we should still be logged in"); } finally { pass1.clear(); } try { tok.logout(); System.out.println("Good, logged out successfully."); } catch (TokenException e) { System.out.println("ERROR: failed to logout from token"); } if(tok.isLoggedIn() == false) { System.out.println("Good, isLoggedIn correctly says we're"+ " not logged in"); } else { System.out.println("ERROR: isLoggedIn incorrectly says we're"+ " logged in"); } try { tok.logout(); System.out.println("ERROR: logged out twice in a row"); } catch (TokenException e) { System.out.println("Good, got an exception when we tried"+ " to log out twice in a row"); } try { pass1 = new Password( passchar1.clone()); tok.login(pass1); pass1.clear(); System.out.println("ERROR: logged in with wrong pw"); } catch (IncorrectPasswordException e) { System.out.println("Good, logging in with wrong PIN gave err"); } System.out.println("Test completed"); tok = null; } catch (IncorrectPasswordException e) { System.out.println("Got an incorrect PIN: "+e); } catch (AlreadyInitializedException e) { System.out.println( "ERROR: This test only works with uninitialized databases"); } catch (TokenException e) { System.out.println("Token error: " + e); } catch (NoSuchTokenException e) { System.out.println("ERROR: could not find internal DB token"); } finally { if(pass1 != null) { pass1.clear(); } if(pass2 != null) { pass2.clear(); } } //System.gc(); //NativeProxy.assertRegistryEmpty(); //System.runFinalization(); } } jss-4.6.3/org/mozilla/jss/tests/SetupDBs.java000066400000000000000000000025331362106420000210530ustar00rootroot00000000000000/* 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.tests; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.*; /** * Create the NSS databases * **/ public class SetupDBs { public static void main(String args[]) { try { if( args.length != 2 ) { System.err.println("Usage: java org.mozilla.jss.tests.SetupDBs " + " \n" + "Password file should have format:\n " + "Internal\\ Key\\ Storage\\ Token=m1oZilla\n " + "NSS\\ FIPS\\ 140-2\\ User\\ Private\\ " + "Key=m1oZilla\n"); System.exit(1); } String dbdir = args[0]; CryptoManager.initialize(dbdir); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); tok.initPassword( new NullPasswordCallback(), new FilePasswordCallback( args[1] ) ); System.exit(0); } catch(Exception e) { e.printStackTrace(); System.exit(1); } } } jss-4.6.3/org/mozilla/jss/tests/SigTest.java000066400000000000000000000104421362106420000207420ustar00rootroot00000000000000/* 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/. */ /* This program demonstrates how to sign data with keys from JSS * * The token name can be either the name of a hardware token, or * one of the internal tokens: * Internal Crypto Services Token * Internal Key Storage Token (keys stored in key4.db) */ package org.mozilla.jss.tests; import java.security.KeyPair; import java.security.PublicKey; import java.util.Enumeration; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.InitializationValues; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.KeyPairGenerator; import org.mozilla.jss.crypto.KeyPairGeneratorSpi; import org.mozilla.jss.crypto.Policy; import org.mozilla.jss.crypto.Signature; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.pkcs11.PK11Token; public class SigTest { public static void usage() { System.out.println( "Usage: java org.mozilla.jss.crypto.SigTest " + " [tokenname]"); } public static void main(String args[]) { try { CryptoToken token; CryptoManager manager; byte[] data = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; byte[] signature; Signature signer; PublicKey pubk; KeyPairGenerator kpgen; KeyPair keyPair; if (args.length < 2 || args.length > 3) { usage(); System.exit(1); } String dbdir = args[0]; InitializationValues vals = new InitializationValues(args[0]); CryptoManager.initialize(vals); manager = CryptoManager.getInstance(); manager.setPasswordCallback(new FilePasswordCallback(args[1])); /* Print out list of available tokens */ Enumeration en = manager.getAllTokens(); System.out.println("Available tokens:"); while (en.hasMoreElements()) { PK11Token p = (PK11Token) en.nextElement(); System.out.println(" token : " + p.getName()); } if (args.length >= 3) { token = manager.getTokenByName(args[2]); } else { //get default internal key storage token token = manager.getInternalKeyStorageToken(); } // Generate an RSA keypair kpgen = token.getKeyPairGenerator(KeyPairAlgorithm.RSA); kpgen.initialize(Policy.RSA_MINIMUM_KEY_SIZE); KeyPairGeneratorSpi.Usage usages[] = { KeyPairGeneratorSpi.Usage.SIGN, KeyPairGeneratorSpi.Usage.VERIFY}; KeyPairGeneratorSpi.Usage usages_mask[] = { KeyPairGeneratorSpi.Usage.SIGN, KeyPairGeneratorSpi.Usage.VERIFY}; kpgen.setKeyPairUsages(usages, usages_mask); keyPair = kpgen.genKeyPair(); // RSA MD5 signer = token.getSignatureContext( SignatureAlgorithm.RSASignatureWithMD5Digest); System.out.println("Created a signing context"); signer.initSign( (org.mozilla.jss.crypto.PrivateKey) keyPair.getPrivate()); System.out.println("initialized the signing operation"); signer.update(data); System.out.println("updated signature with data"); signature = signer.sign(); System.out.println("Successfully signed!"); signer.initVerify(keyPair.getPublic()); System.out.println("initialized verification"); signer.update(data); System.out.println("updated verification with data"); if (signer.verify(signature)) { System.out.println("Signature Verified Successfully!"); } else { throw new Exception("ERROR: Signature failed to verify."); } System.out.println("SigTest passed."); System.exit(0); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } } jss-4.6.3/org/mozilla/jss/tests/StringTestUtil.java000066400000000000000000000050651362106420000223310ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.mozilla.jss.netscape.security.util.DerInputStream; import org.mozilla.jss.netscape.security.util.DerOutputStream; import org.mozilla.jss.netscape.security.util.DerValue; public class StringTestUtil { public final static String NULL_CHARS = "\u0000"; public final static String PRINTABLE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 \'()+,-./:=?"; public final static String NON_PRINTABLE_CHARS = "\"\\"; public final static String CONTROL_CHARS = "\b\t\n\f\r"; public final static String MULTIBYTE_CHARS = "\u6211\u7231\u4F60"; // I love you public static String toString(byte[] array) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < array.length; i++) { if (i > 0) sb.append(" "); sb.append(Integer.toHexString(0xff & array[i] | 0x100).substring(1).toUpperCase()); } return sb.toString(); } public static byte[] normalizeUnicode(byte[] data) throws Exception { try (DerOutputStream os = new DerOutputStream()) { DerValue value = new DerValue(data); byte[] tmp = value.data.toByteArray(); if (tmp[0] == -2 && tmp[1] == -1) { // remove optional big-endian byte-order mark byte tag = value.tag; int length = value.length() - 2; os.putTag((byte) 0, false, tag); os.putLength(length); os.write(tmp, 2, length); return os.toByteArray(); } return data; } } public static byte[] encode(byte tag, String string) throws Exception { try (DerOutputStream os = new DerOutputStream()) { os.putStringType(tag, string); return os.toByteArray(); } } public static String decode(byte tag, byte[] bytes) throws Exception { DerInputStream is = new DerInputStream(bytes); switch (tag) { case DerValue.tag_BMPString: return is.getBMPString(); case DerValue.tag_IA5String: return is.getIA5String(); case DerValue.tag_PrintableString: return is.getPrintableString(); case DerValue.tag_T61String: return is.getT61String(); case DerValue.tag_UniversalString: return is.getUniversalString(); case DerValue.tag_UTF8String: return is.getDerValue().getUTF8String(); default: throw new Exception("Unsupported tag: " + tag); } } } jss-4.6.3/org/mozilla/jss/tests/SymKeyDeriving.java000066400000000000000000000377441362106420000223070ustar00rootroot00000000000000/* ***** 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.tests; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.InitializationValues; import org.mozilla.jss.pkcs11.PKCS11Constants; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Enumeration; /** * Sym Key deriving tests.. * */ public class SymKeyDeriving { private static final byte[] iv8 = new byte [] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 }; private static final byte[] iv16 = new byte [] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9,0xa, 0xb, 0xc,0xd,0xe, 0xf,0x10 }; private static final byte[] derivationData1 = new byte[] { 0x11, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 }; private static final byte[] derivationData2 = new byte [] { 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10 }; private static final byte[] derivationData16 = new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6,0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10 }; public static void main(String args[]) throws Exception { if (args.length != 2) { System.err.println("Usage SymKeyDeriving /path/to/nssdb /path/to/password.txt"); System.exit(1); } SymmetricKey macKeyDev = null; InitializationValues vals = new InitializationValues(args[0]); vals.removeSunProvider = true; CryptoManager.initialize(vals); CryptoManager cm = CryptoManager.getInstance(); cm.setPasswordCallback(new FilePasswordCallback(args[1])); CryptoToken token = cm.getInternalCryptoToken(); CryptoToken keyToken = cm.getInternalKeyStorageToken(); System.out.println("interal token name: " + keyToken.getName()); KeyGenerator keyKg = keyToken.getKeyGenerator(KeyGenAlgorithm.DES3); SymmetricKey baseKey = keyKg.generate(); KeyGenerator keyKgDes = keyToken.getKeyGenerator(KeyGenAlgorithm.DES); SymmetricKey baseKeyDes = keyKgDes.generate(); System.out.println("strength: " + baseKeyDes.getStrength()); KeyGenerator keyKgAES = keyToken.getKeyGenerator(KeyGenAlgorithm.AES); keyKgAES.initialize(128); SymmetricKey baseKeyAES = keyKgAES.generate(); System.out.println("baseKey bytes: "); byte[] baseBytes = baseKey.getEncoded(); displayByteArray(baseBytes,true); /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_EXTRACT_KEY_FROM_KEY test 16 bytes. \n"); SymmetricKeyDeriver deriver = token.getSymmetricKeyDeriver(); System.out.println("deriver: " + deriver); System.out.println("CKM_EXTRACT_KEY_FROM_KEY : " + PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY); long bitPosition = 0; byte[] param = longToBytes(bitPosition); deriver.initDerive( baseKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,(long) 16); SymmetricKey extracted16 = deriver.derive(); System.out.println("Derived key: " + extracted16); if(extracted16 == null) { System.out.println("Failed to derive 16 byte key with mechanism: CKM_EXTRACT_KEY_FROM_KEY \n"); } System.out.println("derivedKey 16 bytes: "); byte[] derivedBytes = extracted16.getEncoded(); displayByteArray(derivedBytes,true); /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_EXTRACT_KEY_FROM_KEY test 8 bytes. \n"); SymmetricKeyDeriver extract8 = token.getSymmetricKeyDeriver(); extract8.initDerive( extracted16, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,(long) 8); SymmetricKey extracted8 = extract8.derive(); System.out.println("Derived key: " + extracted8); if(extracted8 == null) { System.out.println("Failed to derive key extracted 8 bytes with mechanism: CKM_EXTRACT_KEY_FROM_KEY \n"); } byte[] extracted8Bytes = extracted8.getEncoded(); System.out.println("derived extracted 8 bytes of key: "); displayByteArray(extracted8Bytes,true); /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_CONCATENATE_BASE_AND_KEY test 16 + 8 = 24 byte key. \n"); SymmetricKeyDeriver concat = keyToken.getSymmetricKeyDeriver(); concat.initDerive( extracted16,extracted8, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY,null,null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,(long) 0); SymmetricKey concated24 = concat.derive(); if( concated24 == null) { System.out.println("Failed to derive key concated 8 bytes to 16 bytes key: CKM_CONCATENATE_BASE_AND_KEY \n"); } byte[] concated24Bytes = concated24.getEncoded(); System.out.println("derived concated 16 + 8 = 24 byte key: "); displayByteArray(concated24Bytes,true); /*****************************************************************************************************/ // Try ecnrypted des3 derivation System.out.println("\n Mechanism CKM_DES3_ECB_ENCRYPT_DATA test. \n"); SymmetricKeyDeriver encryptDes3 = token.getSymmetricKeyDeriver(); encryptDes3.initDerive( baseKey, /* PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA */ 4354L ,derivationData16 ,null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,(long) 16); SymmetricKey encrypted16 = encryptDes3.derive(); if ( encrypted16 == null) { System.out.println("Failed to derive 16 bytes from encrypted derivation data."); } byte[] encrypted16Bytes = encrypted16.getEncoded(); System.out.println("derived encrypted 16 bytes: " + encrypted16Bytes.length); displayByteArray(encrypted16Bytes,true); Cipher cipher = keyToken.getCipherContext(EncryptionAlgorithm.DES3_ECB); cipher.initEncrypt(baseKey); byte[] ciphertext = cipher.doFinal(derivationData16); displayByteArray(ciphertext,true); if ( ciphertext.length != encrypted16Bytes.length ) { System.out.println("FAILED: encrypted data length not equal to derived key length."); } else { for ( int i = 0; i < ciphertext.length ; i ++) { ciphertext[i]&=0xfe; encrypted16Bytes[i]&=0xfe; } if ( Arrays.equals(ciphertext, encrypted16Bytes)) { System.out.println("PASSED: derived key the same as encrypted data."); } else { System.out.println("FAILED: derived key not the same as encrypted data."); } } /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_DES3_CBC_ENCRYPT_DATA test. \n"); SymmetricKeyDeriver encryptDes3CBC = token.getSymmetricKeyDeriver(); encryptDes3CBC.initDerive( baseKey, /* PKCS11Constants.CKM_DES3_CBC_ENCRYPT_DATA */ 4355L ,derivationData16 ,iv8, PKCS11Constants.CKM_DES3_CBC, PKCS11Constants.CKA_DERIVE,(long) 16); SymmetricKey encryptedDes3CBC = encryptDes3CBC.derive(); if ( encryptedDes3CBC == null) { System.out.println("Failed to derive 16 bytes from encrypted derivation data."); } byte[] encryptedDes3CBCBytes = encryptedDes3CBC.getEncoded(); System.out.println("derived encrypted 16 bytes: " + encryptedDes3CBCBytes.length); displayByteArray(encryptedDes3CBCBytes,true); cipher = keyToken.getCipherContext(EncryptionAlgorithm.DES3_CBC); cipher.initEncrypt(baseKey,new IVParameterSpec(iv8)); ciphertext = cipher.doFinal(derivationData16); displayByteArray(ciphertext,true); if ( ciphertext.length != encryptedDes3CBCBytes.length ) { System.out.println("FAILED: encrypted data length not equal to derived key length."); } else { for ( int i = 0; i < ciphertext.length ; i ++) { ciphertext[i]&=0xfe; encryptedDes3CBCBytes[i]&=0xfe; } if ( Arrays.equals(ciphertext, encryptedDes3CBCBytes)) { System.out.println("PASSED: derived key the same as encrypted data."); } else { System.out.println("FAILED: derived key not the same as encrypted data."); } } /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_AES_ECB_ENCRYPT_DATA test. \n"); SymmetricKeyDeriver encryptAESECB = token.getSymmetricKeyDeriver(); //System.in.read(); encryptAESECB.initDerive( baseKeyAES, /* PKCS11Constants.CKM_AES_ECB_ENCRYPT_DATA */ 4356L ,derivationData16 ,null, PKCS11Constants.CKM_AES_ECB, PKCS11Constants.CKA_DERIVE,(long) 16); SymmetricKey encryptedAESECB = encryptAESECB.derive(); if ( encryptedAESECB == null) { System.out.println("Failed to derive 16 bytes from encrypted derivation data."); } byte[] encryptedAESECBBytes = encryptedAESECB.getEncoded(); System.out.println("derived encrypted 16 bytes: " + encryptedAESECBBytes.length); displayByteArray(encryptedAESECBBytes,true); cipher = keyToken.getCipherContext(EncryptionAlgorithm.AES_128_ECB); cipher.initEncrypt(baseKeyAES); ciphertext = cipher.doFinal(derivationData16); displayByteArray(ciphertext,true); if ( ciphertext.length != encryptedAESECBBytes.length ) { System.out.println("FAILED: encrypted data length not equal to derived key length."); } else { for ( int i = 0; i < ciphertext.length ; i ++) { ciphertext[i]&=0xfe; encryptedAESECBBytes[i]&=0xfe; } if ( Arrays.equals(ciphertext, encryptedAESECBBytes)) { System.out.println("PASSED: derived key the same as encrypted data."); } else { System.out.println("FAILED: derived key not the same as encrypted data."); } } /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_AES_CBC_ENCRYPT_DATA test. \n"); SymmetricKeyDeriver encryptAESCBC= token.getSymmetricKeyDeriver(); //System.in.read(); encryptAESCBC.initDerive( baseKeyAES, /* PKCS11Constants.CKM_AES_CBC_ENCRYPT_DATA */ 4357L ,derivationData16 ,iv16, PKCS11Constants.CKM_AES_CBC, PKCS11Constants.CKA_DERIVE,(long) 16); SymmetricKey encryptedAESCBC = encryptAESCBC.derive(); if ( encryptedAESCBC == null) { System.out.println("Failed to derive 16 bytes from encrypted derivation data."); } byte[] encryptedAESCBCBytes = encryptedAESCBC.getEncoded(); System.out.println("derived encrypted 16 bytes: " + encryptedAESCBCBytes.length); displayByteArray(encryptedAESCBCBytes,true); cipher = keyToken.getCipherContext(EncryptionAlgorithm.AES_128_CBC); cipher.initEncrypt(baseKeyAES,new IVParameterSpec(iv16)); ciphertext = cipher.doFinal(derivationData16); displayByteArray(ciphertext,true); if ( ciphertext.length != encryptedAESCBCBytes.length ) { System.out.println("FAILED: encrypted data length not equal to derived key length."); } else { for ( int i = 0; i < ciphertext.length ; i ++) { ciphertext[i]&=0xfe; encryptedAESCBCBytes[i]&=0xfe; } if ( Arrays.equals(ciphertext, encryptedAESCBCBytes)) { System.out.println("PASSED: derived key the same as encrypted data."); } else { System.out.println("FAILED: derived key not the same as encrypted data."); } } // get vector of symkeys Enumeration ect = null; ect = (Enumeration) cm.getAllTokens(); CryptoToken ct = null; //ct = cm.getTokenByName("ePass Token"); while (ect.hasMoreElements()) { ct = ect.nextElement(); System.out.println("CryptoToken.name= " + ct.getName()); } SymmetricKey[] keys = keyToken.getCryptoStore().getSymmetricKeys(); SymmetricKey macKey = getSymKeyByName(keys, "defKeySet-macKey"); System.out.println("macKey: " + macKey); } public static void displayByteArray(byte[] ba, boolean has_check_sum) { char mask = 0xff; if ( has_check_sum == true ) mask = 0xfe; for(int i=0; i < ba.length; i++) { System.out.print( Integer.toHexString(ba[i]&mask) + " " ); if( (i % 26) == 25 ) { System.out.println(""); } } System.out.println(""); } public static byte[] longToBytes(long x) { ByteBuffer buffer = ByteBuffer.allocate(8); buffer.putLong(x); return buffer.array(); } public static byte[] concatByteArrays(byte[] a, byte[] b) { byte[] result = new byte[a.length + b.length]; System.arraycopy(a, 0, result, 0, a.length); System.arraycopy(b, 0, result, a.length, b.length); return result; } public static SymmetricKey getSymKeyByName( SymmetricKey[] keys, String name) { if ( keys == null || name == null ) { return null; } int len = keys.length; for(int i = 0 ; i < len ; i++ ) { SymmetricKey cur = keys[i]; if ( cur != null ) { if( name.equals(cur.getNickName())) { System.out.println("Found key: " + name + "\n"); return cur; } } } return null; } } jss-4.6.3/org/mozilla/jss/tests/SymKeyGen.java000066400000000000000000000332521362106420000212370ustar00rootroot00000000000000/* 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.tests; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.spec.AlgorithmParameterSpec; import java.util.LinkedList; import java.util.List; import javax.crypto.spec.RC2ParameterSpec; import org.mozilla.jss.CertDatabaseException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.KeyDatabaseException; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.crypto.AlreadyInitializedException; import org.mozilla.jss.crypto.Cipher; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.IVParameterSpec; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.PBEKeyGenParams; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.pkcs11.PK11SecureRandom; import org.mozilla.jss.util.Password; /** * Most of this code is Deprecated look at JCASymKeyGen.java for sample. */ public class SymKeyGen { private CryptoToken token = null; byte[] plainText16Bytes = "Firefox rules!".getBytes(); /* 16 bytes */ byte[] plainText18Bytes = "Thunderbird rules!".getBytes(); /* 18 bytes */ public SymmetricKey genPBEKey(PBEAlgorithm alg, SymmetricKey.Type keyType, int keyStrength) throws Exception { SymmetricKey key = null; byte[] keyData; KeyGenerator kg = token.getKeyGenerator(alg); try { //this is debug code you don't initialize //PBE algs with key Strength doing this should throw //InvaldAlgortithmParameterException kg.initialize(keyStrength); throw new Exception("ERROR: Initializing PBE key with strength " + keyStrength + " succeeded"); } catch( InvalidAlgorithmParameterException e) { } Password pass = new Password( ("passwd1").toCharArray() ); byte[] salt = genSalt(alg.getSaltLength()); PBEKeyGenParams kgp = new PBEKeyGenParams(pass, salt, 2); pass.clear(); kg.initialize(kgp); key = kg.generate(); kgp.clear(); if( key.getType() != keyType ) { throw new Exception("Wrong key type: "+key.getType()); } if( ! key.getOwningToken().equals( token ) ) { throw new Exception("wrong token"); } if( key.getStrength() != keyStrength ) { throw new Exception("wrong strength: "+key.getStrength()); } return key; } public SymmetricKey genPBAKey(KeyGenAlgorithm alg, SymmetricKey.Type keyType, int keyStrength) throws Exception { SymmetricKey key = null; byte[] keyData; KeyGenerator kg = token.getKeyGenerator(alg); try { //this is debug code you don't initialize //PBE algs with key Strength doing this should throw //InvalidAlgorithmParameterException kg.initialize(keyStrength); throw new Exception("ERROR: Initializing PBE key with strength "+ keyStrength + " succeeded"); } catch( InvalidAlgorithmParameterException e) { } Password pass = new Password( ("passwd1").toCharArray() ); byte[] salt = genSalt(8); PBEKeyGenParams kgp = new PBEKeyGenParams(pass, salt, 2); pass.clear(); kg.initialize(kgp); key = kg.generate(); kgp.clear(); if( key.getType() != keyType ) { throw new Exception("Wrong key type: "+key.getType()); } if( ! key.getOwningToken().equals( token ) ) { throw new Exception("wrong token"); } if( key.getStrength() != keyStrength ) { throw new Exception("wrong strength: "+key.getStrength()); } return key; } public SymmetricKey genSymKey(KeyGenAlgorithm alg, SymmetricKey.Type keyType , int keyStrength, int keyLength) throws Exception { SymmetricKey key = null; byte[] keyData; KeyGenerator kg = token.getKeyGenerator(alg); if (alg == KeyGenAlgorithm.AES || alg == KeyGenAlgorithm.RC4 || alg == KeyGenAlgorithm.RC2) { kg.initialize (keyStrength); } key = kg.generate(); if( key.getType() != keyType ) { throw new Exception("wrong algorithm"); } if( ! key.getOwningToken().equals( token ) ) { throw new Exception("wrong token"); } if( key.getStrength() != keyStrength ) { throw new Exception("wrong strength"); } keyData = key.getKeyData(); if( keyData.length != keyLength ) { throw new Exception("key data wrong length: " + keyData.length); } return key; } public boolean cipherTest(SymmetricKey key, EncryptionAlgorithm eAlg ) throws Exception { boolean bStatus = false; int ivLength = 0; AlgorithmParameterSpec algParSpec = null; Cipher cipher = null; cipher = token.getCipherContext(eAlg); // if no padding is used plainText needs to be fixed length // block divisable by 8 bytes byte[] plaintext = plainText18Bytes; if ((eAlg.getMode() == EncryptionAlgorithm.Mode.CBC || eAlg.getMode() == EncryptionAlgorithm.Mode.ECB ) && eAlg.getPadding() == EncryptionAlgorithm.Padding.NONE) { plaintext = plainText16Bytes; } // size 0 means this algorithm does not take an IV. // you need to use the same IV for Encrypt/Decrypt ivLength = eAlg.getIVLength(); if (ivLength != 0 ) { algParSpec = genIV(ivLength); } if (key.getType() == SymmetricKey.RC2) { byte[] iv = new byte[ivLength]; PK11SecureRandom rng = new PK11SecureRandom(); rng.nextBytes(iv); algParSpec = new RC2ParameterSpec(40, iv); } if (algParSpec == null) { cipher.initEncrypt(key); } else { cipher.initEncrypt(key, algParSpec); } byte[] ciphertext = cipher.doFinal(plaintext); if (ivLength == 0) { cipher.initDecrypt(key); } else { cipher.initDecrypt(key, algParSpec); } byte[] recovered = cipher.doFinal(ciphertext); if( recovered.length != plaintext.length ) { throw new Exception("Recovered plaintext has different length ("+ recovered.length+") than original ("+plaintext.length+")"); } if (java.util.Arrays.equals(plaintext, recovered) ) { bStatus = true; } else { throw new Exception("ERROR: unable to recover plaintext"); } return bStatus; // no exception was thrown. } private SymKeyGen( String certDbLoc) { try { CryptoManager.initialize(certDbLoc); CryptoManager cm = CryptoManager.getInstance(); token = cm.getInternalCryptoToken(); } catch (AlreadyInitializedException ex) { ex.printStackTrace(); } catch (CertDatabaseException ex) { ex.printStackTrace(); } catch (NotInitializedException ex) { ex.printStackTrace(); } catch (GeneralSecurityException ex) { ex.printStackTrace(); } catch (KeyDatabaseException ex) { ex.printStackTrace(); } } public IVParameterSpec genIV(int blockSize) throws Exception { // generate an IV byte[] iv = new byte[blockSize]; PK11SecureRandom rng = new PK11SecureRandom(); rng.nextBytes(iv); return new IVParameterSpec(iv); } public byte[] genSalt(int saltSize) throws Exception { byte[] salt = new byte[saltSize]; PK11SecureRandom rng = new PK11SecureRandom(); rng.nextBytes(salt); return salt; } class alg { public KeyGenAlgorithm sAlg; public SymmetricKey.Type keyType; public int size; public int blkSize; List ciphers = new LinkedList<>(); public alg (KeyGenAlgorithm alg, SymmetricKey.Type kType, int sz, int bSize) { sAlg = alg; keyType = kType; size = sz; blkSize = bSize; } public void setEncAlgs(List c) { ciphers = c; } } public static void main(String args[]) { try { if ( args.length < 1 ) { System.out.println("Usage: java org.mozilla.jss.tests." + "SymKeyGen "); System.exit(1); } SymKeyGen skg = new SymKeyGen(args[0]); SymmetricKey key = null; //DES Key key = skg.genSymKey(KeyGenAlgorithm.DES, SymmetricKey.DES, 56, 8); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES_ECB); System.out.println("DES key and cipher tests correct"); // DES3 key key = skg.genSymKey(KeyGenAlgorithm.DES3, SymmetricKey.DES3, 168, 24); skg.cipherTest(key, EncryptionAlgorithm.DES3_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES3_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES3_ECB); System.out.println("DESede key and cipher tests correct"); // AES 128 key key = skg.genSymKey(KeyGenAlgorithm.AES, SymmetricKey.AES, 128, 128/8); skg.cipherTest(key, EncryptionAlgorithm.AES_128_CBC); skg.cipherTest(key, EncryptionAlgorithm.AES_128_ECB); skg.cipherTest(key, EncryptionAlgorithm.AES_128_CBC_PAD); System.out.println("AES 128 key and cipher tests correct"); // AES 192 key key = skg.genSymKey(KeyGenAlgorithm.AES, SymmetricKey.AES, 192, 192/8); skg.cipherTest(key, EncryptionAlgorithm.AES_192_CBC); skg.cipherTest(key, EncryptionAlgorithm.AES_192_ECB); skg.cipherTest(key, EncryptionAlgorithm.AES_192_CBC_PAD); System.out.println("AES 192 key and cipher tests correct"); // AES 256 key key = skg.genSymKey(KeyGenAlgorithm.AES, SymmetricKey.AES, 256, 256/8); skg.cipherTest(key, EncryptionAlgorithm.AES_256_CBC); skg.cipherTest(key, EncryptionAlgorithm.AES_256_ECB); skg.cipherTest(key, EncryptionAlgorithm.AES_256_CBC_PAD); System.out.println("AES 256 key and cipher tests correct"); // RC2 Key key = skg.genSymKey(KeyGenAlgorithm.RC2, SymmetricKey.RC2, 40, 5); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC_PAD); System.out.println("RC2 key and cipher tests correct"); // RC4 key key = skg.genSymKey(KeyGenAlgorithm.RC4, SymmetricKey.RC4, 128, 128/8); skg.cipherTest(key, EncryptionAlgorithm.RC4); System.out.println("RC4 key and cipher tests correct"); //Todo //KeyGenAlgorithm.PBA_SHA1_HMAC, SymmetricKey.SHA1_HMAC, 160); //PBE key gen test. // PBEAlgorithm.PBE_MD2_DES_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_MD2_DES_CBC, SymmetricKey.DES, 56); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES_ECB); //PBEAlgorithm.PBE_MD5_DES_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_MD5_DES_CBC, SymmetricKey.DES, 56); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES_ECB); //PBEAlgorithm.PBE_SHA1_DES_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_DES_CBC, SymmetricKey.DES, 64); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES_ECB); //PBEAlgorithm.PBE_SHA1_DES3_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_DES3_CBC, SymmetricKey.DES3, 168); skg.cipherTest(key, EncryptionAlgorithm.DES3_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES3_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES3_ECB); //PBEAlgorithm.PBE_SHA1_RC2_40_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_RC2_40_CBC, SymmetricKey.RC2, 40); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC_PAD); //PBEAlgorithm.PBE_SHA1_RC2_128_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_RC2_128_CBC, SymmetricKey.RC2, 128); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC_PAD); //PBEAlgorithm.PBE_SHA1_RC4_40 key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_RC4_40, SymmetricKey.RC4, 40); skg.cipherTest(key, EncryptionAlgorithm.RC4); //PBEAlgorithm.PBE_SHA1_RC4_128 key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_RC4_128, SymmetricKey.RC4, 128); skg.cipherTest(key, EncryptionAlgorithm.RC4); System.out.println("Password Based key generation tests correct"); } catch(Exception e) { e.printStackTrace(); } } } jss-4.6.3/org/mozilla/jss/tests/TeletexStringTest.java000066400000000000000000000210121362106420000230140ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.io.IOException; import org.junit.Assert; import org.junit.Test; import org.mozilla.jss.netscape.security.util.DerValue; public class TeletexStringTest { public byte tag = DerValue.tag_T61String; @Test public void testEncodingEmptyString() throws Exception { String string = ""; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingEmptyString() throws Exception { String input = ""; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + input + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingNullCharacters() throws Exception { String string = StringTestUtil.NULL_CHARS; System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); actual = StringTestUtil.normalizeUnicode(actual); System.out.println(" - norm. : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingNullCharacters() throws Exception { String input = StringTestUtil.NULL_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingPrintableCharacters() throws Exception { String string = StringTestUtil.PRINTABLE_CHARS; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingPrintableCharacters() throws Exception { String input = StringTestUtil.PRINTABLE_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + input + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingNonPrintableCharacters() throws Exception { String string = StringTestUtil.NON_PRINTABLE_CHARS; System.out.println("Encoding: [" + string + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingNonPrintableCharacters() throws Exception { String input = StringTestUtil.NON_PRINTABLE_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + input + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + output + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingControlCharacters() throws Exception { String string = StringTestUtil.CONTROL_CHARS; System.out.println("Encoding: [" + StringTestUtil.toString(string.getBytes()) + "]"); byte[] expected = JSSUtil.encode(tag, string); System.out.println(" - expected: " + StringTestUtil.toString(expected)); byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.assertArrayEquals(expected, actual); } @Test public void testDecodingControlCharacters() throws Exception { String input = StringTestUtil.CONTROL_CHARS; byte[] data = JSSUtil.encode(tag, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: [" + StringTestUtil.toString(input.getBytes()) + "]"); String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.assertEquals(input, output); } @Test public void testEncodingMultibyteCharacters() throws Exception { String string = StringTestUtil.MULTIBYTE_CHARS; System.out.println("Encoding: [" + string + "]"); System.out.println(" - expected: IOException"); try { byte[] actual = StringTestUtil.encode(tag, string); System.out.println(" - actual : " + StringTestUtil.toString(actual)); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IOException); } } @Test public void testDecodingMultibyteCharacters() throws Exception { String input = StringTestUtil.MULTIBYTE_CHARS; byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input); System.out.println("Decoding: [" + StringTestUtil.toString(data) + "]"); System.out.println(" - expected: IOException"); try { String output = StringTestUtil.decode(tag, data); System.out.println(" - actual : [" + StringTestUtil.toString(output.getBytes()) + "]"); Assert.fail(); } catch (Exception e) { System.out.println(" - actual : " + e.getClass().getSimpleName()); Assert.assertTrue(e instanceof IOException); } } @Test public void testEncodingTime() throws Exception { System.out.println("Encoding time:"); String string = StringTestUtil.NULL_CHARS + StringTestUtil.PRINTABLE_CHARS + StringTestUtil.NON_PRINTABLE_CHARS + StringTestUtil.CONTROL_CHARS; long t0 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) JSSUtil.encode(tag, string); long t1 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) StringTestUtil.encode(tag, string); long t2 = System.currentTimeMillis(); long time1 = t1 - t0; long time2 = t2 - t1; System.out.println(" - JSS : " + time1 + " ms"); System.out.println(" - Internal: " + time2 + " ms"); } @Test public void testDecodingTime() throws Exception { System.out.println("Decoding time:"); String string = StringTestUtil.NULL_CHARS + StringTestUtil.PRINTABLE_CHARS + StringTestUtil.NON_PRINTABLE_CHARS + StringTestUtil.CONTROL_CHARS; byte[] data = JSSUtil.encode(tag, string); long t0 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) JSSUtil.decode(tag, data); long t1 = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) StringTestUtil.decode(tag, data); long t2 = System.currentTimeMillis(); long time1 = t1 - t0; long time2 = t2 - t1; System.out.println(" - JSS : " + time1 + " ms"); System.out.println(" - Internal: " + time2 + " ms"); } } jss-4.6.3/org/mozilla/jss/tests/TestBuffer.java000066400000000000000000000050761362106420000214400ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.mozilla.jss.nss.Buffer; import org.mozilla.jss.nss.BufferProxy; public class TestBuffer { public static void TestCreateFree() { BufferProxy buf = Buffer.Create(100); assert(buf != null); Buffer.Free(buf); } public static void TestReadWrite() { BufferProxy buf = Buffer.Create(10); byte[] data = { 0x01, 0x00, 0x02, 0x03 }; assert(buf != null); assert(Buffer.Write(buf, data) == 4); byte[] out_data = Buffer.Read(buf, 4); assert(out_data.length == 4); assert(out_data[0] == data[0]); assert(out_data[1] == data[1]); assert(out_data[2] == data[2]); assert(out_data[3] == data[3]); Buffer.Free(buf); } public static void TestCapacities() { BufferProxy buf = Buffer.Create(6); byte[] data = {0x00, 0x01, 0x02}; assert(buf != null); assert(Buffer.Capacity(buf) == 6); assert(Buffer.ReadCapacity(buf) == 0); assert(Buffer.WriteCapacity(buf) == 6); assert(!Buffer.CanRead(buf)); assert(Buffer.CanWrite(buf)); assert(Buffer.Write(buf, data) == data.length); assert(Buffer.CanRead(buf)); assert(Buffer.CanWrite(buf)); assert(Buffer.ReadCapacity(buf) == 3); assert(Buffer.WriteCapacity(buf) == 3); assert(Buffer.Write(buf, data) == data.length); assert(Buffer.CanRead(buf)); assert(!Buffer.CanWrite(buf)); assert(Buffer.ReadCapacity(buf) == 6); assert(Buffer.WriteCapacity(buf) == 0); Buffer.Free(buf); } public static void TestPutGet() { BufferProxy buf = Buffer.Create(2); assert(buf != null); assert(Buffer.Put(buf, (byte) 0x00) == 0x00); assert(Buffer.Get(buf) == 0x00); assert(Buffer.Get(buf) == -1); assert(Buffer.Put(buf, (byte) 0x01) == 0x01); assert(Buffer.Put(buf, (byte) 0x02) == 0x02); assert(Buffer.Put(buf, (byte) 0x03) == -1); assert(Buffer.Get(buf) == 0x01); assert(Buffer.Get(buf) == 0x02); assert(Buffer.Get(buf) == -1); Buffer.Free(buf); } public static void main(String[] args) { System.loadLibrary("jss4"); System.out.println("Calling TestCreateFree()..."); TestCreateFree(); System.out.println("Calling TestReadWrite()..."); TestReadWrite(); System.out.println("Calling TestCapacities()..."); TestCapacities(); System.out.println("Calling TestPutGet()..."); TestPutGet(); } } jss-4.6.3/org/mozilla/jss/tests/TestBufferPRFD.c000066400000000000000000000053131362106420000214070ustar00rootroot00000000000000/* * Test case for Buffer PRFileDesc implementation located under the * org.mozilla.jss.ssl.javax package. This ensures that we can do a * basic SSL handshake and verify that it works alright. */ /* Optional, for enabling asserts */ #define DEBUG 1 /* Header file under test */ #include "BufferPRFD.h" /* NSPR required includes */ #include #include #include #include /* NSS includes */ #include #include #include #include #include #include #include #include /* Standard includes */ #include #include #include #include #include #include #include void test_getsocketoption(PRFileDesc *fd, size_t read_buf_len, size_t write_buf_len) { PRSocketOptionData opt; memset(&opt, 0, sizeof(opt)); opt.option = PR_SockOpt_Nonblocking; assert(PR_GetSocketOption(fd, &opt) == PR_SUCCESS); assert(opt.value.non_blocking == PR_TRUE); memset(&opt, 0, sizeof(opt)); opt.option = PR_SockOpt_Reuseaddr; assert(PR_GetSocketOption(fd, &opt) == PR_SUCCESS); assert(opt.value.reuse_addr == PR_TRUE); memset(&opt, 0, sizeof(opt)); opt.option = PR_SockOpt_Keepalive; assert(PR_GetSocketOption(fd, &opt) == PR_SUCCESS); assert(opt.value.keep_alive == PR_FALSE); memset(&opt, 0, sizeof(opt)); opt.option = PR_SockOpt_NoDelay; assert(PR_GetSocketOption(fd, &opt) == PR_SUCCESS); assert(opt.value.no_delay == PR_TRUE); memset(&opt, 0, sizeof(opt)); opt.option = PR_SockOpt_RecvBufferSize; assert(PR_GetSocketOption(fd, &opt) == PR_SUCCESS); assert(opt.value.recv_buffer_size == read_buf_len); memset(&opt, 0, sizeof(opt)); opt.option = PR_SockOpt_SendBufferSize; assert(PR_GetSocketOption(fd, &opt) == PR_SUCCESS); assert(opt.value.send_buffer_size == write_buf_len); } void test_read_write(PRFileDesc *fd) { } void test_with_buffer_size(size_t read_buf_len, size_t write_buf_len) { /* Initialize Read/Write Buffers */ j_buffer *read_buf = jb_alloc(read_buf_len); j_buffer *write_buf = jb_alloc(write_buf_len); PRFileDesc *fd = newBufferPRFileDesc(read_buf, write_buf, (uint8_t *) "localhost", 9); test_getsocketoption(fd, read_buf_len, write_buf_len); PR_Close(fd); jb_free(read_buf); jb_free(write_buf); } int main(int argc, char** argv) { if (argc != 1) { fprintf(stderr, "usage: %s\n", argv[0]); return 1; } test_with_buffer_size(1023, 1023); test_with_buffer_size(2048, 1023); test_with_buffer_size(1023, 2048); return 0; } jss-4.6.3/org/mozilla/jss/tests/TestBufferPRFD.java000066400000000000000000000253101362106420000221050ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.util.*; import org.mozilla.jss.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.pkcs11.*; import org.mozilla.jss.nss.*; import org.mozilla.jss.ssl.*; import org.mozilla.jss.util.*; public class TestBufferPRFD { public static void TestCreateClose() { byte[] info = {0x01, 0x02, 0x03, 0x04}; BufferProxy left_read = Buffer.Create(10); BufferProxy right_read = Buffer.Create(10); assert(left_read != null); assert(right_read != null); PRFDProxy left = PR.NewBufferPRFD(left_read, right_read, info); PRFDProxy right = PR.NewBufferPRFD(right_read, left_read, info); assert(left != null); assert(right != null); assert(PR.Write(left, info) == 4); assert(PR.Send(left, info, 0, 0) == 4); assert(PR.Send(left, info, 0, 0) == 2); byte[] result = PR.Recv(right, 10, 0, 0); assert(result.length == 10); for (int i = 0; i < 10; i++) { assert(result[i] == info[i % info.length]); } assert(PR.Close(left) == PR.SUCCESS); assert(PR.Close(right) == PR.SUCCESS); Buffer.Free(left_read); Buffer.Free(right_read); } public static SSLFDProxy Setup_NSS_Client(PRFDProxy fd, String host) throws Exception { SSLFDProxy result = SSL.ImportFD(null, fd); assert(result != null); assert(SSL.ResetHandshake(result, false) == SSL.SECSuccess); assert(SSL.SetURL(result, host) == SSL.SECSuccess); TestSSLVersionGetSet(result); return result; } public static SSLFDProxy Setup_NSS_Server(PRFDProxy fd, String host, PK11Cert cert, PK11PrivKey key) throws Exception { SSLFDProxy result = SSL.ImportFD(null, fd); assert(result != null); assert(SSL.ConfigServerCert(result, cert, key) == SSL.SECSuccess); assert(SSL.ConfigServerSessionIDCache(1, 100, 100, null) == SSL.SECSuccess); assert(SSL.ResetHandshake(result, true) == SSL.SECSuccess); assert(SSL.SetURL(result, host) == SSL.SECSuccess); TestSSLVersionGetSet(result); return result; } public static boolean IsHandshakeFinished(SSLFDProxy c_nspr, SSLFDProxy s_nspr) { SecurityStatusResult c_result = SSL.SecurityStatus(c_nspr); SecurityStatusResult s_result = SSL.SecurityStatus(s_nspr); assert(c_result != null && s_result != null); return c_result.on == 1 && s_result.on == 1; } public static void TestSSLVersionGetSet(SSLFDProxy s_nspr) throws Exception { SSLVersionRange initial = SSL.VersionRangeGet(s_nspr); System.out.println("Initial: (" + initial.getMinVersion() + ":" + initial.getMinEnum() + ", " + initial.getMaxVersion() + ":" + initial.getMaxEnum() + ")"); SSLVersionRange vrange = new SSLVersionRange(SSLVersion.TLS_1_1, SSLVersion.TLS_1_3); assert(SSL.VersionRangeSet(s_nspr, vrange) == SSL.SECSuccess); SSLVersionRange actual = SSL.VersionRangeGet(s_nspr); System.out.println("Actual: (" + actual.getMinVersion() + ":" + actual.getMinEnum() + ", " + actual.getMaxVersion() + ":" + actual.getMaxEnum() + ")"); assert(actual.getMinEnum() <= SSLVersion.TLS_1_2.value()); assert(SSLVersion.TLS_1_2.value() <= actual.getMaxEnum()); } public static void InitializeCM(String database, String password) throws Exception { CryptoManager manager; CryptoManager.initialize(database); manager = CryptoManager.getInstance(); manager.setPasswordCallback(new Password(password.toCharArray())); } public static void TestSSLHandshake(String server_nickname, String client_nickname) throws Exception { /* Constants */ String host = "localhost"; byte[] peer_info = host.getBytes(); /* Find SSL Server Certificate */ CryptoManager manager = CryptoManager.getInstance(); PK11Cert server_cert = (PK11Cert) manager.findCertByNickname(server_nickname); PK11PrivKey server_key = (PK11PrivKey) manager.findPrivKeyByCert(server_cert); assert(server_cert != null); assert(server_cert instanceof PK11Cert); assert(server_key != null); assert(server_key instanceof PK11PrivKey); /* Find SSL Client Certificate, if nickname given. */ PK11Cert client_cert = null; if (client_nickname != null) { client_cert = (PK11Cert) manager.findCertByNickname(client_nickname); assert(client_cert != null); } /* Create Buffers and BufferPRFDs */ BufferProxy read_buf = Buffer.Create(1024); BufferProxy write_buf = Buffer.Create(1024); assert(read_buf != null); assert(write_buf != null); PRFDProxy c_buffer = PR.NewBufferPRFD(read_buf, write_buf, peer_info); PRFDProxy s_buffer = PR.NewBufferPRFD(write_buf, read_buf, peer_info); assert(c_buffer != null); assert(s_buffer != null); SSLFDProxy c_nspr = Setup_NSS_Client(c_buffer, host); SSLFDProxy s_nspr = Setup_NSS_Server(s_buffer, host, server_cert, server_key); assert(c_nspr != null); assert(s_nspr != null); /* Apply Client Certificate, if given. When given, request it as the * server. */ if (client_cert != null) { c_nspr.SetClientCert(client_cert); assert(SSL.AttachClientCertCallback(c_nspr) == SSL.SECSuccess); assert(SSL.OptionSet(s_nspr, SSL.REQUEST_CERTIFICATE, 1) == SSL.SECSuccess); } /* Attach alert logging callback handler. */ assert(SSL.EnableAlertLogging(c_nspr) == SSL.SECSuccess); assert(SSL.EnableAlertLogging(s_nspr) == SSL.SECSuccess); assert(!IsHandshakeFinished(c_nspr, s_nspr)); /* Try a handshake */ int count = 0; while(!IsHandshakeFinished(c_nspr, s_nspr)) { if (SSL.ForceHandshake(c_nspr) != SSL.SECSuccess) { int error = PR.GetError(); if (error != PRErrors.WOULD_BLOCK_ERROR) { System.out.println("Unexpected error: " + new String(PR.ErrorToName(error)) + " (" + error + ")"); System.exit(1); } } if (SSL.ForceHandshake(s_nspr) != SSL.SECSuccess) { int error = PR.GetError(); if (error != PRErrors.WOULD_BLOCK_ERROR) { System.out.println("Unexpected error: " + new String(PR.ErrorToName(error)) + " (" + error + ")"); System.exit(1); } } count += 1; if (count >= 40) { System.err.println("Error: unable to make progress after " + count + " steps!"); System.exit(1); } } System.out.println("Handshake completed successfully!\n"); assert(IsHandshakeFinished(c_nspr, s_nspr)); /* Test peer data */ assert(SSL.PeerCertificate(c_nspr) != null); assert(SSL.PeerCertificateChain(c_nspr) != null); if (client_nickname == null) { assert(SSL.PeerCertificate(s_nspr) == null); assert(SSL.PeerCertificateChain(s_nspr) == null); } else { assert(SSL.PeerCertificate(s_nspr) != null); assert(SSL.PeerCertificateChain(s_nspr) != null); } /* Send data from client -> server */ byte[] client_message = "Cooking MCs".getBytes(); assert(PR.Write(c_nspr, client_message) == client_message.length); byte[] server_received = PR.Read(s_nspr, client_message.length); assert(server_received != null); if (server_received.length != client_message.length) { System.out.println("Expected a client message of length " + client_message.length + " but got one of " + server_received.length); System.exit(1); } for (int i = 0; i < client_message.length && i < server_received.length; i++) { if (client_message[i] != server_received[i]) { System.out.println("Received byte " + server_received[i] + " on server but expected " + client_message[i]); System.exit(1); } } /* Send data from server -> client */ byte[] server_message = "like a pound of bacon".getBytes(); assert(PR.Write(s_nspr, server_message) == server_message.length); byte[] client_received = PR.Read(c_nspr, server_message.length); assert(client_received != null); if (client_received.length != server_message.length) { System.out.println("Expected a server message of length " + server_message.length + " but got one of " + client_received.length); System.exit(1); } for (int i = 0; i < server_message.length && i < client_received.length; i++) { if (server_message[i] != client_received[i]) { System.out.println("Received byte " + client_received[i] + " on client but expected " + server_message[i]); System.exit(1); } } /* Close connections */ assert(PR.Shutdown(c_nspr, PR.SHUTDOWN_BOTH) == PR.SUCCESS); assert(PR.Shutdown(s_nspr, PR.SHUTDOWN_BOTH) == PR.SUCCESS); /* Print all alerts. */ for (SSLAlertEvent alert : c_nspr.inboundAlerts) { System.err.println("client inbound: " + alert); } for (SSLAlertEvent alert : c_nspr.outboundAlerts) { System.err.println("client outbound: " + alert); } for (SSLAlertEvent alert : s_nspr.inboundAlerts) { System.err.println("server inbound: " + alert); } for (SSLAlertEvent alert : s_nspr.outboundAlerts) { System.err.println("server outbound: " + alert); } /* Clean up */ assert(PR.Close(c_nspr) == PR.SUCCESS); assert(PR.Close(s_nspr) == PR.SUCCESS); Buffer.Free(read_buf); Buffer.Free(write_buf); } public static void main(String[] args) throws Exception { System.loadLibrary("jss4"); System.out.println("Calling TestCreateClose()..."); TestCreateClose(); System.out.println("Initializing CryptoManager..."); InitializeCM(args[0], args[1]); System.out.println("Calling TestSSLHandshake(Server_RSA, null)..."); TestSSLHandshake("Server_RSA", null); System.out.println("Calling TestSSLHandshake(Server_RSA, Client_RSA)..."); TestSSLHandshake("Server_RSA", "Client_RSA"); System.out.println("Calling TestSSLHandshake(Server_ECDSA, null)..."); TestSSLHandshake("Server_ECDSA", null); System.out.println("Calling TestSSLHandshake(Server_ECDSA, Client_ECDSA)..."); TestSSLHandshake("Server_ECDSA", "Client_ECDSA"); } } jss-4.6.3/org/mozilla/jss/tests/TestBufferPRFDSSL.c000066400000000000000000000341771362106420000220030ustar00rootroot00000000000000/* * Test case for Buffer PRFileDesc implementation located under the * org.mozilla.jss.ssl.javax package. This ensures that we can do a * basic SSL handshake and verify that it works alright. */ /* Optional, for enabling asserts */ #define DEBUG 1 /* Header file under test */ #include "BufferPRFD.h" /* NSPR required includes */ #include #include #include #include /* NSS includes */ #include #include #include #include #include #include #include #include /* Standard includes */ #include #include #include #include #include #include static char *return_password(PK11SlotInfo *slot, PRBool retry, void *arg) { /* Return the password passed in via arg as the password for the PKCS11 * slot. From NSS semantics it appears that this function should allocate * a new copy with strdup as the caller expects to free it. */ if (retry == PR_FALSE) { return strdup((char*) arg); } else { /* Since arg is static, exit on an incorrect password; otherwise, * we'd be stuck in an infinite loop as there's no way to change * the value of arg. */ fprintf(stderr, "Error: Incorrect password!\n"); exit(1); } } static void setup_nss_context(char *database) { /* Create NSS Context to reference the given NSS DB and initialize the * NSS context with the database connection. */ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); NSSInitContext *const ctx = NSS_InitContext(database, "", "", "", NULL, NSS_INIT_READONLY | NSS_INIT_PK11RELOAD); if (ctx == NULL) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: NSPR error code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } if (NSS_Init(database) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: NSPR error code when doing NSS_Init %d: %s\n", err, PR_ErrorToName(err)); exit(1); } } static PRFileDesc *setup_nss_client(PRFileDesc *c_nspr, char *host) { /* Configure the client end of the TLS connection. */ /* Note that most of this comes from the Fedora guide link: */ // https://docs.fedoraproject.org/en-US/Fedora_Security_Team/1/html/Defensive_Coding/sect-Defensive_Coding-TLS-Client-NSS.html PRFileDesc *model = PR_NewTCPSocket(); PRFileDesc *newfd = SSL_ImportFD(NULL, model); if (newfd == NULL) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: NSPR error code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } model = newfd; newfd = SSL_ImportFD(model, c_nspr); if (newfd == NULL) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: SSL_ImportFD error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } c_nspr = newfd; PR_Close(model); // Reset the handshake status after importing. if (SSL_ResetHandshake(c_nspr, PR_FALSE) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: SSL_ResetHandshake error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } if (SSL_SetURL(c_nspr, host) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: SSL_SetURL error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } return c_nspr; } static CERTCertificate *get_cert(char *host) { /* Find and return the certificate for the given host in the NSS DB; * this is only the public key. */ /* Code adapted from mod_nss. */ CERTCertList *clist; CERTCertListNode *cln; /* To do this, we have to iterate over all certs in the "user" NSS * database and see if any has a nickname matching the hostname. */ clist = PK11_ListCerts(PK11CertListUser, NULL); for (cln = CERT_LIST_HEAD(clist); !CERT_LIST_END(cln, clist); cln = CERT_LIST_NEXT(cln)) { CERTCertificate *cert = cln->cert; const char *nickname = (const char*)cln->appData; if (!nickname) { nickname = cert->nickname; } if (strcmp(host, nickname) == 0) { printf("Found cert with nickname: %s\n", nickname); return cert; } } return NULL; } static SECKEYPrivateKey *get_privkey(CERTCertificate *cert, char *password) { /* For the given certificate, return the matching private key. Uses * password as authentication to the PKCS11 database if necessary. */ /* Code adapted from mod_nss. */ PK11SlotInfo *slot = NULL; /* First get the "default" slot -- this is the slot that GenerateTestCert * places its certificates in. */ slot = PK11_GetInternalKeySlot(); if (slot == NULL) { printf("Error finding internal slot!\n"); exit(2); } /* Since the JSS test suite uses a password on its database, we need a * shim function that returns the string. Note that this is implemented * in various places in NSS, but not exposed to calling applications. */ PK11_SetPasswordFunc(return_password); PRInt32 rv = PK11_Authenticate(slot, PR_TRUE, password); if (rv != SECSuccess) { /* This branch won't be reached as our return_password calls exit for * us on an incorrect password. */ printf("Invalid password for slot!\n"); const PRErrorCode err = PR_GetError(); fprintf(stderr, "error %d: %s\n", err, PR_ErrorToName(err)); exit(3); } return PK11_FindPrivateKeyFromCert(slot, cert, NULL); } static PRFileDesc *setup_nss_server(PRFileDesc *s_nspr, char *host, char *password, char *nickname) { /* Set up the server end of the SSL connection and find certificates. */ /* Adapted from aforementioned Fedora developer guide and mod_nss. */ CERTCertificate *cert = get_cert(nickname); if (cert == NULL) { printf("Failed to find certificate for host: %s\n", host); exit(1); } SECKEYPrivateKey *priv_key = get_privkey(cert, password); if (priv_key == NULL) { printf("Failed to find private key for certificate for host: %s\n", host); const PRErrorCode err = PR_GetError(); fprintf(stderr, "error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } PRFileDesc *model = PR_NewTCPSocket(); PRFileDesc *newfd = SSL_ImportFD(NULL, model); if (newfd == NULL) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: NSPR error code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } model = newfd; newfd = SSL_ImportFD(model, s_nspr); if (newfd == NULL) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: SSL_ImportFD error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } s_nspr = newfd; PR_Close(model); /* This part differs from the client side: set the certificate and * private key we're using. */ if (SSL_ConfigServerCert(s_nspr, cert, priv_key, NULL, 0) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: SSL_ConfigServerCert error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } /* We need to initialize the SessionID cache, else NSS will segfault * because it has zero size when it tries to insert the new * connection into the cache... */ SSL_ConfigServerSessionIDCache(1, 100, 100, NULL); // Reset the handshake status -- server end if (SSL_ResetHandshake(s_nspr, PR_TRUE) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: SSL_ResetHandshake error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } if (SSL_SetURL(s_nspr, host) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: SSL_SetURL error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } return s_nspr; } bool is_finished(PRFileDesc *c_nspr, PRFileDesc *s_nspr) { /* Check whether or not the SSL Handshake has finished on both sides of * the connection. Since we cannot be guaranteed that the handshake was * successful, check whether SSL isn't off, i.e., is on or failed. */ int c_sec_status; int s_sec_status; if (SSL_SecurityStatus(c_nspr, &c_sec_status, NULL, NULL, NULL, NULL, NULL) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: SSL_SecurityStatus error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } if (SSL_SecurityStatus(s_nspr, &s_sec_status, NULL, NULL, NULL, NULL, NULL) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: SSL_SecurityStatus error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } return c_sec_status != SSL_SECURITY_STATUS_OFF && s_sec_status != SSL_SECURITY_STATUS_OFF; } int main(int argc, char** argv) { if (argc != 4) { fprintf(stderr, "usage: %s /path/to/nssdb password cert-nickname\n", argv[0]); exit(1); } setup_nss_context(argv[1]); /* Initialize Read/Write Buffers */ /* In order to maintain complete control over our buffers, we need to * create our buffers, sizes, and pointers here. This means that the * PRFileDesc does nothing except hold pointers to our memory and update * the contents/values as it sees fit (send/recv). If instead the buffer * took access (or created access itself), we'd need to get access to * them befor giving it to NSS, as NSS wraps our PRFileDesc in one of * their PRFileDescs, removing our access to fd->secret. */ j_buffer *c_read_buf = jb_alloc(4096); j_buffer *c_write_buf = jb_alloc(4096); PRFileDesc *c_nspr = newBufferPRFileDesc(c_read_buf, c_write_buf, (uint8_t*) "localhost", 9); /* Initialize Server Buffers */ PRFileDesc *s_nspr = newBufferPRFileDesc(c_write_buf, c_read_buf, (uint8_t*) "localhost", 9); /* Set up client and server sockets with NSSL */ char *host = "localhost"; c_nspr = setup_nss_client(c_nspr, host); s_nspr = setup_nss_server(s_nspr, host, argv[2], argv[3]); /* In the handshake step, we blindly try to step both the client and * server ends of the handshake. As NSS stores the contents of what we're * supposed to be sending, as long as our buffers are of "reasonable" * size, we'll be able to step one of the two sides until something useful * happens. */ printf("Trying handshake...\n"); int count = 0; while (!is_finished(c_nspr, s_nspr)) { printf("Client Handshake:\n"); if (SSL_ForceHandshake(c_nspr) != SECSuccess) { const PRErrorCode err = PR_GetError(); if (err != PR_WOULD_BLOCK_ERROR) { fprintf(stderr, "error: SSL_ForceHandshake error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } } printf("\n\nServer Handshake:\n"); if (SSL_ForceHandshake(s_nspr) != SECSuccess) { const PRErrorCode err = PR_GetError(); if (err != PR_WOULD_BLOCK_ERROR) { fprintf(stderr, "error: SSL_ForceHandshake error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } } printf("\n\n"); count += 1; if (count >= 40) { fprintf(stderr, "error: unable to make progress after %d steps!\n", count); exit(1); } } /* Send a test message from client -> server to ensure that the connection * truly is ready. */ /* Note: we don't handle E_WOULDBLOCK here as our messages are small. */ printf("Send a message from the client to the server...\n"); size_t buf_size = 1025; char *buf = calloc(buf_size, sizeof(char)); char *buf2 = calloc(buf_size, sizeof(char)); char *client_message = "Cooking MCs"; char *server_message = "like a pound of bacon"; memcpy(buf, client_message, strlen(client_message)); PRInt32 ret = PR_Write(c_nspr, buf, strlen(buf)); if (ret < 0) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: PR_Write error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } ret = PR_Read(s_nspr, buf2, buf_size - 1); if (ret < 0) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: PR_Read error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } printf("Received message from client: %s [len: %d]\n", buf2, ret); printf("\n\n"); /* Send a message back to confirm we received it! */ printf("Send a message from the server to the client...\n"); memcpy(buf, server_message, strlen(server_message)); ret = PR_Write(s_nspr, buf, strlen(buf)); if (ret < 0) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: PR_Write error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } memset(buf2, 0, buf_size); ret = PR_Read(c_nspr, buf2, buf_size - 1); if (ret < 0) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: PR_Read error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } printf("Received message from client: %s [len: %d]\n", buf2, ret); /* Close the client and then the server end of the connection. */ ret = PR_Shutdown(c_nspr, PR_SHUTDOWN_BOTH); if (ret < 0) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: PR_Shutdown client error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } ret = PR_Shutdown(s_nspr, PR_SHUTDOWN_BOTH); if (ret < 0) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "error: PR_Shutdown server error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } /* Closes the underlying POSIX file descriptors */ PR_Close(c_nspr); PR_Close(s_nspr); /* Free the buffers and their contents */ jb_free(c_read_buf); jb_free(c_write_buf); return 0; } jss-4.6.3/org/mozilla/jss/tests/TestCertificateApprovalCallback.java000066400000000000000000000060471362106420000255720ustar00rootroot00000000000000/* 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.tests; import java.util.Enumeration; import org.mozilla.jss.crypto.InternalCertificate; import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This is a test implementation of the certificate approval callback which * gets invoked when the server presents a certificate which is not * trusted by the client. * * Note this implementation accepts all certificates! */ public class TestCertificateApprovalCallback implements SSLCertificateApprovalCallback { public static Logger logger = LoggerFactory.getLogger(TestCertificateApprovalCallback.class); public boolean approve( org.mozilla.jss.crypto.X509Certificate servercert, SSLCertificateApprovalCallback.ValidityStatus status) { SSLCertificateApprovalCallback.ValidityItem item; logger.debug("in TestCertificateApprovalCallback.approve()"); /* dump out server cert details */ logger.debug("Peer cert details:"); logger.debug(" subject: " + servercert.getSubjectDN()); logger.debug(" issuer: " + servercert.getIssuerDN()); logger.debug(" serial: " + servercert.getSerialNumber()); /* iterate through all the problems */ boolean trust_the_server_cert=false; Enumeration errors = status.getReasons(); int i=0; while (errors.hasMoreElements()) { i++; item = errors.nextElement(); logger.debug("item "+i+ " reason="+item.getReason()+ " depth="+item.getDepth()); org.mozilla.jss.crypto.X509Certificate cert = item.getCert(); if (item.getReason() == SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER) { trust_the_server_cert = true; } logger.debug(" cert details:"); logger.debug(" subject: " + cert.getSubjectDN()); logger.debug(" issuer: " + cert.getIssuerDN()); logger.debug(" serial: " + cert.getSerialNumber()); } if (trust_the_server_cert) { logger.debug("importing certificate."); try { InternalCertificate newcert = org.mozilla.jss.CryptoManager.getInstance(). importCertToPerm(servercert,"testnick"); newcert.setSSLTrust(InternalCertificate.TRUSTED_PEER | InternalCertificate.VALID_PEER); } catch (Exception e) { System.out.println("thrown exception: "+e); } } /* allow the connection to continue. */ /* returning false here would abort the connection */ /* don't do this in production code! */ return true; } } jss-4.6.3/org/mozilla/jss/tests/TestCmac.java000066400000000000000000000066301362106420000210670ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.util.Arrays; import java.util.Base64; import java.security.Key; import javax.crypto.*; import javax.crypto.spec.*; import org.mozilla.jss.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.*; public class TestCmac { private static final byte[] NIST_128 = Base64.getDecoder().decode("K34VFiiu0qar9xWICc9PPA=="); private static final byte[] NIST_192 = Base64.getDecoder().decode("jnOw99oOZFLIEPMrgJB55WL46tJSLGt7"); private static final byte[] NIST_256 = Base64.getDecoder().decode("YD3rEBXKcb4rc67whX13gR81LAc7YQjXLZgQowkU3/Q="); public static void main(String[] args) throws Exception { CryptoManager.initialize(args[0]); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(args[1]); tok.login(cb); testNISTExamples(); } /* * The following test vectors come from NIST's Examples with Intermediate * Values page: * https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values * * These are the same vectors utilized by NSS in: * gtests/freebl_gtest/cmac_unittests.cc * * These same vectors are also found in FRC 4493, Section 4. */ public static void testNISTExamples() throws Exception { byte[] all_input = Base64.getDecoder().decode("a8G+4i5An5bpPX4Rc5MXKq4tilceA6ycnrdvrEWvjlEwyBxGo1zkEeX7wRkaClLv9p8kRd9PmxetK0F75mw3EA=="); int[] input_lengths = new int[] { 0, 16, 20, 64}; byte[][] all_expected = new byte[][] { Base64.getDecoder().decode("ux1pKelZNyh/o30Sm3VnRg=="), Base64.getDecoder().decode("BwoWtGtNQUT3m92d0EoofA=="), Base64.getDecoder().decode("fYVEnqbqGcgjp794g3363g=="), Base64.getDecoder().decode("UfC+v347nZL8SXQXeTY8/g=="), Base64.getDecoder().decode("0X3fRq2qzeUxysSD3nqTZw=="), Base64.getDecoder().decode("npmnvzHnEJAGYvZeYXxRhA=="), Base64.getDecoder().decode("PXXBlO2WBwREqfp+x0Ds+A=="), Base64.getDecoder().decode("odXfDu15D3lNd1iWWfOaEQ=="), Base64.getDecoder().decode("Aoli9ht7+J78a1UfRmfZgw=="), Base64.getDecoder().decode("KKcCP0Uuj4K9S/KNjDfDXA=="), Base64.getDecoder().decode("FWcn3Ah4lEoCPB/gO61tkw=="), Base64.getDecoder().decode("4ZkhkFSfbtVpaiwFbDFUEA==") }; for (int i = 0; i < all_expected.length; i++) { byte[] key = getKey(i); byte[] input = Arrays.copyOf(all_input, input_lengths[i % input_lengths.length]); byte[] expected = all_expected[i]; testCMAC(key, input, expected); } } public static byte[] getKey(int index) { if (index < 4) { return NIST_128; } else if (index < 8) { return NIST_192; } else if (index < 12) { return NIST_256; } return null; } public static void testCMAC(byte[] key_bytes, byte[] input, byte[] expected) throws Exception { Mac mac = Mac.getInstance("AES_CMAC", "Mozilla-JSS"); SecretKeyFactory factory = SecretKeyFactory.getInstance("AES", "Mozilla-JSS"); Key key = factory.generateSecret(new SecretKeySpec(key_bytes, "AES")); mac.init(key); byte[] actual = mac.doFinal(input); assert(Arrays.equals(actual, expected)); } } jss-4.6.3/org/mozilla/jss/tests/TestKBKDF.java000066400000000000000000000133701362106420000210440ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.util.Arrays; import java.util.Base64; import java.security.spec.*; import javax.crypto.*; import javax.crypto.spec.*; import org.mozilla.jss.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.pkcs11.*; import org.mozilla.jss.pkcs11.attrs.*; import org.mozilla.jss.util.*; public class TestKBKDF { public static void main(String[] args) throws Exception { CryptoManager.initialize(args[0]); CryptoManager cm = CryptoManager.getInstance(); TokenSupplier ts = TokenSupplierManager.getTokenSupplier(); ts.setThreadToken(cm.getInternalCryptoToken()); testCounterKDFNistCMAC(); testFeedbackKDFNistCMAC(); testPipelineKDFNistCMAC(); } public static void testCounterKDFNistCMAC() throws Exception { javax.crypto.KeyGenerator kg = javax.crypto.KeyGenerator.getInstance("KbkdfCounterData", "Mozilla-JSS"); SecretKeyFactory skf = SecretKeyFactory.getInstance("AES", "Mozilla-JSS"); byte[] prf_key_bytes = Base64.getDecoder().decode("3/HlCsC2ncQPEFHUbCsGnA=="); SecretKey prf_key = skf.generateSecret(new SecretKeySpec(prf_key_bytes, "AES")); SymmetricKey smkey = ((SecretKeyFacade)prf_key).key; CryptoToken token = smkey.getOwningToken(); PK11Token tkn = (PK11Token)token; KBKDFCounterParams kcp = new KBKDFCounterParams(); kcp.setPRF(PKCS11Algorithm.CKM_AES_CMAC); kcp.setPRFKey(prf_key); kcp.setKeySize(16); kcp.setDerivedKeyAlgorithm(PKCS11Algorithm.CKM_SHA_512_HMAC); kcp.addParameter(new KBKDFIterationVariableParam(true, 8)); byte[] byte_array_param = Base64.getDecoder().decode("wW5uAsWj3MjXi5rBMGh3dhMQRVtOQUaZUdnmwiRaBksz/Yw7ASA6eCRIW/CmQGDEZItwfSYHk1aZMW6l"); kcp.addParameter(new KBKDFByteArrayParam(byte_array_param)); // RHEL 8.2 doesn't support additional derived keys. /*KBKDFDerivedKey kdk = new KBKDFDerivedKey(); kdk.addAttribute(new CKAClass.Data()); kdk.addAttribute(new CKAUsage.Encrypt()); kdk.addAttribute(new CKAValueLen(16)); kcp.addAdditionalDerivedKey(kdk);*/ kg.init(kcp); SecretKey key = kg.generateKey(); assert(key != null); byte[] encoded = key.getEncoded(); byte[] expected = Base64.getDecoder().decode("i+jwhps8C6l7cYY9G594Ew=="); assert(Arrays.equals(encoded, expected)); /*SecretKey other_key = kdk.getKey(key, PKCS11Constants.CKM_SHA512_HMAC, true); byte[] other_encoded = other_key.getEncoded(); byte[] other_expected = Base64.getDecoder().decode("DMdy/9fjofZGZMe3xhxlEg=="); assert(Arrays.equals(encoded, expected));*/ } public static void testFeedbackKDFNistCMAC() throws Exception { javax.crypto.KeyGenerator kg = javax.crypto.KeyGenerator.getInstance("KbkdfFeedbackData", "Mozilla-JSS"); SecretKeyFactory skf = SecretKeyFactory.getInstance("AES", "Mozilla-JSS"); byte[] prf_key_bytes = Base64.getDecoder().decode("ILu+NunIPFGETNMenCCUMQ=="); SecretKey prf_key = skf.generateSecret(new SecretKeySpec(prf_key_bytes, "AES")); SymmetricKey smkey = ((SecretKeyFacade)prf_key).key; CryptoToken token = smkey.getOwningToken(); PK11Token tkn = (PK11Token)token; KBKDFFeedbackParams kfp = new KBKDFFeedbackParams(); kfp.setPRF(PKCS11Algorithm.CKM_AES_CMAC); kfp.setPRFKey(prf_key); kfp.setKeySize(64); kfp.setDerivedKeyAlgorithm(PKCS11Algorithm.CKM_SHA_512_HMAC); kfp.addParameter(new KBKDFOptionalCounterParam(true, 8)); kfp.addParameter(new KBKDFIterationVariableParam()); byte[] byte_array_param = Base64.getDecoder().decode("61B6/2n3fqtqugQgNKXLGZDXenzXKkmE8/skL7RM4PuUnpnZXYHlcQm31c03RqMhbEej"); kfp.addParameter(new KBKDFByteArrayParam(byte_array_param)); byte[] iv = Base64.getDecoder().decode("KPKKUyw744XXLsUyE2f4tg=="); kfp.setInitialValue(iv); kg.init(kfp); SecretKey key = kg.generateKey(); assert(key != null); byte[] encoded = key.getEncoded(); byte[] expected = Base64.getDecoder().decode("J3pHPT9RSvP3YKI4M0PA63mfeanI8fMds34RBHhtO6IMn7KkLSmXzKt/eaXBnwlHBtMuCbzk93rtYWKvCNidHQ=="); assert(Arrays.equals(encoded, expected)); } public static void testPipelineKDFNistCMAC() throws Exception { javax.crypto.KeyGenerator kg = javax.crypto.KeyGenerator.getInstance("KbkdfPipelineData", "Mozilla-JSS"); SecretKeyFactory skf = SecretKeyFactory.getInstance("AES", "Mozilla-JSS"); byte[] prf_key_bytes = Base64.getDecoder().decode("xiVNld0QjpuyngBT3e7DUQ=="); SecretKey prf_key = skf.generateSecret(new SecretKeySpec(prf_key_bytes, "AES")); SymmetricKey smkey = ((SecretKeyFacade)prf_key).key; CryptoToken token = smkey.getOwningToken(); PK11Token tkn = (PK11Token)token; KBKDFPipelineParams kcp = new KBKDFPipelineParams(); kcp.setPRF(PKCS11Algorithm.CKM_AES_CMAC); kcp.setPRFKey(prf_key); kcp.setKeySize(64); kcp.setDerivedKeyAlgorithm(PKCS11Algorithm.CKM_SHA_512_HMAC); kcp.addParameter(new KBKDFOptionalCounterParam(true, 8)); kcp.addParameter(new KBKDFIterationVariableParam()); byte[] byte_array_param = Base64.getDecoder().decode("IvSY/JuNS3IYi84wuph1/CsOs/52h02FQm5uWzsjfJ9EXy2iCmCrGJgC4sFSxKNgKqNC"); kcp.addParameter(new KBKDFByteArrayParam(byte_array_param)); kg.init(kcp); SecretKey key = kg.generateKey(); assert(key != null); byte[] encoded = key.getEncoded(); byte[] expected = Base64.getDecoder().decode("HhM6lS31WhHuA4EgN19h58AWKELIFxYGk7HzncC3lbxvNpHbd1zzr0sKn2n+y+mWef1LSHPdp0P1xqLS6HPybQ=="); assert(Arrays.equals(encoded, expected)); } } jss-4.6.3/org/mozilla/jss/tests/TestKeyGen.java000066400000000000000000000206561362106420000214120ustar00rootroot00000000000000/* 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/. */ /** * Note: when this program is run, it must have a key3.db WITH A PASSWORD * SET in the directory specified by the argument. The first time the * program is run, a key3.db file will be created, but it will not have * a password. This will result in the error: * Token error: org.mozilla.jss.crypto.TokenException: unable to login to token * * To create a database with a password, you can: * use the modutil or keyutil tool, * use the JSS API CryptoToken.changePassword() to set the password * run the test 'TokenAccessTest' * which will create db with a password. */ package org.mozilla.jss.tests; import java.math.BigInteger; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPublicKey; import java.util.Enumeration; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.RSAParameterSpec; import org.mozilla.jss.pkcs11.PK11KeyPairGenerator; import org.mozilla.jss.util.Assert; import org.mozilla.jss.util.Base64OutputStream; public class TestKeyGen { public static void main(String[] args) { try { CryptoManager manager; java.security.KeyPair keyPair; Base64OutputStream base64; if(args.length != 2) { System.err.println("Usage: java org.mozilla.jss.pkcs11." + "TestKeyGen "); System.exit(1); } CryptoManager.initialize(args[0]); manager = CryptoManager.getInstance(); manager.setPasswordCallback( new FilePasswordCallback(args[1]) ); Enumeration tokens = manager.getTokensSupportingAlgorithm(KeyPairAlgorithm.RSA); System.out.println("The following tokens support RSA keygen:"); while(tokens.hasMoreElements()) { System.out.println("\t"+ tokens.nextElement().getName() ); } tokens = manager.getTokensSupportingAlgorithm(KeyPairAlgorithm.DSA); System.out.println("The following tokens support DSA keygen:"); while(tokens.hasMoreElements()) { System.out.println("\t"+ tokens.nextElement().getName() ); } RSAPublicKey rsaPubKey; DSAPublicKey dsaPubKey; DSAParams dsaParams; RSAParameterSpec rsaParams; java.security.KeyPairGenerator kpg = java.security.KeyPairGenerator.getInstance("RSA", "Mozilla-JSS"); // 512-bit RSA with default exponent System.out.println("Generating 512-bit RSA KeyPair!"); for (int cntr=0; cntr<5; cntr++ ) { try { kpg.initialize(512); keyPair = kpg.genKeyPair(); assert( keyPair.getPublic() instanceof RSAPublicKey); rsaPubKey = (RSAPublicKey) keyPair.getPublic(); System.out.println("Generated 512-bit RSA KeyPair!"); System.out.println("Modulus: "+rsaPubKey.getModulus()); System.out.println("Exponent: "+rsaPubKey.getPublicExponent()); break; } catch (org.mozilla.jss.crypto.TokenRuntimeException TRExRSA512) { if (cntr==5) { System.out.println("Generation of 512-bit RSA KeyPair Failed\n"); TRExRSA512.printStackTrace(); } } } // 1024-bit RSA with default exponent System.out.println("Generating 1024-bit RSA KeyPair!"); for (int cntr=0; cntr<5; cntr++ ) { try { kpg.initialize(1024); keyPair = kpg.genKeyPair(); assert( keyPair.getPublic() instanceof RSAPublicKey); rsaPubKey = (RSAPublicKey) keyPair.getPublic(); System.out.println("Generated 1024-bit RSA KeyPair!"); System.out.println("Modulus: "+rsaPubKey.getModulus()); System.out.println("Exponent: "+rsaPubKey.getPublicExponent()); break; } catch (org.mozilla.jss.crypto.TokenRuntimeException TRExRSA1024) { if (cntr==5) { System.out.println("Generation of 1024-bit RSA KeyPair Failed\n"); TRExRSA1024.printStackTrace(); } } } // 512-bit RSA with exponent = 3 System.out.println("Generating 512-bit RSA KeyPair with public exponent=3!"); for (int cntr=0; cntr<5; cntr++ ) { try { rsaParams = new RSAParameterSpec(512, BigInteger.valueOf(3)); kpg.initialize(rsaParams); keyPair = kpg.genKeyPair(); assert( keyPair.getPublic() instanceof RSAPublicKey); rsaPubKey = (RSAPublicKey) keyPair.getPublic(); System.out.println("Generated 512-bit RSA KeyPair with public exponent=3!"); System.out.println("Modulus: "+rsaPubKey.getModulus()); System.out.println("Exponent: "+rsaPubKey.getPublicExponent()); break; } catch (org.mozilla.jss.crypto.TokenRuntimeException TRExRSA512Exp3) { if (cntr==5) { System.out.println("Generation of 512-bit RSA KeyPair with public exponent=3 Failed\n"); TRExRSA512Exp3.printStackTrace(); } } } // 512-bit DSA System.out.println("Generating 512-bit DSA KeyPair!"); kpg = java.security.KeyPairGenerator.getInstance("DSA", "Mozilla-JSS"); for (int cntr=0; cntr<5; cntr++ ) { try { kpg.initialize(512); keyPair = kpg.genKeyPair(); assert( keyPair.getPublic() instanceof DSAPublicKey); dsaPubKey = (DSAPublicKey) keyPair.getPublic(); System.out.println("Generated 512-bit DSA KeyPair!"); dsaParams = dsaPubKey.getParams(); System.out.println("P: "+dsaParams.getP()); System.out.println("Q: "+dsaParams.getQ()); System.out.println("G: "+dsaParams.getG()); System.out.println("Y: "+dsaPubKey.getY()); break; } catch (org.mozilla.jss.crypto.TokenRuntimeException TRExDSA512) { if (cntr==5) { System.out.println("Generation of 512-bit DSA KeyPair Failed\n"); TRExDSA512.printStackTrace(); } } } // 1024-bit DSA, passing in PQG params System.out.println("Generating 1024-bit DSA KeyPair with PQG params!"); for (int cntr=0; cntr<5; cntr++ ) { try { kpg.initialize(PK11KeyPairGenerator.PQG1024); keyPair = kpg.genKeyPair(); assert( keyPair.getPublic() instanceof DSAPublicKey); dsaPubKey = (DSAPublicKey) keyPair.getPublic(); System.out.println("Generated 1024-bit DSA KeyPair with PQG params!"); dsaParams = dsaPubKey.getParams(); System.out.println("P: "+dsaParams.getP()); System.out.println("Q: "+dsaParams.getQ()); System.out.println("G: "+dsaParams.getG()); System.out.println("Y: "+dsaPubKey.getY()); break; } catch (org.mozilla.jss.crypto.TokenRuntimeException TRExDSA1024) { if (cntr==5) { System.out.println("Generation of 1024-bit DSA KeyPair with PQG params Failed\n"); TRExDSA1024.printStackTrace(); } } } // 256-bit EC kpg = java.security.KeyPairGenerator.getInstance("EC", "Mozilla-JSS"); kpg.initialize(256); keyPair = kpg.genKeyPair(); System.out.println("Generated 256-bit EC KeyPair!"); kpg.initialize(384); keyPair = kpg.genKeyPair(); System.out.println("Generated 384-bit EC KeyPair!"); kpg.initialize(521); keyPair = kpg.genKeyPair(); System.out.println("Generated 521-bit EC KeyPair!"); System.out.println("TestKeyGen passed"); System.exit(0); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } } jss-4.6.3/org/mozilla/jss/tests/TestPKCS11Constants.java000066400000000000000000000060421362106420000230200ustar00rootroot00000000000000package org.mozilla.jss.tests; import java.lang.reflect.*; import java.util.*; public class TestPKCS11Constants { /** * This test compares the value of the PKCS11Constants that is maintained * by JSS against the values maintained by Sun in the equivalent methods. * * Note that this should only be run on JDK8, the last JDK to ship an * accessible set of PKCS11Constants */ public static void main(String[] args) throws Exception { // Query the two classes to get references to their definitions. Class jss = Class.forName("org.mozilla.jss.pkcs11.PKCS11Constants"); Class sun = Class.forName("sun.security.pkcs11.wrapper.PKCS11Constants"); assert(!jss.equals(sun)); // Get lists of all fields; lets us call the reflection seervices // once as they're likely slow. Field[] jss_fields = jss.getDeclaredFields(); Field[] sun_fields = sun.getDeclaredFields(); // To easily access the fields, build a HashMap of String->Field, // and maintain a set of all known field names. HashMap jss_map = new HashMap(); HashMap sun_map = new HashMap(); HashSet keys = new HashSet(); for (Field field : jss_fields) { jss_map.put(field.getName(), field); keys.add(field.getName()); } for (Field field : sun_fields) { sun_map.put(field.getName(), field); keys.add(field.getName()); } // For pretty output, sort keys first... String[] keys_sorted = new String[keys.size()]; keys_sorted = keys.toArray(keys_sorted); Arrays.sort(keys_sorted); for (String key : keys_sorted) { // If the field is present in both, validate that the value // is the same across JSS and Sun implementation. Otherwise, // output which implementation it is present in. if (jss_map.containsKey(key) && sun_map.containsKey(key)) { Field jss_field = jss_map.get(key); Field sun_field = sun_map.get(key); // Validate that types are correct before accessing... assert(jss_field.getType() == long.class); assert(sun_field.getType() == long.class); if (jss_field.getLong(null) != sun_field.getLong(null)) { System.err.println("Symbol: " + key + " - NOT OK!!\n"); System.err.println("\tJSS: " + jss_field.getLong(null)); System.err.println("\tSun: " + sun_field.getLong(null)); } assert(jss_field.getLong(null) == sun_field.getLong(null)); System.out.println("Field: " + key + " - OK"); } else if (jss_map.containsKey(key)) { System.err.println("Field: " + key + " - only JSS"); } else if (sun_map.containsKey(key)) { System.err.println("Field: " + key + " - only Sun"); } } } } jss-4.6.3/org/mozilla/jss/tests/TestPRFD.java000066400000000000000000000062601362106420000207560ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.mozilla.jss.nss.PR; import org.mozilla.jss.nss.PRErrors; import org.mozilla.jss.nss.PRFDProxy; public class TestPRFD { public static void TestPROpenNoCreate() { String name = "path_which_should_not_exist_on_any_reasonable_system"; PRFDProxy fd = PR.Open(name, 0x02, 00644); assert(fd == null); } public static void TestPROpenClose() { PRFDProxy fd = PR.Open("results/prfd_open_close", 0x04 | 0x08, 00644); assert(fd != null); assert(PR.Close(fd) == PR.SUCCESS); } public static void TestPROpenWriteClose() { PRFDProxy fd = PR.Open("results/prfd_open_write_close", 0x04 | 0x08, 00644); assert(fd != null); byte[] data = {0x2a, 0x20, 0x2a, 0x20}; assert(PR.Write(fd, data) == 4); assert(PR.Close(fd) == PR.SUCCESS); } public static void TestPRRead() { byte[] data = {0x2a, 0x20, 0x2a, 0x20}; PRFDProxy fd = PR.Open("results/prfd_open_write_close", 0x04, 00644); assert(fd != null); byte[] read_data = PR.Read(fd, 10); assert(read_data != null); assert(read_data.length == data.length); for (int i = 0; i < data.length; i++) { assert(read_data[i] == data[i]); } assert(PR.Close(fd) == PR.SUCCESS); } public static void TestPREmptyRead() { PRFDProxy fd = PR.Open("results/prfd_open_close", 0x04, 00644); assert(fd != null); byte[] read_data = PR.Read(fd, 10); assert(read_data == null || read_data.length == 0); assert(PR.Close(fd) == PR.SUCCESS); } public static void TestNewTCPSocket() { PRFDProxy fd = PR.NewTCPSocket(); assert(fd != null); } public static void TestShutdown() { PRFDProxy fd = PR.NewTCPSocket(); assert(fd != null); PR.Shutdown(fd, PR.SHUTDOWN_RCV); PR.Shutdown(fd, PR.SHUTDOWN_SEND); PR.Shutdown(fd, PR.SHUTDOWN_BOTH); assert(PR.Close(fd) == PR.SUCCESS); } public static void TestConstants() { // Test to ensure constants present System.out.println("PR.SHUTDOWN_RCV: " + PR.SHUTDOWN_RCV); System.out.println("PR.SHUTDOWN_SEND: " + PR.SHUTDOWN_SEND); System.out.println("PR.SHUTDOWN_BOTH: " + PR.SHUTDOWN_BOTH); assert(PR.ErrorToName(PRErrors.WOULD_BLOCK_ERROR).equals("PR_WOULD_BLOCK_ERROR")); } public static void main(String[] args) { System.loadLibrary("jss4"); System.out.println("Calling TestPROpenNoCreate()..."); TestPROpenNoCreate(); System.out.println("Calling TestPROpenClose()..."); TestPROpenClose(); System.out.println("Calling TestPROpenWriteClose()..."); TestPROpenWriteClose(); System.out.println("Calling TestPRRead()..."); TestPRRead(); System.out.println("Calling TestPREmptyRead()..."); TestPREmptyRead(); System.out.println("Calling TestNewTCPSocket()..."); TestNewTCPSocket(); System.out.println("Calling TestShutdown()..."); TestShutdown(); System.out.println("Calling TestConstants()..."); TestConstants(); } } jss-4.6.3/org/mozilla/jss/tests/TestRawSSL.java000066400000000000000000000105051362106420000213330ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.mozilla.jss.nss.PR; import org.mozilla.jss.nss.PRFDProxy; import org.mozilla.jss.nss.SSLFDProxy; import org.mozilla.jss.nss.SSL; import org.mozilla.jss.nss.SecurityStatusResult; import org.mozilla.jss.ssl.SSLCipher; public class TestRawSSL { public static void TestSSLImportFD() throws Exception { PRFDProxy fd = PR.NewTCPSocket(); assert(fd != null); SSLFDProxy ssl_fd = SSL.ImportFD(null, fd); assert(ssl_fd != null); assert(PR.Close(ssl_fd) == PR.SUCCESS); } public static void TestSSLOptions() throws Exception { PRFDProxy fd = PR.NewTCPSocket(); assert(fd != null); SSLFDProxy ssl_fd = SSL.ImportFD(null, fd); assert(ssl_fd != null); // 8 == SSL_ENABLE_SSL3; disable it assert(SSL.OptionSet(ssl_fd, 8, 0) == SSL.SECSuccess); // Validate that the set worked. assert(SSL.OptionGet(ssl_fd, 8) == SSL.SECSuccess); // Renable SSL_ENABLE_SSL3 and validate it worked assert(SSL.OptionSet(ssl_fd, 8, 1) == SSL.SECSuccess); assert(SSL.OptionGet(ssl_fd, 8) == 1); // Ensure that setting an invalid option fails assert(SSL.OptionSet(ssl_fd, 799999, 0) != SSL.SECSuccess); // Ensure that getting an invalid option fails try { SSL.OptionGet(ssl_fd, 79999999); assert(false); } catch (Exception e) { assert(true); } assert(PR.Close(ssl_fd) == PR.SUCCESS); } public static void TestSSLCipherPref() throws Exception { PRFDProxy fd = PR.NewTCPSocket(); assert(fd != null); SSLFDProxy ssl_fd = SSL.ImportFD(null, fd); assert(ssl_fd != null); int cipher = SSLCipher.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384.getID(); // Ensure that setting a ciphersuite works correctly assert(SSL.CipherPrefSet(ssl_fd, cipher, false) == SSL.SECSuccess); assert(SSL.CipherPrefGet(ssl_fd, cipher) == false); assert(SSL.CipherPrefSet(ssl_fd, cipher, true) == SSL.SECSuccess); assert(SSL.CipherPrefGet(ssl_fd, cipher) == true); // Ensure that using an invalid ciphersuite fails. assert(SSL.CipherPrefSet(ssl_fd, 0x999999, false) == SSL.SECFailure); try { SSL.CipherPrefGet(ssl_fd, 0x999999); assert(false); } catch (Exception e) { assert(true); } assert(PR.Close(ssl_fd) == PR.SUCCESS); } public static void TestSSLSetURL() throws Exception { PRFDProxy fd = PR.NewTCPSocket(); assert(fd != null); SSLFDProxy ssl_fd = SSL.ImportFD(null, fd); assert(ssl_fd != null); assert(SSL.SetURL(ssl_fd, "https://google.com") == SSL.SECSuccess); assert(PR.Close(ssl_fd) == PR.SUCCESS); } public static void TestSSLSecurityStatus() throws Exception { PRFDProxy fd = PR.NewTCPSocket(); assert(fd != null); SSLFDProxy ssl_fd = SSL.ImportFD(null, fd); assert(ssl_fd != null); SecurityStatusResult r = SSL.SecurityStatus(ssl_fd); assert(r.on == 0); // Validate toString works System.out.println(r.toString()); assert(PR.Close(ssl_fd) == PR.SUCCESS); } public static void TestSSLResetHandshake() throws Exception { PRFDProxy fd = PR.NewTCPSocket(); assert(fd != null); SSLFDProxy ssl_fd = SSL.ImportFD(null, fd); assert(SSL.ResetHandshake(ssl_fd, false) == SSL.SECSuccess); assert(PR.Close(ssl_fd) == PR.SUCCESS); } public static void main(String[] args) throws Exception { System.loadLibrary("jss4"); if (args.length != 1) { System.out.println("Usage: TestRawSSL /path/to/nssdb"); System.exit(1); } System.out.println("Calling TestSSLImportFD()..."); TestSSLImportFD(); System.out.println("Calling TestSSLOptions()..."); TestSSLOptions(); System.out.println("Calling TestSSLSetURL()..."); TestSSLSetURL(); System.out.println("Calling TestSSLCipherPref()..."); TestSSLCipherPref(); System.out.println("Calling TestSSLSecurityStatus()..."); TestSSLSecurityStatus(); System.out.println("Calling TestSSLResetHandshake()..."); TestSSLResetHandshake(); } } jss-4.6.3/org/mozilla/jss/tests/TestSDR.java000066400000000000000000000063371362106420000206600ustar00rootroot00000000000000/* 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.tests; import java.security.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.*; import org.mozilla.jss.SecretDecoderRing.*; import javax.crypto.*; /** * Secret Decoder ring tests. */ public class TestSDR { public static final EncryptionAlgorithm encAlg = EncryptionAlgorithm.DES3_CBC; public static final KeyGenAlgorithm keyGenAlg = KeyGenAlgorithm.DES3; public static void main(String[] args) throws Exception { if( args.length != 2 ) { throw new Exception("Usage: java TestSDR "); } CryptoManager.initialize(args[0]); CryptoManager cm = CryptoManager.getInstance(); cm.setPasswordCallback( new FilePasswordCallback(args[1]) ); CryptoToken ksToken = cm.getInternalKeyStorageToken(); // // test key management // KeyManager km = new KeyManager(ksToken); byte[] keyID = km.generateKey(keyGenAlg, 0); System.out.println("Successfully generated key"); SecretKey key = km.lookupKey(encAlg, keyID); if( key == null ) { throw new Exception("Error: generated key not found"); } System.out.println("Successfully looked up key"); km.deleteKey(keyID); System.out.println("Successfully deleted key"); key = km.lookupKey(encAlg, keyID); if( key != null ) { throw new Exception("Deleted key still found"); } System.out.println("Good: deleted key not found"); // // test encryption/decryption // keyID = km.generateKey(keyGenAlg, 0); Encryptor encryptor = new Encryptor(ksToken, keyID, encAlg); byte[] plaintext = "Hello, world!".getBytes("UTF-8"); byte[] ciphertext = encryptor.encrypt(plaintext); System.out.println("Successfully encrypted plaintext"); Decryptor decryptor = new Decryptor(ksToken); byte[] recovered = decryptor.decrypt(ciphertext); System.out.println("Decrypted ciphertext"); if( plaintext.length != recovered.length ) { throw new Exception( "Recovered plaintext does not match original plaintext"); } for(int i=0; i < plaintext.length; ++i) { if( plaintext[i] != recovered[i] ) { throw new Exception( "Recovered plaintext does not match original plaintext"); } } System.out.println("Decrypted ciphertext matches original plaintext"); // delete the key and try to decrypt. Decryption should fail. km.deleteKey(keyID); try { recovered = decryptor.decrypt(ciphertext); throw new Exception( "Error: successfully decrypted with deleted key"); } catch (InvalidKeyException ike) { } System.out.println( "Good: as expected did not decrypt plaintext with a " + "deleted key"); System.out.println("TestSDR: Success"); System.exit(0); } } jss-4.6.3/org/mozilla/jss/tests/UTF8ConverterTest.java000066400000000000000000000041051362106420000226350ustar00rootroot00000000000000/* 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.tests; import java.io.ByteArrayOutputStream; import java.io.OutputStreamWriter; import org.apache.commons.lang.RandomStringUtils; import org.mozilla.jss.util.Assert; import org.mozilla.jss.util.UTF8Converter; public class UTF8ConverterTest { public UTF8ConverterTest() throws Exception { } public void testUnicodeToUTF8() throws Exception { // Verify UnicodeToUTF8 by comparing its output // to that of the standard Java conversion routines. String input = RandomStringUtils.random(10); char[] unicode = input.toCharArray(); System.out.print("Input:"); for (int c : unicode) { System.out.print(String.format(" %04x", c)); } System.out.println(); byte[] utf8 = UTF8Converter.UnicodeToUTF8(unicode); System.out.print("Output 1:"); for (byte b : utf8) { System.out.print(String.format(" %02x", b)); } System.out.println(); ByteArrayOutputStream barray = new ByteArrayOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(barray, "UTF8"); writer.write(unicode, 0, unicode.length); writer.close(); byte[] output = barray.toByteArray(); System.out.print("Output 2:"); for (byte b : output) { System.out.print(String.format(" %02x", b)); } System.out.println(); assert(utf8 != null); assert(utf8.length == output.length); for(int i=0; i " + " " + "\n"); System.out.println(" " + " " + "\n"); System.out.println("Note: and " + " are optional.\n But if used, " + "both Url/nickname must be specified."); } public static void main(String args[]) { try { VerifyCert vc = new VerifyCert(); if ( args.length < 3 ) { vc.usage(); return; } String dbdir = args[0]; String password = args[1]; String name = args[2]; String ResponderURL = null; String ResponderNickname = null; //if OCSPResponderURL than must have OCSPCertificateNickname if (args.length == 4 || args.length > 5) vc.usage(); else if (args.length == 5) { ResponderURL= args[3]; ResponderNickname = args[4]; } //initialize JSS InitializationValues vals = new InitializationValues(dbdir); //enable PKIX verify rather than the old NSS cert library, //to verify certificates. vals.PKIXVerify = true; // as a JSS test set the initialize for cooperate to true // One would set this to true if one configured NSS with // to use other PKCS11 modules. vals.cooperate = true; // configure OCSP vals.ocspCheckingEnabled = true; if (ResponderURL != null && ResponderNickname != null) { vals.ocspResponderCertNickname = ResponderNickname; vals.ocspResponderURL = ResponderURL; } CryptoManager.initialize(vals); CryptoManager cm = CryptoManager.getInstance(); PasswordCallback pwd = new Password(password.toCharArray()); cm.setPasswordCallback(pwd); try (FileInputStream fin = new FileInputStream(name)) { byte[] pkg = new byte[fin.available()]; fin.read(pkg); //display the cert vc.showCert(name); //validate the cert vc.validateDerCert(pkg, cm); } catch (java.io.FileNotFoundException e) { //assume name is a nickname of cert in the db vc.validateCertInDB(name, cm); } } catch ( Exception e ) { e.printStackTrace(); System.exit(1); } } public void validateDerCert(byte[] pkg, CryptoManager cm){ ArrayList usageList = new ArrayList<>(); try { Iterator list = CertUsage.getCertUsages(); CertUsage certUsage; while(list.hasNext()) { certUsage = list.next(); if ( !certUsage.equals(CertUsage.UserCertImport) && !certUsage.equals(CertUsage.ProtectedObjectSigner) && !certUsage.equals(CertUsage.AnyCA) ) { if (cm.isCertValid(pkg, true, certUsage) == true) { usageList.add(certUsage.toString()); } } } } catch (Exception e) { e.printStackTrace(); } if (usageList.isEmpty()) { System.out.println("The certificate is not valid."); } else { System.out.println("The certificate is valid for " + "the following usages:\n"); Iterator iterateUsage = usageList.iterator(); while (iterateUsage.hasNext()) { System.out.println(" " + iterateUsage.next()); } } } public void validateCertInDB(String nickname, CryptoManager cm){ ArrayList usageList = new ArrayList<>(); try { Iterator list = CertUsage.getCertUsages(); CertUsage certUsage; while(list.hasNext()) { certUsage = list.next(); if ( !certUsage.equals(CertUsage.UserCertImport) && !certUsage.equals(CertUsage.ProtectedObjectSigner) && !certUsage.equals(CertUsage.AnyCA) ) { if (cm.isCertValid(nickname, true, certUsage) == true) { usageList.add(certUsage.toString()); } } } } catch (Exception e) { e.printStackTrace(); } if (usageList.isEmpty()) { System.out.println("The certificate is not valid."); } else { System.out.println("The certificate is valid for the " + "following usages:\n"); Iterator iterateUsage = usageList.iterator(); while (iterateUsage.hasNext()) { System.out.println(" " + iterateUsage.next()); } } } } jss-4.6.3/org/mozilla/jss/tests/X509CertTest.java000066400000000000000000000246541362106420000215150ustar00rootroot00000000000000/* 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.tests; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.PrivateKey; import java.security.cert.CertificateException; import java.security.interfaces.RSAPublicKey; import java.security.interfaces.ECPublicKey; import java.security.interfaces.ECPrivateKey; import java.util.Base64; import java.util.Calendar; import java.util.Date; import org.mozilla.jss.CertificateUsage; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.KeyPairGenerator; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.netscape.security.util.BigInt; import org.mozilla.jss.netscape.security.util.DerValue; import org.mozilla.jss.netscape.security.x509.AlgorithmId; import org.mozilla.jss.netscape.security.x509.CertificateAlgorithmId; import org.mozilla.jss.netscape.security.x509.CertificateExtensions; import org.mozilla.jss.netscape.security.x509.CertificateIssuerName; import org.mozilla.jss.netscape.security.x509.CertificateSerialNumber; import org.mozilla.jss.netscape.security.x509.CertificateSubjectName; import org.mozilla.jss.netscape.security.x509.CertificateValidity; import org.mozilla.jss.netscape.security.x509.CertificateVersion; import org.mozilla.jss.netscape.security.x509.CertificateX509Key; import org.mozilla.jss.netscape.security.x509.X500Name; import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.mozilla.jss.netscape.security.x509.X509CertInfo; import org.mozilla.jss.netscape.security.x509.X509Key; import org.mozilla.jss.pkcs11.PK11ECPublicKey; import org.mozilla.jss.util.PasswordCallback; public class X509CertTest { public static String subjectDN = "CN = 8a99f98342b97d130142ba2cc30f07d3"; public static String issuerDN = "C = US, ST = North Carolina, O = Red Hat Inc., OU = Red Hat Network, CN = Red Hat Candlepin Authority, E = ca-support@redhat.com "; /* Just some sample code to exercise the new classes */ public static void main(String []args) throws Exception { if( args.length != 2 ) { System.out.println("Usage: X509CertTest "); return; } String dbdir = args[0]; String passwordfile = args[1]; Date notBefore = new Date(); Calendar cal = Calendar.getInstance(); cal.setTime(notBefore); cal.set(Calendar.YEAR, 2037); Date notAfter = cal.getTime(); //Generate ca keyPair CryptoManager.initialize(dbdir); CryptoManager cryptoManager = CryptoManager.getInstance(); CryptoToken token = cryptoManager.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(passwordfile); token.login(cb); testEC(token, notBefore, notAfter); testRSA(token, notBefore, notAfter); testImport(); } public static void testEC(CryptoToken token, Date notBefore, Date notAfter) throws Exception { X509CertImpl certImpl = null; X509CertInfo certInfo = null; KeyPairGenerator gen = token.getKeyPairGenerator(KeyPairAlgorithm.EC); gen.initialize(gen.getCurveCodeByName("secp521r1")); KeyPair keypairCA = gen.genKeyPair(); testKeys(keypairCA); PublicKey pubCA = keypairCA.getPublic(); gen.initialize(gen.getCurveCodeByName("secp521r1")); KeyPair keypairUser = gen.genKeyPair(); testKeys(keypairUser); PublicKey pubUser = keypairUser.getPublic(); CertificateIssuerName issuernameObj = new CertificateIssuerName(new X500Name(issuerDN)); certInfo = createX509CertInfo(convertPublicKeyToX509Key(pubUser), BigInteger.valueOf(1),issuernameObj,subjectDN, notBefore, notAfter, "SHA256withEC"); certImpl = new X509CertImpl(certInfo); certImpl.sign(keypairCA.getPrivate(),"SHA256withEC"); String certOutput = certImpl.toString(); System.out.println("Test certificate output: \n" + certOutput); } public static void testRSA(CryptoToken token, Date notBefore, Date notAfter) throws Exception { X509CertImpl certImpl = null; X509CertInfo certInfo = null; KeyPairGenerator gen = token.getKeyPairGenerator(KeyPairAlgorithm.RSA); gen.initialize(4096); KeyPair keypairCA = gen.genKeyPair(); testKeys(keypairCA); PublicKey pubCA = keypairCA.getPublic(); gen.initialize(4096); KeyPair keypairUser = gen.genKeyPair(); testKeys(keypairUser); PublicKey pubUser = keypairUser.getPublic(); CertificateIssuerName issuernameObj = new CertificateIssuerName(new X500Name(issuerDN)); certInfo = createX509CertInfo(convertPublicKeyToX509Key(pubUser), BigInteger.valueOf(1),issuernameObj,subjectDN, notBefore, notAfter, "SHA256withRSA"); certImpl = new X509CertImpl(certInfo); certImpl.sign(keypairCA.getPrivate(),"SHA256withRSA"); String certOutput = certImpl.toString(); System.out.println("Test certificate output: \n" + certOutput); } public static void testKeys(KeyPair keypair) throws Exception { PublicKey pubKey = keypair.getPublic(); PrivateKey privKey = keypair.getPrivate(); if (pubKey instanceof ECPublicKey) { assert(privKey instanceof ECPrivateKey); ECPublicKey ecPub = (ECPublicKey)pubKey; ECPrivateKey ecPriv = (ECPrivateKey)privKey; // Two public functions we want to test on ECPublicKey: // 1. getW() -> ECPoint // 2. getParams() -> ECParameterSpec assert(ecPub.getW() != null); assert(ecPub.getW().getAffineX() != null); assert(ecPub.getW().getAffineY() != null); assert(ecPub.getParams() != null); assert(ecPriv.getParams() != null); // Since ECParameterSpec doesn't define a comparator, we have to // check each member individually. assert(ecPub.getParams().getCofactor() == ecPriv.getParams().getCofactor()); assert(ecPub.getParams().getCurve().equals(ecPriv.getParams().getCurve())); assert(ecPub.getParams().getGenerator().getAffineX().equals(ecPriv.getParams().getGenerator().getAffineX())); assert(ecPub.getParams().getGenerator().getAffineY().equals(ecPriv.getParams().getGenerator().getAffineY())); assert(ecPub.getParams().getOrder().equals(ecPriv.getParams().getOrder())); } } public static X509CertInfo createX509CertInfo(X509Key x509key, BigInteger serialno, CertificateIssuerName issuernameObj, String subjname, Date notBefore, Date notAfter, String alg) throws Exception { X509CertInfo info = new X509CertInfo(); info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)); info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(serialno)); if (issuernameObj != null) { info.set(X509CertInfo.ISSUER, issuernameObj); } info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(new X500Name(subjname))); info.set(X509CertInfo.VALIDITY, new CertificateValidity(notBefore, notAfter)); info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(AlgorithmId.get(alg))); info.set(X509CertInfo.KEY, new CertificateX509Key(x509key)); info.set(X509CertInfo.EXTENSIONS, new CertificateExtensions()); return info; } public static X509Key convertPublicKeyToX509Key(PublicKey pubk) throws Exception { X509Key xKey = null; if (pubk instanceof RSAPublicKey) { RSAPublicKey rsaKey = (RSAPublicKey) pubk; xKey = new org.mozilla.jss.netscape.security.provider.RSAPublicKey( new BigInt(rsaKey.getModulus()), new BigInt(rsaKey.getPublicExponent())); } else if (pubk instanceof PK11ECPublicKey) { byte encoded[] = pubk.getEncoded(); xKey = X509Key.parse(new DerValue(encoded)); } return xKey; } public static void testImport() throws Exception { CryptoManager cryptoManager = CryptoManager.getInstance(); byte[] cert = Base64.getDecoder().decode( "MIIDRjCCAi6gAwIBAgIJAMHiDXjnZ1J6MA0GCSqGSIb3DQEBCwUAMDgxEDAOBgNV" + "BAoMB0VYQU1QTEUxJDAiBgNVBAMMG1Jvb3QgQ0EgU2lnbmluZyBDZXJ0aWZpY2F0" + "ZTAeFw0xOTAzMDUxNzQzMjFaFw0yMDAzMDQxNzQzMjFaMDgxEDAOBgNVBAoMB0VY" + "QU1QTEUxJDAiBgNVBAMMG1Jvb3QgQ0EgU2lnbmluZyBDZXJ0aWZpY2F0ZTCCASIw" + "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMDv7ovkD+JVEdlLncYDnhzbLOz2" + "c3D37fobufnHHNwNOwfLZj8WdBCzwGJv+XGF+D2JIcKyYwYPR+HOg+xClhuuVleE" + "gMVvgxM+HcpM4heyBD2QczNo1dfXQRBy2AXvRn8Byh+Q6zbN7VoNu8ZaMQOxZx9m" + "EAiDZ7WxHVrEp2a4QrI6I9gKY6SyEHRzVT48JElLFokwhkMpF8vhgtj0Xxr5EEIY" + "yCMOzvZLtpeyH8PUri3Cv/hX1RZKjWqKLSJSKirnZLhZoEEzXtsOmoeeZBeRiabi" + "dPLsxqPfWFx4+BC7t5Vw5FaIt2mPh+q6bjZipO4uWz/p4a9wpqakuzgNsYUCAwEA" + "AaNTMFEwHQYDVR0OBBYEFCvlfY9OzAVsYpJEoqr7QfguO9v5MB8GA1UdIwQYMBaA" + "FCvlfY9OzAVsYpJEoqr7QfguO9v5MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + "AQELBQADggEBAHB1lWjT6bP1jAkk6eTVwBU2pGoGoYMGV3fWQGOmWQP5T7+nHKkU" + "jNMRACoC2hFlypwX8qQ70V5O4U+qrnxDP3EaT1zPsOB0x4DIIrpFgudL9EqnSbJ0" + "kvSz3awwO8x/Nvx7TatCncmTw9c14eqek2puhcQWvxHzWkaDHd9WxPrZJFftbSsn" + "ZGK2A/ybDCnUA5BDeCSDb5gufTd8gbS4wS1NwYcbbrQyHnLJlFcIF4aLkbYuX1bn" + "cYp8pQv3pZ3C/ofA+yBJvPELTaHjDC40MTdjFFfMQTPZswBX2iimoGQ/ProBGg7+" + "rLg2uk5AHff3oo/V1X0SSzo3IpvHh0jhg9I=" ); X509Certificate ret = cryptoManager.importDERCert(cert, CertificateUsage.SSLCA, false, null); assert(ret != null); } } jss-4.6.3/org/mozilla/jss/tests/bbenvSample.sh000066400000000000000000000050161362106420000213100ustar00rootroot00000000000000#! /bin/bash ############################################################################## # Update java-1.8.0-openjdk to the latest and then do # sudo /usr/sbin/alternatives --config java and hit enter # # For example, to check/select your Java version on Linux: # # sudo /usr/sbin/alternatives --config java # # There is 1 program that provides 'java'. # # Selection Command # ----------------------------------------------- # *+ 1 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-3.b16.fc24.x86_64/jre/bin/java) # # Hit Enter to keep the current selection[+], or type selection number: # # You may have multiple entries (like on RHEl-7.x) or only one # This is for linux. On macOS you'll have something like this # JAVA_HOME_64=/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home # ############################################################################## # Each buildbot-slave requires a bbenv.sh file that defines # machine specific variables. This is an example file. HOST=$(hostname | cut -d. -f1) export HOST # if your machine's IP isn't registered in DNS, # you must set appropriate environment variables # that can be resolved locally. # For example, if localhost.localdomain works on your system, set: DOMSUF=localdomain export DOMSUF ARCH=$(uname -s) ulimit -c unlimited 2> /dev/null export NSPR_LOG_MODULES="pkix:1" #export JAVA_HOME_32= #export JAVA_HOME_64= #enable if you have PKITS data export PKITS_DATA=$HOME/pkits/ NSS_BUILD_TARGET="clean nss_build_all" JSS_BUILD_TARGET="clean all" MAKE=make AWK=awk PATCH=patch if [ "${ARCH}" = "SunOS" ]; then AWK=nawk PATCH=gpatch ARCH=SunOS/$(uname -p) fi if [ "${ARCH}" = "Linux" -a -f /etc/system-release ]; then #VERSION=`sed -e 's; release ;;' -e 's; (.*)$;;' -e 's;Red Hat Enterprise Linux Server;RHEL;' -e 's;Red Hat Enterprise Linux Workstation;RHEL;' /etc/system-release` VERSION=$(uname -r | awk -F"." '{ print $1 "." $2 }') ARCH=Linux/4.8 echo ${ARCH} fi PROCESSOR=$(uname -p) if [ "${PROCESSOR}" = "ppc64" ]; then ARCH="${ARCH}/ppc64" fi if [ "${PROCESSOR}" = "powerpc" ]; then ARCH="${ARCH}/ppc" fi PORT_64_DBG=8543 PORT_64_OPT=8544 PORT_32_DBG=8545 PORT_32_OPT=8546 if [ "${NSS_TESTS}" = "memleak" ]; then PORT_64_DBG=8547 PORT_64_OPT=8548 PORT_32_DBG=8549 PORT_32_OPT=8550 fi # change to suit your environent, refer to the instructions on how to do it # at the top of this file JAVA_HOME_64=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-3.b16.fc25.x86_64 export NSS_FORCE_FIPS=1 jss-4.6.3/org/mozilla/jss/tests/buffer_size_1.c000066400000000000000000000506211362106420000214070ustar00rootroot00000000000000#include "j_buffer.h" #include "assert.h" #include #include void test_jb(uint8_t* d) { j_buffer* b = jb_alloc(1); jb_free(b); b = jb_alloc(1); size_t r_o = 0; size_t w_o = 0; int i_r = 0; size_t s_r = 0; uint8_t* r_b = calloc(6, sizeof(uint8_t)); printf("Testing get+put\n"); // pc=0 gc=0 // pc=0 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=0 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=1 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } // pc=1 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=1 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=2 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } // pc=2 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=2 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } printf("Testing write+get\n"); // ws=0 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } // ws=0 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=0 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=1 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } // ws=1 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=1 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=2 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } // ws=2 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=2 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } printf("Testing put+read\n"); // pc=0 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=0 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=0 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=1 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=1 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=1 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=2 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=2 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=2 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } printf("Testing write+read\n"); // ws=0 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=0 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=0 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=1 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=1 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=1 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=2 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=2 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=2 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 1); assert(((w_o - r_o) < 1) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } } int main() { uint8_t* d = (uint8_t*)"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu"; test_jb(d); return 0; } jss-4.6.3/org/mozilla/jss/tests/buffer_size_4.c000066400000000000000000004103671362106420000214210ustar00rootroot00000000000000#include "j_buffer.h" #include "assert.h" #include #include void test_jb(uint8_t* d) { j_buffer* b = jb_alloc(4); jb_free(b); b = jb_alloc(4); size_t r_o = 0; size_t w_o = 0; int i_r = 0; size_t s_r = 0; uint8_t* r_b = calloc(9, sizeof(uint8_t)); printf("Testing get+put\n"); // pc=0 gc=0 // pc=0 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=0 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=0 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=0 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=0 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=1 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } // pc=1 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=1 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=1 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=1 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=1 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=2 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } // pc=2 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=2 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=2 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=2 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=2 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=3 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } // pc=3 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=3 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=3 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=3 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=3 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=4 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } // pc=4 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=4 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=4 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=4 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=4 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=5 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } // pc=5 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=5 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=5 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=5 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // pc=5 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } printf("Testing write+get\n"); // ws=0 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } // ws=0 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=0 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=0 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=0 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=0 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=1 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } // ws=1 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=1 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=1 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=1 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=1 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=2 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } // ws=2 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=2 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=2 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=2 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=2 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=3 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } // ws=3 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=3 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=3 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=3 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=3 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=4 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } // ws=4 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=4 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=4 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=4 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=4 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=5 gc=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } // ws=5 gc=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=5 gc=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=5 gc=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=5 gc=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } // ws=5 gc=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_get(b); if (i_r != EOF) { assert(((uint8_t)i_r) == ((uint8_t)d[r_o])); r_o += 1; } printf("Testing put+read\n"); // pc=0 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=0 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=0 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=0 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=0 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=0 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=1 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=1 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=1 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=1 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=1 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=1 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=2 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=2 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=2 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=2 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=2 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=2 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=3 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=3 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=3 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=3 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=3 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=3 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=4 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=4 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=4 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=4 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=4 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=4 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=5 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=5 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=5 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=5 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=5 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // pc=5 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); i_r = jb_put(b, d[w_o]); if (i_r != EOF) { w_o += 1; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } printf("Testing write+read\n"); // ws=0 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=0 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=0 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=0 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=0 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=0 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 0); if (s_r != 0) { assert(s_r <= 0); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=1 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=1 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=1 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=1 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=1 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=1 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 1); if (s_r != 0) { assert(s_r <= 1); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=2 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=2 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=2 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=2 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=2 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=2 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 2); if (s_r != 0) { assert(s_r <= 2); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=3 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=3 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=3 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=3 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=3 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=3 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 3); if (s_r != 0) { assert(s_r <= 3); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=4 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=4 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=4 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=4 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=4 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=4 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 4); if (s_r != 0) { assert(s_r <= 4); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=5 rs=0 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 0); if (s_r != 0) { assert(s_r <= 0); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=5 rs=1 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 1); if (s_r != 0) { assert(s_r <= 1); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=5 rs=2 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 2); if (s_r != 0) { assert(s_r <= 2); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=5 rs=3 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 3); if (s_r != 0) { assert(s_r <= 3); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=5 rs=4 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 4); if (s_r != 0) { assert(s_r <= 4); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } // ws=5 rs=5 assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_write(b, d + w_o, 5); if (s_r != 0) { assert(s_r <= 5); w_o += s_r; } assert(r_o <= w_o); assert((r_o < w_o) == jb_can_read(b)); assert((w_o - r_o) <= 4); assert(((w_o - r_o) < 4) == jb_can_write(b)); s_r = jb_read(b, r_b, 5); if (s_r != 0) { assert(s_r <= 5); for (size_t i = 0; i < s_r; i++) { assert(d[r_o] == r_b[i]); r_o += 1; } } } int main() { uint8_t* d = (uint8_t*)"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs"; test_jb(d); return 0; } jss-4.6.3/org/mozilla/jss/tests/passwords000066400000000000000000000001251362106420000204620ustar00rootroot00000000000000Internal\ Key\ Storage\ Token=m1oZilla NSS\ FIPS\ 140-2\ User\ Private\ Key=m1oZilla jss-4.6.3/org/mozilla/jss/tests/runSample.sh000066400000000000000000000006621362106420000210220ustar00rootroot00000000000000#!/usr/bin/bash # NOTE: Read the notes at the top of bbenv.sh on how to set things up for # different systems # define a COMPILER_TAG to sync NSS and JSS 'OBJDIR_NAME' directory names export COMPILER_TAG=_gcc export NSPR_DS_INCLUDE=`pwd`/hg/nspr/lib/ds export RUN_BITS=64 export RUN_OPT=DBG export ENVVARS=`pwd`/bbenv.sh # --test-nss ./hg/nss/automation/buildbot-slave/build.sh --build-nss --build-jss --test-jss --nojsssign jss-4.6.3/org/mozilla/jss/tests/startJssSelfServ.sh000077500000000000000000000014431362106420000223440ustar00rootroot00000000000000#!/bin/sh # # 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/. ######################################################################## # # "Starting JSS JSS_SelfServServer..." # JSS_CLASSPATH=$1 TESTDIR=$2 HOSTNAME=$3 PORT=$4 shift 4 JAVA_BIN_AND_OPT=$@ if [ -z "$JAVA_BIN_AND_OPT" ] ; then JAVA_BIN_AND_OPT=${JAVA_HOME}/bin/java fi echo "${JAVA_BIN_AND_OPT} -classpath ${JSS_CLASSPATH} org.mozilla.jss.tests.JSS_SelfServServer ${TESTDIR} passwords ${HOSTNAME} false ${PORT} verboseoff &" ${JAVA_BIN_AND_OPT} -classpath ${JSS_CLASSPATH} org.mozilla.jss.tests.JSS_SelfServServer ${TESTDIR} passwords ${HOSTNAME} false ${PORT} verboseoff & jss-4.6.3/org/mozilla/jss/tests/startJssServ.sh000077500000000000000000000012141362106420000215260ustar00rootroot00000000000000#!/bin/sh # # 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/. ######################################################################## # # "Starting JSS JAA_SSLServer..." # JSS_CLASSPATH=$1 TESTDIR=$2 Port=$3 FipsMode=$4 shift 4 JAVA_BIN_AND_OPT=$@ if [ -z "$JAVA_BIN_AND_OPT" ] ; then JAVA_BIN_AND_OPT=${JAVA_HOME}/bin/java fi ${JAVA_BIN_AND_OPT} -classpath ${JSS_CLASSPATH} org.mozilla.jss.tests.JSS_SSLServer ${TESTDIR} passwords localhost JSSTestServerCert true ${Port} ${FipsMode} & jss-4.6.3/org/mozilla/jss/tests/startJsseServ.sh000077500000000000000000000023101362106420000216710ustar00rootroot00000000000000#!/bin/sh # # 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/. ######################################################################## # # "Starting JSSE JSSE_SSLServer Test..." # JSS_CLASSPATH=$1 Port=$2 ClientAuth=$3 TestDir=$4 dbFile=$5 provider=$6 nssConfigFile=$7 nssPWFile=$8 shift 8 JAVA_BIN_AND_OPT=$@ if [ -z "$JAVA_BIN_AND_OPT" ] ; then JAVA_BIN_AND_OPT=${JAVA_HOME}/bin/java fi #echo "command" #echo "JSS_CLASSPATH=${JSS_CLASSPATH}" #echo "Port=${Port}" #echo "ClientAuth=${ClientAuth}" #echo "TestDir=${TestDir}" #echo "dbFile=${dbFile}" #echo "provider=${provider}" #echo "nssConfigFile=${nssConfigFile}" #echo "nssPWFile=${nssPWFile}" #echo "JAVA_BIN_AND_OPT=${JAVA_BIN_AND_OPT}" echo "${JAVA_BIN_AND_OPT} -classpath ${JSS_CLASSPATH} org.mozilla.jss.tests.JSSE_SSLServer ${Port} TLS ${ClientAuth} ${TestDir} ${dbFile} ${provider} ${nssConfigFile} ${nssPWFile}&" echo "command" ${JAVA_BIN_AND_OPT} -classpath ${JSS_CLASSPATH} org.mozilla.jss.tests.JSSE_SSLServer ${Port} TLS ${ClientAuth} ${TestDir} ${dbFile} ${provider} ${nssConfigFile} ${nssPWFile}& jss-4.6.3/org/mozilla/jss/tests/unix.sh000066400000000000000000000147221362106420000200410ustar00rootroot00000000000000# # 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/. #!/usr/bin/tcsh if ( `uname` == "AIX" ) then setenv LIBPATH ../../../../../dist/AIX4.2_DBG.OBJ/lib:/share/builds/components/jdk/1.1.6/AIX/lib/aix/native_threads echo Testing \"jssjava\" on `uname` `uname -v`.`uname -r` DBG platform . . . ../../../../../dist/AIX4.2_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/AIX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -v`.`uname -r` DBG platform . . . ../../../../../dist/AIX4.2_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/AIX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 setenv LIBPATH ../../../../../dist/AIX4.2_OPT.OBJ/lib:/share/builds/components/jdk/1.1.6/AIX/lib/aix/native_threads echo Testing \"jssjava\" on `uname` `uname -v`.`uname -r` OPT platform . . . ../../../../../dist/AIX4.2_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/AIX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 else if ( `uname` == "HP-UX" ) then setenv SHLIB_PATH ../../../../../dist/HP-UXB.11.00_DBG.OBJ/lib:/share/builds/components/jdk/1.1.5/HP-UX/lib/PA_RISC/native_threads echo Testing \"jssjava\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/HP-UXB.11.00_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/HP-UX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/HP-UXB.11.00_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/HP-UX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 setenv SHLIB_PATH ../../../../../dist/HP-UXB.11.00_OPT.OBJ/lib:/share/builds/components/jdk/1.1.5/HP-UX/lib/PA_RISC/native_threads echo Testing \"jssjava\" on `uname` `uname -r` OPT platform . . . ../../../../../dist/HP-UXB.11.00_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/HP-UX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 else if ( ( `uname` == "IRIX" ) || ( `uname` == "IRIX64" ) ) then setenv LD_LIBRARY_PATH ../../../../../dist/IRIX6.2_PTH_DBG.OBJ/lib:/share/builds/components/jdk/1.1.5/IRIX/lib32/sgi/native_threads echo Testing \"jssjava\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/IRIX6.2_PTH_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/IRIX/lib/rt.jar org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/IRIX6.2_PTH_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/IRIX/lib/rt.jar org.mozilla.jss.crypto.PQGGen 512 setenv LD_LIBRARY_PATH ../../../../../dist/IRIX6.2_PTH_OPT.OBJ/lib:/share/builds/components/jdk/1.1.5/IRIX/lib32/sgi/native_threads echo Testing \"jssjava\" on `uname` `uname -r` OPT platform . . . ../../../../../dist/IRIX6.2_PTH_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/IRIX/lib/rt.jar org.mozilla.jss.crypto.PQGGen 512 else if ( `uname` == "OSF1" ) then setenv LD_LIBRARY_PATH ../../../../../dist/OSF1V4.0D_DBG.OBJ/lib:/share/builds/components/jdk/1.1.6/OSF1/lib/alpha echo Testing \"jssjava\" on `uname` `uname -r`D DBG platform . . . ../../../../../dist/OSF1V4.0D_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/OSF1/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -r`D DBG platform . . . ../../../../../dist/OSF1V4.0D_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/OSF1/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 setenv LD_LIBRARY_PATH ../../../../../dist/OSF1V4.0D_OPT.OBJ/lib:/share/builds/components/jdk/1.1.6/OSF1/lib/alpha echo Testing \"jssjava\" on `uname` `uname -r`D OPT platform . . . ../../../../../dist/OSF1V4.0D_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/OSF1/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 else if ( ( `uname` == "SunOS" ) && ( `uname -r` == "5.5.1" ) ) then setenv LD_LIBRARY_PATH ../../../../../dist/SunOS5.5.1_DBG.OBJ/lib:/share/builds/components/jdk/1.1.6/SunOS/lib/sparc/native_threads echo Testing \"jssjava\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/SunOS5.5.1_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/SunOS5.5.1_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 setenv LD_LIBRARY_PATH ../../../../../dist/SunOS5.5.1_OPT.OBJ/lib:/share/builds/components/jdk/1.1.6/SunOS/lib/sparc/native_threads echo Testing \"jssjava\" on `uname` `uname -r` OPT platform . . . ../../../../../dist/SunOS5.5.1_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 else if ( ( `uname` == "SunOS" ) && ( `uname -r` == "5.6" ) ) then setenv LD_LIBRARY_PATH ../../../../../dist/SunOS5.6_DBG.OBJ/lib:/share/builds/components/jdk/1.1.6/SunOS/lib/sparc/native_threads echo Testing \"jssjava\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/SunOS5.6_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/SunOS5.6_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 setenv LD_LIBRARY_PATH ../../../../../dist/SunOS5.6_OPT.OBJ/lib:/share/builds/components/jdk/1.1.6/SunOS/lib/sparc/native_threads echo Testing \"jssjava\" on `uname` `uname -r` OPT platform . . . ../../../../../dist/SunOS5.6_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 endif jss-4.6.3/org/mozilla/jss/util/000077500000000000000000000000001362106420000163275ustar00rootroot00000000000000jss-4.6.3/org/mozilla/jss/util/Assert.java000066400000000000000000000040241362106420000204330ustar00rootroot00000000000000/* 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.util; /** * C-style assertions in Java. * * @see org.mozilla.jss.util.AssertionException * @version $Revision$ $Date$ */ public class Assert { /** * Assert that a condition is true. If it is not true, abort by * throwing an AssertionException. * * @param cond The condition that is being tested. * @deprecated The assert keyword should be used instead. */ @Deprecated public static void _assert(boolean cond) { if(!cond) { throw new org.mozilla.jss.util.AssertionException( "assertion failure!"); } } /** * Assert that a condition is true. If it is not true, abort by throwing * an AssertionException. * * @param cond The condition that is being tested. * @param msg A message describing what is wrong if the condition is false. * @deprecated The assert keyword should be used instead. */ @Deprecated public static void _assert(boolean cond, String msg) { if(!cond) { throw new org.mozilla.jss.util.AssertionException(msg); } } /** * Throw an AssertionException if this statement is reached. * * @param msg A message describing what was reached. */ public static void notReached(String msg) { throw new AssertionException("should not be reached: " + msg); } /** * Throw an AssertionException if this statement is reached. */ public static void notReached() { throw new AssertionException("should not be reached"); } /** * Throw an AssertionException because functionality is not yet implemented. * * @param msg A message describing what is not implemented. */ public static void notYetImplemented(String msg) { throw new AssertionException("not yet implemented: " + msg); } } jss-4.6.3/org/mozilla/jss/util/AssertionException.java000066400000000000000000000020521362106420000230170ustar00rootroot00000000000000/* 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.util; /** * Assertion exceptions are thrown when assertion code is invoked * and fails to operate properly. They subclass Error, so they will * not be caught by exception handlers. Instead, they will cause the * VM to halt and print a stack trace. * * @see org.mozilla.jss.util.Assert * @version $Revision$ $Date$ */ public class AssertionException extends RuntimeException { private static final long serialVersionUID = 1L; public AssertionException() {} public AssertionException(String mesg) { super(mesg); } public AssertionException(String mesg, Throwable cause) { super(mesg, cause); } public AssertionException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/util/Base64InputStream.java000066400000000000000000000172721362106420000224230ustar00rootroot00000000000000/* 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.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.FileInputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.util.Arrays; /** * Reads in base-64 encoded input and spits out the raw binary decoding. */ public class Base64InputStream extends FilterInputStream { private static final int WOULD_BLOCK = -2; // // decoding table // private static int[] table = new int[256]; // one-time initialization of decoding table static { int i; for( i=0; i < 256; ++i) { table[i] = -1; } int c; for( c = 'A', i=0; c <= 'Z'; ++c, ++i) { table[c] = i; } for( c = 'a'; c <= 'z'; ++c, ++i) { table[c] = i; } for( c='0'; c <= '9'; ++c, ++i) { table[c] = i; } table['+'] = 62; table['/'] = 63; } // prev is the previous significant character read from the in stream. // Significant characters are those that are part of the encoded data, // as opposed to whitespace. private int prev, savedPrev; // state is the current state of our state machine. The states are 1-5. // State 5 represents end-of-file, which occurs when we read the last // character from the input stream, or a base64 padding character ('='). // States 1-4 indicate which character of the current 4-character block we // are looking for. After state 4 we wrap back to state 1. The state // is not advanced when we read an insignificant character (such as // whitespace). private int state = 1, savedState; public Base64InputStream(InputStream in) { super(in); } public long skip(long n) throws IOException { long count = 0; while( (count < n) && (read() != -1) ) { ++count; } return count; } /** * param block Whether or not to block waiting for input. */ private int read(boolean block) throws IOException { int cur, ret=0; boolean done = false; while(!done) { if( in.available() < 1 && !block) { return WOULD_BLOCK; } cur = in.read(); switch(state) { case 1: if( cur == -1 ) { // end of file state = 5; return -1; } if( cur == '=' ) { state = 5; throw new IOException("Invalid pad character"); } if( table[cur] != -1 ) { prev = cur; state = 2; } break; case 2: if( cur == -1 ) { state = 5; throw new EOFException("Unexpected end-of-file"); } if( cur == '=' ) { state = 5; throw new IOException("Invalid pad character"); } if( table[cur] != -1 ) { ret = (table[prev]<<2) | ((table[cur]&0x30)>>4); prev = cur; state = 3; done = true; } break; case 3: if( cur == -1 ) { state = 5; throw new EOFException("Unexpected end-of-file"); } if( cur == '=' ) { // pad character state = 5; return -1; } if( table[cur] != -1 ) { ret = ((table[prev]&0x0f)<<4) | ((table[cur]&0x3c)>>2); prev = cur; state = 4; done = true; } break; case 4: if( cur == -1 ) { state = 5; throw new EOFException("Unexpected end-of-file"); } if( cur == '=' ) { // pad character state = 5; return -1; } if( table[cur] != -1 ) { ret = ((table[prev]&0x03)<<6) | table[cur]; state = 1; done = true; } break; case 5: // end of file return -1; //break; default: assert(false); break; } } return ret; } public int read() throws IOException { return read(true); } public int read(byte[] b, int off, int len) throws IOException { int count = 0; if( len < 0 ) { throw new IndexOutOfBoundsException("len is negative"); } if( off < 0 ) { throw new IndexOutOfBoundsException("off is negative"); } while( count < len ) { int cur = read(count==0); if( cur == -1 ) { // end-of-file if( count == 0 ) { return -1; } else { return count; } } if( cur == WOULD_BLOCK ) { assert(count>0); return count; } assert( cur >= 0 && cur <= 255); b[off+(count++)] = (byte) cur; } return count; } public int available() throws IOException { // We really don't know how much is left. in.available() could all // be whitespace. return 0; } public boolean markSupported() { return in.markSupported(); } public void mark(int readlimit) { in.mark(readlimit); savedPrev = prev; savedState = state; } public void close() throws IOException { in.close(); } public void reset() throws IOException { in.reset(); prev = savedPrev; state = savedState; } public static void main(String args[]) throws Exception { String infile = args[0]; String b64file = infile.concat(".b64"); String newfile = infile.concat(".recov"); ByteArrayOutputStream origStream = new ByteArrayOutputStream(); ByteArrayOutputStream b64OStream = new ByteArrayOutputStream(); Base64OutputStream b64Stream = new Base64OutputStream( new PrintStream(b64OStream), 18); int numread; byte []data = new byte[1024]; try (FileInputStream fis = new FileInputStream(infile)) { while ((numread = fis.read(data, 0, 1024)) != -1) { origStream.write(data, 0, numread); b64Stream.write(data, 0, numread); } } b64Stream.close(); origStream.close(); ByteArrayOutputStream newStream = new ByteArrayOutputStream(); ByteArrayInputStream bais = new ByteArrayInputStream(b64OStream.toByteArray()); try (Base64InputStream bis = new Base64InputStream(bais)) { while ((numread = bis.read(data, 0, 1024)) != -1) { newStream.write(data, 0, numread); } } newStream.close(); if( ! Arrays.equals(origStream.toByteArray(), newStream.toByteArray())){ throw new Exception("Did not recover original data"); } } } jss-4.6.3/org/mozilla/jss/util/Base64OutputStream.java000066400000000000000000000106701362106420000226170ustar00rootroot00000000000000/* 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/. */ /* * We would like to eventually use Sun's base64 encoder, but it is not * public yet. It is in the sun.misc package in JDK1.2. */ package org.mozilla.jss.util; import java.io.FilterOutputStream; import java.io.PrintStream; import java.io.IOException; /** * An output stream filter that takes arbitrary bytes and outputs their * base64 encoding. Call flush() or close() to write out the final padding. * The class also automatically puts line breaks in the output stream. */ public class Base64OutputStream extends FilterOutputStream { /** * Create a stream that does not insert line breaks. To have line * breaks, use the other constructor. */ public Base64OutputStream(PrintStream out) { super(out); charsOnLine = 0; inputCount = 0; input = new byte[3]; doLineBreaks = false; } /** * @param quadsPerLine Number of 4-character blocks to write before * outputting a line break. For example, for 76-characters per line, * pass in 76/4 = 19. */ public Base64OutputStream(PrintStream out, int quadsPerLine) { this(out); doLineBreaks = true; assert(quadsPerLine > 0); charsPerLine = quadsPerLine*4; } public void write(int oneByte) throws IOException { input[inputCount++] = (byte)(0xff & oneByte); if(inputCount==3) { outputOneAtom(); if(doLineBreaks) { if(charsOnLine==charsPerLine) { ((PrintStream)out).println(); charsOnLine=0; } assert(charsOnLine < charsPerLine); } } assert(inputCount < 3); } /** * This flushes the stream and closes the next stream downstream. */ public void close() throws IOException { flush(); out.close(); } /** * Calling this will put the ending padding on the base64 stream, * so don't call it until you have no data left. The class does no * unnecessary buffering, so you probably shouldn't call it at all. */ public void flush() throws IOException { if(inputCount > 0) { outputOneAtom(); } if(doLineBreaks) { ((PrintStream)out).println(); charsOnLine = 0; } } public void write(byte[] buffer) throws IOException { write(buffer, 0, buffer.length); } public void write(byte[] buffer, int offset, int count) throws IOException { int i; int byteCount; for(i=offset, byteCount=0; byteCount < count; i++, byteCount++) { write(buffer[i]); } } private final static char encoding[] = { // 0 1 2 3 4 5 6 7 'A','B','C','D','E','F','G','H', // 0 'I','J','K','L','M','N','O','P', // 1 'Q','R','S','T','U','V','W','X', // 2 'Y','Z','a','b','c','d','e','f', // 3 'g','h','i','j','k','l','m','n', // 4 'o','p','q','r','s','t','u','v', // 5 'w','x','y','z','0','1','2','3', // 6 '4','5','6','7','8','9','+','/' // 7 }; /** * Output 3 bytes of input as 4 bytes of base-64 encoded output. * If there are fewer than 3 bytes available, the output will be * padded according to the spec. Padding should only happen at the end * of the stream. */ private void outputOneAtom() throws IOException { byte[] output = new byte[4]; if(inputCount==0) { return; } // If we have fewer than 3 bytes, pad the rest with zeroes if(inputCount<3) { input[2]=0; if(inputCount<2) { input[1]=0; } } // Do a base64 encoding output[0] = (byte) encoding[ (input[0]>>>2) & 0x3f ]; output[1] = (byte) encoding[ (input[0]<<4)&0x30 | (input[1]>>>4)&0xf ]; output[2] = (byte) encoding[ (input[1]<<2)&0x3c | (input[2]>>>6)&0x3 ]; output[3] = (byte) encoding[ input[2]&0x3f ]; // add padding if(inputCount<3) { output[3] = (byte)'='; if(inputCount<2) { output[2] = (byte)'='; } } out.write(output); inputCount=0; if(doLineBreaks) { charsOnLine += 4; } } ////////////////////////////////////////////////////////////////////// // Private data ////////////////////////////////////////////////////////////////////// private byte[] input; // buffered input, max 3 bytes (after 3 we write // them out base64-encoded) private short inputCount; // number of bytes in input buffer private short charsOnLine; // number of bytes on the current line private int charsPerLine; // maximum characters per line private static final int DEFAULT_QUADS_PER_LINE=16; //64 chars private boolean doLineBreaks; } jss-4.6.3/org/mozilla/jss/util/ConsolePasswordCallback.java000066400000000000000000000016561362106420000237440ustar00rootroot00000000000000/* 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.util; /** * A password callback that obtains its password from the console. * Asterisks are echoed at the prompt. */ public class ConsolePasswordCallback implements PasswordCallback { public ConsolePasswordCallback() {} public Password getPasswordFirstAttempt(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { System.out.println("Enter password for "+info.getName()); return Password.readPasswordFromConsole(); } public Password getPasswordAgain(PasswordCallbackInfo token) throws PasswordCallback.GiveUpException { System.out.println("Password incorrect, try again"); return getPasswordFirstAttempt(token); } } jss-4.6.3/org/mozilla/jss/util/EC.java000066400000000000000000000062671362106420000174740ustar00rootroot00000000000000package org.mozilla.jss.util; import java.math.BigInteger; import java.util.Arrays; import java.security.spec.ECPoint; import java.security.spec.ECParameterSpec; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.util.ECCurve; import org.mozilla.jss.netscape.security.util.Utils; public class EC { public static ECPoint decodeNSSPoint(byte[] data) { int index = 0; // JSS likes to prepend a zero to "help" BigInteger users. We've // since removed the BigInteger from call tree. if (data[index] == 0x00) { index += 1; } // CKA_EC_POINT is defined by PKCS#11 to be the DER-encoding of // ANSI X9.62 ECPoint value Q. ASNI X9.62 defines the ECPoint // conversion process in Section 4.3.6 Point-to-Octet-String // Conversion and Section 4.3.7 Octet-String-to-Point Conversion. // // We handle only the uncompressed forms for now. if (data[index] == 0x04) { index += 1; // In the uncompressed form, the length is 2l+1 (or, with JSS's // padding, 2l+2), where l is the length of a point element. int total_length = data.length - index; // Remaining length should be even by above. assert((total_length & 1) == 0); // Length of the point is now half of the total_length. int point_length = total_length / 2; // X coordinate is the first half of the data. BigInteger x1 = new BigInteger(1, Arrays.copyOfRange(data, index, index + point_length)); // Y coordinate is the second half of the data. index += point_length; BigInteger y1 = new BigInteger(1, Arrays.copyOfRange(data, index, index + point_length)); // We should now be at the end of the buffer; there should be // no trailing data. assert(index + point_length == data.length); return new ECPoint(x1, y1); } // Handling of other forms is complicated and depends on the // underlying curve; we might not have that information here. throw new RuntimeException("Unrecognized CKA_EC_POINT encoding form: " + data[index]); } public static ECParameterSpec decodeNSSOID(byte[] data) { int offset = 0; if (data[offset] == 0x00) { offset += 1; } ASN1Value value; try { value = ASN1Util.decode(OBJECT_IDENTIFIER.getTemplate(), Arrays.copyOfRange(data, offset, data.length)); if (!(value instanceof OBJECT_IDENTIFIER)) { throw new RuntimeException("Unrecognized byte data: " + Utils.HexEncode(data)); } } catch (Exception e) { throw new RuntimeException(e.getMessage() + "\nData: " + Utils.HexEncode(data), e); } OBJECT_IDENTIFIER oid = (OBJECT_IDENTIFIER)value; ECCurve curve = ECCurve.fromOID(oid); if (curve == null) { throw new RuntimeException("Unrecognized curve: " + Utils.HexEncode(data) + " == OID " + oid); } return curve.getECParameterSpec(); } } jss-4.6.3/org/mozilla/jss/util/ECCurve.java000066400000000000000000000153161362106420000204740ustar00rootroot00000000000000package org.mozilla.jss.util; import java.math.BigInteger; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.EllipticCurve; import java.security.spec.ECField; import java.security.spec.ECFieldFp; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; /** * Database of common, public elliptic curves. * * Data taken from jss.pkcs11.PK11KeyPairGenerator, the OpenJDK CurveDB, * and djb's SafeCurves webpage. */ public enum ECCurve { P256( new String[] { "ansip256r1", "secp256r1", "nistp256", "P-256", "NIST P-256", "X9.62 prime256v1"}, // names new OBJECT_IDENTIFIER[] { ECOIDs.CURVE_ANSI_P256V1 }, // OIDs new ECFieldFp(new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16)), // field new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), // a new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), // b new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), // generator.X new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), // generator.Y new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), // order // OpenJDK lists this curve as having a cofactor of one, but NIST // doesn't share their cofactor. 1 // cofactor ), P384( new String[] { "ansip384r1", "secp384r1", "nistp384", "P-384", "NIST P-384" }, // names new OBJECT_IDENTIFIER[] { ECOIDs.CURVE_SECG_P384R1 }, // OIDs new ECFieldFp(new BigInteger("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff", 16)), // field new BigInteger("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc", 16), // a new BigInteger("b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef", 16), // b new BigInteger("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", 16), // generator.X new BigInteger("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", 16), // generator.Y new BigInteger("ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973", 16), // order // OpenJDK lists this curve as having a cofactor of one, but NIST // doesn't share their cofactor. 1 // cofactor ), P521( new String[] { "ansip521r1", "secp521r1", "nistp521", "P-521", "NIST P-521" }, // names new OBJECT_IDENTIFIER[] { ECOIDs.CURVE_SECG_P521R1 }, // OIDs new ECFieldFp(new BigInteger("1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), // field new BigInteger("1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", 16), // a new BigInteger("51953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 16), // b new BigInteger("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 16), // generator.X new BigInteger("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 16), // generator.Y new BigInteger("1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", 16), // order // OpenJDK lists this curve as having a cofactor of one, but NIST // doesn't share their cofactor. 1 // cofactor ); // OIDs are defined at the bottom of this class. private String[] names; private OBJECT_IDENTIFIER[] oids; private ECField field; private BigInteger a; private BigInteger b; private BigInteger generatorX; private BigInteger generatorY; private BigInteger order; private int cofactor; private ECCurve(String[] names, OBJECT_IDENTIFIER[] oids, ECField field, BigInteger a, BigInteger b, ECPoint generator, BigInteger order, int cofactor) { this.names = names; this.oids = oids; this.field = field; this.a = a; this.b = b; this.generatorX = generator.getAffineX(); this.generatorY = generator.getAffineY(); this.order = order; this.cofactor = cofactor; } private ECCurve(String[] names, OBJECT_IDENTIFIER[] oids, ECField field, BigInteger a, BigInteger b, BigInteger generatorX, BigInteger generatorY, BigInteger order, int cofactor) { this.names = names; this.oids = oids; this.field = field; this.a = a; this.b = b; this.generatorX = generatorX; this.generatorY = generatorY; this.order = order; this.cofactor = cofactor; } public String[] getNames() { return names; } public OBJECT_IDENTIFIER[] getOIDs() { return oids; } public ECField getField() { return field; } public BigInteger getA() { return a; } public BigInteger getB() { return b; } public EllipticCurve getEC() { return new EllipticCurve(field, a, b); } public BigInteger getGeneratorX() { return generatorX; } public BigInteger getGeneratorY() { return generatorY; } public ECPoint getGenerator() { return new ECPoint(generatorX, generatorY); } public BigInteger getOrder() { return order; } public ECParameterSpec getECParameterSpec() { return new ECParameterSpec(getEC(), getGenerator(), getOrder(), getCofactor()); } public int getCofactor() { return cofactor; } public static ECCurve fromOID(OBJECT_IDENTIFIER oid) { for (ECCurve curve : ECCurve.values()) { for (OBJECT_IDENTIFIER curve_oid : curve.oids) { if (curve_oid.equals(oid)) { return curve; } } } return null; } public static ECCurve fromName(String name) { for (ECCurve curve : ECCurve.values()) { for (String curve_name : curve.names) { if (curve_name.equalsIgnoreCase(name)) { return curve; } } } return null; } } jss-4.6.3/org/mozilla/jss/util/ECOIDs.java000066400000000000000000000105671362106420000202110ustar00rootroot00000000000000package org.mozilla.jss.util; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; public class ECOIDs { // OID Base Arcs public static final OBJECT_IDENTIFIER ANSI_X962_PRIME_CURVE = new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10045, 3, 1 } ); public static final OBJECT_IDENTIFIER ANSI_X962_BINARY_CURVE = new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10045, 3, 0 } ); public static final OBJECT_IDENTIFIER SECG_EC_CURVE = new OBJECT_IDENTIFIER( new long[] { 1, 3, 132, 0 } ); // ANSI Prime curves public static final OBJECT_IDENTIFIER CURVE_ANSI_P192V1 = ANSI_X962_PRIME_CURVE.subBranch(1); public static final OBJECT_IDENTIFIER CURVE_ANSI_P192V2 = ANSI_X962_PRIME_CURVE.subBranch(2); public static final OBJECT_IDENTIFIER CURVE_ANSI_P192V3 = ANSI_X962_PRIME_CURVE.subBranch(3); public static final OBJECT_IDENTIFIER CURVE_ANSI_P239V1 = ANSI_X962_PRIME_CURVE.subBranch(4); public static final OBJECT_IDENTIFIER CURVE_ANSI_P239V2 = ANSI_X962_PRIME_CURVE.subBranch(5); public static final OBJECT_IDENTIFIER CURVE_ANSI_P239V3 = ANSI_X962_PRIME_CURVE.subBranch(6); public static final OBJECT_IDENTIFIER CURVE_ANSI_P256V1 = ANSI_X962_PRIME_CURVE.subBranch(7); // ANSI Binary curves public static final OBJECT_IDENTIFIER CURVE_ANSI_PNB163V1 = ANSI_X962_BINARY_CURVE.subBranch(1); public static final OBJECT_IDENTIFIER CURVE_ANSI_PNB163V2 = ANSI_X962_BINARY_CURVE.subBranch(2); public static final OBJECT_IDENTIFIER CURVE_ANSI_PNB163V3 = ANSI_X962_BINARY_CURVE.subBranch(3); public static final OBJECT_IDENTIFIER CURVE_ANSI_PNB176V1 = ANSI_X962_BINARY_CURVE.subBranch(4); public static final OBJECT_IDENTIFIER CURVE_ANSI_TNB191V1 = ANSI_X962_BINARY_CURVE.subBranch(5); public static final OBJECT_IDENTIFIER CURVE_ANSI_TNB191V2 = ANSI_X962_BINARY_CURVE.subBranch(6); public static final OBJECT_IDENTIFIER CURVE_ANSI_TNB191V3 = ANSI_X962_BINARY_CURVE.subBranch(7); public static final OBJECT_IDENTIFIER CURVE_ANSI_ONB191V4 = ANSI_X962_BINARY_CURVE.subBranch(8); public static final OBJECT_IDENTIFIER CURVE_ANSI_ONB191V5 = ANSI_X962_BINARY_CURVE.subBranch(9); public static final OBJECT_IDENTIFIER CURVE_ANSI_PNB208W1 = ANSI_X962_BINARY_CURVE.subBranch(10); public static final OBJECT_IDENTIFIER CURVE_ANSI_TNB239V1 = ANSI_X962_BINARY_CURVE.subBranch(11); public static final OBJECT_IDENTIFIER CURVE_ANSI_TNB239V2 = ANSI_X962_BINARY_CURVE.subBranch(12); public static final OBJECT_IDENTIFIER CURVE_ANSI_TNB239V3 = ANSI_X962_BINARY_CURVE.subBranch(13); public static final OBJECT_IDENTIFIER CURVE_ANSI_ONB239V4 = ANSI_X962_BINARY_CURVE.subBranch(14); public static final OBJECT_IDENTIFIER CURVE_ANSI_ONB239V5 = ANSI_X962_BINARY_CURVE.subBranch(15); public static final OBJECT_IDENTIFIER CURVE_ANSI_PNB272W1 = ANSI_X962_BINARY_CURVE.subBranch(16); public static final OBJECT_IDENTIFIER CURVE_ANSI_PNB304W1 = ANSI_X962_BINARY_CURVE.subBranch(17); public static final OBJECT_IDENTIFIER CURVE_ANSI_TNB359V1 = ANSI_X962_BINARY_CURVE.subBranch(18); public static final OBJECT_IDENTIFIER CURVE_ANSI_PNB368W1 = ANSI_X962_BINARY_CURVE.subBranch(19); public static final OBJECT_IDENTIFIER CURVE_ANSI_TNB431R1 = ANSI_X962_BINARY_CURVE.subBranch(20); // SEG Prime curves public static final OBJECT_IDENTIFIER CURVE_SECG_P112R1 = SECG_EC_CURVE.subBranch(6); public static final OBJECT_IDENTIFIER CURVE_SECG_P112R2 = SECG_EC_CURVE.subBranch(7); public static final OBJECT_IDENTIFIER CURVE_SECG_P128R1 = SECG_EC_CURVE.subBranch(28); public static final OBJECT_IDENTIFIER CURVE_SECG_P128R2 = SECG_EC_CURVE.subBranch(29); public static final OBJECT_IDENTIFIER CURVE_SECG_P160K1 = SECG_EC_CURVE.subBranch(9); public static final OBJECT_IDENTIFIER CURVE_SECG_P160R1 = SECG_EC_CURVE.subBranch(8); public static final OBJECT_IDENTIFIER CURVE_SECG_P160R2 = SECG_EC_CURVE.subBranch(30); public static final OBJECT_IDENTIFIER CURVE_SECG_P192K1 = SECG_EC_CURVE.subBranch(31); public static final OBJECT_IDENTIFIER CURVE_SECG_P224K1 = SECG_EC_CURVE.subBranch(32); public static final OBJECT_IDENTIFIER CURVE_SECG_P224R1 = SECG_EC_CURVE.subBranch(33); public static final OBJECT_IDENTIFIER CURVE_SECG_P256K1 = SECG_EC_CURVE.subBranch(10); public static final OBJECT_IDENTIFIER CURVE_SECG_P384R1 = SECG_EC_CURVE.subBranch(34); public static final OBJECT_IDENTIFIER CURVE_SECG_P521R1 = SECG_EC_CURVE.subBranch(35); } jss-4.6.3/org/mozilla/jss/util/GlobalRefProxy.c000066400000000000000000000032101362106420000213660ustar00rootroot00000000000000#include #include #include #include "java_ids.h" #include "jssutil.h" jobject JSS_PR_wrapGlobalRef(JNIEnv *env, jobject *ref) { jbyteArray pointer = NULL; jclass proxyClass; jmethodID constructor; jobject refObj = NULL; PR_ASSERT(env != NULL && ref != NULL && *ref != NULL); /* Convert pointer to byte array. */ pointer = JSS_ptrToByteArray(env, *ref); /* Lookup the class and constructor. */ proxyClass = (*env)->FindClass(env, GLOBAL_REF_PROXY_CLASS_NAME); if (proxyClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID(env, proxyClass, PLAIN_CONSTRUCTOR, GLOBAL_REF_CONSTRUCTOR_SIG); if (constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* Call the constructor. */ refObj = (*env)->NewObject(env, proxyClass, constructor, pointer); finish: if (refObj == NULL && *ref != NULL) { /* Something didn't work, so free resources. */ (*env)->DeleteGlobalRef(env, *ref); } PR_ASSERT(refObj || (*env)->ExceptionOccurred(env)); return refObj; } PRStatus JSS_PR_getGlobalRef(JNIEnv *env, jobject ref_proxy, jobject *ref) { return JSS_getPtrFromProxy(env, ref_proxy, (void**)ref); } JNIEXPORT void JNICALL Java_org_mozilla_jss_util_GlobalRefProxy_releaseNativeResources (JNIEnv *env, jobject this) { jobject ref; PR_ASSERT(env != NULL && this != NULL); if (JSS_PR_getGlobalRef(env, this, &ref) != PR_SUCCESS) { return; } (*env)->DeleteGlobalRef(env, ref); } jss-4.6.3/org/mozilla/jss/util/GlobalRefProxy.h000066400000000000000000000003111362106420000213720ustar00rootroot00000000000000#include #include #include #pragma once jobject JSS_PR_wrapGlobalRef(JNIEnv *env, jobject *ref); PRStatus JSS_PR_getGlobalRef(JNIEnv *env, jobject ref_proxy, jobject *ref); jss-4.6.3/org/mozilla/jss/util/GlobalRefProxy.java000066400000000000000000000003221362106420000220660ustar00rootroot00000000000000package org.mozilla.jss.util; public class GlobalRefProxy extends NativeProxy { public GlobalRefProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); } jss-4.6.3/org/mozilla/jss/util/IncorrectPasswordException.java000066400000000000000000000013741362106420000245310ustar00rootroot00000000000000/* 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.util; public class IncorrectPasswordException extends Exception { private static final long serialVersionUID = 1L; public IncorrectPasswordException() { super(); } public IncorrectPasswordException(String mesg) { super(mesg); } public IncorrectPasswordException(String mesg, Throwable cause) { super(mesg, cause); } public IncorrectPasswordException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/util/InvalidNicknameException.java000066400000000000000000000013621362106420000241070ustar00rootroot00000000000000/* 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.util; public class InvalidNicknameException extends Exception { private static final long serialVersionUID = 1L; public InvalidNicknameException() { super(); } public InvalidNicknameException(String mesg) { super(mesg); } public InvalidNicknameException(String mesg, Throwable cause) { super(mesg, cause); } public InvalidNicknameException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/util/NSPRerrs.h000066400000000000000000000133111362106420000201550ustar00rootroot00000000000000/* 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/. */ /* General NSPR 2.0 errors */ /* Caller must #include "prerror.h" */ ER2( PR_OUT_OF_MEMORY_ERROR, "Memory allocation attempt failed." ) ER2( PR_BAD_DESCRIPTOR_ERROR, "Invalid file descriptor." ) ER2( PR_WOULD_BLOCK_ERROR, "The operation would have blocked." ) ER2( PR_ACCESS_FAULT_ERROR, "Invalid memory address argument." ) ER2( PR_INVALID_METHOD_ERROR, "Invalid function for file type." ) ER2( PR_ILLEGAL_ACCESS_ERROR, "Invalid memory address argument." ) ER2( PR_UNKNOWN_ERROR, "Some unknown error has occurred." ) ER2( PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread." ) ER2( PR_NOT_IMPLEMENTED_ERROR, "function not implemented." ) ER2( PR_IO_ERROR, "I/O function error." ) ER2( PR_IO_TIMEOUT_ERROR, "I/O operation timed out." ) ER2( PR_IO_PENDING_ERROR, "I/O operation on busy file descriptor." ) ER2( PR_DIRECTORY_OPEN_ERROR, "The directory could not be opened." ) ER2( PR_INVALID_ARGUMENT_ERROR, "Invalid function argument." ) ER2( PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)." ) ER2( PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported." ) ER2( PR_IS_CONNECTED_ERROR, "Already connected." ) ER2( PR_BAD_ADDRESS_ERROR, "Network address is invalid." ) ER2( PR_ADDRESS_IN_USE_ERROR, "Local Network address is in use." ) ER2( PR_CONNECT_REFUSED_ERROR, "Connection refused by peer." ) ER2( PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable." ) ER2( PR_CONNECT_TIMEOUT_ERROR, "Connection attempt timed out." ) ER2( PR_NOT_CONNECTED_ERROR, "Network file descriptor is not connected." ) ER2( PR_LOAD_LIBRARY_ERROR, "Failure to load dynamic library." ) ER2( PR_UNLOAD_LIBRARY_ERROR, "Failure to unload dynamic library." ) ER2( PR_FIND_SYMBOL_ERROR, "Symbol not found in any of the loaded dynamic libraries." ) ER2( PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources." ) ER2( PR_DIRECTORY_LOOKUP_ERROR, "A directory lookup on a network address has failed." ) ER2( PR_TPD_RANGE_ERROR, "Attempt to access a TPD key that is out of range." ) ER2( PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full." ) ER2( PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full." ) ER2( PR_NOT_SOCKET_ERROR, "Network operation attempted on non-network file descriptor." ) ER2( PR_NOT_TCP_SOCKET_ERROR, "TCP-specific function attempted on a non-TCP file descriptor." ) ER2( PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound." ) ER2( PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied." ) ER2( PR_OPERATION_NOT_SUPPORTED_ERROR, "The requested operation is not supported by the platform." ) ER2( PR_PROTOCOL_NOT_SUPPORTED_ERROR, "The host operating system does not support the protocol requested." ) ER2( PR_REMOTE_FILE_ERROR, "Access to the remote file has been severed." ) ER2( PR_BUFFER_OVERFLOW_ERROR, "The value requested is too large to be stored in the data buffer provided." ) ER2( PR_CONNECT_RESET_ERROR, "TCP connection reset by peer." ) ER2( PR_RANGE_ERROR, "Unused." ) ER2( PR_DEADLOCK_ERROR, "The operation would have deadlocked." ) ER2( PR_FILE_IS_LOCKED_ERROR, "The file is already locked." ) ER2( PR_FILE_TOO_BIG_ERROR, "Write would result in file larger than the system allows." ) ER2( PR_NO_DEVICE_SPACE_ERROR, "The device for storing the file is full." ) ER2( PR_PIPE_ERROR, "Unused." ) ER2( PR_NO_SEEK_DEVICE_ERROR, "Unused." ) ER2( PR_IS_DIRECTORY_ERROR, "Cannot perform a normal file operation on a directory." ) ER2( PR_LOOP_ERROR, "Symbolic link loop." ) ER2( PR_NAME_TOO_LONG_ERROR, "File name is too long." ) ER2( PR_FILE_NOT_FOUND_ERROR, "File not found." ) ER2( PR_NOT_DIRECTORY_ERROR, "Cannot perform directory operation on a normal file." ) ER2( PR_READ_ONLY_FILESYSTEM_ERROR, "Cannot write to a read-only file system." ) ER2( PR_DIRECTORY_NOT_EMPTY_ERROR, "Cannot delete a directory that is not empty." ) ER2( PR_FILESYSTEM_MOUNTED_ERROR, "Cannot delete or rename a file object while the file system is busy." ) ER2( PR_NOT_SAME_DEVICE_ERROR, "Cannot rename a file to a file system on another device." ) ER2( PR_DIRECTORY_CORRUPTED_ERROR, "The directory object in the file system is corrupted." ) ER2( PR_FILE_EXISTS_ERROR, "Cannot create or rename a filename that already exists." ) ER2( PR_MAX_DIRECTORY_ENTRIES_ERROR, "Directory is full. No additional filenames may be added." ) ER2( PR_INVALID_DEVICE_STATE_ERROR, "The required device was in an invalid state." ) ER2( PR_DEVICE_IS_LOCKED_ERROR, "The device is locked." ) ER2( PR_NO_MORE_FILES_ERROR, "No more entries in the directory." ) ER2( PR_END_OF_FILE_ERROR, "Encountered end of file." ) ER2( PR_FILE_SEEK_ERROR, "Seek error." ) ER2( PR_FILE_IS_BUSY_ERROR, "The file is busy." ) ER2( PR_IN_PROGRESS_ERROR, "Operation is still in progress (probably a non-blocking connect)." ) ER2( PR_ALREADY_INITIATED_ERROR, "Operation has already been initiated (probably a non-blocking connect)." ) #ifdef PR_GROUP_EMPTY_ERROR ER2( PR_GROUP_EMPTY_ERROR, "The wait group is empty." ) #endif #ifdef PR_INVALID_STATE_ERROR ER2( PR_INVALID_STATE_ERROR, "Object state improper for request." ) #endif #ifdef PR_NETWORK_DOWN_ERROR ER2( PR_NETWORK_DOWN_ERROR, "Network is down." ) #endif #ifdef PR_SOCKET_SHUTDOWN_ERROR ER2( PR_SOCKET_SHUTDOWN_ERROR, "The socket was previously shut down." ) #endif #ifdef PR_CONNECT_ABORTED_ERROR ER2( PR_CONNECT_ABORTED_ERROR, "TCP Connection aborted." ) #endif #ifdef PR_HOST_UNREACHABLE_ERROR ER2( PR_HOST_UNREACHABLE_ERROR, "Host is unreachable." ) #endif /* always last */ ER2( PR_MAX_ERROR, "Placeholder for the end of the list" ) jss-4.6.3/org/mozilla/jss/util/NativeEnclosure.c000066400000000000000000000032631362106420000216050ustar00rootroot00000000000000#include #include #include "java_ids.h" #include "NativeEnclosure.h" PRStatus JSS_PR_LoadNativeEnclosure(JNIEnv *env, jobject this, jobject *ptrObj, jlong *ptrSize) { jclass this_class = NULL; jfieldID field_id = NULL; PR_ASSERT(env != NULL && this != NULL && ptrObj != NULL && ptrSize != NULL); this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { return PR_FAILURE; } field_id = (*env)->GetFieldID(env, this_class, "mPointer", "L" NATIVE_PROXY_CLASS_NAME ";"); if (field_id == NULL) { return PR_FAILURE; } *ptrObj = (*env)->GetObjectField(env, this, field_id); if (ptrObj == NULL) { return PR_FAILURE; } field_id = (*env)->GetFieldID(env, this_class, "mPointerSize", "J"); if (field_id == NULL) { return PR_FAILURE; } *ptrSize = (*env)->GetLongField(env, this, field_id); return PR_SUCCESS; } PRStatus JSS_PR_StoreNativeEnclosure(JNIEnv *env, jobject this, jobject ptrObj, jlong ptrSize) { jclass this_class = NULL; jfieldID field_id = NULL; PR_ASSERT(env != NULL && this != NULL && ptrObj != NULL); this_class = (*env)->GetObjectClass(env, this); if (this_class == NULL) { return PR_FAILURE; } field_id = (*env)->GetFieldID(env, this_class, "mPointer", "L" NATIVE_PROXY_CLASS_NAME ";"); if (field_id == NULL) { return PR_FAILURE; } (*env)->SetObjectField(env, this, field_id, ptrObj); field_id = (*env)->GetFieldID(env, this_class, "mPointerSize", "J"); if (field_id == NULL) { return PR_FAILURE; } (*env)->SetLongField(env, this, field_id, ptrSize); return PR_SUCCESS; } jss-4.6.3/org/mozilla/jss/util/NativeEnclosure.h000066400000000000000000000003721362106420000216100ustar00rootroot00000000000000#include #include #include PRStatus JSS_PR_LoadNativeEnclosure(JNIEnv *env, jobject this, jobject *ptrObj, jlong *ptrSize); PRStatus JSS_PR_StoreNativeEnclosure(JNIEnv *env, jobject this, jobject ptrObj, jlong ptrSize); jss-4.6.3/org/mozilla/jss/util/NativeEnclosure.java000066400000000000000000000046221362106420000223040ustar00rootroot00000000000000package org.mozilla.jss.util; /** * Classes extending NativeEnclsoure wrap a single NativeProxy instance, * allowing it to be accessed from the JNI layer but be allocated and scoped * from the Java layer. * * Because this class implements AutoCloseable, it is suggested to add * constructors to derived classes which call open; this'll allow a single * try-with-resources block to scope the lifetime of this object: * *
 * try (NEC obj = new NEC(...)) {
 *      // ... do something with obj ...
 * }
 * 
* * Extending classes implement acquireNativeResources() and * releaseNativeResources(). Before this instance is passed to the JNI layer, * open() should be called, allocating all necessary resources. After making * all necessary JNI calls, close() should be called to free resources. * Ideally, open() and close() should be called close to the JNI calls, * wrapped by the developer to limit accidental memory leaks. */ public abstract class NativeEnclosure implements AutoCloseable { /** * Enclosed NativeProxy reference. */ public NativeProxy mPointer; /** * Size of enclosed mPointer. */ public long mPointerSize; /** * Allocate and initialize mPointer with its enclosed value. * * Note that this method prevents you from accidentally leaking memory; * to call open() twice, call close() first. */ public final void open() throws Exception { if (mPointer == null) { acquireNativeResources(); } } @Deprecated protected void finalize() throws Throwable { close(); } /** * Deinitialize and free mPointer. * * Must be called to prevent memory leaks. */ public final void close() throws Exception { if (mPointer != null) { releaseNativeResources(); mPointer.close(); } mPointer = null; mPointerSize = 0; } /** * Allocate native resources, setting mPointer and mPointerSize as * appropriate. */ protected abstract void acquireNativeResources() throws Exception; /** * Called to deallocate native resources; note that mPointer.close() * is called afterwards. * * If mPointer.close() should be a no-op, extend from StaticVoidRef and * do any required cleanup here. */ protected abstract void releaseNativeResources() throws Exception; } jss-4.6.3/org/mozilla/jss/util/NativeErrcodes.c000066400000000000000000000347751362106420000214300ustar00rootroot00000000000000/* 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/. */ #include #include #include #include #include #include typedef struct { PRErrorCode native; int java; } Errcode; /* * This table correlates NSPR and NSS error codes to the enums defined * in o.m.util.NativeErrcodes. It must be kept in sync with that class. */ static Errcode errcodeTable[] = { {PR_OUT_OF_MEMORY_ERROR, 1}, {PR_BAD_DESCRIPTOR_ERROR, 2}, {PR_WOULD_BLOCK_ERROR, 3}, {PR_ACCESS_FAULT_ERROR, 4}, {PR_INVALID_METHOD_ERROR, 5}, {PR_ILLEGAL_ACCESS_ERROR, 6}, {PR_UNKNOWN_ERROR, 7}, {PR_PENDING_INTERRUPT_ERROR, 8}, {PR_NOT_IMPLEMENTED_ERROR, 9}, {PR_IO_ERROR, 10}, {PR_IO_TIMEOUT_ERROR, 11}, {PR_IO_PENDING_ERROR, 12}, {PR_DIRECTORY_OPEN_ERROR, 13}, {PR_INVALID_ARGUMENT_ERROR, 14}, {PR_ADDRESS_NOT_AVAILABLE_ERROR, 15}, {PR_ADDRESS_NOT_SUPPORTED_ERROR, 16}, {PR_IS_CONNECTED_ERROR, 17}, {PR_BAD_ADDRESS_ERROR, 18}, {PR_ADDRESS_IN_USE_ERROR, 19}, {PR_CONNECT_REFUSED_ERROR, 20}, {PR_NETWORK_UNREACHABLE_ERROR, 21}, {PR_CONNECT_TIMEOUT_ERROR, 22}, {PR_NOT_CONNECTED_ERROR, 23}, {PR_LOAD_LIBRARY_ERROR, 24}, {PR_UNLOAD_LIBRARY_ERROR, 25}, {PR_FIND_SYMBOL_ERROR, 26}, {PR_INSUFFICIENT_RESOURCES_ERROR, 27}, {PR_DIRECTORY_LOOKUP_ERROR, 28}, {PR_TPD_RANGE_ERROR, 29}, {PR_PROC_DESC_TABLE_FULL_ERROR, 30}, {PR_SYS_DESC_TABLE_FULL_ERROR, 31}, {PR_NOT_SOCKET_ERROR, 32}, {PR_NOT_TCP_SOCKET_ERROR, 33}, {PR_SOCKET_ADDRESS_IS_BOUND_ERROR, 34}, {PR_NO_ACCESS_RIGHTS_ERROR, 35}, {PR_OPERATION_NOT_SUPPORTED_ERROR, 36}, {PR_PROTOCOL_NOT_SUPPORTED_ERROR, 37}, {PR_REMOTE_FILE_ERROR, 38}, {PR_BUFFER_OVERFLOW_ERROR, 39}, {PR_CONNECT_RESET_ERROR, 40}, {PR_RANGE_ERROR, 41}, {PR_DEADLOCK_ERROR, 42}, {PR_FILE_IS_LOCKED_ERROR, 43}, {PR_FILE_TOO_BIG_ERROR, 44}, {PR_NO_DEVICE_SPACE_ERROR, 45}, {PR_PIPE_ERROR, 46}, {PR_NO_SEEK_DEVICE_ERROR, 47}, {PR_IS_DIRECTORY_ERROR, 48}, {PR_LOOP_ERROR, 49}, {PR_NAME_TOO_LONG_ERROR, 50}, {PR_FILE_NOT_FOUND_ERROR, 51}, {PR_NOT_DIRECTORY_ERROR, 52}, {PR_READ_ONLY_FILESYSTEM_ERROR, 53}, {PR_DIRECTORY_NOT_EMPTY_ERROR, 54}, {PR_FILESYSTEM_MOUNTED_ERROR, 55}, {PR_NOT_SAME_DEVICE_ERROR, 56}, {PR_DIRECTORY_CORRUPTED_ERROR, 57}, {PR_FILE_EXISTS_ERROR, 58}, {PR_MAX_DIRECTORY_ENTRIES_ERROR, 59}, {PR_INVALID_DEVICE_STATE_ERROR, 60}, {PR_DEVICE_IS_LOCKED_ERROR, 61}, {PR_NO_MORE_FILES_ERROR, 62}, {PR_END_OF_FILE_ERROR, 63}, {PR_FILE_SEEK_ERROR, 64}, {PR_FILE_IS_BUSY_ERROR, 65}, {PR_OPERATION_ABORTED_ERROR, 66}, {PR_IN_PROGRESS_ERROR, 67}, {PR_ALREADY_INITIATED_ERROR, 68}, {PR_GROUP_EMPTY_ERROR, 69}, {PR_INVALID_STATE_ERROR, 70}, {PR_NETWORK_DOWN_ERROR, 71}, {PR_SOCKET_SHUTDOWN_ERROR, 72}, {PR_CONNECT_ABORTED_ERROR, 73}, {PR_HOST_UNREACHABLE_ERROR, 74}, {SSL_ERROR_BASE, 77}, {SSL_ERROR_EXPORT_ONLY_SERVER, 78}, {SSL_ERROR_US_ONLY_SERVER, 79}, {SSL_ERROR_NO_CYPHER_OVERLAP, 80}, {SSL_ERROR_NO_CERTIFICATE, 81}, {SSL_ERROR_BAD_CERTIFICATE, 82}, {SSL_ERROR_BAD_CLIENT, 83}, {SSL_ERROR_BAD_SERVER, 84}, {SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, 85}, {SSL_ERROR_UNSUPPORTED_VERSION, 86}, {SSL_ERROR_WRONG_CERTIFICATE, 87}, {SSL_ERROR_BAD_CERT_DOMAIN, 88}, {SSL_ERROR_POST_WARNING, 89}, {SSL_ERROR_SSL2_DISABLED, 90}, {SSL_ERROR_BAD_MAC_READ, 91}, {SSL_ERROR_BAD_MAC_ALERT, 92}, {SSL_ERROR_BAD_CERT_ALERT, 93}, {SSL_ERROR_REVOKED_CERT_ALERT, 94}, {SSL_ERROR_EXPIRED_CERT_ALERT, 95}, {SSL_ERROR_SSL_DISABLED, 96}, {SSL_ERROR_FORTEZZA_PQG, 97}, {SSL_ERROR_UNKNOWN_CIPHER_SUITE, 98}, {SSL_ERROR_NO_CIPHERS_SUPPORTED, 99}, {SSL_ERROR_BAD_BLOCK_PADDING, 100}, {SSL_ERROR_RX_RECORD_TOO_LONG, 101}, {SSL_ERROR_TX_RECORD_TOO_LONG, 102}, {SSL_ERROR_RX_MALFORMED_HELLO_REQUEST, 103}, {SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, 104}, {SSL_ERROR_RX_MALFORMED_SERVER_HELLO, 105}, {SSL_ERROR_RX_MALFORMED_CERTIFICATE, 106}, {SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH, 107}, {SSL_ERROR_RX_MALFORMED_CERT_REQUEST, 108}, {SSL_ERROR_RX_MALFORMED_HELLO_DONE, 109}, {SSL_ERROR_RX_MALFORMED_CERT_VERIFY, 110}, {SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH, 111}, {SSL_ERROR_RX_MALFORMED_FINISHED, 112}, {SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER, 113}, {SSL_ERROR_RX_MALFORMED_ALERT, 114}, {SSL_ERROR_RX_MALFORMED_HANDSHAKE, 115}, {SSL_ERROR_RX_MALFORMED_APPLICATION_DATA, 116}, {SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST, 117}, {SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO, 118}, {SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO, 119}, {SSL_ERROR_RX_UNEXPECTED_CERTIFICATE, 120}, {SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH, 121}, {SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST, 122}, {SSL_ERROR_RX_UNEXPECTED_HELLO_DONE, 123}, {SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY, 124}, {SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH, 125}, {SSL_ERROR_RX_UNEXPECTED_FINISHED, 126}, {SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER, 127}, {SSL_ERROR_RX_UNEXPECTED_ALERT, 128}, {SSL_ERROR_RX_UNEXPECTED_HANDSHAKE, 129}, {SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, 130}, {SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, 131}, {SSL_ERROR_RX_UNKNOWN_HANDSHAKE, 132}, {SSL_ERROR_RX_UNKNOWN_ALERT, 133}, {SSL_ERROR_CLOSE_NOTIFY_ALERT, 134}, {SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT, 135}, {SSL_ERROR_DECOMPRESSION_FAILURE_ALERT, 136}, {SSL_ERROR_HANDSHAKE_FAILURE_ALERT, 137}, {SSL_ERROR_ILLEGAL_PARAMETER_ALERT, 138}, {SSL_ERROR_UNSUPPORTED_CERT_ALERT, 139}, {SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT, 140}, {SSL_ERROR_GENERATE_RANDOM_FAILURE, 141}, {SSL_ERROR_SIGN_HASHES_FAILURE, 142}, {SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE, 143}, {SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE, 144}, {SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE, 145}, {SSL_ERROR_ENCRYPTION_FAILURE, 146}, {SSL_ERROR_DECRYPTION_FAILURE, 147}, {SSL_ERROR_SOCKET_WRITE_FAILURE, 148}, {SSL_ERROR_MD5_DIGEST_FAILURE, 149}, {SSL_ERROR_SHA_DIGEST_FAILURE, 150}, {SSL_ERROR_MAC_COMPUTATION_FAILURE, 151}, {SSL_ERROR_SYM_KEY_CONTEXT_FAILURE, 152}, {SSL_ERROR_SYM_KEY_UNWRAP_FAILURE, 153}, {SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED, 154}, {SSL_ERROR_IV_PARAM_FAILURE, 155}, {SSL_ERROR_INIT_CIPHER_SUITE_FAILURE, 156}, {SSL_ERROR_SESSION_KEY_GEN_FAILURE, 157}, {SSL_ERROR_NO_SERVER_KEY_FOR_ALG, 158}, {SSL_ERROR_TOKEN_INSERTION_REMOVAL, 159}, {SSL_ERROR_TOKEN_SLOT_NOT_FOUND, 160}, {SSL_ERROR_NO_COMPRESSION_OVERLAP, 161}, {SSL_ERROR_HANDSHAKE_NOT_COMPLETED, 162}, {SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE, 163}, {SSL_ERROR_CERT_KEA_MISMATCH, 164}, {SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA, 165}, {SSL_ERROR_SESSION_NOT_FOUND, 166}, {SSL_ERROR_DECRYPTION_FAILED_ALERT, 167}, {SSL_ERROR_RECORD_OVERFLOW_ALERT, 168}, {SSL_ERROR_UNKNOWN_CA_ALERT, 169}, {SSL_ERROR_ACCESS_DENIED_ALERT, 170}, {SSL_ERROR_DECODE_ERROR_ALERT, 171}, {SSL_ERROR_DECRYPT_ERROR_ALERT, 172}, {SSL_ERROR_EXPORT_RESTRICTION_ALERT, 173}, {SSL_ERROR_PROTOCOL_VERSION_ALERT, 174}, {SSL_ERROR_INSUFFICIENT_SECURITY_ALERT, 175}, {SSL_ERROR_INTERNAL_ERROR_ALERT, 176}, {SSL_ERROR_USER_CANCELED_ALERT, 177}, {SSL_ERROR_NO_RENEGOTIATION_ALERT, 178}, {SEC_ERROR_IO, 179}, {SEC_ERROR_LIBRARY_FAILURE, 180}, {SEC_ERROR_BAD_DATA, 181}, {SEC_ERROR_OUTPUT_LEN, 182}, {SEC_ERROR_INPUT_LEN, 183}, {SEC_ERROR_INVALID_ARGS, 184}, {SEC_ERROR_INVALID_ALGORITHM, 185}, {SEC_ERROR_INVALID_AVA, 186}, {SEC_ERROR_INVALID_TIME, 187}, {SEC_ERROR_BAD_DER, 188}, {SEC_ERROR_BAD_SIGNATURE, 189}, {SEC_ERROR_EXPIRED_CERTIFICATE, 190}, {SEC_ERROR_REVOKED_CERTIFICATE, 191}, {SEC_ERROR_UNKNOWN_ISSUER, 192}, {SEC_ERROR_BAD_KEY, 193}, {SEC_ERROR_BAD_PASSWORD, 194}, {SEC_ERROR_RETRY_PASSWORD, 195}, {SEC_ERROR_NO_NODELOCK, 196}, {SEC_ERROR_BAD_DATABASE, 197}, {SEC_ERROR_NO_MEMORY, 198}, {SEC_ERROR_UNTRUSTED_ISSUER, 199}, {SEC_ERROR_UNTRUSTED_CERT, 200}, {SEC_ERROR_DUPLICATE_CERT, 201}, {SEC_ERROR_DUPLICATE_CERT_NAME, 202}, {SEC_ERROR_ADDING_CERT, 203}, {SEC_ERROR_FILING_KEY, 204}, {SEC_ERROR_NO_KEY, 205}, {SEC_ERROR_CERT_VALID, 206}, {SEC_ERROR_CERT_NOT_VALID, 207}, {SEC_ERROR_CERT_NO_RESPONSE, 208}, {SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, 209}, {SEC_ERROR_CRL_EXPIRED, 210}, {SEC_ERROR_CRL_BAD_SIGNATURE, 211}, {SEC_ERROR_CRL_INVALID, 212}, {SEC_ERROR_EXTENSION_VALUE_INVALID, 213}, {SEC_ERROR_EXTENSION_NOT_FOUND, 214}, {SEC_ERROR_CA_CERT_INVALID, 215}, {SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, 216}, {SEC_ERROR_CERT_USAGES_INVALID, 217}, {SEC_INTERNAL_ONLY, 218}, {SEC_ERROR_INVALID_KEY, 219}, {SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, 220}, {SEC_ERROR_OLD_CRL, 221}, {SEC_ERROR_NO_EMAIL_CERT, 222}, {SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, 223}, {SEC_ERROR_NOT_A_RECIPIENT, 224}, {SEC_ERROR_PKCS7_KEYALG_MISMATCH, 225}, {SEC_ERROR_PKCS7_BAD_SIGNATURE, 226}, {SEC_ERROR_UNSUPPORTED_KEYALG, 227}, {SEC_ERROR_DECRYPTION_DISALLOWED, 228}, {XP_SEC_FORTEZZA_BAD_CARD, 229}, {XP_SEC_FORTEZZA_NO_CARD, 230}, {XP_SEC_FORTEZZA_NONE_SELECTED, 231}, {XP_SEC_FORTEZZA_MORE_INFO, 232}, {XP_SEC_FORTEZZA_PERSON_NOT_FOUND, 233}, {XP_SEC_FORTEZZA_NO_MORE_INFO, 234}, {XP_SEC_FORTEZZA_BAD_PIN, 235}, {XP_SEC_FORTEZZA_PERSON_ERROR, 236}, {SEC_ERROR_NO_KRL, 237}, {SEC_ERROR_KRL_EXPIRED, 238}, {SEC_ERROR_KRL_BAD_SIGNATURE, 239}, {SEC_ERROR_REVOKED_KEY, 240}, {SEC_ERROR_KRL_INVALID, 241}, {SEC_ERROR_NEED_RANDOM, 242}, {SEC_ERROR_NO_MODULE, 243}, {SEC_ERROR_NO_TOKEN, 244}, {SEC_ERROR_READ_ONLY, 245}, {SEC_ERROR_NO_SLOT_SELECTED, 246}, {SEC_ERROR_CERT_NICKNAME_COLLISION, 247}, {SEC_ERROR_KEY_NICKNAME_COLLISION, 248}, {SEC_ERROR_SAFE_NOT_CREATED, 249}, {SEC_ERROR_BAGGAGE_NOT_CREATED, 250}, {XP_JAVA_REMOVE_PRINCIPAL_ERROR, 251}, {XP_JAVA_DELETE_PRIVILEGE_ERROR, 252}, {XP_JAVA_CERT_NOT_EXISTS_ERROR, 253}, {SEC_ERROR_BAD_EXPORT_ALGORITHM, 254}, {SEC_ERROR_EXPORTING_CERTIFICATES, 255}, {SEC_ERROR_IMPORTING_CERTIFICATES, 256}, {SEC_ERROR_PKCS12_DECODING_PFX, 257}, {SEC_ERROR_PKCS12_INVALID_MAC, 258}, {SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, 259}, {SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE, 260}, {SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, 261}, {SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, 262}, {SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, 263}, {SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT, 264}, {SEC_ERROR_PKCS12_CERT_COLLISION, 265}, {SEC_ERROR_USER_CANCELLED, 266}, {SEC_ERROR_PKCS12_DUPLICATE_DATA, 267}, {SEC_ERROR_MESSAGE_SEND_ABORTED, 268}, {SEC_ERROR_INADEQUATE_KEY_USAGE, 269}, {SEC_ERROR_INADEQUATE_CERT_TYPE, 270}, {SEC_ERROR_CERT_ADDR_MISMATCH, 271}, {SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, 272}, {SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, 273}, {SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, 274}, {SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, 275}, {SEC_ERROR_PKCS12_UNABLE_TO_WRITE, 276}, {SEC_ERROR_PKCS12_UNABLE_TO_READ, 277}, {SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, 278}, {SEC_ERROR_KEYGEN_FAIL, 279}, {SEC_ERROR_INVALID_PASSWORD, 280}, {SEC_ERROR_RETRY_OLD_PASSWORD, 281}, {SEC_ERROR_BAD_NICKNAME, 282}, {SEC_ERROR_NOT_FORTEZZA_ISSUER, 283}, {SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, 284}, {SEC_ERROR_JS_INVALID_MODULE_NAME, 285}, {SEC_ERROR_JS_INVALID_DLL, 286}, {SEC_ERROR_JS_ADD_MOD_FAILURE, 287}, {SEC_ERROR_JS_DEL_MOD_FAILURE, 288}, {SEC_ERROR_OLD_KRL, 289}, {SEC_ERROR_CKL_CONFLICT, 290}, {SEC_ERROR_CERT_NOT_IN_NAME_SPACE, 291}, {SEC_ERROR_KRL_NOT_YET_VALID, 292}, {SEC_ERROR_CRL_NOT_YET_VALID, 293}, {SEC_ERROR_UNKNOWN_CERT, 294}, {SEC_ERROR_UNKNOWN_SIGNER, 295}, {SEC_ERROR_CERT_BAD_ACCESS_LOCATION, 296}, {SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, 297}, {SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, 298}, {SEC_ERROR_OCSP_MALFORMED_REQUEST, 299}, {SEC_ERROR_OCSP_SERVER_ERROR, 300}, {SEC_ERROR_OCSP_TRY_SERVER_LATER, 301}, {SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, 302}, {SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, 303}, {SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, 304}, {SEC_ERROR_OCSP_UNKNOWN_CERT, 305}, {SEC_ERROR_OCSP_NOT_ENABLED, 306}, {SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, 307}, {SEC_ERROR_OCSP_MALFORMED_RESPONSE, 308}, {SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, 309}, {SEC_ERROR_OCSP_FUTURE_RESPONSE, 310}, {SEC_ERROR_OCSP_OLD_RESPONSE, 311}, {SEC_ERROR_DIGEST_NOT_FOUND, 312}, {SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE, 313} }; #define numErrcodes (sizeof(errcodeTable)/sizeof(Errcode)) static int errcodeCompare(const void *elem1, const void *elem2) { Errcode *ec1, *ec2; ec1 = (Errcode*) elem1; ec2 = (Errcode*) elem2; if( ec1->native < ec2->native ) { return -1; } else if( ec1->native == ec2->native ) { return 0; } else { /* ec1->native > ec2->native */ return 1; } } #ifdef DEBUG static int initialized = 0; #endif /************************************************************************ ** ** J S S _ i n i t E r r c o d e T r a n s l a t i o n T a b l e. ** ** Initializes the error code translation table. This should be called ** by CryptoManager.initialize(), and must be called before any calls to ** JSS_ConvertNativeErrcodeToJava. ** */ void JSS_initErrcodeTranslationTable() { /* sort the table by native errcode */ qsort(errcodeTable, numErrcodes, sizeof(Errcode), errcodeCompare); #ifdef DEBUG initialized = 1; #endif } /************************************************************************ ** ** J S S _ C o n v e r t N a t i v e E r r c o d e T o J a v a ** ** Converts an NSPR or NSS error code to a Java error code. ** (defined in the class o.m.util.NativeErrcodes) ** ** Returns ** The Java error code, or -1 if a corresponding Java error code could ** not be found. */ int JSS_ConvertNativeErrcodeToJava(PRErrorCode nativeErrcode) { Errcode key; Errcode *target; #ifdef DEBUG PR_ASSERT(initialized); #endif key.native = nativeErrcode; key.java = -1; target = bsearch( &key, errcodeTable, numErrcodes, sizeof(Errcode), errcodeCompare ); if( target == NULL ) { return -1; } else { return target->java; } } jss-4.6.3/org/mozilla/jss/util/NativeErrcodes.java000066400000000000000000000506551362106420000221220ustar00rootroot00000000000000/* 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.util; /** An enumeration of all error codes from NSS and NSPR. The integer values associated with each error code are subject to change, so DO NOT DEPEND ON THEM. Only use the symbolic names. */ public class NativeErrcodes { public static final int PR_OUT_OF_MEMORY_ERROR = 1; public static final int PR_BAD_DESCRIPTOR_ERROR = 2; public static final int PR_WOULD_BLOCK_ERROR = 3; public static final int PR_ACCESS_FAULT_ERROR = 4; public static final int PR_INVALID_METHOD_ERROR = 5; public static final int PR_ILLEGAL_ACCESS_ERROR = 6; public static final int PR_UNKNOWN_ERROR = 7; public static final int PR_PENDING_INTERRUPT_ERROR = 8; public static final int PR_NOT_IMPLEMENTED_ERROR = 9; public static final int PR_IO_ERROR = 10; public static final int PR_IO_TIMEOUT_ERROR = 11; public static final int PR_IO_PENDING_ERROR = 12; public static final int PR_DIRECTORY_OPEN_ERROR = 13; public static final int PR_INVALID_ARGUMENT_ERROR = 14; public static final int PR_ADDRESS_NOT_AVAILABLE_ERROR = 15; public static final int PR_ADDRESS_NOT_SUPPORTED_ERROR = 16; public static final int PR_IS_CONNECTED_ERROR = 17; public static final int PR_BAD_ADDRESS_ERROR = 18; public static final int PR_ADDRESS_IN_USE_ERROR = 19; public static final int PR_CONNECT_REFUSED_ERROR = 20; public static final int PR_NETWORK_UNREACHABLE_ERROR = 21; public static final int PR_CONNECT_TIMEOUT_ERROR = 22; public static final int PR_NOT_CONNECTED_ERROR = 23; public static final int PR_LOAD_LIBRARY_ERROR = 24; public static final int PR_UNLOAD_LIBRARY_ERROR = 25; public static final int PR_FIND_SYMBOL_ERROR = 26; public static final int PR_INSUFFICIENT_RESOURCES_ERROR = 27; public static final int PR_DIRECTORY_LOOKUP_ERROR = 28; public static final int PR_TPD_RANGE_ERROR = 29; public static final int PR_PROC_DESC_TABLE_FULL_ERROR = 30; public static final int PR_SYS_DESC_TABLE_FULL_ERROR = 31; public static final int PR_NOT_SOCKET_ERROR = 32; public static final int PR_NOT_TCP_SOCKET_ERROR = 33; public static final int PR_SOCKET_ADDRESS_IS_BOUND_ERROR = 34; public static final int PR_NO_ACCESS_RIGHTS_ERROR = 35; public static final int PR_OPERATION_NOT_SUPPORTED_ERROR = 36; public static final int PR_PROTOCOL_NOT_SUPPORTED_ERROR = 37; public static final int PR_REMOTE_FILE_ERROR = 38; public static final int PR_BUFFER_OVERFLOW_ERROR = 39; public static final int PR_CONNECT_RESET_ERROR = 40; public static final int PR_RANGE_ERROR = 41; public static final int PR_DEADLOCK_ERROR = 42; public static final int PR_FILE_IS_LOCKED_ERROR = 43; public static final int PR_FILE_TOO_BIG_ERROR = 44; public static final int PR_NO_DEVICE_SPACE_ERROR = 45; public static final int PR_PIPE_ERROR = 46; public static final int PR_NO_SEEK_DEVICE_ERROR = 47; public static final int PR_IS_DIRECTORY_ERROR = 48; public static final int PR_LOOP_ERROR = 49; public static final int PR_NAME_TOO_LONG_ERROR = 50; public static final int PR_FILE_NOT_FOUND_ERROR = 51; public static final int PR_NOT_DIRECTORY_ERROR = 52; public static final int PR_READ_ONLY_FILESYSTEM_ERROR = 53; public static final int PR_DIRECTORY_NOT_EMPTY_ERROR = 54; public static final int PR_FILESYSTEM_MOUNTED_ERROR = 55; public static final int PR_NOT_SAME_DEVICE_ERROR = 56; public static final int PR_DIRECTORY_CORRUPTED_ERROR = 57; public static final int PR_FILE_EXISTS_ERROR = 58; public static final int PR_MAX_DIRECTORY_ENTRIES_ERROR = 59; public static final int PR_INVALID_DEVICE_STATE_ERROR = 60; public static final int PR_DEVICE_IS_LOCKED_ERROR = 61; public static final int PR_NO_MORE_FILES_ERROR = 62; public static final int PR_END_OF_FILE_ERROR = 63; public static final int PR_FILE_SEEK_ERROR = 64; public static final int PR_FILE_IS_BUSY_ERROR = 65; public static final int PR_OPERATION_ABORTED_ERROR = 66; public static final int PR_IN_PROGRESS_ERROR = 67; public static final int PR_ALREADY_INITIATED_ERROR = 68; public static final int PR_GROUP_EMPTY_ERROR = 69; public static final int PR_INVALID_STATE_ERROR = 70; public static final int PR_NETWORK_DOWN_ERROR = 71; public static final int PR_SOCKET_SHUTDOWN_ERROR = 72; public static final int PR_CONNECT_ABORTED_ERROR = 73; public static final int PR_HOST_UNREACHABLE_ERROR = 74; public static final int SSL_ERROR_BASE = 77; public static final int SSL_ERROR_EXPORT_ONLY_SERVER = 78; public static final int SSL_ERROR_US_ONLY_SERVER = 79; public static final int SSL_ERROR_NO_CYPHER_OVERLAP = 80; public static final int SSL_ERROR_NO_CERTIFICATE = 81; public static final int SSL_ERROR_BAD_CERTIFICATE = 82; public static final int SSL_ERROR_BAD_CLIENT = 83; public static final int SSL_ERROR_BAD_SERVER = 84; public static final int SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE = 85; public static final int SSL_ERROR_UNSUPPORTED_VERSION = 86; public static final int SSL_ERROR_WRONG_CERTIFICATE = 87; public static final int SSL_ERROR_BAD_CERT_DOMAIN = 88; public static final int SSL_ERROR_POST_WARNING = 89; public static final int SSL_ERROR_SSL2_DISABLED = 90; public static final int SSL_ERROR_BAD_MAC_READ = 91; public static final int SSL_ERROR_BAD_MAC_ALERT = 92; public static final int SSL_ERROR_BAD_CERT_ALERT = 93; public static final int SSL_ERROR_REVOKED_CERT_ALERT = 94; public static final int SSL_ERROR_EXPIRED_CERT_ALERT = 95; public static final int SSL_ERROR_SSL_DISABLED = 96; /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. * SSL_ERROR_FORTEZZA_PQG is a placeholder for backward * compatibility. */ @Deprecated public static final int SSL_ERROR_FORTEZZA_PQG = 97; public static final int SSL_ERROR_UNKNOWN_CIPHER_SUITE = 98; public static final int SSL_ERROR_NO_CIPHERS_SUPPORTED = 99; public static final int SSL_ERROR_BAD_BLOCK_PADDING = 100; public static final int SSL_ERROR_RX_RECORD_TOO_LONG = 101; public static final int SSL_ERROR_TX_RECORD_TOO_LONG = 102; public static final int SSL_ERROR_RX_MALFORMED_HELLO_REQUEST = 103; public static final int SSL_ERROR_RX_MALFORMED_CLIENT_HELLO = 104; public static final int SSL_ERROR_RX_MALFORMED_SERVER_HELLO = 105; public static final int SSL_ERROR_RX_MALFORMED_CERTIFICATE = 106; public static final int SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH = 107; public static final int SSL_ERROR_RX_MALFORMED_CERT_REQUEST = 108; public static final int SSL_ERROR_RX_MALFORMED_HELLO_DONE = 109; public static final int SSL_ERROR_RX_MALFORMED_CERT_VERIFY = 110; public static final int SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH = 111; public static final int SSL_ERROR_RX_MALFORMED_FINISHED = 112; public static final int SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER = 113; public static final int SSL_ERROR_RX_MALFORMED_ALERT = 114; public static final int SSL_ERROR_RX_MALFORMED_HANDSHAKE = 115; public static final int SSL_ERROR_RX_MALFORMED_APPLICATION_DATA = 116; public static final int SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST = 117; public static final int SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO = 118; public static final int SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO = 119; public static final int SSL_ERROR_RX_UNEXPECTED_CERTIFICATE = 120; public static final int SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH = 121; public static final int SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST = 122; public static final int SSL_ERROR_RX_UNEXPECTED_HELLO_DONE = 123; public static final int SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY = 124; public static final int SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH = 125; public static final int SSL_ERROR_RX_UNEXPECTED_FINISHED = 126; public static final int SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER = 127; public static final int SSL_ERROR_RX_UNEXPECTED_ALERT = 128; public static final int SSL_ERROR_RX_UNEXPECTED_HANDSHAKE = 129; public static final int SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA = 130; public static final int SSL_ERROR_RX_UNKNOWN_RECORD_TYPE = 131; public static final int SSL_ERROR_RX_UNKNOWN_HANDSHAKE = 132; public static final int SSL_ERROR_RX_UNKNOWN_ALERT = 133; public static final int SSL_ERROR_CLOSE_NOTIFY_ALERT = 134; public static final int SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT = 135; public static final int SSL_ERROR_DECOMPRESSION_FAILURE_ALERT = 136; public static final int SSL_ERROR_HANDSHAKE_FAILURE_ALERT = 137; public static final int SSL_ERROR_ILLEGAL_PARAMETER_ALERT = 138; public static final int SSL_ERROR_UNSUPPORTED_CERT_ALERT = 139; public static final int SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT = 140; public static final int SSL_ERROR_GENERATE_RANDOM_FAILURE = 141; public static final int SSL_ERROR_SIGN_HASHES_FAILURE = 142; public static final int SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE = 143; public static final int SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE = 144; public static final int SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE = 145; public static final int SSL_ERROR_ENCRYPTION_FAILURE = 146; public static final int SSL_ERROR_DECRYPTION_FAILURE = 147; public static final int SSL_ERROR_SOCKET_WRITE_FAILURE = 148; public static final int SSL_ERROR_MD5_DIGEST_FAILURE = 149; public static final int SSL_ERROR_SHA_DIGEST_FAILURE = 150; public static final int SSL_ERROR_MAC_COMPUTATION_FAILURE = 151; public static final int SSL_ERROR_SYM_KEY_CONTEXT_FAILURE = 152; public static final int SSL_ERROR_SYM_KEY_UNWRAP_FAILURE = 153; public static final int SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED = 154; public static final int SSL_ERROR_IV_PARAM_FAILURE = 155; public static final int SSL_ERROR_INIT_CIPHER_SUITE_FAILURE = 156; public static final int SSL_ERROR_SESSION_KEY_GEN_FAILURE = 157; public static final int SSL_ERROR_NO_SERVER_KEY_FOR_ALG = 158; public static final int SSL_ERROR_TOKEN_INSERTION_REMOVAL = 159; public static final int SSL_ERROR_TOKEN_SLOT_NOT_FOUND = 160; public static final int SSL_ERROR_NO_COMPRESSION_OVERLAP = 161; public static final int SSL_ERROR_HANDSHAKE_NOT_COMPLETED = 162; public static final int SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE = 163; public static final int SSL_ERROR_CERT_KEA_MISMATCH = 164; public static final int SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA = 165; public static final int SSL_ERROR_SESSION_NOT_FOUND = 166; public static final int SSL_ERROR_DECRYPTION_FAILED_ALERT = 167; public static final int SSL_ERROR_RECORD_OVERFLOW_ALERT = 168; public static final int SSL_ERROR_UNKNOWN_CA_ALERT = 169; public static final int SSL_ERROR_ACCESS_DENIED_ALERT = 170; public static final int SSL_ERROR_DECODE_ERROR_ALERT = 171; public static final int SSL_ERROR_DECRYPT_ERROR_ALERT = 172; public static final int SSL_ERROR_EXPORT_RESTRICTION_ALERT = 173; public static final int SSL_ERROR_PROTOCOL_VERSION_ALERT = 174; public static final int SSL_ERROR_INSUFFICIENT_SECURITY_ALERT = 175; public static final int SSL_ERROR_INTERNAL_ERROR_ALERT = 176; public static final int SSL_ERROR_USER_CANCELED_ALERT = 177; public static final int SSL_ERROR_NO_RENEGOTIATION_ALERT = 178; public static final int SEC_ERROR_IO = 179; public static final int SEC_ERROR_LIBRARY_FAILURE = 180; public static final int SEC_ERROR_BAD_DATA = 181; public static final int SEC_ERROR_OUTPUT_LEN = 182; public static final int SEC_ERROR_INPUT_LEN = 183; public static final int SEC_ERROR_INVALID_ARGS = 184; public static final int SEC_ERROR_INVALID_ALGORITHM = 185; public static final int SEC_ERROR_INVALID_AVA = 186; public static final int SEC_ERROR_INVALID_TIME = 187; public static final int SEC_ERROR_BAD_DER = 188; public static final int SEC_ERROR_BAD_SIGNATURE = 189; public static final int SEC_ERROR_EXPIRED_CERTIFICATE = 190; public static final int SEC_ERROR_REVOKED_CERTIFICATE = 191; public static final int SEC_ERROR_UNKNOWN_ISSUER = 192; public static final int SEC_ERROR_BAD_KEY = 193; public static final int SEC_ERROR_BAD_PASSWORD = 194; public static final int SEC_ERROR_RETRY_PASSWORD = 195; public static final int SEC_ERROR_NO_NODELOCK = 196; public static final int SEC_ERROR_BAD_DATABASE = 197; public static final int SEC_ERROR_NO_MEMORY = 198; public static final int SEC_ERROR_UNTRUSTED_ISSUER = 199; public static final int SEC_ERROR_UNTRUSTED_CERT = 200; public static final int SEC_ERROR_DUPLICATE_CERT = 201; public static final int SEC_ERROR_DUPLICATE_CERT_NAME = 202; public static final int SEC_ERROR_ADDING_CERT = 203; public static final int SEC_ERROR_FILING_KEY = 204; public static final int SEC_ERROR_NO_KEY = 205; public static final int SEC_ERROR_CERT_VALID = 206; public static final int SEC_ERROR_CERT_NOT_VALID = 207; public static final int SEC_ERROR_CERT_NO_RESPONSE = 208; public static final int SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE = 209; public static final int SEC_ERROR_CRL_EXPIRED = 210; public static final int SEC_ERROR_CRL_BAD_SIGNATURE = 211; public static final int SEC_ERROR_CRL_INVALID = 212; public static final int SEC_ERROR_EXTENSION_VALUE_INVALID = 213; public static final int SEC_ERROR_EXTENSION_NOT_FOUND = 214; public static final int SEC_ERROR_CA_CERT_INVALID = 215; public static final int SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID = 216; public static final int SEC_ERROR_CERT_USAGES_INVALID = 217; public static final int SEC_INTERNAL_ONLY = 218; public static final int SEC_ERROR_INVALID_KEY = 219; public static final int SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION = 220; public static final int SEC_ERROR_OLD_CRL = 221; public static final int SEC_ERROR_NO_EMAIL_CERT = 222; public static final int SEC_ERROR_NO_RECIPIENT_CERTS_QUERY = 223; public static final int SEC_ERROR_NOT_A_RECIPIENT = 224; public static final int SEC_ERROR_PKCS7_KEYALG_MISMATCH = 225; public static final int SEC_ERROR_PKCS7_BAD_SIGNATURE = 226; public static final int SEC_ERROR_UNSUPPORTED_KEYALG = 227; public static final int SEC_ERROR_DECRYPTION_DISALLOWED = 228; /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. * XP_SEC_FORTEZZA_BAD_CARD, XP_SEC_FORTEZZA_NO_CARD, * XP_SEC_FORTEZZA_NONE_SELECTED, XP_SEC_FORTEZZA_MORE_INFO * XP_SEC_FORTEZZA_PERSON_NOT_FOUND, XP_SEC_FORTEZZA_NO_MORE_INFO * XP_SEC_FORTEZZA_BAD_PIN and XP_SEC_FORTEZZA_PERSON_ERROR are * placeholder for backward compatibility. */ public static final int XP_SEC_FORTEZZA_BAD_CARD = 229; public static final int XP_SEC_FORTEZZA_NO_CARD = 230; public static final int XP_SEC_FORTEZZA_NONE_SELECTED = 231; public static final int XP_SEC_FORTEZZA_MORE_INFO = 232; public static final int XP_SEC_FORTEZZA_PERSON_NOT_FOUND = 233; public static final int XP_SEC_FORTEZZA_NO_MORE_INFO = 234; public static final int XP_SEC_FORTEZZA_BAD_PIN = 235; public static final int XP_SEC_FORTEZZA_PERSON_ERROR = 236; public static final int SEC_ERROR_NO_KRL = 237; public static final int SEC_ERROR_KRL_EXPIRED = 238; public static final int SEC_ERROR_KRL_BAD_SIGNATURE = 239; public static final int SEC_ERROR_REVOKED_KEY = 240; public static final int SEC_ERROR_KRL_INVALID = 241; public static final int SEC_ERROR_NEED_RANDOM = 242; public static final int SEC_ERROR_NO_MODULE = 243; public static final int SEC_ERROR_NO_TOKEN = 244; public static final int SEC_ERROR_READ_ONLY = 245; public static final int SEC_ERROR_NO_SLOT_SELECTED = 246; public static final int SEC_ERROR_CERT_NICKNAME_COLLISION = 247; public static final int SEC_ERROR_KEY_NICKNAME_COLLISION = 248; public static final int SEC_ERROR_SAFE_NOT_CREATED = 249; public static final int SEC_ERROR_BAGGAGE_NOT_CREATED = 250; public static final int XP_JAVA_REMOVE_PRINCIPAL_ERROR = 251; public static final int XP_JAVA_DELETE_PRIVILEGE_ERROR = 252; public static final int XP_JAVA_CERT_NOT_EXISTS_ERROR = 253; public static final int SEC_ERROR_BAD_EXPORT_ALGORITHM = 254; public static final int SEC_ERROR_EXPORTING_CERTIFICATES = 255; public static final int SEC_ERROR_IMPORTING_CERTIFICATES = 256; public static final int SEC_ERROR_PKCS12_DECODING_PFX = 257; public static final int SEC_ERROR_PKCS12_INVALID_MAC = 258; public static final int SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM = 259; public static final int SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE = 260; public static final int SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE = 261; public static final int SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM = 262; public static final int SEC_ERROR_PKCS12_UNSUPPORTED_VERSION = 263; public static final int SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT = 264; public static final int SEC_ERROR_PKCS12_CERT_COLLISION = 265; public static final int SEC_ERROR_USER_CANCELLED = 266; public static final int SEC_ERROR_PKCS12_DUPLICATE_DATA = 267; public static final int SEC_ERROR_MESSAGE_SEND_ABORTED = 268; public static final int SEC_ERROR_INADEQUATE_KEY_USAGE = 269; public static final int SEC_ERROR_INADEQUATE_CERT_TYPE = 270; public static final int SEC_ERROR_CERT_ADDR_MISMATCH = 271; public static final int SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY = 272; public static final int SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN = 273; public static final int SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME = 274; public static final int SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY = 275; public static final int SEC_ERROR_PKCS12_UNABLE_TO_WRITE = 276; public static final int SEC_ERROR_PKCS12_UNABLE_TO_READ = 277; public static final int SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED = 278; public static final int SEC_ERROR_KEYGEN_FAIL = 279; public static final int SEC_ERROR_INVALID_PASSWORD = 280; public static final int SEC_ERROR_RETRY_OLD_PASSWORD = 281; public static final int SEC_ERROR_BAD_NICKNAME = 282; /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. * SEC_ERROR_NOT_FORTEZZA_ISSUER is a placeholder for backward * compatibility. */ @Deprecated public static final int SEC_ERROR_NOT_FORTEZZA_ISSUER = 283; public static final int SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY = 284; public static final int SEC_ERROR_JS_INVALID_MODULE_NAME = 285; public static final int SEC_ERROR_JS_INVALID_DLL = 286; public static final int SEC_ERROR_JS_ADD_MOD_FAILURE = 287; public static final int SEC_ERROR_JS_DEL_MOD_FAILURE = 288; public static final int SEC_ERROR_OLD_KRL = 289; public static final int SEC_ERROR_CKL_CONFLICT = 290; public static final int SEC_ERROR_CERT_NOT_IN_NAME_SPACE = 291; public static final int SEC_ERROR_KRL_NOT_YET_VALID = 292; public static final int SEC_ERROR_CRL_NOT_YET_VALID = 293; public static final int SEC_ERROR_UNKNOWN_CERT = 294; public static final int SEC_ERROR_UNKNOWN_SIGNER = 295; public static final int SEC_ERROR_CERT_BAD_ACCESS_LOCATION = 296; public static final int SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE = 297; public static final int SEC_ERROR_OCSP_BAD_HTTP_RESPONSE = 298; public static final int SEC_ERROR_OCSP_MALFORMED_REQUEST = 299; public static final int SEC_ERROR_OCSP_SERVER_ERROR = 300; public static final int SEC_ERROR_OCSP_TRY_SERVER_LATER = 301; public static final int SEC_ERROR_OCSP_REQUEST_NEEDS_SIG = 302; public static final int SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST = 303; public static final int SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS = 304; public static final int SEC_ERROR_OCSP_UNKNOWN_CERT = 305; public static final int SEC_ERROR_OCSP_NOT_ENABLED = 306; public static final int SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER = 307; public static final int SEC_ERROR_OCSP_MALFORMED_RESPONSE = 308; public static final int SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE = 309; public static final int SEC_ERROR_OCSP_FUTURE_RESPONSE = 310; public static final int SEC_ERROR_OCSP_OLD_RESPONSE = 311; public static final int SEC_ERROR_DIGEST_NOT_FOUND = 312; public static final int SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE = 313; } jss-4.6.3/org/mozilla/jss/util/NativeProxy.java000066400000000000000000000154421362106420000214700ustar00rootroot00000000000000/* 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.util; import java.util.HashSet; import java.lang.AutoCloseable; import java.lang.Thread; import java.util.Arrays; import org.mozilla.jss.CryptoManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * NativeProxy, a superclass for Java classes that mirror C data structures. * * It contains some code to help make sure that native memory is getting * freed properly. * * @author nicolson * @version $Revision$ $Date$ */ public abstract class NativeProxy implements AutoCloseable { public static Logger logger = LoggerFactory.getLogger(NativeProxy.class); private static final boolean saveStacktraces = assertsEnabled() && CryptoManager.JSS_DEBUG; /** * Create a NativeProxy from a byte array representing a C pointer. * This is the primary way of creating a NativeProxy; it should be called * from the constructor of your subclass. * * @param pointer A byte array, created with JSS_ptrToByteArray, that * contains a pointer pointing to a native data structure. The * NativeProxy instance acts as a proxy for that native data structure. */ public NativeProxy(byte[] pointer) { this(pointer, true); } /** * Create a NativeProxy from a byte array representing a C pointer. * This allows for creating an untracked NativeProxy instance (when * track=false), which allows for creating NativeProxy instances out * of stack-allocated variables and/or creating NativeProxies which * aren't freed. */ protected NativeProxy(byte[] pointer, boolean track) { mPointer = pointer; if (track) { assert(pointer != null); registry.add(this); if (saveStacktraces) { mTrace = Arrays.toString(Thread.currentThread().getStackTrace()); } } } /** * Deep comparison operator. * @return true if obj has the same underlying native * pointer. false if the obj is null or has * a different underlying native pointer. */ public boolean equals(Object obj) { if(obj==null) { return false; } if( ! (obj instanceof NativeProxy) ) { return false; } if (((NativeProxy)obj).mPointer == null) { /* If mPointer is null, we have no way to compare the values * of the pointers, so assume they're unequal. */ return false; } return Arrays.equals(((NativeProxy)obj).mPointer, mPointer); } /** * Release the native resources used by this proxy. * Subclasses of NativeProxy must define this method to clean up * data structures in C code that are referenced by this proxy. * releaseNativeResources() will usually be implemented as a native method. *

You don't call this method; NativeProxy.finalize() or close() calls * it for you.

* * If you free these resources explicitly, call clear(); instead. */ protected abstract void releaseNativeResources(); /** * Finalize this NativeProxy by releasing its native resources. * The finalizer calls releaseNativeResources() so you don't have to. * This finalizer should be called from the finalize() method of all * subclasses: * class MyProxy extends NativeProxy { * [...] * protected void finalize() throws Throwable { * // do any object-specific finalization other than * // releasing native resources * [...] * super.finalize(); * } * } * * @deprecated finalize() in Object has been deprecated. Use close(...) * from the AutoCloseable interface instead. */ @Deprecated protected void finalize() throws Throwable { close(); } /** * Close this NativeProxy by releasing its native resources if they * haven't otherwise been freed. * * See comment in finalize. */ public final void close() throws Exception { try { if (registry.remove(this)) { releaseNativeResources(); } } finally { mPointer = null; } } /** * Call clear(...) to clear the value of the pointer, setting it to null. * * This should be used when the pointer has been freed by another means. * Similar to finalize(...) or close(...), except that it doesn't call * releaseNativeResources(...). * * See also: JSS_clearPtrFromProxy(...) in jssutil.h */ public final void clear() { this.mPointer = null; registry.remove(this); } /** * Byte array containing native pointer bytes. */ private byte mPointer[]; /** * String containing backtrace of pointer generation. */ private String mTrace; /** *

Native Proxy Registry *

In debug mode, we keep track of all NativeProxy objects in a * static registry. Whenever a NativeProxy is constructed, it * registers. Whenever it finalizes, it unregisters. At the end of * the game, we should be able to garbage collect and then assert that * the registry is empty. This could be done, for example, in the * jssjava JVM after main() completes. * * This registration process verifies that people are calling * NativeProxy.finalize() from their subclasses of NativeProxy, so that * releaseNativeResources() gets called. */ static HashSet registry = new HashSet(); /** * Internal helper to check whether or not assertions are enabled in the * JVM. * * See: https://docs.oracle.com/javase/8/docs/technotes/guides/language/assert.html */ private static boolean assertsEnabled() { boolean enabled = false; assert enabled = true; return enabled; } /** * Assert that the Registry is empty. Only works in debug mode; in * ship mode, it is a no-op. If the Registry is not empty when this * is called, an assertion (org.mozilla.jss.util.AssertionException) * is thrown. */ public synchronized static void assertRegistryEmpty() { if (!registry.isEmpty()) { logger.warn(registry.size() + " NativeProxys are still registered."); if (saveStacktraces) { for (NativeProxy proxy : registry) { logger.warn("\t" + Arrays.toString(proxy.mPointer) + " ::: " + proxy.mTrace); } } } else { logger.debug("NativeProxy registry is empty"); } } } jss-4.6.3/org/mozilla/jss/util/NotImplementedException.java000066400000000000000000000014671362106420000240050ustar00rootroot00000000000000/* 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.util; /** * This exception is thrown whenever something isn't implemented. */ public class NotImplementedException extends Exception { private static final long serialVersionUID = 1L; public NotImplementedException() { super(); } public NotImplementedException(String mesg) { super(mesg); } public NotImplementedException(String mesg, Throwable cause) { super(mesg, cause); } public NotImplementedException(String mesg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(mesg, cause, enableSuppression, writableStackTrace); } } jss-4.6.3/org/mozilla/jss/util/NullPasswordCallback.java000066400000000000000000000017231362106420000232470ustar00rootroot00000000000000/* 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.util; /** * A PasswordCallback that immediately gives up. This should be used * when a user is not available to enter a password. Any operations * that require a password will fail if this is used, unless the token * has already been logged in manually. * * @see org.mozilla.jss.crypto.CryptoToken#login */ public class NullPasswordCallback implements PasswordCallback { public Password getPasswordFirstAttempt(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { throw new PasswordCallback.GiveUpException(); } public Password getPasswordAgain(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { throw new PasswordCallback.GiveUpException(); } } jss-4.6.3/org/mozilla/jss/util/Password.java000066400000000000000000000213071362106420000207770ustar00rootroot00000000000000/* 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.util; import java.io.CharConversionException; import java.io.Console; import java.io.PrintWriter; import java.io.StringWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Stores a password. clear should be * called when the password is no longer needed so that the sensitive * information is not left in memory. *

A Password can be used as a hard-coded * PasswordCallback. * @see PasswordCallback */ public class Password implements PasswordCallback, Cloneable, java.io.Serializable { private static final long serialVersionUID = 1L; public static Logger logger = LoggerFactory.getLogger(Password.class); // store the location where the Password object was created private StackTraceElement[] stackTrace = new Throwable().getStackTrace(); /** * Don't use this if you aren't Password. */ private Password() { cleared = true; } /** * Creates a Password from a char array, then wipes the char array. * @param pw A char[] containing the password. This array will be * cleared (set to zeroes) by the constructor. */ public Password(char[] pw) { int i; int length = pw.length; cleared = false; password = new char[length]; for(i=0; i < length; i++) { password[i] = pw[i]; pw[i] = 0; } } /** * An implementation of * PasswordCallback.getPasswordFirstAttempt. This allows * a Password object to be treated as a * PasswordCallback. This method simply returns a clone * of the password. * * @return A copy of the password. The caller is responsible for * clearing this copy. */ public synchronized Password getPasswordFirstAttempt(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { if(cleared) { throw new PasswordCallback.GiveUpException(); } return (Password)this.clone(); } /** * Compares this password to another and returns true if they * are the same. */ public synchronized boolean equals(Object obj) { if(obj == null || !(obj instanceof Password)) { return false; } Password pw = (Password)obj; if( pw.password==null || password==null) { return false; } if( pw.password.length != password.length ) { return false; } for(int i=0; i < password.length; i++) { if(pw.password[i] != password[i]) { return false; } } return true; } /** * An implementation of PasswordCallback.getPasswordAgain. * This allows a Password object to be used as a * PasswordCallback. This method is only called after * a call to getPasswordFirstAttempt returned the wrong * password. This means the password is incorrect and there's no * sense returning it again, so a GiveUpException is thrown. */ public synchronized Password getPasswordAgain(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { throw new PasswordCallback.GiveUpException(); } /** * Returns the char array underlying this password. It must not be * modified in any way. */ public synchronized char[] getChars() { return password; } /** * Returns a char array that is a copy of the password. * The caller is responsible for wiping the returned array, * for example using wipeChars. */ public synchronized char[] getCharCopy() { return password.clone(); } /** * Returns a null-terminated byte array that is the byte-encoding of * this password. * The returned array is a copy of the password. * The caller is responsible for wiping the returned array, * for example using wipeChars. */ synchronized byte[] getByteCopy() { return charToByte( password.clone() ); } /** * Clears the password so that sensitive data is no longer present * in memory. This should be called as soon as the password is no * longer needed. */ public synchronized void clear() { int i; int len = password.length; for(i=0; i < len; i++) { password[i] = 0; } cleared = true; } /** * Clones the password. The resulting clone will be completely independent * of the parent, which means it will have to be separately cleared. */ public synchronized Object clone() { Password dolly = new Password(); dolly.password = password.clone(); dolly.cleared = cleared; return dolly; } /** * The finalizer clears the sensitive information before releasing * it to the garbage collector, but it should have been cleared manually * before this point anyway. * * @deprecated finalize() in Object has been deprecated */ @Deprecated protected void finalize() throws Throwable { if (cleared) return; // clear the password first clear(); StringWriter sw = new StringWriter(); PrintWriter out = new PrintWriter(sw, true); int i = 0; // show where the password was created for (; i < stackTrace.length; i++) { StackTraceElement ste = stackTrace[i]; String className = ste.getClassName(); if (Password.class.getName().equals(className)) continue; out.println("Uncleared Password object created at " + ste); i++; break; } // show who called the code for (; i < stackTrace.length; i++) { StackTraceElement ste = stackTrace[i]; out.println(" called by " + ste); } out.println("Please report the above trace to your software vendors."); logger.warn(sw.toString()); } /** * Converts a char array to a null-terminated byte array using a standard * encoding, which is currently UTF8. The caller is responsible for * clearing the copy (with wipeBytes, for example). * * @param charArray A character array, which should not be null. It will * be wiped with zeroes. * @return A copy of the charArray, converted from Unicode to UTF8. It * is the responsibility of the caller to clear the output byte array; * wipeBytes is ideal for this purpose. * @see Password#wipeBytes */ public static byte[] charToByte(char[] charArray) { byte[] byteArray; assert(charArray != null); try { byteArray = UTF8Converter.UnicodeToUTF8NullTerm(charArray); } catch(CharConversionException e) { throw new RuntimeException("Password could not be converted from" +" Unicode: " + e.getMessage(), e); // byteArray = new byte[] {0}; } finally { wipeChars(charArray); } return byteArray; } /** * Wipes a byte array by setting all its elements to zero. * null must not be passed in. */ public static void wipeBytes(byte[] byteArray) { assert(byteArray != null); UTF8Converter.wipeBytes(byteArray); } /** * Wipes a char array by setting all its elements to zero. * null must not be passed in. */ public static void wipeChars(char[] charArray) { int i; assert(charArray != null); for(i=0; i < charArray.length; i++) { charArray[i] = 0; } } /** * Reads a password from the console with echo disabled. This is a blocking * call which will return after the user types a newline. * It only works with ASCII password characters. * The call is synchronized because it alters terminal settings in * a way that is not thread-safe. * * @exception org.mozilla.jss.util.PasswordCallback.GiveUpException * If the user enters no password (just hits * <enter>). * @return The password the user entered at the command line. */ 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; // true if the char[] has been cleared of sensitive information private boolean cleared; } jss-4.6.3/org/mozilla/jss/util/PasswordCallback.java000066400000000000000000000044141362106420000224140ustar00rootroot00000000000000/* 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.util; /** * Represents a password callback, which is called to login to the key * database and to PKCS #11 tokens. *

The simplest implementation of a PasswordCallback is a Password object. * * @see org.mozilla.jss.util.Password * @see org.mozilla.jss.util.NullPasswordCallback * @see org.mozilla.jss.util.ConsolePasswordCallback * @see org.mozilla.jss.CryptoManager#setPasswordCallback */ public interface PasswordCallback { /** * This exception is thrown if the PasswordCallback * wants to stop guessing passwords. */ public static class GiveUpException extends Exception { private static final long serialVersionUID = 1L; public GiveUpException() { super(); } public GiveUpException(String mesg) { super(mesg); } } /** * Supplies a password. This is called on the first attempt; if it * returns the wrong password, getPasswordAgain will * be called on subsequent attempts. * * @param info Information about the token that is being logged into. * @return The password. This password object is owned by and will * be cleared by the caller. * @exception GiveUpException If the callback does not want to supply * a password. */ public Password getPasswordFirstAttempt(PasswordCallbackInfo info) throws GiveUpException; /** * Tries supplying a password again. This callback will be called if * the first callback returned an invalid password. It will be called * repeatedly until it returns a correct password, or it gives up by * throwing a GiveUpException. * * @param info Information about the token that is being logged into. * @return The password. This password object is owned by and will * be cleared by the caller. * @exception GiveUpException If the callback does not want to supply * a password. This may often be the case if the first attempt failed. */ public Password getPasswordAgain(PasswordCallbackInfo info) throws GiveUpException; } jss-4.6.3/org/mozilla/jss/util/PasswordCallbackInfo.java000066400000000000000000000023471362106420000232330ustar00rootroot00000000000000/* 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.util; /** * An object of this class is passed to a PasswordCallback to give it * information about the token that is being logged into. */ public class PasswordCallbackInfo { /** * @param name The name of the file or token that is being logged into. * @param type The type of object (FILE or * TOKEN) that is being logged into. */ public PasswordCallbackInfo(String name, int type) { assert(type==FILE || type==TOKEN); this.name = name; this.type = type; } /** * The name of the file or token that is being logged into. */ public String getName() { return name; } /** * The type of object that is being logged into, FILE * or TOKEN. */ public int getType() { return type; } protected String name; protected int type; /** * Logging into a file. */ static public final int FILE = 0; /** * Logging into a PKCS #11 token. */ static public final int TOKEN = 1; } jss-4.6.3/org/mozilla/jss/util/SECerrs.h000066400000000000000000000470521362106420000200160ustar00rootroot00000000000000/* 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/. */ /* General security error codes */ /* Caller must #include "secerr.h" */ ER3(SEC_ERROR_IO, SEC_ERROR_BASE + 0, "An I/O error occurred during security authorization.") ER3(SEC_ERROR_LIBRARY_FAILURE, SEC_ERROR_BASE + 1, "security library failure.") ER3(SEC_ERROR_BAD_DATA, SEC_ERROR_BASE + 2, "security library: received bad data.") ER3(SEC_ERROR_OUTPUT_LEN, SEC_ERROR_BASE + 3, "security library: output length error.") ER3(SEC_ERROR_INPUT_LEN, SEC_ERROR_BASE + 4, "security library has experienced an input length error.") ER3(SEC_ERROR_INVALID_ARGS, SEC_ERROR_BASE + 5, "security library: invalid arguments.") ER3(SEC_ERROR_INVALID_ALGORITHM, SEC_ERROR_BASE + 6, "security library: invalid algorithm.") ER3(SEC_ERROR_INVALID_AVA, SEC_ERROR_BASE + 7, "security library: invalid AVA.") ER3(SEC_ERROR_INVALID_TIME, SEC_ERROR_BASE + 8, "Improperly formatted time string.") ER3(SEC_ERROR_BAD_DER, SEC_ERROR_BASE + 9, "security library: improperly formatted DER-encoded message.") ER3(SEC_ERROR_BAD_SIGNATURE, SEC_ERROR_BASE + 10, "Peer's certificate has an invalid signature.") ER3(SEC_ERROR_EXPIRED_CERTIFICATE, SEC_ERROR_BASE + 11, "Peer's Certificate has expired.") ER3(SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_BASE + 12, "Peer's Certificate has been revoked.") ER3(SEC_ERROR_UNKNOWN_ISSUER, SEC_ERROR_BASE + 13, "Peer's Certificate issuer is not recognized.") ER3(SEC_ERROR_BAD_KEY, SEC_ERROR_BASE + 14, "Peer's public key is invalid.") ER3(SEC_ERROR_BAD_PASSWORD, SEC_ERROR_BASE + 15, "The security password entered is incorrect.") ER3(SEC_ERROR_RETRY_PASSWORD, SEC_ERROR_BASE + 16, "New password entered incorrectly. Please try again.") ER3(SEC_ERROR_NO_NODELOCK, SEC_ERROR_BASE + 17, "security library: no nodelock.") ER3(SEC_ERROR_BAD_DATABASE, SEC_ERROR_BASE + 18, "security library: bad database.") ER3(SEC_ERROR_NO_MEMORY, SEC_ERROR_BASE + 19, "security library: memory allocation failure.") ER3(SEC_ERROR_UNTRUSTED_ISSUER, SEC_ERROR_BASE + 20, "Peer's certificate issuer has been marked as not trusted by the user.") ER3(SEC_ERROR_UNTRUSTED_CERT, SEC_ERROR_BASE + 21, "Peer's certificate has been marked as not trusted by the user.") ER3(SEC_ERROR_DUPLICATE_CERT, (SEC_ERROR_BASE + 22), "Certificate already exists in your database.") ER3(SEC_ERROR_DUPLICATE_CERT_NAME, (SEC_ERROR_BASE + 23), "Downloaded certificate's name duplicates one already in your database.") ER3(SEC_ERROR_ADDING_CERT, (SEC_ERROR_BASE + 24), "Error adding certificate to database.") ER3(SEC_ERROR_FILING_KEY, (SEC_ERROR_BASE + 25), "Error refiling the key for this certificate.") ER3(SEC_ERROR_NO_KEY, (SEC_ERROR_BASE + 26), "The private key for this certificate cannot be found in key database") ER3(SEC_ERROR_CERT_VALID, (SEC_ERROR_BASE + 27), "This certificate is valid.") ER3(SEC_ERROR_CERT_NOT_VALID, (SEC_ERROR_BASE + 28), "This certificate is not valid.") ER3(SEC_ERROR_CERT_NO_RESPONSE, (SEC_ERROR_BASE + 29), "Cert Library: No Response") ER3(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, (SEC_ERROR_BASE + 30), "The certificate issuer's certificate has expired. Check your system date and time.") ER3(SEC_ERROR_CRL_EXPIRED, (SEC_ERROR_BASE + 31), "The CRL for the certificate's issuer has expired. Update it or check your system date and time.") ER3(SEC_ERROR_CRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 32), "The CRL for the certificate's issuer has an invalid signature.") ER3(SEC_ERROR_CRL_INVALID, (SEC_ERROR_BASE + 33), "New CRL has an invalid format.") ER3(SEC_ERROR_EXTENSION_VALUE_INVALID, (SEC_ERROR_BASE + 34), "Certificate extension value is invalid.") ER3(SEC_ERROR_EXTENSION_NOT_FOUND, (SEC_ERROR_BASE + 35), "Certificate extension not found.") ER3(SEC_ERROR_CA_CERT_INVALID, (SEC_ERROR_BASE + 36), "Issuer certificate is invalid.") ER3(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, (SEC_ERROR_BASE + 37), "Certificate path length constraint is invalid.") ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38), "Certificate usages field is invalid.") ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39), "**Internal ONLY module**") ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40), "The key does not support the requested operation.") ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41), "Certificate contains unknown critical extension.") ER3(SEC_ERROR_OLD_CRL, (SEC_ERROR_BASE + 42), "New CRL is not later than the current one.") ER3(SEC_ERROR_NO_EMAIL_CERT, (SEC_ERROR_BASE + 43), "Not encrypted or signed: you do not yet have an email certificate.") ER3(SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, (SEC_ERROR_BASE + 44), "Not encrypted: you do not have certificates for each of the recipients.") ER3(SEC_ERROR_NOT_A_RECIPIENT, (SEC_ERROR_BASE + 45), "Cannot decrypt: you are not a recipient, or matching certificate and \ private key not found.") ER3(SEC_ERROR_PKCS7_KEYALG_MISMATCH, (SEC_ERROR_BASE + 46), "Cannot decrypt: key encryption algorithm does not match your certificate.") ER3(SEC_ERROR_PKCS7_BAD_SIGNATURE, (SEC_ERROR_BASE + 47), "Signature verification failed: no signer found, too many signers found, \ or improper or corrupted data.") ER3(SEC_ERROR_UNSUPPORTED_KEYALG, (SEC_ERROR_BASE + 48), "Unsupported or unknown key algorithm.") ER3(SEC_ERROR_DECRYPTION_DISALLOWED, (SEC_ERROR_BASE + 49), "Cannot decrypt: encrypted using a disallowed algorithm or key size.") /* Fortezza Alerts */ ER3(XP_SEC_FORTEZZA_BAD_CARD, (SEC_ERROR_BASE + 50), "Fortezza card has not been properly initialized. \ Please remove it and return it to your issuer.") ER3(XP_SEC_FORTEZZA_NO_CARD, (SEC_ERROR_BASE + 51), "No Fortezza cards Found") ER3(XP_SEC_FORTEZZA_NONE_SELECTED, (SEC_ERROR_BASE + 52), "No Fortezza card selected") ER3(XP_SEC_FORTEZZA_MORE_INFO, (SEC_ERROR_BASE + 53), "Please select a personality to get more info on") ER3(XP_SEC_FORTEZZA_PERSON_NOT_FOUND, (SEC_ERROR_BASE + 54), "Personality not found") ER3(XP_SEC_FORTEZZA_NO_MORE_INFO, (SEC_ERROR_BASE + 55), "No more information on that Personality") ER3(XP_SEC_FORTEZZA_BAD_PIN, (SEC_ERROR_BASE + 56), "Invalid Pin") ER3(XP_SEC_FORTEZZA_PERSON_ERROR, (SEC_ERROR_BASE + 57), "Couldn't initialize Fortezza personalities.") /* end fortezza alerts. */ ER3(SEC_ERROR_NO_KRL, (SEC_ERROR_BASE + 58), "No KRL for this site's certificate has been found.") ER3(SEC_ERROR_KRL_EXPIRED, (SEC_ERROR_BASE + 59), "The KRL for this site's certificate has expired.") ER3(SEC_ERROR_KRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 60), "The KRL for this site's certificate has an invalid signature.") ER3(SEC_ERROR_REVOKED_KEY, (SEC_ERROR_BASE + 61), "The key for this site's certificate has been revoked.") ER3(SEC_ERROR_KRL_INVALID, (SEC_ERROR_BASE + 62), "New KRL has an invalid format.") ER3(SEC_ERROR_NEED_RANDOM, (SEC_ERROR_BASE + 63), "security library: need random data.") ER3(SEC_ERROR_NO_MODULE, (SEC_ERROR_BASE + 64), "security library: no security module can perform the requested operation.") ER3(SEC_ERROR_NO_TOKEN, (SEC_ERROR_BASE + 65), "The security card or token does not exist, needs to be initialized, or has been removed.") ER3(SEC_ERROR_READ_ONLY, (SEC_ERROR_BASE + 66), "security library: read-only database.") ER3(SEC_ERROR_NO_SLOT_SELECTED, (SEC_ERROR_BASE + 67), "No slot or token was selected.") ER3(SEC_ERROR_CERT_NICKNAME_COLLISION, (SEC_ERROR_BASE + 68), "A certificate with the same nickname already exists.") ER3(SEC_ERROR_KEY_NICKNAME_COLLISION, (SEC_ERROR_BASE + 69), "A key with the same nickname already exists.") ER3(SEC_ERROR_SAFE_NOT_CREATED, (SEC_ERROR_BASE + 70), "error while creating safe object") ER3(SEC_ERROR_BAGGAGE_NOT_CREATED, (SEC_ERROR_BASE + 71), "error while creating baggage object") ER3(XP_JAVA_REMOVE_PRINCIPAL_ERROR, (SEC_ERROR_BASE + 72), "Couldn't remove the principal") ER3(XP_JAVA_DELETE_PRIVILEGE_ERROR, (SEC_ERROR_BASE + 73), "Couldn't delete the privilege") ER3(XP_JAVA_CERT_NOT_EXISTS_ERROR, (SEC_ERROR_BASE + 74), "This principal doesn't have a certificate") ER3(SEC_ERROR_BAD_EXPORT_ALGORITHM, (SEC_ERROR_BASE + 75), "Required algorithm is not allowed.") ER3(SEC_ERROR_EXPORTING_CERTIFICATES, (SEC_ERROR_BASE + 76), "Error attempting to export certificates.") ER3(SEC_ERROR_IMPORTING_CERTIFICATES, (SEC_ERROR_BASE + 77), "Error attempting to import certificates.") ER3(SEC_ERROR_PKCS12_DECODING_PFX, (SEC_ERROR_BASE + 78), "Unable to import. Decoding error. File not valid.") ER3(SEC_ERROR_PKCS12_INVALID_MAC, (SEC_ERROR_BASE + 79), "Unable to import. Invalid MAC. Incorrect password or corrupt file.") ER3(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, (SEC_ERROR_BASE + 80), "Unable to import. MAC algorithm not supported.") ER3(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE,(SEC_ERROR_BASE + 81), "Unable to import. Only password integrity and privacy modes supported.") ER3(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, (SEC_ERROR_BASE + 82), "Unable to import. File structure is corrupt.") ER3(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, (SEC_ERROR_BASE + 83), "Unable to import. Encryption algorithm not supported.") ER3(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, (SEC_ERROR_BASE + 84), "Unable to import. File version not supported.") ER3(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT,(SEC_ERROR_BASE + 85), "Unable to import. Incorrect privacy password.") ER3(SEC_ERROR_PKCS12_CERT_COLLISION, (SEC_ERROR_BASE + 86), "Unable to import. Same nickname already exists in database.") ER3(SEC_ERROR_USER_CANCELLED, (SEC_ERROR_BASE + 87), "The user pressed cancel.") ER3(SEC_ERROR_PKCS12_DUPLICATE_DATA, (SEC_ERROR_BASE + 88), "Not imported, already in database.") ER3(SEC_ERROR_MESSAGE_SEND_ABORTED, (SEC_ERROR_BASE + 89), "Message not sent.") ER3(SEC_ERROR_INADEQUATE_KEY_USAGE, (SEC_ERROR_BASE + 90), "Certificate key usage inadequate for attempted operation.") ER3(SEC_ERROR_INADEQUATE_CERT_TYPE, (SEC_ERROR_BASE + 91), "Certificate type not approved for application.") ER3(SEC_ERROR_CERT_ADDR_MISMATCH, (SEC_ERROR_BASE + 92), "Address in signing certificate does not match address in message headers.") ER3(SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, (SEC_ERROR_BASE + 93), "Unable to import. Error attempting to import private key.") ER3(SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, (SEC_ERROR_BASE + 94), "Unable to import. Error attempting to import certificate chain.") ER3(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, (SEC_ERROR_BASE + 95), "Unable to export. Unable to locate certificate or key by nickname.") ER3(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, (SEC_ERROR_BASE + 96), "Unable to export. Private Key could not be located and exported.") ER3(SEC_ERROR_PKCS12_UNABLE_TO_WRITE, (SEC_ERROR_BASE + 97), "Unable to export. Unable to write the export file.") ER3(SEC_ERROR_PKCS12_UNABLE_TO_READ, (SEC_ERROR_BASE + 98), "Unable to import. Unable to read the import file.") ER3(SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, (SEC_ERROR_BASE + 99), "Unable to export. Key database corrupt or deleted.") ER3(SEC_ERROR_KEYGEN_FAIL, (SEC_ERROR_BASE + 100), "Unable to generate public/private key pair.") ER3(SEC_ERROR_INVALID_PASSWORD, (SEC_ERROR_BASE + 101), "Password entered is invalid. Please pick a different one.") ER3(SEC_ERROR_RETRY_OLD_PASSWORD, (SEC_ERROR_BASE + 102), "Old password entered incorrectly. Please try again.") ER3(SEC_ERROR_BAD_NICKNAME, (SEC_ERROR_BASE + 103), "Certificate nickname already in use.") ER3(SEC_ERROR_NOT_FORTEZZA_ISSUER, (SEC_ERROR_BASE + 104), "Peer FORTEZZA chain has a non-FORTEZZA Certificate.") ER3(SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, (SEC_ERROR_BASE + 105), "A sensitive key cannot be moved to the slot where it is needed.") ER3(SEC_ERROR_JS_INVALID_MODULE_NAME, (SEC_ERROR_BASE + 106), "Invalid module name.") ER3(SEC_ERROR_JS_INVALID_DLL, (SEC_ERROR_BASE + 107), "Invalid module path/filename") ER3(SEC_ERROR_JS_ADD_MOD_FAILURE, (SEC_ERROR_BASE + 108), "Unable to add module") ER3(SEC_ERROR_JS_DEL_MOD_FAILURE, (SEC_ERROR_BASE + 109), "Unable to delete module") ER3(SEC_ERROR_OLD_KRL, (SEC_ERROR_BASE + 110), "New KRL is not later than the current one.") ER3(SEC_ERROR_CKL_CONFLICT, (SEC_ERROR_BASE + 111), "New CKL has different issuer than current CKL. Delete current CKL.") ER3(SEC_ERROR_CERT_NOT_IN_NAME_SPACE, (SEC_ERROR_BASE + 112), "The Certifying Authority for this certificate is not permitted to issue a \ certificate with this name.") ER3(SEC_ERROR_KRL_NOT_YET_VALID, (SEC_ERROR_BASE + 113), "The key revocation list for this certificate is not yet valid.") ER3(SEC_ERROR_CRL_NOT_YET_VALID, (SEC_ERROR_BASE + 114), "The certificate revocation list for this certificate is not yet valid.") ER3(SEC_ERROR_UNKNOWN_CERT, (SEC_ERROR_BASE + 115), "The requested certificate could not be found.") ER3(SEC_ERROR_UNKNOWN_SIGNER, (SEC_ERROR_BASE + 116), "The signer's certificate could not be found.") ER3(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, (SEC_ERROR_BASE + 117), "The location for the certificate status server has invalid format.") ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, (SEC_ERROR_BASE + 118), "The OCSP response cannot be fully decoded; it is of an unknown type.") ER3(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 119), "The OCSP server returned unexpected/invalid HTTP data.") ER3(SEC_ERROR_OCSP_MALFORMED_REQUEST, (SEC_ERROR_BASE + 120), "The OCSP server found the request to be corrupted or improperly formed.") ER3(SEC_ERROR_OCSP_SERVER_ERROR, (SEC_ERROR_BASE + 121), "The OCSP server experienced an internal error.") ER3(SEC_ERROR_OCSP_TRY_SERVER_LATER, (SEC_ERROR_BASE + 122), "The OCSP server suggests trying again later.") ER3(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, (SEC_ERROR_BASE + 123), "The OCSP server requires a signature on this request.") ER3(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, (SEC_ERROR_BASE + 124), "The OCSP server has refused this request as unauthorized.") ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, (SEC_ERROR_BASE + 125), "The OCSP server returned an unrecognizable status.") ER3(SEC_ERROR_OCSP_UNKNOWN_CERT, (SEC_ERROR_BASE + 126), "The OCSP server has no status for the certificate.") ER3(SEC_ERROR_OCSP_NOT_ENABLED, (SEC_ERROR_BASE + 127), "You must enable OCSP before performing this operation.") ER3(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, (SEC_ERROR_BASE + 128), "You must set the OCSP default responder before performing this operation.") ER3(SEC_ERROR_OCSP_MALFORMED_RESPONSE, (SEC_ERROR_BASE + 129), "The response from the OCSP server was corrupted or improperly formed.") ER3(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, (SEC_ERROR_BASE + 130), "The signer of the OCSP response is not authorized to give status for \ this certificate.") ER3(SEC_ERROR_OCSP_FUTURE_RESPONSE, (SEC_ERROR_BASE + 131), "The OCSP response is not yet valid (contains a date in the future).") ER3(SEC_ERROR_OCSP_OLD_RESPONSE, (SEC_ERROR_BASE + 132), "The OCSP response contains out-of-date information.") ER3(SEC_ERROR_DIGEST_NOT_FOUND, (SEC_ERROR_BASE + 133), "The CMS or PKCS #7 Digest was not found in signed message.") ER3(SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE, (SEC_ERROR_BASE + 134), "The CMS or PKCS #7 Message type is unsupported.") ER3(SEC_ERROR_MODULE_STUCK, (SEC_ERROR_BASE + 135), "PKCS #11 module could not be removed because it is still in use.") ER3(SEC_ERROR_BAD_TEMPLATE, (SEC_ERROR_BASE + 136), "Could not decode ASN.1 data. Specified template was invalid.") ER3(SEC_ERROR_CRL_NOT_FOUND, (SEC_ERROR_BASE + 137), "No matching CRL was found.") ER3(SEC_ERROR_REUSED_ISSUER_AND_SERIAL, (SEC_ERROR_BASE + 138), "You are attempting to import a cert with the same issuer/serial as \ an existing cert, but that is not the same cert.") ER3(SEC_ERROR_BUSY, (SEC_ERROR_BASE + 139), "NSS could not shutdown. Objects are still in use.") ER3(SEC_ERROR_EXTRA_INPUT, (SEC_ERROR_BASE + 140), "DER-encoded message contained extra unused data.") ER3(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, (SEC_ERROR_BASE + 141), "Unsupported elliptic curve.") ER3(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, (SEC_ERROR_BASE + 142), "Unsupported elliptic curve point form.") ER3(SEC_ERROR_UNRECOGNIZED_OID, (SEC_ERROR_BASE + 143), "Unrecognized Object Identifier.") ER3(SEC_ERROR_OCSP_INVALID_SIGNING_CERT, (SEC_ERROR_BASE + 144), "Invalid OCSP signing certificate in OCSP response.") ER3(SEC_ERROR_REVOKED_CERTIFICATE_CRL, (SEC_ERROR_BASE + 145), "Certificate is revoked in issuer's certificate revocation list.") ER3(SEC_ERROR_REVOKED_CERTIFICATE_OCSP, (SEC_ERROR_BASE + 146), "Issuer's OCSP responder reports certificate is revoked.") ER3(SEC_ERROR_CRL_INVALID_VERSION, (SEC_ERROR_BASE + 147), "Issuer's Certificate Revocation List has an unknown version number.") ER3(SEC_ERROR_CRL_V1_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 148), "Issuer's V1 Certificate Revocation List has a critical extension.") ER3(SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 149), "Issuer's V2 Certificate Revocation List has an unknown critical extension.") ER3(SEC_ERROR_UNKNOWN_OBJECT_TYPE, (SEC_ERROR_BASE + 150), "Unknown object type specified.") ER3(SEC_ERROR_INCOMPATIBLE_PKCS11, (SEC_ERROR_BASE + 151), "PKCS #11 driver violates the spec in an incompatible way.") ER3(SEC_ERROR_NO_EVENT, (SEC_ERROR_BASE + 152), "No new slot event is available at this time.") ER3(SEC_ERROR_CRL_ALREADY_EXISTS, (SEC_ERROR_BASE + 153), "CRL already exists.") ER3(SEC_ERROR_NOT_INITIALIZED, (SEC_ERROR_BASE + 154), "NSS is not initialized.") ER3(SEC_ERROR_TOKEN_NOT_LOGGED_IN, (SEC_ERROR_BASE + 155), "The operation failed because the PKCS#11 token is not logged in.") ER3(SEC_ERROR_OCSP_RESPONDER_CERT_INVALID, (SEC_ERROR_BASE + 156), "Configured OCSP responder's certificate is invalid.") ER3(SEC_ERROR_OCSP_BAD_SIGNATURE, (SEC_ERROR_BASE + 157), "OCSP response has an invalid signature.") ER3(SEC_ERROR_OUT_OF_SEARCH_LIMITS, (SEC_ERROR_BASE + 158), "Cert validation search is out of search limits") ER3(SEC_ERROR_INVALID_POLICY_MAPPING, (SEC_ERROR_BASE + 159), "Policy mapping contains anypolicy") ER3(SEC_ERROR_POLICY_VALIDATION_FAILED, (SEC_ERROR_BASE + 160), "Cert chain fails policy validation") ER3(SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE, (SEC_ERROR_BASE + 161), "Unknown location type in cert AIA extension") ER3(SEC_ERROR_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 162), "Server returned bad HTTP response") ER3(SEC_ERROR_BAD_LDAP_RESPONSE, (SEC_ERROR_BASE + 163), "Server returned bad LDAP response") ER3(SEC_ERROR_FAILED_TO_ENCODE_DATA, (SEC_ERROR_BASE + 164), "Failed to encode data with ASN1 encoder") ER3(SEC_ERROR_BAD_INFO_ACCESS_LOCATION, (SEC_ERROR_BASE + 165), "Bad information access location in cert extension") ER3(SEC_ERROR_LIBPKIX_INTERNAL, (SEC_ERROR_BASE + 166), "Libpkix internal error occured during cert validation.") ER3(SEC_ERROR_PKCS11_GENERAL_ERROR, (SEC_ERROR_BASE + 167), "A PKCS #11 module returned CKR_GENERAL_ERROR, indicating that an unrecoverable error has occurred.") ER3(SEC_ERROR_PKCS11_FUNCTION_FAILED, (SEC_ERROR_BASE + 168), "A PKCS #11 module returned CKR_FUNCTION_FAILED, indicating that the requested function could not be performed. Trying the same operation again might succeed.") ER3(SEC_ERROR_PKCS11_DEVICE_ERROR, (SEC_ERROR_BASE + 169), "A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot.") ER3(SEC_ERROR_BAD_INFO_ACCESS_METHOD, (SEC_ERROR_BASE + 170), "Unknown information access method in certificate extension.") ER3(SEC_ERROR_CRL_IMPORT_FAILED, (SEC_ERROR_BASE + 171), "Error attempting to import a CRL.") jss-4.6.3/org/mozilla/jss/util/SSLerrs.h000066400000000000000000000356671362106420000200560ustar00rootroot00000000000000/* 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/. */ /* SSL-specific security error codes */ /* caller must include "sslerr.h" */ ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0, "Unable to communicate securely. Peer does not support high-grade encryption.") ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1, "Unable to communicate securely. Peer requires high-grade encryption which is not supported.") ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2, "Cannot communicate securely with peer: no common encryption algorithm(s).") ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3, "Unable to find the certificate or key necessary for authentication.") ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4, "Unable to communicate securely with peer: peers's certificate was rejected.") /* unused (SSL_ERROR_BASE + 5),*/ ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6, "The server has encountered bad data from the client.") ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7, "The client has encountered bad data from the server.") ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8, "Unsupported certificate type.") ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9, "Peer using unsupported version of security protocol.") /* unused (SSL_ERROR_BASE + 10),*/ ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11, "Client authentication failed: private key in key database does not match public key in certificate database.") ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12, "Unable to communicate securely with peer: requested domain name does not match the server's certificate.") /* SSL_ERROR_POST_WARNING (SSL_ERROR_BASE + 13), defined in sslerr.h */ ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14), "Peer only supports SSL version 2, which is locally disabled.") ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15), "SSL received a record with an incorrect Message Authentication Code.") ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16), "SSL peer reports incorrect Message Authentication Code.") ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17), "SSL peer cannot verify your certificate.") ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18), "SSL peer rejected your certificate as revoked.") ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19), "SSL peer rejected your certificate as expired.") ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20), "Cannot connect: SSL is disabled.") ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21), "Cannot connect: SSL peer is in another FORTEZZA domain.") ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22), "An unknown SSL cipher suite has been requested.") ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23), "No cipher suites are present and enabled in this program.") ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24), "SSL received a record with bad block padding.") ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25), "SSL received a record that exceeded the maximum permissible length.") ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26), "SSL attempted to send a record that exceeded the maximum permissible length.") /* * Received a malformed (too long or short or invalid content) SSL handshake. */ ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27), "SSL received a malformed Hello Request handshake message.") ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28), "SSL received a malformed Client Hello handshake message.") ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29), "SSL received a malformed Server Hello handshake message.") ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30), "SSL received a malformed Certificate handshake message.") ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31), "SSL received a malformed Server Key Exchange handshake message.") ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32), "SSL received a malformed Certificate Request handshake message.") ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33), "SSL received a malformed Server Hello Done handshake message.") ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34), "SSL received a malformed Certificate Verify handshake message.") ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35), "SSL received a malformed Client Key Exchange handshake message.") ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36), "SSL received a malformed Finished handshake message.") /* * Received a malformed (too long or short) SSL record. */ ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37), "SSL received a malformed Change Cipher Spec record.") ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38), "SSL received a malformed Alert record.") ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39), "SSL received a malformed Handshake record.") ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40), "SSL received a malformed Application Data record.") /* * Received an SSL handshake that was inappropriate for the state we're in. * E.g. Server received message from server, or wrong state in state machine. */ ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41), "SSL received an unexpected Hello Request handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42), "SSL received an unexpected Client Hello handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43), "SSL received an unexpected Server Hello handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44), "SSL received an unexpected Certificate handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45), "SSL received an unexpected Server Key Exchange handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46), "SSL received an unexpected Certificate Request handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47), "SSL received an unexpected Server Hello Done handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48), "SSL received an unexpected Certificate Verify handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49), "SSL received an unexpected Client Key Exchange handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50), "SSL received an unexpected Finished handshake message.") /* * Received an SSL record that was inappropriate for the state we're in. */ ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51), "SSL received an unexpected Change Cipher Spec record.") ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52), "SSL received an unexpected Alert record.") ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53), "SSL received an unexpected Handshake record.") ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54), "SSL received an unexpected Application Data record.") /* * Received record/message with unknown discriminant. */ ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55), "SSL received a record with an unknown content type.") ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56), "SSL received a handshake message with an unknown message type.") ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57), "SSL received an alert record with an unknown alert description.") /* * Received an alert reporting what we did wrong. (more alerts above) */ ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58), "SSL peer has closed this connection.") ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59), "SSL peer was not expecting a handshake message it received.") ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60), "SSL peer was unable to successfully decompress an SSL record it received.") ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61), "SSL peer was unable to negotiate an acceptable set of security parameters.") ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62), "SSL peer rejected a handshake message for unacceptable content.") ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63), "SSL peer does not support certificates of the type it received.") ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64), "SSL peer had some unspecified issue with the certificate it received.") ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65), "SSL experienced a failure of its random number generator.") ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66), "Unable to digitally sign data required to verify your certificate.") ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67), "SSL was unable to extract the public key from the peer's certificate.") ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68), "Unspecified failure while processing SSL Server Key Exchange handshake.") ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69), "Unspecified failure while processing SSL Client Key Exchange handshake.") ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70), "Bulk data encryption algorithm failed in selected cipher suite.") ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71), "Bulk data decryption algorithm failed in selected cipher suite.") ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72), "Attempt to write encrypted data to underlying socket failed.") ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73), "MD5 digest function failed.") ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74), "SHA-1 digest function failed.") ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75), "MAC computation failed.") ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76), "Failure to create Symmetric Key context.") ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77), "Failure to unwrap the Symmetric key in Client Key Exchange message.") ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78), "SSL Server attempted to use domestic-grade public key with export cipher suite.") ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79), "PKCS11 code failed to translate an IV into a param.") ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80), "Failed to initialize the selected cipher suite.") ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81), "Client failed to generate session keys for SSL session.") ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82), "Server has no key for the attempted key exchange algorithm.") ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83), "PKCS#11 token was inserted or removed while operation was in progress.") ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84), "No PKCS#11 token could be found to do a required operation.") ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85), "Cannot communicate securely with peer: no common compression algorithm(s).") ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86), "Cannot initiate another SSL handshake until current handshake is complete.") ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87), "Received incorrect handshakes hash values from peer.") ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88), "The certificate provided cannot be used with the selected key exchange algorithm.") ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA , (SSL_ERROR_BASE + 89), "No certificate authority is trusted for SSL client authentication.") ER3(SSL_ERROR_SESSION_NOT_FOUND , (SSL_ERROR_BASE + 90), "Client's SSL session ID not found in server's session cache.") ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT , (SSL_ERROR_BASE + 91), "Peer was unable to decrypt an SSL record it received.") ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT , (SSL_ERROR_BASE + 92), "Peer received an SSL record that was longer than is permitted.") ER3(SSL_ERROR_UNKNOWN_CA_ALERT , (SSL_ERROR_BASE + 93), "Peer does not recognize and trust the CA that issued your certificate.") ER3(SSL_ERROR_ACCESS_DENIED_ALERT , (SSL_ERROR_BASE + 94), "Peer received a valid certificate, but access was denied.") ER3(SSL_ERROR_DECODE_ERROR_ALERT , (SSL_ERROR_BASE + 95), "Peer could not decode an SSL handshake message.") ER3(SSL_ERROR_DECRYPT_ERROR_ALERT , (SSL_ERROR_BASE + 96), "Peer reports failure of signature verification or key exchange.") ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT , (SSL_ERROR_BASE + 97), "Peer reports negotiation not in compliance with export regulations.") ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT , (SSL_ERROR_BASE + 98), "Peer reports incompatible or unsupported protocol version.") ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT , (SSL_ERROR_BASE + 99), "Server requires ciphers more secure than those supported by client.") ER3(SSL_ERROR_INTERNAL_ERROR_ALERT , (SSL_ERROR_BASE + 100), "Peer reports it experienced an internal error.") ER3(SSL_ERROR_USER_CANCELED_ALERT , (SSL_ERROR_BASE + 101), "Peer user canceled handshake.") ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102), "Peer does not permit renegotiation of SSL security parameters.") ER3(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED , (SSL_ERROR_BASE + 103), "SSL server cache not configured and not disabled for this socket.") ER3(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT , (SSL_ERROR_BASE + 104), "SSL peer does not support requested TLS hello extension.") ER3(SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT , (SSL_ERROR_BASE + 105), "SSL peer could not obtain your certificate from the supplied URL.") ER3(SSL_ERROR_UNRECOGNIZED_NAME_ALERT , (SSL_ERROR_BASE + 106), "SSL peer has no certificate for the requested DNS name.") ER3(SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT , (SSL_ERROR_BASE + 107), "SSL peer was unable to get an OCSP response for its certificate.") ER3(SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT , (SSL_ERROR_BASE + 108), "SSL peer reported bad certificate hash value.") ER3(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 109), "SSL received an unexpected New Session Ticket handshake message.") ER3(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 110), "SSL received a malformed New Session Ticket handshake message.") ER3(SSL_ERROR_DECOMPRESSION_FAILURE, (SSL_ERROR_BASE + 111), "SSL received a compressed record that could not be decompressed.") ER3(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, (SSL_ERROR_BASE + 112), "Renegotiation is not allowed on this SSL socket.") jss-4.6.3/org/mozilla/jss/util/StaticVoidPointer.c000066400000000000000000000022671362106420000221140ustar00rootroot00000000000000#include #include #include "java_ids.h" #include "jssutil.h" jobject JSS_PR_wrapStaticVoidPointer(JNIEnv *env, void **ref) { jbyteArray pointer = NULL; jclass proxyClass; jmethodID constructor; jobject refObj = NULL; PR_ASSERT(env != NULL && ref != NULL && *ref != NULL); /* Convert pointer to byte array. */ pointer = JSS_ptrToByteArray(env, *ref); /* Lookup the class and constructor. */ proxyClass = (*env)->FindClass(env, STATIC_VOID_POINTER_CLASS_NAME); if (proxyClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID(env, proxyClass, PLAIN_CONSTRUCTOR, STATIC_VOID_POINTER_CONSTRUCTOR_SIG); if (constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* Call the constructor. */ refObj = (*env)->NewObject(env, proxyClass, constructor, pointer); finish: PR_ASSERT(refObj || (*env)->ExceptionOccurred(env)); return refObj; } PRStatus JSS_PR_getStaticVoidRef(JNIEnv *env, jobject ref_proxy, void **ref) { return JSS_getPtrFromProxy(env, ref_proxy, ref); } jss-4.6.3/org/mozilla/jss/util/StaticVoidPointer.h000066400000000000000000000002621362106420000221120ustar00rootroot00000000000000#include #include jobject JSS_PR_wrapStaticVoidPointer(JNIEnv *env, void **ref); PRStatus JSS_PR_getStaticVoidRef(JNIEnv *env, jobject ref_proxy, void **ref); jss-4.6.3/org/mozilla/jss/util/StaticVoidPointer.java000066400000000000000000000017641362106420000226140ustar00rootroot00000000000000/* 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.util; import java.util.HashSet; import java.lang.AutoCloseable; import java.lang.Thread; import java.util.Arrays; import org.mozilla.jss.CryptoManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * StaticVoidPointer is a Java class that mirror a statically allocated * `void *` pointer in C. * * This is helpful for implementing NativeEnclosure and preventing the * resulting pointer from getting tracked in the usual NativeProxy allocation * trackers and avoiding a double free. */ public class StaticVoidPointer extends NativeProxy { public StaticVoidPointer(byte[] pointer) { super(pointer, false); } protected void releaseNativeResources() { /* Do nothing: this is a static pointer that doesn't need freeing. */ } } jss-4.6.3/org/mozilla/jss/util/Tunnel.java000066400000000000000000000006751362106420000204470ustar00rootroot00000000000000/* 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.util; /** * A class to allow friendly functions access to other parts of JSS. */ public class Tunnel { protected static byte[] GetPasswordByteCopy(Password pw) { return pw.getByteCopy(); } } jss-4.6.3/org/mozilla/jss/util/UTF8Converter.java000066400000000000000000000230331362106420000216110ustar00rootroot00000000000000/* 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.util; import java.io.CharConversionException; /** * Class for converting between char arrays and byte arrays. The conversion * is guaranteed (in optimized mode only) not to leave any data hanging around * in memory unless there is a catastrophic VM error, which is useful for * encoding passwords. */ public class UTF8Converter { /** * Creates a new UTF8-encoded byte array representing the * char[] passed in. The output array will NOT be null-terminated. * *

This call is safe for passwords; all internal buffers are cleared. * The output array is the owned by the caller, who has responsibility * for clearing it. * *

See http://www.stonehard.com/unicode/standard/ for the UTF-16 * and UTF-8 standards. * * @param unicode An array of Unicode characters, which may have UCS4 * characters encoded in UTF-16. This array must not be null. * @exception CharConversionException If the input characters are invalid. */ public static byte[] UnicodeToUTF8(char[] unicode) throws CharConversionException { return UnicodeToUTF8(unicode, false); } /** * Creates a new null-terminated UTF8-encoded byte array representing the * char[] passed in. * *

This call is safe for passwords; all internal buffers are cleared. * The output array is the owned by the caller, who has responsibility * for clearing it. * *

See http://www.stonehard.com/unicode/standard/ for the UTF-16 * and UTF-8 standards. * * @param unicode An array of Unicode characters, which may have UCS4 * characters encoded in UTF-16. This array must not be null. * @exception CharConversionException If the input characters are invalid. */ public static byte[] UnicodeToUTF8NullTerm(char [] unicode) throws CharConversionException { return UnicodeToUTF8(unicode, true); } /** * Do the work of the above functions. */ protected static byte[] UnicodeToUTF8(char[] unicode, boolean nullTerminate) throws CharConversionException { int uni; // unicode index int utf; // UTF8 index int maxsize; // maximum size of UTF8 output byte[] utf8 = null; // UTF8 output buffer byte[] temp = null; // used to create an array of the correct size char c; // Unicode character int ucs4; // UCS4 encoding of a character boolean failed = true; assert(unicode != null); if(unicode == null) { return null; } try { // Allocate worst-case size (UTF8 bytes == 1.5 times Unicode bytes) maxsize = unicode.length * 3; //chars are 2 bytes each if(nullTerminate) { maxsize++; } utf8 = new byte[maxsize]; for(uni=0, utf=0; uni < unicode.length; uni++) { // // Convert UCS2 to UCS4 // c = unicode[uni]; if( c >= 0xd800 && c <= 0xdbff) { // This is the high half of a UTF-16 char ucs4 = (c-0xd800)<<10; // Now get the lower half if(uni == unicode.length-1) { //There is no lower half throw new CharConversionException(); } c = unicode[++uni]; if(c < 0xdc00 || c > 0xdfff) { // not in the low-half zone throw new CharConversionException(); } ucs4 |= c-0xdc00; ucs4 += 0x00010000; } else if(c >=0xdc00 && c <=0xdfff) { // My class rejects orphaned low-half characters, but the Java // class allows them. I think they really are bogus, so // let's pretend the Java class rejects them too. throw new CharConversionException("Orphaned low-half character: 0x" + Integer.toHexString(c)); } else { // UCS2 char to UCS4 ucs4 = unicode[uni]; } // // UCS4 to UTF8 conversion // if(ucs4 < 0x80) { // 0000 0000 - 0000 007f (ASCII) utf8[utf++] = (byte)ucs4; } else if(ucs4 < 0x800) { // 0000 0080 - 0000 07ff utf8[utf++] = (byte) (0xc0 | ucs4>>6); utf8[utf++] = (byte) (0x80 | (ucs4 & 0x3f) ); } else if(ucs4 < 0x0010000) { // 0000 0800 - 0000 ffff utf8[utf++] = (byte) (0xe0 | ucs4>>12); utf8[utf++] = (byte) (0x80 | ((ucs4>>6) & 0x3f) ); utf8[utf++] = (byte) (0x80 | (ucs4 & 0x3f) ); } else if(ucs4 < 0x00200000) { // 001 0000 - 001f ffff utf8[utf++] = (byte) (0xf0 | ucs4>>18); utf8[utf++] = (byte) (0x80 | ((ucs4>>12) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>6) & 0x3f) ); utf8[utf++] = (byte) (0x80 | (ucs4 & 0x3f) ); } else if(ucs4 < 0x00200000) { // 0020 0000 - 03ff ffff utf8[utf++] = (byte) (0xf8 | ucs4>>24); utf8[utf++] = (byte) (0x80 | ((ucs4>>18) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>12) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>6) & 0x3f) ); utf8[utf++] = (byte) (0x80 | (ucs4 & 0x3f) ); } else { // 0400 0000 - 7fff ffff utf8[utf++] = (byte) (0xfc | ucs4>>30); utf8[utf++] = (byte) (0x80 | ((ucs4>>24) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>18) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>12) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>6) & 0x3f) ); utf8[utf++] = (byte) (0x80 | (ucs4 & 0x3f) ); } } if(nullTerminate) { utf8[utf++] = 0; } // // Copy into a correct-sized array // try { int i; // last index is the size of the UTF8 temp = new byte[utf]; for(i=0; i < utf; i++) { temp[i] = utf8[i]; utf8[i] = 0; } utf8 = temp; temp = null; } finally { if(temp != null) { wipeBytes(temp); } } failed = false; return utf8; } finally { // Cleanup data locations where the password was written if(failed && utf8 != null) { wipeBytes(utf8); utf8 = null; } ucs4 = 0; c = 0; } } /** * Wipes a byte array by setting all of its bytes to zero. * @param array The input array must not be null. */ public static void wipeBytes(byte[] array) { int i; assert(array != null); if(array == null) { return; } for(i=0; i < array.length; i++) { array[i] = 0; } } /** * Testing method */ public static void main(String[] args) { char[] unicode; byte[] utf8; int i, j; try { // // Regular ascii // System.out.println("ASCII Test:"); unicode = new char[128]; for(i=0; i< 128; i++) { unicode[i] = (char) i; } utf8 = UnicodeToUTF8(unicode); i = 0; while( i < 128) { for(j = i; j < 128 && j < i+20; j++) { System.out.print((int)unicode[j] + " "); } System.out.println(); for(j = i; j < 128 && j < i+20; j++) { System.out.print((int)utf8[j] + " "); } System.out.println("\n"); // two lines i = j; } // // UCS2 // System.out.println("UCS2 test:"); unicode = new char[] {'\u0000', '\u007f', '\u0080', '\u0400', '\u07ff', '\u0800', '\u3167', '\ud7ff', '\ue000', '\uffff'}; utf8 = UnicodeToUTF8(unicode); for(i=0; i<10; i++) { System.out.print( Integer.toHexString(unicode[i]) + " "); } System.out.println(); for(i=0; i "+utf8.length+ " bytes of utf8\n"); // // empty array // System.out.println("Empty input test:"); unicode = new char[0]; utf8 = UnicodeToUTF8(unicode); assert(utf8 != null); assert(utf8.length == 0); System.out.println("given 0 bytes Unicode, produces 0 length utf8\n"); // // UCS4 // System.out.println("UCS4 Test:"); unicode = new char[] {'\ud800', '\udc00', '\uda85', '\ude47', '\udbff', '\udfff'}; utf8 = UnicodeToUTF8(unicode); for(i=0; i < 6; i++) { System.out.print( Integer.toHexString(unicode[i]) + " "); } System.out.println(); for(i=0; i < utf8.length; i++) { System.out.print( Integer.toHexString(utf8[i]) + " "); } System.out.println("\n"); // // high half with no low half // System.out.println("high half at end of input:"); try { unicode = new char[] {'\ud800'}; utf8 = UnicodeToUTF8(unicode); throw new RuntimeException("should have failed on bad UCS4"); } catch (CharConversionException e) { System.out.println("Correctly caught bad UCS4\n"); } // // high half with something else // System.out.println("high half with something other than low half:"); try { unicode = new char[] {'\ud800', '\u007f'}; utf8 = UnicodeToUTF8(unicode); throw new RuntimeException("should have failed on bad UCS4"); } catch (CharConversionException e) { System.out.println("Correctly caught bad UCS4\n"); } // // orphaned low half // System.out.println("orphaned low half test:"); try { unicode = new char[] {'\u0032', '\udc01', '\u0033'}; utf8 = UnicodeToUTF8(unicode); throw new RuntimeException("should have failed on bad UCS4"); } catch (CharConversionException e) { System.out.println("Correctly caught bad UCS4\n"); } // // null-terminated // System.out.println("null-terminating:"); unicode = new char[] {'f', 'o', 'o', 'b', 'a', 'r'}; utf8 = UnicodeToUTF8NullTerm(unicode); for(i=0; i < unicode.length; i++) { System.out.print(unicode[i] + " "); } System.out.println(); for(i=0; i < utf8.length; i++) { System.out.print(utf8[i] + " "); } System.out.println("\n"); } catch(CharConversionException e) { System.out.println("Error converting Unicode "+e); } } } jss-4.6.3/org/mozilla/jss/util/errstrings.c000066400000000000000000000040061362106420000206750ustar00rootroot00000000000000/* 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/. */ #include "nspr.h" struct tuple_str { PRErrorCode errNum; const char * errString; }; typedef struct tuple_str tuple_str; #define ER2(a,b) {a, b}, #define ER3(a,b,c) {a, c}, #include "secerr.h" #include "sslerr.h" static const tuple_str errStrings[] = { /* keep this list in ascending order of error numbers */ #include "SSLerrs.h" #include "SECerrs.h" #include "NSPRerrs.h" }; static const PRInt32 numStrings = sizeof(errStrings) / sizeof(tuple_str); /* Returns a UTF-8 encoded constant error string for "errNum". * Returns NULL of errNum is unknown. */ const char * JSS_strerror(PRErrorCode errNum) { PRInt32 low = 0; PRInt32 high = numStrings - 1; PRInt32 i; PRErrorCode num; static int initDone; /* make sure table is in ascending order. * binary search depends on it. */ if (!initDone) { PRErrorCode lastNum = 0x80000000; for (i = low; i <= high; ++i) { num = errStrings[i].errNum; if (num <= lastNum) { fprintf(stderr, "sequence error in error strings at item %d\n" "error %d (%s)\n" "should come after \n" "error %d (%s)\n", i, lastNum, errStrings[i-1].errString, num, errStrings[i].errString); } lastNum = num; } initDone = 1; } /* Do binary search of table. */ while (low + 1 < high) { i = (low + high) / 2; num = errStrings[i].errNum; if (errNum == num) return errStrings[i].errString; if (errNum < num) high = i; else low = i; } if (errNum == errStrings[low].errNum) return errStrings[low].errString; if (errNum == errStrings[high].errNum) return errStrings[high].errString; return NULL; } jss-4.6.3/org/mozilla/jss/util/java_ids.h000066400000000000000000000271531362106420000202700ustar00rootroot00000000000000/* 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/. */ #ifndef JAVA_IDS_H #define JAVA_IDS_H PR_BEGIN_EXTERN_C /* ** JNI uses strings to identify Java classes, fields, and methods. Rather ** than put lots of string constants in our JNI code, we define them once ** here. This has two benefits: it reduces the probability of typos ** (we only have to type the names once), and it allows us to more ** easily change these identifiers. */ #define PLAIN_CONSTRUCTOR "" #define PLAIN_CONSTRUCTOR_SIG "()V" /* * Algorithm */ #define ALGORITHM_CLASS_NAME "org/mozilla/jss/crypto/Algorithm" #define OID_INDEX_FIELD_NAME "oidIndex" #define OID_INDEX_FIELD_SIG "I" /* * BigInteger */ #define BIG_INTEGER_CLASS_NAME "java/math/BigInteger" #define BIG_INTEGER_CONSTRUCTOR_NAME "" #define BIG_INTEGER_CONSTRUCTOR_SIG "([B)V" /* * CipherContextProxy */ #define CIPHER_CONTEXT_PROXY_CLASS_NAME "org/mozilla/jss/pkcs11/CipherContextProxy" #define CIPHER_CONTEXT_PROXY_CONSTRUCTOR_SIG "([B)V" /* * Collection */ #define COLLECTION_CLASS_NAME "java/util/Collection" #define COLLECTION_ADD_NAME "add" #define COLLECTION_ADD_SIG "(Ljava/lang/Object;)Z" /* * InetAddress */ #define GET_ADDR_NAME "getAddress" #define GET_ADDR_SIG "()[B" /* * InputStream */ #define ISTREAM_READ_NAME "read" #define ISTREAM_READ_SIG "([B)I" /* * KeyPair */ #define KEY_PAIR_CLASS_NAME "java/security/KeyPair" #define KEY_PAIR_CONSTRUCTOR_NAME "" #define KEY_PAIR_CONSTRUCTOR_SIG "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V" /* * KeyProxy */ #define KEY_PROXY_FIELD "keyProxy" #define KEY_PROXY_SIG "Lorg/mozilla/jss/pkcs11/KeyProxy;" /* * KeyType */ #define KEYTYPE_CLASS_NAME "org/mozilla/jss/pkcs11/KeyType" #define NULL_KEYTYPE_FIELD "NULL" #define RSA_KEYTYPE_FIELD "RSA" #define DSA_KEYTYPE_FIELD "DSA" #define EC_KEYTYPE_FIELD "EC" #define FORTEZZA_KEYTYPE_FIELD "FORTEZZA" #define DH_KEYTYPE_FIELD "DH" #define KEA_KEYTYPE_FIELD "KEA" #define KEYTYPE_FIELD_SIG "Lorg/mozilla/jss/pkcs11/KeyType;" #define DES_KEYTYPE_FIELD "DES" #define DES3_KEYTYPE_FIELD "DES3" #define RC4_KEYTYPE_FIELD "RC4" #define RC2_KEYTYPE_FIELD "RC2" #define SHA1_HMAC_KEYTYPE_FIELD "SHA1_HMAC" #define AES_KEYTYPE_FIELD "AES" #define GENERIC_SECRET_KEYTYPE_FIELD "GENERIC_SECRET" /* * NativeProxy */ #define NATIVE_PROXY_CLASS_NAME "org/mozilla/jss/util/NativeProxy" #define NATIVE_PROXY_POINTER_FIELD "mPointer" #define NATIVE_PROXY_POINTER_SIG "[B" /* * NSSInit */ #define NSSINIT_CLASS_NAME "org/mozilla/jss/NSSInit" #define NSSINIT_ISINITIALIZED_NAME "isInitialized" #define NSSINIT_ISINITIALIZED_SIG "()Z" /* * OutputStream */ #define OSTREAM_WRITE_NAME "write" #define OSTREAM_WRITE_SIG "([BII)V" /* * Password */ #define PASSWORD_CLASS_NAME "org/mozilla/jss/util/Password" #define PASSWORD_CONSTRUCTOR_SIG "([C)V" #define PW_GET_BYTE_COPY_NAME "getByteCopy" #define PW_GET_BYTE_COPY_SIG "()[B" #define PW_CLEAR_NAME "clear" #define PW_CLEAR_SIG "()V" /* * PasswordCallback */ #define PW_CALLBACK_GET_PW_FIRST_NAME "getPasswordFirstAttempt" #define PW_CALLBACK_GET_PW_FIRST_SIG "(Lorg/mozilla/jss/util/PasswordCallbackInfo;)Lorg/mozilla/jss/util/Password;" #define PW_CALLBACK_GET_PW_AGAIN_NAME "getPasswordAgain" #define PW_CALLBACK_GET_PW_AGAIN_SIG "(Lorg/mozilla/jss/util/PasswordCallbackInfo;)Lorg/mozilla/jss/util/Password;" /* * PK11Cert */ #define CERT_CLASS_NAME "org/mozilla/jss/pkcs11/PK11Cert" #define CERT_CONSTRUCTOR_NAME "" #define CERT_CONSTRUCTOR_SIG "([B[BLjava/lang/String;)V" #define CERT_PROXY_FIELD "certProxy" #define CERT_PROXY_SIG "Lorg/mozilla/jss/pkcs11/CertProxy;" /* * PK11InternalCert */ #define INTERNAL_CERT_CLASS_NAME "org/mozilla/jss/pkcs11/PK11InternalCert" /* * PK11TokenCert */ #define TOKEN_CERT_CLASS_NAME "org/mozilla/jss/pkcs11/PK11TokenCert" /* * PK11InternalTokenCert */ #define INTERNAL_TOKEN_CERT_CLASS_NAME "org/mozilla/jss/pkcs11/PK11InternalTokenCert" /* * PK11DSAPublicKey */ #define PK11_DSA_PUBKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11DSAPublicKey" /* * PK11ECPublicKey */ #define PK11_EC_PUBKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11ECPublicKey" /* * PK11Module */ #define PK11MODULE_CLASS_NAME "org/mozilla/jss/pkcs11/PK11Module" #define PK11MODULE_CONSTRUCTOR_SIG "([B)V" #define PK11MODULE_PROXY_FIELD "moduleProxy" #define PK11MODULE_PROXY_SIG "Lorg/mozilla/jss/pkcs11/ModuleProxy;" /* * PK11PrivKey */ #define PK11PRIVKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11PrivKey" #define PK11PRIVKEY_CONSTRUCTOR_NAME "" #define PK11PRIVKEY_CONSTRUCTOR_SIG "([B)V" /* * PK11PubKey */ #define PK11PUBKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11PubKey" #define PK11PUBKEY_CONSTRUCTOR_NAME "" #define PK11PUBKEY_CONSTRUCTOR_SIG "([B)V" /* * PK11RSAPublicKey */ #define PK11_RSA_PUBKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11RSAPublicKey" /* * PK11Signature */ #define PK11SIGNATURE_CLASS_NAME "org/mozilla/jss/pkcs11/PK11Signature" #define SIG_CONTEXT_PROXY_FIELD "sigContext" #define SIG_CONTEXT_PROXY_SIG "Lorg/mozilla/jss/pkcs11/SigContextProxy;" #define SIG_ALGORITHM_FIELD "algorithm" #define SIG_ALGORITHM_SIG "Lorg/mozilla/jss/crypto/Algorithm;" #define SIG_PW_FIELD "pwExtractor" #define SIG_PW_SIG "Lorg/mozilla/jss/crypto/PasswordExtractor;" #define SIG_KEY_FIELD "key" #define SIG_KEY_SIG "Lorg/mozilla/jss/pkcs11/PK11Key;" /* * PK11Store */ #define PK11STORE_PROXY_FIELD "storeProxy" #define PK11STORE_PROXY_SIG "Lorg/mozilla/jss/pkcs11/TokenProxy;" /* * PK11SymKey */ #define PK11SYMKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11SymKey" #define PK11SYMKEY_CONSTRUCTOR_SIG "([B)V" #define PK11SYMKEY_CONSTRUCTOR_1_SIG "([BLjava/lang/String;)V" /* * PK11Token */ #define PK11TOKEN_PROXY_FIELD "tokenProxy" #define PK11TOKEN_PROXY_SIG "Lorg/mozilla/jss/pkcs11/TokenProxy;" #define PK11TOKEN_CLASS_NAME "org/mozilla/jss/pkcs11/PK11Token" #define PK11TOKEN_CONSTRUCTOR_NAME "" #define PK11TOKEN_CONSTRUCTOR_SIG "([BZZ)V" /* * PrivateKey.KeyType */ #define PRIVKEYTYPE_CLASS_NAME "org/mozilla/jss/crypto/PrivateKey$Type" #define PRIVKEYTYPE_SIG "Lorg/mozilla/jss/crypto/PrivateKey$Type;" #define RSA_PRIVKEYTYPE_FIELD "RSA" #define DSA_PRIVKEYTYPE_FIELD "DSA" #define EC_PRIVKEYTYPE_FIELD "EC" /* * PQGParams */ #define PQG_PARAMS_CONSTRUCTOR_NAME "" #define PQG_PARAMS_CONSTRUCTOR_SIG "(Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;ILjava/math/BigInteger;)V" /* * SigContextProxy */ #define SIG_CONTEXT_PROXY_CLASS_NAME "org/mozilla/jss/pkcs11/SigContextProxy" #define SIG_CONTEXT_PROXY_CONSTRUCTOR_NAME "" #define SIG_CONTEXT_PROXY_CONSTRUCTOR_SIG "([B)V" /* * Socket */ #define SOCKET_GET_OUTPUT_STREAM_NAME "getOutputStream" #define SOCKET_GET_OUTPUT_STREAM_SIG "()Ljava/io/OutputStream;" #define SOCKET_GET_INPUT_STREAM_NAME "getInputStream" #define SOCKET_GET_INPUT_STREAM_SIG "()Ljava/io/InputStream;" #define GET_INET_ADDR_NAME "getInetAddress" #define GET_INET_ADDR_SIG "()Ljava/net/InetAddress;" #define GET_PORT_NAME "getPort" #define GET_PORT_SIG "()I" #define GET_LOCAL_ADDR_NAME "getLocalAddress" #define GET_LOCAL_PORT_NAME "getLocalPort" #define SOCKET_CLOSE_NAME "close" #define SOCKET_CLOSE_SIG "()V" #define SET_SO_TIMEOUT_NAME "setSoTimeout" #define SET_SO_TIMEOUT_SIG "(I)V" #define GET_KEEPALIVE_NAME "getKeepAlive" #define GET_KEEPALIVE_SIG "()Z" #define GET_SEND_BUF_SIZE "getSendBufferSize" #define GET_RECV_BUF_SIZE "getReceiveBufferSize" #define GET_BUF_SIZE_SIG "()I" /* * CryptoManager * */ #define CRYPTO_MANAGER_NAME "org/mozilla/jss/CryptoManager" #define GET_OCSP_POLICY_NAME "getOCSPPolicy" #define GET_OCSP_POLICY_SIG "()I" /* * SocketBase */ #define SOCKET_BASE_NAME "org/mozilla/jss/ssl/SocketBase" #define PROCESS_EXCEPTIONS_NAME "processExceptions" #define PROCESS_EXCEPTIONS_SIG "(Ljava/lang/Throwable;Ljava/lang/Throwable;)Ljava/lang/Throwable;" #define SUPPORTS_IPV6_NAME "supportsIPV6" #define SUPPORTS_IPV6_SIG "()Z" /* * SSLAlertEvent */ #define SSL_ALERT_EVENT_CLASS "org/mozilla/jss/ssl/SSLAlertEvent" /* * SSLCertificateApprovalCallback */ #define SSLCERT_APP_CB_APPROVE_NAME "approve" #define SSLCERT_APP_CB_APPROVE_SIG "(Lorg/mozilla/jss/crypto/X509Certificate;Lorg/mozilla/jss/ssl/SSLCertificateApprovalCallback$ValidityStatus;)Z" /* * SSLSecurityStatus */ #define SSL_SECURITY_STATUS_CLASS_NAME "org/mozilla/jss/ssl/SSLSecurityStatus" #define SSL_SECURITY_STATUS_CONSTRUCTOR_NAME "" #define SSL_SECURITY_STATUS_CONSTRUCTOR_SIG "(ILjava/lang/String;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/mozilla/jss/crypto/X509Certificate;)V" /* * 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;" /* * StringBuffer */ #define STRING_BUFFER_NAME "java/lang/StringBuffer" #define STRING_BUFFER_APPEND_NAME "append" #define STRING_BUFFER_APPEND_SIG "(Ljava/lang/String;)Ljava/lang/StringBuffer;" /* * ValidityStatus */ #define SSLCERT_APP_CB_VALIDITY_STATUS_CLASS \ "org/mozilla/jss/ssl/SSLCertificateApprovalCallback$ValidityStatus" #define SSLCERT_APP_CB_VALIDITY_STATUS_ADD_REASON_NAME "addReason" #define SSLCERT_APP_CB_VALIDITY_STATUS_ADD_REASON_SIG \ "(ILorg/mozilla/jss/pkcs11/PK11Cert;I)V" /* * SymKeyProxy */ #define SYM_KEY_PROXY_FIELD "keyProxy" #define SYM_KEY_PROXY_SIG "Lorg/mozilla/jss/pkcs11/SymKeyProxy;" /* * Throwable */ #define THROWABLE_NAME "java/lang/Throwable" #define THROWABLE_TO_STRING_NAME "toString" #define THROWABLE_TO_STRING_SIG "()Ljava/lang/String;" /* * TokenCallbackInfo */ #define TOKEN_CBINFO_CLASS_NAME "org/mozilla/jss/pkcs11/TokenCallbackInfo" #define TOKEN_CBINFO_CONSTRUCTOR_NAME "" #define TOKEN_CBINFO_CONSTRUCTOR_SIG "(Ljava/lang/String;)V" /* * Vector */ #define VECTOR_ADD_ELEMENT_NAME "addElement" #define VECTOR_ADD_ELEMENT_SIG "(Ljava/lang/Object;)V" /* * X509Certificate */ #define X509_CERT_CLASS "org/mozilla/jss/crypto/X509Certificate" /* * SSLVersionRange */ #define SSL_VERSION_RANGE_CLASS_NAME "org/mozilla/jss/ssl/SSLVersionRange" #define SSL_VERSION_RANGE_CONSTRUCTOR_NAME "" #define SSL_VERSION_RANGE_CONSTRUCTOR_SIG "(II)V" /* * PRFDProxy */ #define PRFD_PROXY_CLASS_NAME "org/mozilla/jss/nss/PRFDProxy" #define PRFD_PROXY_CONSTRUCTOR_SIG "([B)V" /* * SSLFDProxy */ #define SSLFD_PROXY_CLASS_NAME "org/mozilla/jss/nss/SSLFDProxy" #define SSLFD_PROXY_CONSTRUCTOR_SIG "([B)V" #define SSLFD_PROXY_CLIENT_CERT_FIELD "clientCert" #define SSLFD_PROXY_CLIENT_CERT_SIG "Lorg/mozilla/jss/pkcs11/PK11Cert;" #define SSLFD_PROXY_EVENT_LIST_SIG "Ljava/util/ArrayList;" /* * SecurityStatusResult */ #define SECURITY_STATUS_CLASS_NAME "org/mozilla/jss/nss/SecurityStatusResult" #define SECURITY_STATUS_CONSTRUCTOR_SIG "(I[BII[B[B)V" /* * BufferProxy */ #define BUFFER_PROXY_CLASS_NAME "org/mozilla/jss/nss/BufferProxy" #define BUFFER_PROXY_CONSTRUCTOR_SIG "([B)V" /* * GlobalRefProxy */ #define GLOBAL_REF_PROXY_CLASS_NAME "org/mozilla/jss/util/GlobalRefProxy" #define GLOBAL_REF_CONSTRUCTOR_SIG "([B)V" /* * StaticVoidProxy */ #define STATIC_VOID_POINTER_CLASS_NAME "org/mozilla/jss/util/StaticVoidPointer" #define STATIC_VOID_POINTER_CONSTRUCTOR_SIG "([B)V" /* * PKCS#11 CKAttribute */ #define CK_ATTRIBUTE_CLASS_NAME "org/mozilla/jss/pkcs11/attrs/CKAttribute" /* * KBKDF classes */ #define KBKDF_DATA_PARAMETER_CLASS_NAME "org/mozilla/jss/crypto/KBKDFDataParameter" #define KBKDF_DERIVED_KEY_CLASS_NAME "org/mozilla/jss/crypto/KBKDFDerivedKey" PR_END_EXTERN_C #endif jss-4.6.3/org/mozilla/jss/util/jss_bigint.h000066400000000000000000000030751362106420000206400ustar00rootroot00000000000000/* 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/. */ /* Need to include these first: #include #include */ #ifndef JSS_BIG_INT_H #define JSS_BIG_INT_H PR_BEGIN_EXTERN_C /*********************************************************************** * * J S S _ O c t e t S t r i n g T o B y t e A r r a y * * Converts a representation of an integer as a big-endian octet string * stored in a SECItem (as used by the low-level crypto functions) to a * representation of an integer as a big-endian Java byte array. Prepends * a zero byte to force it to be positive. */ jbyteArray JSS_OctetStringToByteArray(JNIEnv *env, SECItem *item); /*********************************************************************** * * J S S _ B y t e A r r a y T o O c t e t S t r i n g * * Converts an integer represented as a big-endian Java byte array to * an integer represented as a big-endian octet string in a SECItem. * * INPUTS * byteArray * A Java byte array containing an integer represented in * big-endian format. Must not be NULL. * item * Pointer to a SECItem that will be filled with the integer * from the byte array, in big-endian format. * RETURNS * PR_SUCCESS if the operation was successful, PR_FAILURE if an exception * was thrown. */ PRStatus JSS_ByteArrayToOctetString(JNIEnv *env, jbyteArray byteArray, SECItem *item); PR_END_EXTERN_C #endif jss-4.6.3/org/mozilla/jss/util/jss_exceptions.h000066400000000000000000000101471362106420000215430ustar00rootroot00000000000000/* 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/. */ /* These are class names suitable for passing to JSS_nativeThrow or ** JSS_nativeThrowMsg. They are the fully qualified class name of the ** exception, separated by slashes instead of periods. */ #ifndef JSS_EXCEPTIONS_H #define JSS_EXCEPTIONS_H PR_BEGIN_EXTERN_C #define JAVA_LANG_EXCEPTION "java/lang/Exception" #define ALREADY_INITIALIZED_EXCEPTION "org/mozilla/jss/crypto/AlreadyInitializedException" #define ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION "java/lang/ArrayIndexOutOfBoundsException" #define INDEX_OUT_OF_BOUNDS_EXCEPTION "java/lang/IndexOutOfBoundsException" #define BAD_PADDING_EXCEPTION "javax/crypto/BadPaddingException" #define BIND_EXCEPTION "java/net/BindException" #define CERT_DATABASE_EXCEPTION "org/mozilla/jss/CertDatabaseException" #define CERTIFICATE_EXCEPTION "java/security/cert/CertificateException" #define CERTIFICATE_ENCODING_EXCEPTION "java/security/cert/CertificateEncodingException" #define CERTIFICATE_EXPIRED_EXCEPTION "java/security/cert/CertificateExpiredException" #define CERTIFICATE_NOT_YET_VALID_EXCEPTION "java/security/cert/CertificateNotYetValidException" #define CERTIFICATE_PARSING_EXCEPTION "java/security/cert/CertificateParsingException" #define CERTIFICATE_REVOKED_EXCEPTION "java/security/cert/CertificateRevokedException" #define CRL_IMPORT_EXCEPTION "org/mozilla/jss/CRLImportException" #define DIGEST_EXCEPTION "java/security/DigestException" #define GENERAL_SECURITY_EXCEPTION "java/security/GeneralSecurityException" #define GENERIC_EXCEPTION "java/lang/Exception" #define GIVE_UP_EXCEPTION "org/mozilla/jss/util/PasswordCallback$GiveUpException" #define ILLEGAL_ARGUMENT_EXCEPTION "java/lang/IllegalArgumentException" #define ILLEGAL_BLOCK_SIZE_EXCEPTION "org/mozilla/jss/crypto/IllegalBlockSizeException" #define INCORRECT_PASSWORD_EXCEPTION "org/mozilla/jss/util/IncorrectPasswordException" #define INTERRUPTED_IO_EXCEPTION "java/io/InterruptedIOException" #define INVALID_DER_EXCEPTION "org/mozilla/jss/crypto/InvalidDERException" #define INVALID_NICKNAME_EXCEPTION "org/mozilla/jss/util/InvalidNicknameException" #define INVALID_KEY_FORMAT_EXCEPTION "org/mozilla/jss/crypto/InvalidKeyFormatException" #define INVALID_PARAMETER_EXCEPTION "java/security/InvalidParameterException" #define IO_EXCEPTION "java/io/IOException" #define KEY_DATABASE_EXCEPTION "org/mozilla/jss/KeyDatabaseException" #define KEY_EXISTS_EXCEPTION "org/mozilla/jss/crypto/KeyAlreadyImportedException" #define KEYSTORE_EXCEPTION "java/security/KeyStoreException" #define NICKNAME_CONFLICT_EXCEPTION "org/mozilla/jss/NicknameConflictException" #define NO_SUCH_ALG_EXCEPTION "java/security/NoSuchAlgorithmException" #define NO_SUCH_ITEM_ON_TOKEN_EXCEPTION "org/mozilla/jss/crypto/NoSuchItemOnTokenException" #define NO_SUCH_TOKEN_EXCEPTION "org/mozilla/jss/NoSuchTokenException" #define NOT_EXTRACTABLE_EXCEPTION "org/mozilla/jss/crypto/SymmetricKey$NotExtractableException" #define NULL_POINTER_EXCEPTION "java/lang/NullPointerException" #define OBJECT_NOT_FOUND_EXCEPTION "org/mozilla/jss/crypto/ObjectNotFoundException" #define OUT_OF_MEMORY_ERROR "java/lang/OutOfMemoryError" #define PK11_EXCEPTION "org/mozilla/jss/pkcs11/PK11Exception" #define PQG_PARAM_GEN_EXCEPTION "org/mozilla/jss/crypto/PQGParamGenException" /* This is a RuntimeException */ #define SECURITY_EXCEPTION "java/lang/SecurityException" #define SIGNATURE_EXCEPTION "java/security/SignatureException" #define SOCKET_EXCEPTION "java/net/SocketException" #define SSLSOCKET_EXCEPTION "org/mozilla/jss/ssl/SSLSocketException" #define SOCKET_TIMEOUT_EXCEPTION "java/net/SocketTimeoutException" #define TOKEN_EXCEPTION "org/mozilla/jss/crypto/TokenException" #define TOKEN_NOT_INITIALIZED_EXCEPTION "org/mozilla/jss/pkcs11/PK11Token$NotInitializedException" #define USER_CERT_CONFLICT_EXCEPTION "org/mozilla/jss/UserCertConflictException" #define UNSUPPORTED_OPERATION_EXCEPTION "java/lang/UnsupportedOperationException" PR_END_EXTERN_C #endif jss-4.6.3/org/mozilla/jss/util/jssutil.c000066400000000000000000000641601362106420000201770ustar00rootroot00000000000000/* 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/. */ #include #include #include #include #include #include "jssutil.h" #include "jss_bigint.h" #include "jss_exceptions.h" #include "java_ids.h" #include "nss.h" #include "cert.h" #include "certt.h" #include "pk11util.h" #include "secerr.h" /*********************************************************************** ** ** J S S _ t h r o w M s g P r E r r A r g ** ** Throw an exception in native code. You should return right after ** calling this function. ** ** throwableClassName is the name of the throwable you are throwing in ** JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. ** ** message is the message parameter of the throwable. It must not be NULL. ** If you don't have a message, call JSS_throw. ** ** errCode is a PRErrorCode returned from PR_GetError(). ** ** Example: ** JSS_throwMsg(env, ILLEGAL_ARGUMENT_EXCEPTION, PR_GetError()); ** return -1; */ void JSS_throwMsgPrErrArg(JNIEnv *env, const char *throwableClassName, const char *message, PRErrorCode errCode) { const char *errStr = JSS_strerror(errCode); char *msg = NULL; int msgLen; if( errStr == NULL ) { errStr = "Unknown error"; } msgLen = strlen(message) + strlen(errStr) + 40; msg = PR_Malloc(msgLen); if( msg == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } PR_snprintf(msg, msgLen, "%s: (%ld) %s", message, errCode, errStr); JSS_throwMsg(env, throwableClassName, msg); finish: if(msg != NULL) { PR_Free(msg); } } /*********************************************************************** ** ** J S S _ t h r o w M s g ** ** Throw an exception in native code. You should return right after ** calling this function. ** ** throwableClassName is the name of the throwable you are throwing in ** JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. ** ** message is the message parameter of the throwable. It must not be NULL. ** If you don't have a message, call JSS_throw. ** ** Example: ** JSS_throwMsg(env, ILLEGAL_ARGUMENT_EXCEPTION, ** "Bogus argument, you ninny"); ** return -1; */ void JSS_throwMsg(JNIEnv *env, const char *throwableClassName, const char *message) { jclass throwableClass; jint VARIABLE_MAY_NOT_BE_USED result; /* validate arguments */ PR_ASSERT(env!=NULL && throwableClassName!=NULL && message!=NULL); throwableClass = NULL; if(throwableClassName) { throwableClass = (*env)->FindClass(env, throwableClassName); /* make sure the class was found */ PR_ASSERT(throwableClass != NULL); } if(throwableClass == NULL) { throwableClass = (*env)->FindClass(env, GENERIC_EXCEPTION); } PR_ASSERT(throwableClass != NULL); result = (*env)->ThrowNew(env, throwableClass, message); PR_ASSERT(result == 0); } /*********************************************************************** ** ** J S S _ t h r o w ** ** Throw an exception in native code. You should return right after ** calling this function. ** ** throwableClassName is the name of the throwable you are throwing in ** JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. ** ** Example: ** JSS_throw(env, ILLEGAL_ARGUMENT_EXCEPTION); ** return -1; */ void JSS_throw(JNIEnv *env, char *throwableClassName) { jclass throwableClass; jobject throwable; jmethodID constructor; jint VARIABLE_MAY_NOT_BE_USED result; PR_ASSERT( (*env)->ExceptionOccurred(env) == NULL ); /* Lookup the class */ throwableClass = NULL; if(throwableClassName) { throwableClass = (*env)->FindClass(env, throwableClassName); /* make sure the class was found */ PR_ASSERT(throwableClass != NULL); } if(throwableClass == NULL) { throwableClass = (*env)->FindClass(env, GENERIC_EXCEPTION); } PR_ASSERT(throwableClass != NULL); /* Lookup up the plain vanilla constructor */ constructor = (*env)->GetMethodID( env, throwableClass, PLAIN_CONSTRUCTOR, PLAIN_CONSTRUCTOR_SIG); if(constructor == NULL) { /* Anything other than OutOfMemory is a bug */ ASSERT_OUTOFMEM(env); return; } /* Create an instance of the throwable */ throwable = (*env)->NewObject(env, throwableClass, constructor); if(throwable == NULL) { /* Anything other than OutOfMemory is a bug */ ASSERT_OUTOFMEM(env); return; } /* Throw the new instance */ result = (*env)->Throw(env, throwable); PR_ASSERT(result == 0); } /*********************************************************************** ** ** J S S _ g e t P t r F r o m P r o x y ** ** Given a NativeProxy, extract the pointer and store it at the given ** address. ** ** nativeProxy: a JNI reference to a NativeProxy. ** ptr: address of a void* that will receive the pointer extracted from ** the NativeProxy. ** Returns: PR_SUCCESS on success, PR_FAILURE if an exception was thrown. ** ** Example: ** DataStructure *recovered; ** jobject proxy; ** JNIEnv *env; ** [...] ** if(JSS_getPtrFromProxy(env, proxy, (void**)&recovered) != PR_SUCCESS) { ** return; // exception was thrown! ** } */ PRStatus JSS_getPtrFromProxy(JNIEnv *env, jobject nativeProxy, void **ptr) { #ifdef DEBUG jclass nativeProxyClass; #endif jclass proxyClass; jfieldID byteArrayField; jbyteArray byteArray; int size; PR_ASSERT(env!=NULL && nativeProxy != NULL && ptr != NULL); if( nativeProxy == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); return PR_FAILURE; } proxyClass = (*env)->GetObjectClass(env, nativeProxy); PR_ASSERT(proxyClass != NULL); #ifdef DEBUG nativeProxyClass = (*env)->FindClass( env, NATIVE_PROXY_CLASS_NAME); if(nativeProxyClass == NULL) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } /* make sure what we got was really a NativeProxy object */ PR_ASSERT( (*env)->IsInstanceOf(env, nativeProxy, nativeProxyClass) ); #endif byteArrayField = (*env)->GetFieldID( env, proxyClass, NATIVE_PROXY_POINTER_FIELD, NATIVE_PROXY_POINTER_SIG); if(byteArrayField==NULL) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } byteArray = (jbyteArray) (*env)->GetObjectField(env, nativeProxy, byteArrayField); if (byteArray == NULL) { *ptr = NULL; } else { size = sizeof(*ptr); PR_ASSERT((*env)->GetArrayLength(env, byteArray) == size); (*env)->GetByteArrayRegion(env, byteArray, 0, size, (void*)ptr); } if( (*env)->ExceptionOccurred(env) ) { PR_ASSERT(PR_FALSE); return PR_FAILURE; } else { return PR_SUCCESS; } } /*********************************************************************** ** ** J S S _ g e t P t r F r o m P r o x y O w n e r ** ** Given an object which contains a NativeProxy, extract the pointer ** from the NativeProxy and store it at the given address. ** ** proxyOwner: an object which contains a NativeProxy member. ** proxyFieldName: the name of the NativeProxy member. ** proxyFieldSig: the signature of the NativeProxy member. ** ptr: address of a void* that will receive the extract pointer. ** Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. ** ** Example: ** ** public class Owner { ** protected MyProxy myProxy; ** [...] ** } ** ** ** DataStructure *recovered; ** jobject owner; ** JNIEnv *env; ** [...] ** if(JSS_getPtrFromProxyOwner(env, owner, "myProxy", (void**)&recovered) ** != PR_SUCCESS) { ** return; // exception was thrown! ** } */ PRStatus JSS_getPtrFromProxyOwner(JNIEnv *env, jobject proxyOwner, char* proxyFieldName, char *proxyFieldSig, void **ptr) { jclass ownerClass; jfieldID proxyField; jobject proxyObject; PR_ASSERT(env!=NULL && proxyOwner!=NULL && proxyFieldName!=NULL && ptr!=NULL); /* * Get proxy object */ ownerClass = (*env)->GetObjectClass(env, proxyOwner); proxyField = (*env)->GetFieldID(env, ownerClass, proxyFieldName, proxyFieldSig); if(proxyField == NULL) { return PR_FAILURE; } proxyObject = (*env)->GetObjectField(env, proxyOwner, proxyField); if (proxyObject == NULL) { return PR_FAILURE; } /* * Get the pointer from the Native Reference object */ return JSS_getPtrFromProxy(env, proxyObject, ptr); } /*********************************************************************** ** ** J S S _ p t r T o B y t e A r r a y ** ** Turn a C pointer into a Java byte array. The byte array can be passed ** into a NativeProxy constructor. ** ** Returns a byte array containing the pointer, or NULL if an exception ** was thrown. */ jbyteArray JSS_ptrToByteArray(JNIEnv *env, void *ptr) { return JSS_ToByteArray(env, (void *)&ptr, sizeof(ptr)); } /*********************************************************************** * * J S S _ O c t e t S t r i n g T o B y t e A r r a y * * Converts a representation of an integer as a big-endian octet string * stored in a SECItem (as used by the low-level crypto functions) to a * representation of an integer as a big-endian Java byte array. Prepends * a zero byte to force it to be positive. Returns NULL if an exception * occurred. * */ jbyteArray JSS_OctetStringToByteArray(JNIEnv *env, SECItem *item) { jbyteArray array; jbyte *bytes; int size; /* size of the resulting byte array */ PR_ASSERT(env != NULL && item->len>0); /* allow space for extra zero byte */ size = item->len+1; array = (*env)->NewByteArray(env, size); if(array == NULL) { ASSERT_OUTOFMEM(env); return NULL; } bytes = (*env)->GetByteArrayElements(env, array, NULL); if(bytes == NULL) { ASSERT_OUTOFMEM(env); return NULL; } /* insert a 0 as the MSByte to force the string to be positive */ bytes[0] = 0; /* now insert the rest of the bytes */ memcpy(bytes+1, item->data, size-1); JSS_DerefByteArray(env, array, bytes, 0); return array; } #define ZERO_SECITEM(item) {(item).data=NULL; (item).len=0;} /*********************************************************************** * * J S S _ B y t e A r r a y T o O c t e t S t r i n g * * Converts an integer represented as a big-endian Java byte array to * an integer represented as a big-endian octet string in a SECItem. * * INPUTS * byteArray * A Java byte array containing an integer represented in * big-endian format. Must not be NULL. * item * Pointer to a SECItem that will be filled with the integer * from the byte array, in big-endian format. * RETURNS * PR_SUCCESS if the operation was successful, PR_FAILURE if an exception * was thrown. */ PRStatus JSS_ByteArrayToOctetString(JNIEnv *env, jbyteArray byteArray, SECItem *item) { jbyte *bytes=NULL; PRStatus status=PR_FAILURE; jsize size; PR_ASSERT(env!=NULL && byteArray!=NULL && item!=NULL); ZERO_SECITEM(*item); size = (*env)->GetArrayLength(env, byteArray); PR_ASSERT(size > 0); bytes = (*env)->GetByteArrayElements(env, byteArray, NULL); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } item->data = (unsigned char*) PR_Malloc(size); if(item->data == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } item->len = size; memcpy(item->data, bytes, size); status = PR_SUCCESS; finish: JSS_DerefByteArray(env, byteArray, bytes, JNI_ABORT); if(status != PR_SUCCESS) { SECITEM_FreeItem(item, PR_FALSE); } return status; } /************************************************************************ * * J S S _ w i p e C h a r A r r a y * * Given a string, set it to all zeroes. Be a chum and don't pass in NULL. */ void JSS_wipeCharArray(char* array) { PR_ASSERT(array != NULL); if(array == NULL) { return; } for(; *array != '\0'; array++) { *array = '\0'; } } #ifdef DEBUG static int debugLevel = JSS_TRACE_VERBOSE; #else static int debugLevel = JSS_TRACE_ERROR; #endif /********************************************************************** * * J S S _ t r a c e * * Sends a trace message. * * INPUTS * level * The trace level. * mesg * The trace message. Must not be NULL. */ void JSS_trace(JNIEnv *env, jint level, char *mesg) { PR_ASSERT(env!=NULL && mesg!=NULL); if(level <= debugLevel) { printf("%s\n", mesg); fflush(stdout); } } /*********************************************************************** * A S S E R T _ O U T O F M E M * * In most JNI calls that throw Exceptions, OutOfMemoryError is the only * one that doesn't indicate a bug in the code. If a JNI function throws * an exception (or returns an unexpected NULL), you can call this to * PR_ASSERT that it is due to an OutOfMemory condition. It takes a JNIEnv*, * which better not be NULL. */ void JSS_assertOutOfMem(JNIEnv *env) { jclass VARIABLE_MAY_NOT_BE_USED memErrClass; jthrowable excep; PR_ASSERT(env != NULL); /* Make sure an exception has been thrown, and save it */ excep = (*env)->ExceptionOccurred(env); PR_ASSERT(excep != NULL); /* Clear the exception so we can call JNI exceptions */ (*env)->ExceptionClear(env); /* See if the thrown exception was an OutOfMemoryError */ memErrClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); PR_ASSERT(memErrClass != NULL); PR_ASSERT( (*env)->IsInstanceOf(env, excep, memErrClass) ); /* Re-throw the exception */ (*env)->Throw(env, excep); } /*********************************************************************** * Copies the contents of a SECItem into a new Java byte array. * * item * A SECItem. Must not be NULL. * RETURNS * A Java byte array. NULL will be returned if an exception was * thrown. */ jbyteArray JSS_SECItemToByteArray(JNIEnv *env, SECItem *item) { jbyteArray array=NULL; PR_ASSERT(env!=NULL && item!=NULL); PR_ASSERT(item->len == 0 || item->data != NULL); array = (*env)->NewByteArray(env, item->len); if( array == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } (*env)->SetByteArrayRegion(env, array, 0, item->len, (jbyte*)item->data); finish: return array; } /*********************************************************************** * J S S _ B y t e A r r a y T o S E C I t e m * * Copies the contents of a Java byte array into a new SECItem. * * byteArray * A Java byte array. Must not be NULL. * RETURNS * A newly allocated SECItem, or NULL iff an exception was thrown. */ SECItem* JSS_ByteArrayToSECItem(JNIEnv *env, jbyteArray byteArray) { SECItem *item = NULL; PR_ASSERT(env!=NULL && byteArray!=NULL); /* Create a new SECItem */ item = PR_NEW(SECItem); if( item == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* Setup the length, allocate the buffer */ item->len = (*env)->GetArrayLength(env, byteArray); item->data = PR_Malloc(item->len); /* copy the bytes from the byte array into the SECItem */ (*env)->GetByteArrayRegion(env, byteArray, 0, item->len, (jbyte*)item->data); if( (*env)->ExceptionOccurred(env) ) { SECITEM_FreeItem(item, PR_TRUE /*freeit*/); item = NULL; } finish: return item; } /************************************************************************ ** JSS_ToByteArray. ** ** Converts the given chararacter array to a Java byte array. ** ** Returns ** The new jbyteArray object or NULL on failure. */ jbyteArray JSS_ToByteArray(JNIEnv *env, const void *data, int length) { jbyteArray byteArray; byteArray = (*env)->NewByteArray(env, length); if (byteArray == NULL) { PR_ASSERT((*env)->ExceptionOccurred(env) != NULL); return NULL; } (*env)->SetByteArrayRegion(env, byteArray, 0, length, (jbyte *)data); if ((*env)->ExceptionOccurred(env) != NULL) { PR_ASSERT(PR_FALSE); return NULL; } return byteArray; } /************************************************************************ ** JSS_RefByteArray. ** ** References the contents of a Java ByteArray into *data, and optionally ** records length information to *lenght. Must be dereferenced via calling ** JSS_DerefByteArray. ** ** Returns ** bool - whether or not the operation succeeded. The operation succeeds ** if *data is successfully referenced (i.e., is non-null). */ bool JSS_RefByteArray(JNIEnv *env, jbyteArray array, jbyte **data, jsize *length) { bool ret = false; jsize array_length = 0; if (env == NULL || data == NULL) { goto done; } *data = NULL; if (array == NULL) { goto done; } array_length = (*env)->GetArrayLength(env, array); if (array_length <= 0) { goto done; } *data = (*env)->GetByteArrayElements(env, array, NULL); if (*data != NULL) { ret = true; } done: if (length != NULL) { *length = array_length; } return ret; } /************************************************************************ ** JSS_DerefByteArray. ** ** Dereferences the specified ByteArray and passed reference. mode is the ** same as given to (*env)->ReleaseByteArrayElements: 0 for copy and free, ** JNI_COMMIT for copy without freeing, and JNI_ABORT for free-only. ** */ void JSS_DerefByteArray(JNIEnv *env, jbyteArray array, void *data, jint mode) { if (env == NULL || array == NULL || data == NULL) { return; } (*env)->ReleaseByteArrayElements(env, array, (jbyte *) data, mode); } /************************************************************************ ** JSS_FromByteArray. ** ** Converts the given chararacter array from a Java byte array into a array of ** uint_t. When length is passed and is not NULL, *length is updated with the ** length of the byte array. The actual allocated size of *data is one more ** than *length to NULL terminate it. Note: *data must be freed with ** free(*data) after use, not with (*env)->ReleaseByteArrayElements. ** ** Returns ** bool - whether or not the operation succeeded. */ bool JSS_FromByteArray(JNIEnv *env, jbyteArray array, uint8_t **data, size_t *length) { jsize array_length = 0; jbyte *array_data = NULL; if (env == NULL || array == NULL || data == NULL) { return false; } *data = NULL; if (!JSS_RefByteArray(env, array, &array_data, &array_length)) { return false; } /* Defensive coding: Java's byte arrays are not null terminated, allocate * a structure one larger to guarantee C functions work as expected. */ *data = calloc(array_length + 1, sizeof(uint8_t)); memcpy(*data, array_data, array_length); // Copy length, if specified if (length != NULL) { *length = array_length; } // Give back our reference to array_data after destroying the contents. JSS_DerefByteArray(env, array, array_data, JNI_ABORT); return true; } /************************************************************************ ** JSS_RefJString ** ** Converts the given jstring object to a char *; must be freed with ** JSS_DerefJString(). ** ** Returns ** A reference to the characters underlying the given string. */ const char *JSS_RefJString(JNIEnv *env, jstring str) { const char *result = NULL; if (str == NULL) { return result; } /* Saving is_copy is useless in most cases: according to the Java * docs, we always have to call ReleaseStringUTFChars: * https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html */ result = (*env)->GetStringUTFChars(env, str, NULL); /* We've received a NULL result out of a non-NULL input string. This * means that the JNI code had an issue parsing the string as UTF8, so * raise an exception. */ if (result == NULL) { JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "Unable to parse Java String as UTF-8."); } return result; } /************************************************************************ ** JSS_DerefJString ** ** Returns the reference given by the JVM to a jstring's contents. ** */ void JSS_DerefJString(JNIEnv *env, jstring str, const char *ref) { if (str != NULL && ref != NULL) { (*env)->ReleaseStringUTFChars(env, str, ref); } } /************************************************************************ ** JSS_PK11_WrapCertToChain ** ** See jssutil.h for more information. ** */ jobjectArray JSS_PK11_WrapCertToChain(JNIEnv *env, CERTCertificate *cert, SECCertUsage certUsage) { CERTCertList *chain = CERT_GetCertChainFromCert(cert, PR_Now(), certUsage); // The only failure cases here are when we're out of memory; in which // case, there's not much more for us to do but return NULL. if (chain == NULL) { return NULL; } return JSS_PK11_wrapCertChain(env, &chain); } /************************************************************************ ** JSS_ExceptionToSECStatus ** ** When the JNI has thrown a known exception, convert this to a SECStatus ** code and set the appropriate PRErrorCode. ** ** See jssutil.h for a list of supported exceptions. ** */ SECStatus JSS_ExceptionToSECStatus(JNIEnv *env) { jclass clazz; jthrowable except = (*env)->ExceptionOccurred(env); if (except == NULL) { // No exception occurred; exit with success. PORT_SetError(0); return SECSuccess; } // Now we have to handle get the various cases. Each case involves looking // up a class by name and comparing it via IsInstanceOf(...). We ignore // failures which may occur on lookup. // CERTIFICATE_ENCODING_EXCEPTION <-> SEC_ERROR_CERT_NOT_VALID clazz = (*env)->FindClass(env, CERTIFICATE_ENCODING_EXCEPTION); if (clazz != NULL && (*env)->IsInstanceOf(env, except, clazz)) { PORT_SetError(SEC_ERROR_CERT_NOT_VALID); return SECFailure; } // CERTIFICATE_EXPIRED_EXCEPTION <-> SEC_ERROR_EXPIRED_CERTIFICATE clazz = (*env)->FindClass(env, CERTIFICATE_EXPIRED_EXCEPTION); if (clazz != NULL && (*env)->IsInstanceOf(env, except, clazz)) { PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE); return SECFailure; } // CERTIFICATE_NOT_YET_VALID_EXCEPTION <-> SEC_ERROR_CERT_NOT_VALID clazz = (*env)->FindClass(env, CERTIFICATE_NOT_YET_VALID_EXCEPTION); if (clazz != NULL && (*env)->IsInstanceOf(env, except, clazz)) { PORT_SetError(SEC_ERROR_CERT_NOT_VALID); return SECFailure; } // CERTIFICATE_PARSING_EXCEPTION <-> SEC_ERROR_BAD_DER clazz = (*env)->FindClass(env, CERTIFICATE_PARSING_EXCEPTION); if (clazz != NULL && (*env)->IsInstanceOf(env, except, clazz)) { PORT_SetError(SEC_ERROR_BAD_DER); return SECFailure; } // CERTIFICATE_REVOKED_EXCEPTION <-> SEC_ERROR_REVOKED_CERTIFICATE clazz = (*env)->FindClass(env, CERTIFICATE_REVOKED_EXCEPTION); if (clazz != NULL && (*env)->IsInstanceOf(env, except, clazz)) { PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); return SECFailure; } // Handle the default case. Since these error messages are mostly // user-facing and don't get used internally, setting PR_UNKNOWN_ERROR // here is safe. PORT_SetError(PR_UNKNOWN_ERROR); return SECFailure; } /************************************************************************ ** JSS_SECStatusToException ** ** Convert a failing SECStatus and PRErrorCode combination into a raised ** JNI exception. ** ** See jssutil.h for a list of supported exceptions. ** */ void JSS_SECStatusToException(JNIEnv *env, SECStatus result, PRErrorCode code) { JSS_SECStatusToExceptionMessage(env, result, code, ""); } void JSS_SECStatusToExceptionMessage(JNIEnv *env, SECStatus result, PRErrorCode code, const char *message) { if (result == SECSuccess) { // We ignore PRErrorCode here. However, while we could clear an // exception if it occurred, we don't; that's the caller's choice to // make. return; } if (result == SECFailure) { switch (code) { case SEC_ERROR_CERT_NOT_VALID: JSS_throwMsgPrErrArg(env, CERTIFICATE_NOT_YET_VALID_EXCEPTION, message, code); break; case SEC_ERROR_EXPIRED_CERTIFICATE: JSS_throwMsgPrErrArg(env, CERTIFICATE_EXPIRED_EXCEPTION, message, code); break; case SEC_ERROR_BAD_DER: JSS_throwMsgPrErrArg(env, CERTIFICATE_PARSING_EXCEPTION, message, code); break; case SEC_ERROR_REVOKED_CERTIFICATE: JSS_throwMsgPrErrArg(env, CERTIFICATE_REVOKED_EXCEPTION, message, code); break; default: JSS_throwMsgPrErrArg(env, JAVA_LANG_EXCEPTION, message, code); break; } } } /*********************************************************************** ** ** JSS_clearPtrFromProxy ** ** See also: jssutil.h */ PRStatus JSS_clearPtrFromProxy(JNIEnv *env, jobject nativeProxy) { jclass proxyClass; jmethodID nativeProxyClear; PR_ASSERT(env!=NULL && nativeProxy != NULL); if( nativeProxy == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); return PR_FAILURE; } proxyClass = (*env)->GetObjectClass(env, nativeProxy); PR_ASSERT(proxyClass != NULL); nativeProxyClear = (*env)->GetMethodID(env, proxyClass, "clear", "()V"); if (nativeProxyClear == NULL) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } (*env)->CallVoidMethod(env, nativeProxy, nativeProxyClear); if ((*env)->ExceptionOccurred(env)) { PR_ASSERT(PR_FALSE); return PR_FAILURE; } else { return PR_SUCCESS; } } /* * External references to the rcs and sccsc ident information in * jssver.c. These are here to prevent the compiler from optimizing * away the symbols in jssver.c */ extern const char __jss_base_rcsid[]; extern const char __jss_base_sccsid[]; jss-4.6.3/org/mozilla/jss/util/jssutil.h000066400000000000000000000305721362106420000202040ustar00rootroot00000000000000/* 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/. */ #include #include #include #include #include #ifndef JSS_NATIVE_UTIL_H #define JSS_NATIVE_UTIL_H /* The following #defines are used to suppress undesired compiler warnings * that have been deemed inappropriate. * * IMPORTANT: These are ONLY used on an "as-needed" basis! */ #ifdef __GNUC__ #define FUNCTION_MAY_NOT_BE_USED __attribute__ ((unused)) #define VARIABLE_MAY_NOT_BE_USED __attribute__ ((unused)) #else #define FUNCTION_MAY_NOT_BE_USED #define VARIABLE_MAY_NOT_BE_USED #endif PR_BEGIN_EXTERN_C /**** NSPR private thread functions ****/ /* PRThread* PR_AttachThread(PRThreadType type, PRThreadPriority priority, PRThreadStack *stack); void PR_DetachThread(void); */ #define PR_AttachThread(a, b, c) ((PRThread*)1) #define PR_DetachThread() /* defined in CryptoManager.c */ extern JavaVM *JSS_javaVM; /*********************************************************************** * J S S _ t h r o w M s g * * Throw an exception in native code. You should return right after * calling this function. * * throwableClassName is the name of the throwable you are throwing in * JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. * * message is the message parameter of the throwable. It must not be NULL. * If you don't have a message, call JSS_nativeThrow. * * Example: * JSS_nativeThrowMsg(env, "java/lang/IllegalArgumentException", * "Bogus argument, you ninny"); * return -1; */ void JSS_throwMsg(JNIEnv *env, const char *throwableClassName, const char *message); #define JSS_nativeThrowMsg JSS_throwMsg /*********************************************************************** * J S S _ t h r o w * * Throw an exception in native code. You should return right after * calling this function. * * throwableClassName is the name of the throwable you are throwing in * JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. * * Example: * JSS_nativeThrow(env, "java/lang/IllegalArgumentException"); * return -1; */ void JSS_throw(JNIEnv *env, char *throwableClassName); #define JSS_nativeThrow JSS_throw /*********************************************************************** * A S S E R T _ O U T O F M E M * * In most JNI calls that throw Exceptions, OutOfMemoryError is the only * one that doesn't indicate a bug in the code. If a JNI function throws * an exception (or returns an unexpected NULL), you can call this to * PR_ASSERT that it is due to an OutOfMemory condition. It takes a JNIEnv*, * which better not be NULL. */ void JSS_assertOutOfMem(JNIEnv *env); #ifdef DEBUG #define ASSERT_OUTOFMEM(env) JSS_assertOutOfMem(env) #else #define ASSERT_OUTOFMEM(env) #endif /*********************************************************************** ** ** J S S _ g e t P t r F r o m P r o x y ** ** Given a NativeProxy, extract the pointer and store it at the given ** address. ** ** nativeProxy: a JNI reference to a NativeProxy. ** ptr: address of a void* that will receive the pointer extracted from ** the NativeProxy. ** Returns: PR_SUCCESS on success, PR_FAILURE if an exception was thrown. ** ** Example: ** DataStructure *recovered; ** jobject proxy; ** JNIEnv *env; ** [...] ** if(JSS_getPtrFromProxy(env, proxy, (void**)&recovered) != PR_SUCCESS) { ** return; // exception was thrown! ** } */ PRStatus JSS_getPtrFromProxy(JNIEnv *env, jobject nativeProxy, void **ptr); /*********************************************************************** ** ** J S S _ c l e a r P t r F r o m P r o x y ** ** Given a NativeProxy, clear the value of the pointer stored in it. This ** helps to ensure that a double free doesn't occur. ** ** Returns: PR_SUCCESS on success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_clearPtrFromProxy(JNIEnv *env, jobject nativeProxy); /*********************************************************************** ** ** J S S _ g e t P t r F r o m P r o x y O w n e r ** ** Given an object which contains a NativeProxy, extract the pointer ** from the NativeProxy and store it at the given address. ** ** proxyOwner: an object which contains a NativeProxy member. ** proxyFieldName: the name of the NativeProxy member. ** proxyFieldSig: the signature of the NativeProxy member. ** ptr: address of a void* that will receive the extract pointer. ** Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. ** ** Example: ** ** public class Owner { ** protected MyProxy myProxy; ** [...] ** } ** ** ** DataStructure *recovered; ** jobject owner; ** JNIEnv *env; ** [...] ** if(JSS_getPtrFromProxyOwner(env, owner, "myProxy", (void**)&recovered) ** != PR_SUCCESS) { ** return; // exception was thrown! ** } */ PRStatus JSS_getPtrFromProxyOwner(JNIEnv *env, jobject proxyOwner, char* proxyFieldName, char *proxyFieldSig, void **ptr); /* * Turn a C pointer into a Java byte array. The byte array can be passed * into a NativeProxy constructor. * * Returns a byte array containing the pointer, or NULL if an exception * was thrown. */ jbyteArray JSS_ptrToByteArray(JNIEnv *env, void *ptr); /************************************************************************ * * J S S _ w i p e C h a r A r r a y * * Given a string, set it to all zeroes. Don't pass in NULL. */ void JSS_wipeCharArray(char* array); /********************************************************************** * * J S S _ t r a c e * * Sends a trace message. * * INPUTS * level * The trace level (see below for constants). Must be > 0. * mesg * The trace message. Must not be NULL. */ void JSS_trace(JNIEnv *env, jint level, char *mesg); /* trace levels */ #define JSS_TRACE_ERROR 1 #define JSS_TRACE_VERBOSE 5 #define JSS_TRACE_OBNOXIOUS 10 /*********************************************************************** * J S S _ S E C I t e m T o B y t e A r r a y * * Copies the contents of a SECItem into a new Java byte array. * * item * A SECItem. Must not be NULL. * RETURNS * A Java byte array. NULL will be returned if an exception was * thrown. */ jbyteArray JSS_SECItemToByteArray(JNIEnv *env, SECItem *item); /*********************************************************************** * J S S _ B y t e A r r a y T o S E C I t e m * * Copies the contents of a Java byte array into a new SECItem. * * byteArray * A Java byte array. Must not be NULL. * RETURNS * A newly allocated SECItem, or NULL iff an exception was thrown. */ SECItem* JSS_ByteArrayToSECItem(JNIEnv *env, jbyteArray byteArray); /*********************************************************************** * J S S _ s t r e r r o r * * Provides string representations for NSPR, SEC, and SSL errors. * Swiped from PSM. * * RETURNS * A UTF-8 encoded constant error string for errNum. * NULL if errNum is unknown. */ const char * JSS_strerror(PRErrorCode errNum); /*********************************************************************** ** ** J S S _ t h r o w M s g P r E r r A r g ** ** Throw an exception in native code. You should return right after ** calling this function. ** ** throwableClassName is the name of the throwable you are throwing in ** JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. ** ** message is the message parameter of the throwable. It must not be NULL. ** If you don't have a message, call JSS_throw. ** ** errCode is a PRErrorCode returned from PR_GetError(). ** ** Example: ** JSS_throwMsg(env, ILLEGAL_ARGUMENT_EXCEPTION, PR_GetError()); ** return -1; */ void JSS_throwMsgPrErrArg(JNIEnv *env, const char *throwableClassName, const char *message, PRErrorCode errCode); #define JSS_throwMsgPrErr(e, cn, m) \ JSS_throwMsgPrErrArg((e), (cn), (m), PR_GetError()) #define JSS_throwMsgPortErr(e, cn, m) \ JSS_throwMsgPrErrArg((e), (cn), (m), PORT_GetError()) /************************************************************************ ** ** J S S _ i n i t E r r c o d e T r a n s l a t i o n T a b l e. ** ** Initializes the error code translation table. This should be called ** by CryptoManager.initialize(), and must be called before any calls to ** JSS_ConvertNativeErrcodeToJava. ** */ void JSS_initErrcodeTranslationTable(); /************************************************************************ ** ** J S S _ C o n v e r t N a t i v e E r r c o d e T o J a v a ** ** Converts an NSPR or NSS error code to a Java error code. ** (defined in the class o.m.util.NativeErrcodes) ** ** Returns ** The Java error code, or -1 if a corresponding Java error code could ** not be found. */ int JSS_ConvertNativeErrcodeToJava(int nativeErrcode); /************************************************************************ ** JSS_ToByteArray. ** ** Converts the given chararacter array to a Java byte array. ** ** Returns ** The new jbyteArray object or NULL on failure. */ jbyteArray JSS_ToByteArray(JNIEnv *env, const void *data, int length); /************************************************************************ ** JSS_RefByteArray. ** ** References the contents of a Java ByteArray into *data, and optionally ** records length information to *lenght. Must be dereferenced via calling ** JSS_DerefByteArray. ** ** Returns ** bool - whether or not the operation succeeded. */ bool JSS_RefByteArray(JNIEnv *env, jbyteArray array, jbyte **data, jsize *length); /************************************************************************ ** JSS_DerefByteArray. ** ** Dereferences the specified ByteArray and passed reference. mode is the ** same as given to (*env)->ReleaseByteArrayElements: 0 for copy and free, ** JNI_COMMIT for copy without freeing, and JNI_ABORT for free-only. ** */ void JSS_DerefByteArray(JNIEnv *env, jbyteArray array, void *data, jint mode); /************************************************************************ ** JSS_FromByteArray. ** ** Converts the given chararacter array from a Java byte array into a array of ** uint_t. When length is passed and is not NULL, *length is updated with the ** length of the array. ** ** Returns ** bool - whether or not the operation succeeded. */ bool JSS_FromByteArray(JNIEnv *env, jbyteArray array, uint8_t **data, size_t *length); /************************************************************************ ** JSS_RefJString ** ** Converts the given jstring object to a char *; must be freed with ** JSS_DerefJString(). ** ** Returns ** A reference to the characters underlying the given string. */ const char *JSS_RefJString(JNIEnv *env, jstring str); /************************************************************************ ** JSS_DerefJString ** ** Returns the reference given by the JVM to a jstring's contents. ** */ void JSS_DerefJString(JNIEnv *env, jstring str, const char *ref); /************************************************************************ ** JSS_PK11_WrapCertToChain ** ** Inquires about the certificate chain for cert, and returns the full or ** partial as a jobjectArray for use in JNI'd code. ** */ jobjectArray JSS_PK11_WrapCertToChain(JNIEnv *env, CERTCertificate *cert, SECCertUsage certUsage); /************************************************************************ ** JSS_ExceptionToSECStatus ** ** When the JNI has thrown a known exception, convert this to a SECStatus ** code and set the appropriate PRErrorCode. ** ** The supported exceptions are: ** - CertificateException ** */ SECStatus JSS_ExceptionToSECStatus(JNIEnv *env); /************************************************************************ ** JSS_SECStatusToException ** ** Convert a failing SECStatus and PRErrorCode combination into a raised ** JNI exception. ** ** The supported exceptions are: ** - CertificateException ** */ void JSS_SECStatusToException(JNIEnv *env, SECStatus result, PRErrorCode code); /************************************************************************ ** JSS_SECStatusToException ** ** Convert a failing SECStatus and PRErrorCode combination into a raised ** JNI exception with the specified message. ** ** The supported exceptions are: ** - CertificateException ** */ void JSS_SECStatusToExceptionMessage(JNIEnv *env, SECStatus result, PRErrorCode code, const char *message); PR_END_EXTERN_C #endif jss-4.6.3/org/mozilla/jss/util/jssver.c000066400000000000000000000014031362106420000200050ustar00rootroot00000000000000/* 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/. */ #include "jssver.h" /* Library identity and versioning */ #if defined(DEBUG) #define _DEBUG_STRING " (debug)" #else #define _DEBUG_STRING "" #endif /* * Version information for the 'ident' and 'what commands * * NOTE: the first component of the concatenated rcsid string * must not end in a '$' to prevent rcs keyword substitution. */ const char __jss_base_rcsid[] = "$Header: JSS " JSS_VERSION _DEBUG_STRING " " __DATE__ " " __TIME__ " $"; const char __jss_base_sccsid[] = "@(#)JSS " JSS_VERSION _DEBUG_STRING " " __DATE__ " " __TIME__; jss-4.6.3/org/mozilla/jss/util/jssver.h.in000066400000000000000000000020001362106420000204110ustar00rootroot00000000000000/* 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/. */ #ifndef JSSVER_H #define JSSVER_H /* * JSS's major version, minor version, patch level, and whether * this is a beta release. * * The format of the version string should be * ".[.] []" */ /********************************************************************/ /* The VERSION Strings should be updated everytime a new release */ /* of JSS is generated. Note that this is done by changing */ /* cmake/JSSConfig.cmake. */ /********************************************************************/ #define JSS_VERSION "${JSS_VERSION}" #define JSS_VMAJOR ${JSS_VERSION_MAJOR} #define JSS_VMINOR ${JSS_VERSION_MINOR} #define JSS_VPATCH ${JSS_VERSION_PATCH} #define JSS_BETA ${JSS_VERSION_BETA} #endif jss-4.6.3/samples/000077500000000000000000000000001362106420000137615ustar00rootroot00000000000000jss-4.6.3/samples/PQGGen.java000066400000000000000000000036131362106420000157100ustar00rootroot00000000000000/* 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/. */ import org.mozilla.jss.*; import org.mozilla.jss.crypto.*; /** * A command-line utility for generating PQG parameters for DSA * Key operations. Can be used for testing. * Takes the keysize as the sole argument. */ public class PQGGen { public static void main(String args[]) { int size; PQGParams pqg; try { if(args.length != 1) { throw new Exception("Usage: java PQGGen "); } size = Integer.parseInt(args[0]); System.out.println("Generating PQG parameters for "+size+ "-bit keypairs. This could take hours..."); CryptoManager.initialize("."); pqg = PQGParams.generate(size); System.out.println("Generated PQG Parameters."); System.out.println("Verifying PQG Parameters. "+ "This could take a few minutes..."); if( ! pqg.paramsAreValid() ) { throw new Exception("ERROR: Generated parameters are invalid."); } System.out.println("Parameters are valid!"); System.out.println("P: "+pqg.getP()); System.out.println("Q: "+pqg.getQ()); System.out.println("G: "+pqg.getG()); System.out.println("H: "+pqg.getH()); System.out.println("seed: "+pqg.getSeed()); System.out.println("counter: "+pqg.getCounter()); } catch(NumberFormatException e) { System.err.println("Invalid key size: "+e); } catch(PQGParamGenException e) { System.err.println(e); } catch(java.security.InvalidParameterException e) { System.err.println("Invalid key size: "+e); } catch(Exception e) { System.err.println(e); } } } jss-4.6.3/samples/README.txt000066400000000000000000000001101362106420000154470ustar00rootroot00000000000000Better sample code is available in the org/mozilla/jss/tests directory. jss-4.6.3/samples/inputfile.pfx000066400000000000000000000103221362106420000164750ustar00rootroot000000000000000€0€ *†H†÷  €$€0€0€  *†H†÷  €$€0‚0‚   *†H†÷   ‚¥0‚¡0   *†H†÷  0 Ð*vÃ~Å/[‚€‚€‚€–Å=õC,ʆ´éƒLÖKQ÷ˆt¹ôrÒ„ó#QA¼R×–Ø×É3)c‡gˆqÃȵÝG?o;féÙ€H ø[yûspXêmà%R–@4~Š€üQØ%:SÔΠ­ ‹}V¹úΛ Eš=Êól¥o+á÷K>;¯ 6¬m´#„aE±h5e?­/£:'ñ(¶y[8ô€ëfI (4Fq HãòG>5çÄÀí¿Ù‹t©c£%5­TLR[¹áÿÊÄÓl}lõ¨Öz–t›Ã¥¡Aü@ü¿ÀûÊ :›{“cè},Á»VBã®NØ25ëX àÚt16dÁÃÉ¥´CXcͽÓ[ƶ«4oûD?תz ¸OÉäUºüî´3ãqü½JʘZ—ƒ›fËF2ÜÙÊ>|ûR„½’µßŠÀ¦Î¯†ïÖV ˜ž-Â!Mna–vàK·%s.\# ¨t‘Q@/™¤•zˆ´ê›BñâMáàÅÖ1®¢WÜq I:£Ä;÷©!¸ö–Ö~0; ôTZ7._ö%p¾¢Öß&Oî—½!ËÔfçѦ5v“¸¿Uµïu[Ÿ(ªWµÝiseçS"ýÞóN÷Œû…!#Nðˆ×)Œ.s•éQ`ïË ®‡íkG¯Þ,âð6ƒœ£ƒ[‹k7Wæƒ(Î £á;Qû/¾uÄz%,ÈÀ鸚༠?¿äU 5TÄÆÙü0 bÃ;JÔ™B1xN»+'±oÈ3Ç” !Ù«ûêñ`ö)MËGÑï÷MË<ý8qçaáÙ0Å.*%úªä¯ÐN¸ &Ì[K¹O1b0;   *†H†÷  1.,,,CMS Administrator's ID0#   *†H†÷  1ôé"HÍn!Ù+„¸_Ϋ0€  *†H†÷  €0€0€  *†H†÷ 0  *†H†÷  0 ˆ—Õù¶$ª €¾)ØÕ¸’Ì>ŒØoäqƇ8.¢Ð4Ebp a±ÀèípÁe€yz¥Á;ùmh‚‚¸‚¸òý*³Å/6GÚ[ÎÖ½@Ô» €ÛCBéߨè©òpvr3¡¡êr’«SÖ¾{KDÇK0ƒrþ2òYÑ®¥=“Wbשd¼gÚ®ÚŸêšRJŸ¢ñçbõYžïÎòò€c['y^t“ù쟴Wê„ó?ÔçmTt> ‰[ùSoÇʹ[©„;ø%à"„Ç ÞU=æ…6ÞëÍS-x¶` ~ÐP­£TÁpW<£âtœ„DÒõÿwj˜r&¤lV(c¾i7ŠÅ‹ál¬N@$}:¢›<ù·C¬aª¶ùÒfî;[Ó‘ÙÔ  Áñ±ßnVýì-•-‚„0x>kÚ…X7ž³’#{ªÜŒ¨%f,èâÁ ¤áwÛæqü-F“¶¤]Ù`Ìv-Ô23,,ÅÍB¶ší¹CÄ…㯿+I=2m`9 ð2]4ÿP*²½MPN=$ÃÄ1N0 UÐÑjá¤WòðU^Õþ0‹ð–¡þ«B§ð ¶^WYìû­VÉÕ…`+sEê4pï*`Å‹HGEãƒ)Ô©Üåç½:¤]?Ä™`S;ÚV‘ceαVi—S[²ºµéMßÇ4׈UÀ‚"Ô+‚æ]Þ/á ¢kvdµ[$µX½Lò8òö„‰œˆdÿeÁÜ‚Ä%Vo4óq'C0ß.ú'º¶íM6•¬¿ÌŒJml;$Üh‰KBÐíLM)¦Õ[wãÈl~ê` ý¶ŸmAý.RiŽkÓž‰ …8‰VS#îðjæUaÂÝÁŠcˆbH—›ãÝî\г‰?L éï.’'g™ýÓ š²ß5àv_Øi—|úWØcWc‡ë á^CŸ= àõ’ ûe–êwŒ™K›IÌ+ÙN~šL\EÌS˜î­Ṵ̀ÐT,ª"d4¼òȦζ QXÎÈÚ{’nrÔìÀÚw$ª`½“¬Òjhl¼”à¨á3OþeŠ·Â3¥‹Ùÿ1ŽÉÖyNÝ nY@$¶ÐJ}Å`‰C Ö³+_S­£î+ì p[o: «ô—͆n7Gq6Ñ@<îC!‰l¦‡R“Ò3 }ƒ£rK [[9½;c‘¶^µi&ó>zœ~m1!!¢Ì…ÜóŒ]è²ß3»¯'®fnAQ:6å>Y6ä0xà ñ’v8‹>܈GFª”Äþ|Ž©ˆ1ž5^»Â ü™d3¯ ‚£ÅOMtÝv͹„0ÌýKÕnö^(#Jr©˸n®¡Ÿðáè[&`äî+Éfi‡Ì°g9eº-«e ³›t"´~A3`=e)õ ¸ßq–PžÏ _{’ùîÀ\]èú˜3!Y7EíQV%i”,.‡Á¼‚ùªgÓe8dœSí XE*Lï˜á³„_cIIÚŠ_îŒfŠÁ°OËfl•æÀy¶qùµ#W6:0Æz °i0´üAšÿy¨¾.Y&6f/-®aU`?‹^Ž`D’PãÚ£ýRb’ OËÉâ˜!Û{pνÎ^LdcPO#eÃSaŠÄÚ~s7ê©Ñ‡„á‘4œÆÓ—'Ôrº4Ù\1r»ÖÌZhþ»è¿#g)ÿ†$Züýæ*.}õ×R£G*Š#¤Ž÷‚ÔŠCs–³2$kZ)~›à„¤\Ò ‡¦]3>@ZûaAL!öjŒØ{T/ûv Óè³K šT·äÈjûé…k±í×Eyµ ›ê·Å¥èxý}`'nç Äh9AŠ$ê'X&¢ðòxøÑ½„d쳟HÒ¯Fù. œruŸ¢Ñ¸Ž S ¨ÚoûÞ¸ñ<¤84k[P“ Œõdø™Åëm…—¯nb050!0 +ÁÒšžšÀ>c“TŸA~‘­µÅ¾‚¥n—zâ”p˜ îzÙá¯.jss-4.6.3/samples/pkcs12.java000066400000000000000000000263031362106420000157330ustar00rootroot00000000000000/* 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/. */ /** * This program reads in a PKCS #12 file and dumps its contents to the screen. * At the same time, it creates a new PKCS #12 file. As it reads through the * old file, it writes its contents into the new file. Then the new file * is encrypted and MACed with a new, different password. */ /* note that this code still has some problems reading PKCS12 file * generated with Communicator. */ import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.BMPString; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.crypto.CryptoStore; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.JSSSecureRandom; import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.pkcs12.AuthenticatedSafes; import org.mozilla.jss.pkcs12.CertBag; import org.mozilla.jss.pkcs12.PFX; import org.mozilla.jss.pkcs12.PasswordConverter; import org.mozilla.jss.pkcs12.SafeBag; import org.mozilla.jss.pkix.cert.Certificate; import org.mozilla.jss.pkix.primitive.Attribute; import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo; import org.mozilla.jss.pkix.primitive.PrivateKeyInfo; import org.mozilla.jss.util.ConsolePasswordCallback; import org.mozilla.jss.util.Password; public class pkcs12 { public static void main(String []args) { try { // Read arguments if( args.length != 3 ) { System.out.println("Usage: PFX "); System.exit(-1); } // open input file for reading FileInputStream infile=null; try { infile = new FileInputStream(args[1]); } catch (FileNotFoundException f) { System.out.println("Cannot open file "+args[1]+ " for reading: "+f.getMessage()); return; } int certfile = 0; // initialize CryptoManager. This is necessary because there is // crypto involved with decoding a PKCS #12 file CryptoManager.initialize( args[0] ); CryptoManager manager = CryptoManager.getInstance(); // Decode the P12 file PFX.Template pfxt = new PFX.Template(); PFX pfx; try (BufferedInputStream is = new BufferedInputStream(infile, 2048)) { pfx = (PFX) pfxt.decode(is); } System.out.println("Decoded PFX"); // print out information about the top-level PFX structure System.out.println("Version: "+pfx.getVersion()); AuthenticatedSafes authSafes = pfx.getAuthSafes(); SEQUENCE safeContentsSequence = authSafes.getSequence(); System.out.println("AuthSafes has "+ safeContentsSequence.size()+" SafeContents"); // Get the password for the old file System.out.println("Enter password: "); Password pass = Password.readPasswordFromConsole(); // get new password, which will be used for the new file we create // later System.out.println("Enter new password:"); Password newPass = Password.readPasswordFromConsole(); // Verify the MAC on the PFX. This is important to be sure // it hasn't been tampered with. StringBuffer sb = new StringBuffer(); if( pfx.verifyAuthSafes(pass, sb) ) { System.out.println("AuthSafes verifies correctly."); } else { System.out.println("AuthSafes failed to verify because: "+ sb); } // Create a new AuthenticatedSafes. As we read the contents of the // old authSafes, we will store them into the new one. After we have // cycled through all the contents, they will all have been copied into // the new authSafes. AuthenticatedSafes newAuthSafes = new AuthenticatedSafes(); // Loop over contents of the old authenticated safes //for(int i=0; i < asSeq.size(); i++) { for(int i=0; i < safeContentsSequence.size(); i++) { // The safeContents may or may not be encrypted. We always send // the password in. It will get used if it is needed. If the // decryption of the safeContents fails for some reason (like // a bad password), then this method will throw an exception SEQUENCE safeContents = authSafes.getSafeContentsAt(pass, i); System.out.println("\n\nSafeContents #"+i+" has "+ safeContents.size()+" bags"); // Go through all the bags in this SafeContents for(int j=0; j < safeContents.size(); j++) { SafeBag safeBag = (SafeBag) safeContents.elementAt(j); // The type of the bag is an OID System.out.println("\nBag "+j+" has type "+ safeBag.getBagType() ); // look for bag attributes SET attribs = safeBag.getBagAttributes(); if( attribs == null ) { System.out.println("Bag has no attributes"); } else { for(int b=0; b < attribs.size(); b++) { Attribute a = (Attribute) attribs.elementAt(b); if( a.getType().equals(SafeBag.FRIENDLY_NAME)) { // the friendly name attribute is a nickname BMPString bs = (BMPString) ((ANY)a.getValues(). elementAt(0)).decodeWith( BMPString.getTemplate()); System.out.println("Friendly Name: "+bs); } else if(a.getType().equals(SafeBag.LOCAL_KEY_ID)){ // the local key id is used to match a key // to its cert. The key id is the SHA-1 hash of // the DER-encoded cert. OCTET_STRING os =(OCTET_STRING) ((ANY)a.getValues(). elementAt(0)).decodeWith( OCTET_STRING.getTemplate()); System.out.println("LocalKeyID:"); /* AuthenticatedSafes. print_byte_array(os.toByteArray()); */ } else { System.out.println("Unknown attribute type: "+ a.getType().toString()); } } } // now look at the contents of the bag ASN1Value val = safeBag.getInterpretedBagContent(); if( val instanceof PrivateKeyInfo ) { // A PrivateKeyInfo contains an unencrypted private key System.out.println("content is PrivateKeyInfo"); } else if( val instanceof EncryptedPrivateKeyInfo ) { // An EncryptedPrivateKeyInfo is, well, an encrypted // PrivateKeyInfo. Usually, strong crypto is used in // an EncryptedPrivateKeyInfo. EncryptedPrivateKeyInfo epki = ((EncryptedPrivateKeyInfo)val); System.out.println( "content is EncryptedPrivateKeyInfo, algoid:" + epki.getEncryptionAlgorithm().getOID()); // Because we are in a PKCS #12 file, the passwords are // char-to-byte converted in a special way. We have to // use the special converter class instead of the default. PrivateKeyInfo pki = epki.decrypt(pass, new org.mozilla.jss.pkcs12.PasswordConverter() ); // import the key into the key3.db CryptoToken tok = manager.getTokenByName("Internal Key Storage Token"); CryptoStore store = tok.getCryptoStore(); tok.login( new ConsolePasswordCallback()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); pki.encode(baos); store.importPrivateKey(baos.toByteArray(), PrivateKey.RSA); // re-encrypt the PrivateKeyInfo with the new password // and random salt byte[] salt = new byte[ PBEAlgorithm.PBE_SHA1_DES3_CBC.getSaltLength()]; JSSSecureRandom rand = CryptoManager.getInstance(). getSecureRNG(); rand.nextBytes(salt); epki = EncryptedPrivateKeyInfo.createPBE( PBEAlgorithm.PBE_SHA1_DES3_CBC, newPass, salt, 1, new PasswordConverter(), pki); // Overwrite the previous EncryptedPrivateKeyInfo with // this new one we just created using the new password. // This is what will get put in the new PKCS #12 file // we are creating. safeContents.insertElementAt( new SafeBag( safeBag.getBagType(), epki, safeBag.getBagAttributes()), i); safeContents.removeElementAt(i+1); } else if( val instanceof CertBag ) { System.out.println("content is CertBag"); CertBag cb = (CertBag) val; if( cb.getCertType().equals(CertBag.X509_CERT_TYPE)) { // this is an X.509 certificate OCTET_STRING os = (OCTET_STRING)cb.getInterpretedCert(); Certificate cert = (Certificate) ASN1Util.decode(Certificate.getTemplate(), os.toByteArray()); cert.getInfo().print(System.out); } else { System.out.println("Unrecognized cert type"); } } else { System.out.println("content is ANY"); } } // Add the new safe contents to the new authsafes if( authSafes.safeContentsIsEncrypted(i) ) { newAuthSafes.addEncryptedSafeContents( AuthenticatedSafes.DEFAULT_KEY_GEN_ALG, newPass, null, AuthenticatedSafes.DEFAULT_ITERATIONS, safeContents); } else { newAuthSafes.addSafeContents( safeContents ); } } // Create new PFX from the new authsafes PFX newPfx = new PFX(newAuthSafes); // Add a MAC to the new PFX newPfx.computeMacData(newPass, null, PFX.DEFAULT_ITERATIONS); // write the new PFX out to a file FileOutputStream fos = new FileOutputStream(args[2]); newPfx.encode(fos); fos.close(); } catch( Exception e ) { e.printStackTrace(); } } } jss-4.6.3/tools/000077500000000000000000000000001362106420000134555ustar00rootroot00000000000000jss-4.6.3/tools/Dockerfiles/000077500000000000000000000000001362106420000157075ustar00rootroot00000000000000jss-4.6.3/tools/Dockerfiles/debian_jdk11000066400000000000000000000022361362106420000200510ustar00rootroot00000000000000FROM debian:testing # Install generic dependencies to build jss RUN true \ && apt-get update \ && apt-get dist-upgrade -y \ && apt-get install -y debhelper libnss3-dev libnss3-tools libnss3 \ openjdk-11-jdk pkg-config quilt g++ mercurial \ zlib1g-dev libslf4j-java liblog4j2-java \ libcommons-lang-java libjaxb-api-java cmake \ zip unzip junit4 \ && mkdir -p /home/sandbox \ && apt-get autoremove -y \ && apt-get clean -y \ && apt-get autoclean -y \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Perform the actual build WORKDIR /home/sandbox/jss CMD true \ && export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \ && rm -rf build \ && mkdir build \ && cd build \ && cmake .. \ && make all \ && ctest --output-on-failure \ && true jss-4.6.3/tools/Dockerfiles/fedora_27000066400000000000000000000017421362106420000174060ustar00rootroot00000000000000FROM fedora:27 # Install generic dependencies to build jss RUN true \ && dnf update -y --refresh \ && dnf install -y dnf-plugins-core gcc make rpm-build \ && dnf copr -y enable ${JSS_4_6_REPO:-@pki/master} \ && dnf build-dep -y jss \ && mkdir -p /home/sandbox \ && dnf clean -y all \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Install dependencies from the spec file in case they've changed # since the last release on this platform. RUN true \ && dnf build-dep -y --spec /home/sandbox/jss/jss.spec \ && true # Perform the actual RPM build WORKDIR /home/sandbox/jss CMD true \ && bash ./build.sh --with-timestamp --with-commit-id rpm \ && dnf install -y /root/build/jss/RPMS/*.rpm \ && true jss-4.6.3/tools/Dockerfiles/fedora_28000066400000000000000000000017421362106420000174070ustar00rootroot00000000000000FROM fedora:28 # Install generic dependencies to build jss RUN true \ && dnf update -y --refresh \ && dnf install -y dnf-plugins-core gcc make rpm-build \ && dnf copr -y enable ${JSS_4_6_REPO:-@pki/master} \ && dnf build-dep -y jss \ && mkdir -p /home/sandbox \ && dnf clean -y all \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Install dependencies from the spec file in case they've changed # since the last release on this platform. RUN true \ && dnf build-dep -y --spec /home/sandbox/jss/jss.spec \ && true # Perform the actual RPM build WORKDIR /home/sandbox/jss CMD true \ && bash ./build.sh --with-timestamp --with-commit-id rpm \ && dnf install -y /root/build/jss/RPMS/*.rpm \ && true jss-4.6.3/tools/Dockerfiles/fedora_29000066400000000000000000000017421362106420000174100ustar00rootroot00000000000000FROM fedora:29 # Install generic dependencies to build jss RUN true \ && dnf update -y --refresh \ && dnf install -y dnf-plugins-core gcc make rpm-build \ && dnf copr -y enable ${JSS_4_6_REPO:-@pki/master} \ && dnf build-dep -y jss \ && mkdir -p /home/sandbox \ && dnf clean -y all \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Install dependencies from the spec file in case they've changed # since the last release on this platform. RUN true \ && dnf build-dep -y --spec /home/sandbox/jss/jss.spec \ && true # Perform the actual RPM build WORKDIR /home/sandbox/jss CMD true \ && bash ./build.sh --with-timestamp --with-commit-id rpm \ && dnf install -y /root/build/jss/RPMS/*.rpm \ && true jss-4.6.3/tools/Dockerfiles/fedora_29_jdk11000066400000000000000000000020731362106420000204000ustar00rootroot00000000000000FROM fedora:29 # Install generic dependencies to build jss RUN true \ && dnf update -y --refresh \ && dnf install -y dnf-plugins-core gcc make rpm-build cmake \ glassfish-jaxb-api java-11-openjdk nss-tools \ apache-commons-lang gcc-c++ java-11-openjdk-devel \ jpackage-utils slf4j nss zlib-devel nss-devel \ nspr-devel perl slf4j-jdk14 junit \ && mkdir -p /home/sandbox \ && dnf clean -y all \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Perform the actual RPM build WORKDIR /home/sandbox/jss CMD true \ && export JAVA_HOME=/usr/lib/jvm/jre-11-openjdk \ && rm -rf build \ && mkdir build \ && cd build \ && cmake .. \ && make all \ && ctest --output-on-failure \ && true jss-4.6.3/tools/Dockerfiles/fedora_30000066400000000000000000000017421362106420000174000ustar00rootroot00000000000000FROM fedora:30 # Install generic dependencies to build jss RUN true \ && dnf update -y --refresh \ && dnf install -y dnf-plugins-core gcc make rpm-build \ && dnf copr -y enable ${JSS_4_6_REPO:-@pki/master} \ && dnf build-dep -y jss \ && mkdir -p /home/sandbox \ && dnf clean -y all \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Install dependencies from the spec file in case they've changed # since the last release on this platform. RUN true \ && dnf build-dep -y --spec /home/sandbox/jss/jss.spec \ && true # Perform the actual RPM build WORKDIR /home/sandbox/jss CMD true \ && bash ./build.sh --with-timestamp --with-commit-id rpm \ && dnf install -y /root/build/jss/RPMS/*.rpm \ && true jss-4.6.3/tools/Dockerfiles/fedora_31000066400000000000000000000017421362106420000174010ustar00rootroot00000000000000FROM fedora:31 # Install generic dependencies to build jss RUN true \ && dnf update -y --refresh \ && dnf install -y dnf-plugins-core gcc make rpm-build \ && dnf copr -y enable ${JSS_4_6_REPO:-@pki/master} \ && dnf build-dep -y jss \ && mkdir -p /home/sandbox \ && dnf clean -y all \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Install dependencies from the spec file in case they've changed # since the last release on this platform. RUN true \ && dnf build-dep -y --spec /home/sandbox/jss/jss.spec \ && true # Perform the actual RPM build WORKDIR /home/sandbox/jss CMD true \ && bash ./build.sh --with-timestamp --with-commit-id rpm \ && dnf install -y /root/build/jss/RPMS/*.rpm \ && true jss-4.6.3/tools/Dockerfiles/fedora_latest_jdk11000066400000000000000000000020771362106420000214460ustar00rootroot00000000000000FROM fedora:latest # Install generic dependencies to build jss RUN true \ && dnf update -y --refresh \ && dnf install -y dnf-plugins-core gcc make rpm-build cmake \ glassfish-jaxb-api java-11-openjdk nss-tools \ apache-commons-lang gcc-c++ java-11-openjdk-devel \ jpackage-utils slf4j nss zlib-devel nss-devel \ nspr-devel perl slf4j-jdk14 junit \ && mkdir -p /home/sandbox \ && dnf clean -y all \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Perform the actual RPM build WORKDIR /home/sandbox/jss CMD true \ && export JAVA_HOME=/usr/lib/jvm/jre-11-openjdk \ && rm -rf build \ && mkdir build \ && cd build \ && cmake .. \ && make all \ && ctest --output-on-failure \ && true jss-4.6.3/tools/Dockerfiles/fedora_rawhide000066400000000000000000000021001362106420000205660ustar00rootroot00000000000000FROM fedora:rawhide # Install generic dependencies to build jss RUN true \ && dnf update -y --refresh \ && dnf install -y dnf-plugins-core gcc make rpm-build cmake \ glassfish-jaxb-api java-11-openjdk nss-tools \ apache-commons-lang gcc-c++ java-11-openjdk-devel \ jpackage-utils slf4j nss zlib-devel nss-devel \ nspr-devel perl slf4j-jdk14 junit \ && mkdir -p /home/sandbox \ && dnf clean -y all \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Perform the actual RPM build WORKDIR /home/sandbox/jss CMD true \ && export JAVA_HOME=/usr/lib/jvm/jre-11-openjdk \ && rm -rf build \ && mkdir build \ && cd build \ && cmake .. \ && make all \ && ctest --output-on-failure \ && true jss-4.6.3/tools/Dockerfiles/fedora_sandbox000066400000000000000000000026511362106420000206140ustar00rootroot00000000000000FROM fedora:rawhide # Install generic dependencies to build jss RUN true \ && dnf update -y --refresh \ && dnf install -y dnf-plugins-core gcc make rpm-build cmake \ glassfish-jaxb-api nss-tools apache-commons-lang \ gcc-c++ jpackage-utils slf4j zlib-devel perl \ slf4j-jdk14 junit ninja-build gyp gtest mercurial \ python-unversioned-command \ && dnf build-dep nss nspr jss -y \ && mkdir -p /home/sandbox \ && dnf clean -y all \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Download and build NSPR and NSS RUN true \ && cd /home/sandbox \ && hg clone https://hg.mozilla.org/projects/nspr \ && hg clone https://hg.mozilla.org/projects/nss \ && cd nss \ && ./build.sh --enable-fips --enable-libpkix \ && true # Perform the actual RPM build WORKDIR /home/sandbox/jss CMD true \ && export SANDBOX=1 \ && rm -rf build \ && mkdir build \ && cd build \ && CFLAGS="-Wall -Wextra -Werror -Og -ggdb" cmake -DCMAKE_BUILD_TYPE=Debug .. \ && make all \ && ctest --output-on-failure \ && true jss-4.6.3/tools/Dockerfiles/pkcs11check000066400000000000000000000023141362106420000177320ustar00rootroot00000000000000FROM fedora:latest # Install generic dependencies to check style RUN true \ && dnf update -y --refresh \ && dnf install -y nss nss-devel python2 python3 gcc java-devel \ && mkdir -p /home/sandbox \ && dnf clean -y all \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Generate a new PKCS11Constants.java and compare the differences WORKDIR /home/sandbox/jss CMD true \ && python2 ./tools/build_pkcs11_constants.py \ --pkcs11t /usr/include/nss3/pkcs11t.h \ --pkcs11n /usr/include/nss3/pkcs11n.h \ -o PKCS11Constants-py2.java \ && python3 ./tools/build_pkcs11_constants.py -s \ --pkcs11t /usr/include/nss3/pkcs11t.h \ --pkcs11n /usr/include/nss3/pkcs11n.h \ -o PKCS11Constants-py3.java \ && diff PKCS11Constants-py2.java PKCS11Constants-py3.java \ && diff PKCS11Constants-py3.java org/mozilla/jss/pkcs11/PKCS11Constants.java \ && true jss-4.6.3/tools/Dockerfiles/stylecheck000066400000000000000000000011721362106420000177710ustar00rootroot00000000000000FROM fedora:latest # Install generic dependencies to check style RUN true \ && dnf update -y --refresh \ && dnf install -y perl ShellCheck python2-pylint python3-pylint \ && mkdir -p /home/sandbox \ && dnf clean -y all \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Perform the style checks WORKDIR /home/sandbox/jss CMD true \ && bash ./tools/test_shell_style.sh \ && true jss-4.6.3/tools/Dockerfiles/ubuntu_jdk8000066400000000000000000000021731362106420000200770ustar00rootroot00000000000000FROM ubuntu:rolling # Install generic dependencies to build jss RUN true \ && apt-get update \ && apt-get dist-upgrade -y \ && apt-get install -y debhelper libnss3-dev libnss3-tools libnss3 \ openjdk-8-jdk pkg-config quilt g++ mercurial \ zlib1g-dev libslf4j-java liblog4j2-java \ libcommons-lang-java libjaxb-api-java cmake \ zip unzip junit4 \ && mkdir -p /home/sandbox \ && apt-get autoremove -y \ && apt-get clean -y \ && apt-get autoclean -y \ && rm -rf /usr/share/doc /usr/share/doc-base \ /usr/share/man /usr/share/locale /usr/share/zoneinfo \ && true # Link in the current version of jss from the git repository WORKDIR /home/sandbox COPY . /home/sandbox/jss # Perform the actual build WORKDIR /home/sandbox/jss CMD true \ && rm -rf build \ && mkdir build \ && cd build \ && CFLAGS="-Wall -Wextra -Werror" cmake .. \ && make all \ && ctest --output-on-failure \ && true jss-4.6.3/tools/autoenv.sh000077500000000000000000000040101362106420000154700ustar00rootroot00000000000000#!/bin/sh # This script attempts to detect the correct environmental variables required # to build JSS from source. # Try and detect a JDK installation. if [ "x$JAVA_HOME" = "x" ] && [ -e "/etc/alternatives/java_sdk" ]; then export JAVA_HOME="/etc/alternatives/java_sdk" fi if [ "x$JAVA_HOME" = "x" ]; then # Prefer JDK 8 installation, if present... java8_jdk="$(find /usr/lib/jvm -maxdepth 1 -mindepth 1 -type d | grep '\(\-8\-\|-1\.8\.\)' | sort | tail -n 1)" if [ -d "$java8_jdk" ]; then export JAVA_HOME="$java8_jdk" fi fi if [ "x$JAVA_HOME" = "x" ]; then # Attempt to automatically detect it from java program... system_java="$(java -XshowSettings:properties -version 2>&1 > /dev/null | grep 'java.home' | sed 's/^.* = //g')" dirname_system_java="$(dirname "$system_java")" if [ -e "$system_java/bin/javac" ]; then export JAVA_HOME="$system_java" elif [ -e "$dirname_system_java/bin/javac" ]; then export JAVA_HOME="$dirname_system_java" fi fi # Validate that JAVA_HOME was set; otherwise, exit. if [ "x$JAVA_HOME" = "x" ]; then echo "Unable to detect JAVA_HOME installation automatically!" 1>&2 return 1 fi # Check if we're running in 64-bit mode. if [ "x$(getconf LONG_BIT)" = "x64" ]; then export USE_64=1 fi # Check if we're in a location with nss/nspr above us; if not, use the system # versions. if [ ! -d ../nspr ] || [ ! -d ../nss ]; then export USE_INSTALLED_NSPR=1 export USE_INSTALLED_NSS=1 export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 NSPR_INCLUDE_DIR="$(pkg-config --cflags-only-I nspr | sed 's/-I//')" NSPR_LIB_DIR="$(pkg-config --libs-only-L nspr | sed 's/-L//')" NSS_INCLUDE_DIR="$(pkg-config --cflags-only-I nss | sed 's/-I//')" NSS_LIB_DIR="$(pkg-config --libs-only-L nss | sed 's/-L//')" export NSPR_INCLUDE_DIR export NSPR_LIB_DIR export NSS_INCLUDE_DIR export NSS_LIB_DIR export XCFLAGS="-g" else export USE_INSTALLED_NSPR="" export USE_INSTALLED_NSS="" fi jss-4.6.3/tools/build_pkcs11_constants.py000077500000000000000000000740751362106420000204240ustar00rootroot00000000000000#!/usr/bin/env python3 """ Copyright (C) 2018 Red Hat See licenses in base of jss repository: https://github.com/dogtagpki/jss Utility to automatically build PKCS11Constants.java from NSS's pkcs11t.h and pkcs11n.h headers. See documentation under docs/pkcs11_constants.md for more information. """ from __future__ import print_function import os import subprocess import sys import tempfile import argparse import textwrap BLACKLIST = [ 'CK_PTR', 'CK_VOID', 'CK_CALLBACK_FUNCTION', 'CK_DECLARE_FUNCTION', 'CK_DECLARE_FUNCTION_POINTER', 'CK_UNAVAILABLE_INFORMATION' ] def parse_c_value(c_value): """ Evaluates a given c numeric value and converts it to a hexadecimal value. Returns the resulting value. """ # Without introducing external dependencies, this is the best way # to parse the value of the constant. Since this step is used in a # explicitly-user-controlled environment (the user passed the paths # to the header files we parse here), this is no worse than the # user calling eval() themselves. Further, this is only run manually, # and not as part of every build, so again this should be considered # safe within our use cases and threat model. Thus, disable pylint # the warnings about eval for this function. # pylint: disable=eval-used value = eval(c_value.replace('UL', '').replace('L', '')) value = hex(value) value = value[2:].upper() value = "0x" + "0" * (8 - len(value)) + value return value class ConstantDefinition(object): """ Wrapper class to accumlate information about a constant's definition. This tracks all the information necessary to define a constant and represent its context in the ecosystem. """ # Since this is largely a data-storage class, we're bound to have too many # attributes because we're tracking metadata about the constants and their # values. Disable pylint warnings related to this. # pylint: disable=too-many-instance-attributes,too-many-arguments PREFIXES = ['CKA_', 'CKC_', 'CKD_', 'CKF_', 'CKG_', 'CKH_', 'CKK_', 'CKM_', 'CKN_', 'CKO_', 'CKP_', 'CKR_', 'CKS_', 'CKT_', 'CKU_', 'CKZ_', 'NSSCK_', 'SFTK_', 'CK_'] def __init__(self, header_file="pkcs11t.h", line_number=1, line="", name="DEFAULT", value=1): self.header_file = header_file self.line_number = line_number self.line = line.replace('/*', '/ *').replace('*/', '* /') self.name = name self.value = value self.checked = False self.resolved = False self.stdout = "" self.stderr = "" self.resolved_history = [] self.resolved_value = "" def resolve_value(self, other_constants): """ Given a list of other constants (also of type ConstantDefinition), get their values and resolve this constant's value based off of the other constants and their values. In particular, if this constant's value includes as a substring a key from other_constants, replace the occurrence with the value from the other constant. Note that other_constants must be a pre-ordered list in reverse alphabetical order. E.g., for the map { "a": "b | c", "b": "3", "c": "4"}, then "a" will eventually resolve to "3 | 4". The resolved value and the resolution chain are attached to instance variables: self.resolved_value self.resolved_history And self.resolved is set to True. """ value = self.value value_history = [] changed = True # Since we can't truly parse C in Python (or, parse C well outside of # a C compiler), we can't really parse the obj's value for tokens and # then check if the tokens match our constants and replace them. # So, we loop while the constant was changed. while changed: changed = False # One of our assertions was that other_constants was provided to # us in reverse alphabetical order. This means that the constant # "AA" is present before "A"; thus a simple loop lets us process # symbols in the expected order if they're present in this obj's # value. One example is CKT_NSS_UNTRUSTED: it has a value of # "CKT_NSS_MUST_VERIFY_TRUST", but CKT_NSS is another token; if # "CKT_NSS" is processed first, CKT_NSS_UNTRUSTED then takes # a value of "(0xCE534350)_MUST_VERIFY_TRUST" which isn't a valid # value. for obj in other_constants: if obj.name in value: # We wrap the replacement in parenthesis in case it is a # mathematical expression which needs to be parsed. These # parenthesis disappear when we compute its value later, # after we are done resolving all symbols into numeric # expressions. replacement = '(' + obj.value + ')' # Note that if the target symbol is already resolved, we # can save the steps of resolving its value again by using # its resolved value here. This has the side effect of # shortening our resolution history in verbose mode, but # that history is still all contained in the output file. if obj.resolved: replacement = '(' + obj.resolved_value + ')' value_history.append((value, obj.name, replacement)) value = value.replace(obj.name, replacement) changed = True # Pass the processed numeric expression for value into "parse_c_value" # and save it as the resolved value. try: self.resolved_value = parse_c_value(value) except Exception as e: print("Failed to parse value for constant: " + self.name, file=sys.stderr) raise e self.resolved_history = value_history self.resolved = True def check_output(self, nss_args): """ Checks the output of cc against the value of the constant in this object. This ensures that what we think the value to be is what was intended for the value to be. Raises an exception if the value differs. """ # This made an intentional design choice to run each constant's check # separately; we could've grouped several (or all) of the constants # together in one check like we did the output Java class, but this has # the downside of making detecting which symbol is incorrect harder. # Small, minimal template to check if the value differs. If it does, # this program will exit with status 1 which we detect later. This # also helps to ensure that our resolved value truly is numeric. program_template = """ #include "pkcs11t.h" #include "pkcs11n.h" int main() { if (%s != %s) { return 1; } return 0; } """ % (self.name, self.resolved_value) # Create a temporary directory; this is preserved in case of failure # such that the caller of this script can identify why it failed. temp_dir = tempfile.mkdtemp(prefix="tmp-jss-pkcs11constants-") path = os.path.join(temp_dir, "test.c") exec_path = os.path.join(temp_dir, "test.exe") temp_program = open(path, 'w') temp_program.write(program_template) temp_program.close() # Build a minimal cc call; note that nss_args is the output from # pkg-config such that we can correctly link this program and # have the correct includes for nss. cc_call = ["cc", "-o", exec_path, path] + nss_args proc = subprocess.Popen(cc_call, stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc.wait() self.stdout = proc.stdout.read() if not isinstance(self.stdout, str): self.stdout = self.stdout.decode('utf8') self.stderr = proc.stderr.read() if not isinstance(self.stderr, str): self.stderr = self.stderr.decode('utf8') if self.stdout: print("When checking symbol '%s' (stdout):" % self.name) print(self.stdout) print("\n") if self.stderr: print("When checking symbol '%s' (stderr):" % self.name) print(self.stderr) print("\n") # Check whether or not the program compiled correctly; note that # this comes after the stdout/stderr writes, so our caller can # see what the error was. ret = proc.returncode if proc.returncode != 0: raise Exception(("Unknown error with symbol '%s': cc ret: %d " + "@ %s; command: %s") % (self.name, ret, temp_dir, ' '.join(cc_call))) # Since the program compiled correctly, run it to ensure the value # is correct. ret = subprocess.call(exec_path) if ret != 0: raise Exception(("Value for symbol '%s' different from expected:" + " wasn't '%s' @ %s") % (self.name, self.resolved_value, temp_dir)) # With no errors, clean up the temporary data. if os.path.exists(exec_path): os.remove(exec_path) if os.path.exists(path): os.remove(path) if os.path.exists(temp_dir): os.rmdir(temp_dir) self.checked = True def is_included(self): """ Returns true iff name begins with an allowed prefix. """ for prefix in self.PREFIXES: if self.name.startswith(prefix): return True return False def get_source_content(self, verbose): """ Converts a value to a Java-like value in its source context. This processes the value to convert it to Java and also appends context information when verbose information has been specified. Note that if verbose is specified, the prefixed comments can differ based on whether or not system was specified and extended checks were run. """ # In particular, "source context" means in this case "comments" # and the particular java delcaration. Our constants must be of # type long because several of them exceed the value of a signed # integer and Java lacks unsigned integers. One example is # CKT_NSS which has value 0xCE534350. # We make the requirement strict here that all values are numeric # and resolved of all internal symbols. if not self.resolved: raise Exception("Must resolve all references before calling!") comment_header = "\n /**\n" comment_info = " * Content automatically generated; see NSS " comment_info += "documentation for more information.\n" comment_info += " *\n" comment_info += " * Source file: %s\n" % self.header_file # In verbose mode, output additional debugging information. if verbose: comment_info += " * Line number: %s\n" % self.line_number comment_info += " * Line: %s\n" % self.line comment_info += " * Parsed name: %s\n" % self.name comment_info += " * Parsed value: %s\n" % self.value # In verbose mode, save resolution history. This is useful for # detecting errors made during resolution. if self.resolved_history and verbose: comment_info += " *\n" for step in self.resolved_history: comment_info += (" * Resolution step: in [%s]\n" + " * replaced [%s] with [%s]\n") % step # In verbose mode, save the output of the system/cc check, if any. if self.checked and verbose: if self.stdout: comment_info += " *\n" comment_info += " * check stdout:\n" for line in self.stdout.split("\n"): comment_line = " * %s" % line.strip() comment_info += comment_line.rstrip() + "\n" if self.stderr: comment_info += " *\n" comment_info += " * check stderr:\n" for line in self.stderr.split("\n"): comment_line = " * %s" % line.strip() comment_info += comment_line.rstrip() + "\n" comment_footer = " */\n" comment = comment_header + comment_info + comment_footer # Actual definition of the constant; needs a "L" so that unsigned # values get processed correctly. source_template = " public static final long %s = %sL;\n" source_line = source_template % (self.name, self.resolved_value) return comment + source_line def read_lines(file_handle): """ Given a pointer to a file, returns contents of the file as a list, removing the trailing whitespace from all lines. """ # readlines() leaves the newline character attached, and in general, # we don't care about whitespace at the end. We care about prefixed # whitespace when reading the copyright header though, hence rstrip() # and not strip(). return list(map(lambda x: x.rstrip(), file_handle.readlines())) def parse_token(line, offset, parenthesis=True): """ From a line, parse a single "token" starting at the given character offset. The definition of a token is a continguous, non-whitespace segment of characters; parenthesis allow the token to continue over whitespace. Returns a tuple (token, index_of_last_character). In particular, "(some content)" is treated as a single token, "(something else" is an error (lacks a trailing parenthesis), and "some content" is two separate tokens. """ # Parenthesis occur when the constant is a compound expression # like in the case of CKO_NSS: (CKO_VENDOR_DEFINED | NSSCK_VENDOR_NSS). # We need the entire expression to be parsed as a single "value", # hence keeping track of parenthesis. Other symbols (such as curly # braces or square brackets) are ignored because they don't appear # in useful #define statements. token_start = offset while token_start < len(line) and line[token_start].isspace(): token_start += 1 paren_count = 0 token_end = token_start while token_end < len(line) and (not line[token_end].isspace() or paren_count != 0): if line[token_end] == '(': if not parenthesis: break paren_count += 1 if line[token_end] == ')': paren_count -= 1 token_end += 1 if paren_count != 0: raise Exception("Cannot parse line: spans multiple lines: %s" % line) token = line[token_start:token_end] return token, token_end def parse_define(line): """ Assuming that this line begins with '#define', parse the two parts of the define statement: the name of the define and the value it takes. Returns a tuple (name, value). """ if not line.startswith('#define'): raise Exception("Cannot parse line: doesn't begin with #define!\n" + line) name, name_end = parse_token(line, len('#define'), parenthesis=False) value, _ = parse_token(line, name_end, parenthesis=True) return name, value def parse_copyright(file_contents): """ In the contents of a file, find all comments before the first macro statement and include them in the returned copyright headers. """ in_comment = False copyright_headers = [] # We need to parse the copyright value for legal reasons. While in # practice the copyright could be anywhere, we assume it is in the # comments before the first macro statement in the file. This makes # an attempt to remove blank lines that are not part of a comment, # and does basic sanity checking on the locations of block comments. # This _will_ get confused as it doesn't completely parse comments, # but that confusion should be limited to later in the file, which # we ignore. for line_num in range(0, len(file_contents)): line = file_contents[line_num] have_start = "/*" in line have_end = "*/" in line have_pound = '#' in line if have_start and have_end: # In this case, both a /* and */ appeared, so we make an effort # to detect which came first and update our state accordingly. start_index = line.index("/*") end_index = line.index("*/") start_before_end = start_index < end_index and line.endswith("*/") if start_before_end: in_comment = False else: in_comment = True # Either way, save the line and hope it is a valid comment :) copyright_headers.append(line) elif have_start: # We're beginning a comment, save this line. in_comment = True copyright_headers.append(line) elif have_end: # We're ending a comment, save this line. in_comment = False copyright_headers.append(line) elif in_comment: # We're in a comment, save this line. copyright_headers.append(line) elif not in_comment and have_pound: # We're not in a comment, assume the pound means a macro # statement and exit. break # else: we're not in a comment and this is a random line, so don't # bother saving it. return "\n".join(copyright_headers) + "\n\n" def parse_header(header, verbose): """ Parse the contents of the file path (header) for #define statements and the copyright headers. The #define statements are returned as a list of items of type ConstantDefinition. The copyright header is returned as a string. """ file_contents = read_lines(header) # Capture all definitions first, and create ConstantDefinition from them. defines = [] for line_num in range(1, len(file_contents)+1): line = file_contents[line_num-1].lstrip() if line.startswith('#define'): name, value = parse_define(line) if name in BLACKLIST: if verbose: print("Skipping blacklisted constant: " + name) continue new_definition = ConstantDefinition(header.name, line_num, line, name, value) defines.append(new_definition) # Also save the copyright headers from this file for legal reasons. copyright_headers = "/* Copyright statements from %s */\n" % header.name copyright_headers += parse_copyright(file_contents) return defines, copyright_headers def remove_by_name(objs, name): """ Helper function to take a list of objects and remove the occurrences of constants with the same name, updating the list in place. This is necessary to make our list behave like an ordered set. """ # Build a list of indices where the object occurs; this should be # only one index, but we handle the case where it appears multiple # times in the list. indices = [] for index in range(0, len(objs)): obj = objs[index] if obj.name == name: indices.append(index) # Create a copy of the array and modify the copy; in particular, by # removing objects in reversed order, we can ensure that we don't # need to update the value of the indices (e.g., if we processed # the indices (1, 2, 3), we'd have to subtract one from 2 and 3 # after processing the first index (1)... this gets messy, so # processing in reverse order (3, 2, 1) ensures we don't have to. for index in reversed(sorted(indices)): objs.pop(index) def filter_objects(objs): """ From all known defined objects (of type ConstantDefinition), filter the output to only contain objects which should be included, i.e., whose name begins with a whitelisted prefix. Return the result as a new list. """ results = [] for obj in objs: if obj.is_included(): # Before appending an object, we must first remove an previous # references to it in the results list. This is mostly an issue # so that we don't have duplicate definitions in our file, but # also because some constants appear multiple times in pkcs11n.h # due to GCC deprecation hacks. remove_by_name(results, obj.name) results.append(obj) else: # It isn't an error and is merely informational to ignore some # symbols at this stage. print("Symbol ignored due to unmatched prefix: %s" % obj.name) return results def resolve_internal_references(objs): """ Resolve all internal references between symbols in objs, modifying the objects in place. That is, if SYM_A = SYM_B and SYM_B = 3 are of type ConstantDefinition, modify them so SYM_A = 3 and SYM_B = 3. This also works if the symbol names are inside the value. Note that obj.resolve_value must be passed a list of constants ordered by reverse alphabetical order on the name of the symbol. """ # To build the sorted order, we're going to use O(2n) space: first # build a dictionary mapping everything, and then construct a new # list based on the order. This isn't terribly expensive as the # objects are small and the O(n log n) sort could/should dominate. obj_map = {} for obj in objs: obj_map[obj.name] = obj sorted_objs = [] for key in reversed(sorted(obj_map.keys())): sorted_objs.append(obj_map[key]) for obj in objs: obj.resolve_value(sorted_objs) def check_references(objs): """ Perform extended checks against all known symbols; this assumes that the passed pkcs11t.h and pkcs11n.h are the system-installed version. In particular, given our current set of symbols, create a minimal C program which checks our computed value against the actual value in the header; this ensures all known symbols are parsed correctly. Depends on the following external programs being in PATH: - pkg-config - cc """ # This method just wraps calling obj.check_output() for all constants. # Print statement because this step takes a while (~30s); might as well # tell the user. :) print("Performing extended value checks...") # Such that we can link against nss and find the includes, use pkg-config. # Note that pkg-config is already a soft-dependency (it is utilized in # the README for linking against the system NSS), so using it here # isn't bad. proc = subprocess.Popen(["pkg-config", "--libs", "--cflags", "nss"], stdout=subprocess.PIPE) proc.wait() pkg_config = proc.stdout.read() if not isinstance(pkg_config, str): pkg_config = pkg_config.decode('utf8') # Make a safer argument list out of them so we don't need to fork out # to the shell. nss_args = pkg_config.strip().split(' ') for obj in objs: obj.check_output(nss_args) def build_class(objs, headers, verbose): """ From a dictionary of objects (obj_map), generate a Java class for the constants. Returns the text contents (str) of the generated class file. """ # Our generated Java class has the following structure: # # - Our Copyright and information block # - Our headers copyright blocks # - Class definition # - Constant comment # - Constant definition # - ... (repeat) # - End class definition # # Note that our result is a single string, not a list of lines. file_header = textwrap.dedent("""\ /** * PKCS11Constants.java - part of the JSS project * Copyright (C) 2018 Red Hat, Inc. * * This file is automatically generated (tools/build_pkcs11_constants.py) * from the contents of NSS's pkcs11t.h and pkcs11n.h headers. This * replaces the sun.security.pkcs11.wrapper.PKCS11Constants interface * which was removed from public visibility in JDK 9 due to the * introduction of modules. * * For more information, please see the documentation under * jss/docs/pkcs11_constants.md. * * Below are the copyright statements for the sourced files: */ """) for header in headers: file_header += header file_header += textwrap.dedent("""\ package org.mozilla.jss.pkcs11; public interface PKCS11Constants { """) file_body = "" for obj in objs: file_body += obj.get_source_content(verbose) file_footer = "}\n" return file_header + file_body + file_footer def test_compilation(file_contents): """ Given the contents of the generated Java class, try to compile it. This allows us to verify that our Java class is valid and doesn't break the build. Depends on the following programs being in the PATH: - javac """ # Since this is a stand-alone package, we don't require CLASSPATH to # include anything. # Create a temporary directory so we can create a file of the correct # name for Java, but also so that in the event of failure, the user # can view the file to see what is wrong as we haven't written it # to the output location yet. java_dir = tempfile.mkdtemp(prefix="tmp-jss-pkcs11constants-") java_path = os.path.join(java_dir, "PKCS11Constants.java") class_path = java_path.replace(".java", ".class") temp_program = open(java_path, 'w') temp_program.write(file_contents) temp_program.close() # The subprocess.call will output stdout/stderr of the called program. javac_call = ["javac", java_path] ret = subprocess.call(javac_call) if ret != 0: raise Exception("Error! Generated java code does not compile!") # If successful, clean up after ourselves. if os.path.exists(class_path): os.remove(class_path) if os.path.exists(java_path): os.remove(java_path) if os.path.exists(java_dir): os.rmdir(java_dir) def write_class(file_contents, output): """ Helper method to write the contents of the file to the specified file handle (output). """ output.write(file_contents) output.close() def parse_args(): """ Parses arguments passed to the application """ parser = argparse.ArgumentParser() # This enables the checks against a system-installed NSS; this is slow # (~30s) and is hence not enabled by default (and also not possible # against a source NSS tree without more work). However it is useful for # verifying our parsing routines. parser.add_argument("-s", "--system", action="store_true", help="pkcs11t.h is installed; perfrom system checks") # This is the path to the pkcs11t.h header file from the NSS we wish to # build against. pkcs11t.h is the main header which contains most of the # RSA/"Cryptoki" values. parser.add_argument("--pkcs11t", type=argparse.FileType('r'), required=True, help="Path to pkcs11t.h header") # This is the path to the pkcs11n.h header file from the NSS we whish to # build against. pkcs11n.h is the header which contains NSS/Netscape # specific values. parser.add_argument("--pkcs11n", type=argparse.FileType('r'), required=True, help="Path to pkcs11n.h header") # Path to output the generated file to. parser.add_argument("-o", "--output", type=argparse.FileType('w'), required=True, help="Path to write PKCS11Constants.java") # Enables verbose or debugging mode, which writes additional information # to the generated output. parser.add_argument("-v", "--verbose", action="store_true", help="Write verbose comments in output") return parser.parse_args() def main(): """ Main method for utility parser. """ args = parse_args() # The high level flow of the program is as follows: # # - Parse the pkcs11t header # - Parse the pkcs11n header # - Combine the resulting definitions in that order # - Resolve internal references/convert symbols to numeric values # - If extended checks are requested, run them # - Check that the generated class compiles # - Write the generated class as output # # The philosophy of this utility is anything that is a "warning" should # instead be treated as an error, with the exception of compiler warnings # when performing extended system checks. All exceptions are raised as # exceptions, and are not caught by this main method and thus will be # reported to the caller as the occur. This ensures that the output won't # be malformed and won't be generated unless it is correct. # # In particular: # # - All #define statements are considered constant definitions. # - If a #define cannot be parsed, this is an error. # - If a symbol value cannot be resolved to a numeric value, this is # an error. # - If a parsed value is not the same as the system version, this is # an error. # - If the resulting Java program does not compile, this is an error. t_objs, t_copyright = parse_header(args.pkcs11t, args.verbose) t_objs_filtered = filter_objects(t_objs) n_objs, n_copyright = parse_header(args.pkcs11n, args.verbose) n_objs_filtered = filter_objects(n_objs) objs = t_objs_filtered[:] objs.extend(n_objs_filtered) headers = [t_copyright, n_copyright] resolve_internal_references(objs) if args.system: # Since this is a system call, ignore the paths to the headers and # assume they are the same as what is found by pkg-config. check_references(objs) output_contents = build_class(objs, headers, args.verbose) test_compilation(output_contents) write_class(output_contents, args.output) print("Success generating constant definitions") if __name__ == "__main__": main() jss-4.6.3/tools/common_roots.sh000077500000000000000000000022441362106420000165340ustar00rootroot00000000000000#!/bin/bash # This script reads the contents of the OS CA bundle store, # /usr/share/pki/ca-trust-source/ca-bundle.trust.p11-kit # and places the contained CAs into the specified NSS DB. # # This NSS DB is used by various JSS tests that aren't enabled # by default because they require an active internet connection. nssdb="$1" if [ -z "$nssdb" ] && [ -e "build" ]; then nssdb="build/results/cadb" elif [ -z "$nssdb" ] && [ -e "../build" ]; then nssdb="../build/results/cadb" elif [ -z "$nssdb" ] || [ "x$nssdb" == "x--help" ]; then echo "Usage: $0 [/path/to/nssdb]" 1>&2 echo "" 1>&2 echo "Must provide path to NSS DB!" 1>&2 exit 1 fi if [ -e "$nssdb" ]; then rm -rf "$nssdb" fi mkdir -p "$nssdb" echo "" > "$nssdb/password.txt" certutil -N -d "$nssdb" -f "$nssdb/password.txt" trust extract --format=pem-bundle --filter=ca-anchors "$nssdb/complete.pem" # From: https://serverfault.com/questions/391396/how-to-split-a-pem-file csplit -f "$nssdb/individual-" "$nssdb/complete.pem" '/-----BEGIN CERTIFICATE-----/' '{*}' for cert in "$nssdb"/individual*; do certutil -A -a -i "$cert" -n "$cert" -t CT,C,C -d "$nssdb" -f "$nssdb/password.txt" done jss-4.6.3/tools/javadoc/000077500000000000000000000000001362106420000150645ustar00rootroot00000000000000jss-4.6.3/tools/javadoc/overview.html000066400000000000000000000003621362106420000176210ustar00rootroot00000000000000 JSS: Java Security Services

Java native interface which provides a bridge for java-based applications to use native Network Security Services (NSS). jss-4.6.3/tools/logging.properties000066400000000000000000000024661362106420000172310ustar00rootroot00000000000000# --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2020 Red Hat, Inc. # All rights reserved. # Modifications: configuration parameters # --- END COPYRIGHT BLOCK --- # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (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.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This was taken from Dogtag PKI's configuration. # See: https://github.com/dogtagpki/pki/blob/master/base/common/share/etc/logging.properties java.util.logging.ConsoleHandler.level = ALL java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter java.util.logging.SimpleFormatter.format = %4$s: %5$s%6$s%n .level = FINE .handlers = java.util.logging.ConsoleHandler jss-4.6.3/tools/reproducible_jar.sh000077500000000000000000000025271362106420000173350ustar00rootroot00000000000000#!/bin/bash # A shell script to create a reproducible jar distirbution for JSS. # # This will extract the created JSS build and normalize timestamp and file # insertion order. This will help to ensure that anyone building in the same # environment will receive the same jar file assuming the contents of Java # haven't changed. # # Usage: # reproducible_jar.sh /path/to/input.jar /path/to/tmp/dir /path/to/output.jar set -e function extract() { local jar="$1" local path="$2" if [ -d "$path" ]; then rm -rf "$path" fi mkdir -p "$path" unzip -q "$jar" -d "$path" } function normalize_timestamps() { local path="$1" find "$path" -exec touch -t 201801010000 {} + } function add_manifest() { local path="$1" local output="$2" pushd "$path" >/dev/null zip -X -q "$output" "META-INF" zip -X -q "$output" "META-INF/MANIFEST.MF" popd >/dev/null } function add_classes() { local path="$1" local output="$2" pushd "$path" >/dev/null for file in $(find "org" | sort); do zip -X -q "$output" "$file" done popd >/dev/null } abs_jar="$(realpath "$1")" abs_path="$(realpath "$2")" abs_output="$(realpath "$3")" extract "$abs_jar" "$abs_path" normalize_timestamps "$abs_path" add_manifest "$abs_path" "$abs_output" add_classes "$abs_path" "$abs_output" jss-4.6.3/tools/run_container.sh000077500000000000000000000040201362106420000166560ustar00rootroot00000000000000#!/bin/bash # This tool attempts to detect the presence of various tools to run the CI # images. If present, it'll use them to run the specified container image. function rc_buildah() { buildah_path="$(command -v buildah)" podman_path="$(command -v podman)" [ "x$buildah_path" != "x" ] && [ "x$podman_path" != "x" ] } function rc_docker() { docker_path="$(command -v docker)" [ "x$docker_path" != "x" ] } function rc_run() { local image="$1" local ret=0 if [ ! -f "tools/Dockerfiles/$image" ]; then echo "Error: tools/Dockerfiles/$image is not a file; must be an" 1>&2 echo "existing location to launch container." 1>&2 exit 1 fi if rc_buildah; then buildah bud --tag "jss_$image:latest" -f "tools/Dockerfiles/$image" . ret="$?" if [ "x$ret" != "x0" ]; then echo "Container build exited with status: $ret" return $ret fi podman run "jss_$image:latest" ret="$?" if [ "x$ret" != "x0" ]; then echo "Container run exited with status: $ret" return $ret fi elif rc_docker; then docker build --tag "jss_$image:latest" -f "tools/Dockerfiles/$image" . ret="$?" if [ "x$ret" != "x0" ]; then echo "Container build exited with status: $ret" return $ret fi docker run "jss_$image:latest" ret="$?" if [ "x$ret" != "x0" ]; then echo "Container run exited with status: $ret" return $ret fi else echo "No supported container platform; please rerun with podman" 1>&2 echo "and buildah or docker installed." 1>&2 fi } if [[ "x$1" =~ "help" ]] || [ "x$1" = "x-h" ]; then echo "Usage: $0 " 1>&2 echo "" 1>&2 echo "Run the container task using buildah+podman or docker" 1>&2 echo "Note: must be the name of a file located under" 1>&2 echo " tools/Dockerfiles in the main repo." 1>&2 exit 0 fi rc_run "$1" jss-4.6.3/tools/run_test.sh.in000077500000000000000000000014011362106420000162600ustar00rootroot00000000000000#!/bin/bash # This utility gets templated to build/run_test.sh to help with running a # single test after building JSS. This gives the caller more flexibility # with command line arguments and ensures that the correct build artifacts # get used. export LD_LIBRARY_PATH="${NSS_LIBRARIES}:${CMAKE_BINARY_DIR}:${NSPR_LIBRARIES}" if [ "$1" == "--gdb" ]; then shift gdb --args "${Java_JAVA_EXECUTABLE}" -classpath "${TEST_CLASSPATH}" -ea -Djava.library.path="$LD_LIBRARY_PATH" "$@" elif [ "$1" == "--valgrind" ]; then shift valgrind "${Java_JAVA_EXECUTABLE}" -classpath "${TEST_CLASSPATH}" -ea -Djava.library.path="$LD_LIBRARY_PATH" "$@" else "${Java_JAVA_EXECUTABLE}" -classpath "${TEST_CLASSPATH}" -ea -Djava.library.path="$LD_LIBRARY_PATH" "$@" fi jss-4.6.3/tools/test_python_style.sh000077500000000000000000000010331362106420000176110ustar00rootroot00000000000000#!/bin/sh set -e # # Usage: # test_python_style.sh [path] # # Tests the style of Python scripts in the build tree for compliance with pylint # guidance. Runs: # # pylint # # On all checked files. If [path] is specified, assumed to be the root of the # jss repository. Otherwise, defaults to `pwd`. # root_source_dir="$1" if [ "x$root_source_dir" = "x" ]; then root_source_dir="$(pwd)" fi python_check() { target_file="$1" pylint "$root_source_dir/$target_file" } python_check "tools/build_pkcs11_constants.py" jss-4.6.3/tools/test_shell_style.sh000077500000000000000000000016051362106420000174040ustar00rootroot00000000000000#!/bin/sh set -e # # Usage: # test_shell_style.sh [path] # # Tests the style of shell scripts in the build tree for compliance with strict # guidance. Runs: # # `shellcheck ` # # On all checked files. If [path] is specified, assumed to be the root of the # jss repository. Otherwise, defaults to `pwd`. # root_source_dir="$1" if [ "x$root_source_dir" = "x" ]; then root_source_dir="$(pwd)" fi shell_check() { target_file="$1" shellcheck -x "$root_source_dir/$target_file" if [ ! -x "$root_source_dir/$target_file" ]; then echo "$root_source_dir/$target_file must be executable!" return 1 fi echo "$root_source_dir/$target_file OK" } shell_check "build.sh" shell_check "tools/autoenv.sh" shell_check "tools/reproducible_jar.sh" shell_check "tools/run_container.sh" shell_check "tools/test_python_style.sh" shell_check "tools/test_shell_style.sh"